Legacy GM How can I prevent items from respawning after death? (SOLVED)

L

Linkruler

Guest
So I asked this question before back on the old GameMaker forums, but it seems it was lost in the transition (correct me if I'm wrong). I am making an action platforming game right now with many collectibles like coins and health pickups. When they are collected, each instance is destroyed, but when the player dies and respawns, they return back due to the room being reset upon death. What is the best method to prevent things from reappearing without creating multiple of the same object?

Please let me know if there is any code I need to provide to help deliberate this problem
 

obscene

Member
due to the room being reset upon death
Just don't do this!

Now if you go to a different room and come back your room would need to be set to persistent.

If you need to save this stuff for a save / load system that's an entirely different problem but assuming you don't need that as you didn't mention it.
 
L

Linkruler

Guest
Just don't do this!

Now if you go to a different room and come back your room would need to be set to persistent.

If you need to save this stuff for a save / load system that's an entirely different problem but assuming you don't need that as you didn't mention it.
Well, I was still wanting the room to be reset so enemies respawn and the boss health can be reset. Setting my room to persistent also messes with how I reset the room if the player returns to he main menu mid-level and restarts the game.
 

Focksbot

Member
In the create event for each of these items, you could have it test a variable to see if an item in this location was picked up in the previous life, then destroy it if it has.

I suppose that would mean needing a separate variable for each item in the room though - very tedious.
 
N

Never Mind

Guest
I was trying to think about different ways to implement it. There are tons.

You could have a persistent object that is created at Game Start.
I'll call mine
obj_persistent:
Create Event
Code:
foundList = ds_list_create();
Alarm Zero Event
Code:
for(i=0; i<ds_list_size(foundList); i++;){ //loop through the list
with( ds_list_find_value(foundList,i) ){ 
instance_destroy(); 
}
}
Room Restart Event
Code:
alarm[0] = 1;
Game End Event
Code:
ds_list_destroy(foundList);
---------------------------------------

You could then add code to either the items Destroy Event, or to their parents Destroy Event.
Code:
with(obj_persistent){
ds_list_add(foundList,other.id);
}
This assumes that the instance id's stay the same It's just an idea to get you thinking anyway.
Choosing what to do depends on how you have things set up and how you want them.
 
Last edited by a moderator:
L

Linkruler

Guest
Alright, so I translated this information over to my game and it doesn't seem to be doing much. I put the room restart event code into a room start code though, since I could not find the option for a room restart event. I made sure the object was placed in the room and the code that is to be added to the destroy event was applied before the instance_destroy() line of code.

If you don't mind me asking, I would love a little bit of explanation to your thinking of the code in the alarm event. I'm still learning, so I'd love to understand what's going on there
 
You might want to watch my tutorial on using a ds_map to save the states of certain things placed in your room. I think it could be a helpful system for you.

 
N

Never Mind

Guest
^This! For sure.
Anyway, I will give you a little more insight into the hodge-podge idea I wrote up.

I did make up the Room Restart Event . :p Sorry.
You tried putting code into the Room Start Event, but instead I would try to make the same thing happen wherever you currently call: room_restart()
A with() construction could come in handy, I'd read that page in the manual. You could also probably do something like: obj_persistent.alarm[0] = 1;

The idea goes as follows:---------------------------------------------------------------------------------------
In the beginning, we create a persistent controller that stores a list. At first the list is empty.

We assume that when you pick up an item, it's instance in the room gets destroyed.
So at some point when that happens ( it could be where it calls instance_destroy(), in it's Destroy Event, or it's parents Destroy Event ) we need to add the items id to the controllers list.

Later when you restart the room, we need to make sure the controllers Alarm Zero is to 1 so it waits a step. Once the room is loaded we can loop through the list and destroy instances with those id's.

The controller is persistent so it remembers the destroy list even if the room is restarted.
--------------------------------------------------------------------------------------------------------------------------

I usually go through a process of trial and error, so I wasn't trying to claim this idea would work straight out.
There are more things to consider with this solution, and that's why I agree with studying and going through a polished tutorial.
PixelatedPope is dope, I'm subscribed.

Issues with my idea I've thought about:
We need to make sure not to create the persistent controller at Room Start!
Or to drop it into a room in the Room Editor! (unless it's a menu / start room that's only visited once)

There are two reasons for this:
1) If you visit the room more than once, it will create duplicate controllers.
2) If the room restarts, it might throw off the numbers that instances in the room are given as id's. Then the list could store the wrong (or non existing) instances to destroy.

This idea also doesn't remember items you picked up in other rooms. Make sure to ds_list_clear() the list when you switch rooms.
 
Last edited by a moderator:
L

Linkruler

Guest
Ah okay, that makes more sense now, thanks!

So looking at Pixelated_Pope's tutorial is helping me grasp this a lot more. I understand everything that's going on, yet the only issue I'm having now is that my game is still crashing. For some reason, GameMaker will not find the variable I have in obj_game_manager (which I named obj_despawn for my game). This is the crashing log I've gotten, even after following the video:

Variable obj_despawn.<unknown variable>(100064, -2147483648) not set before reading it.
at gml_Object_obj_coin_CreateEvent_1 (line 6) - var _save_data = ds_map_find_value(obj_despawn.save_data,key)
 
L

Linkruler

Guest
So I'm considering changing it from a local variable into a global variable (global.save_data) so it could be called properly. Would that be an acceptable way to solve this issue or is there a better way to handle this?

EDIT: I tried doing this, and it seemed to work at first! but after a second death it seemed to undo the work of the first death to make room for the second.

Here's my example:

This is how the coins normally look:



I collect the front two and then die:



I collect the other two and then die again:

 
Last edited by a moderator:

obscene

Member
You might want to watch my tutorial on using a ds_map to save the states of certain things placed in your room. I think it could be a helpful system for you.

I love this tutorial. I hacked away at my own system a long time ago and I hate it and would love to redo it. If I did this would be the way.
 
N

Never Mind

Guest
It looks like you might be clearing the map accidentally / re-creating it at the start of the room.

@obscene agreed.
I would much rather point to a solid tutorial (especially video) than confuse the situation trying to explain a half baked idea.
 
Last edited by a moderator:
L

Linkruler

Guest
So would that be caused by having obj_despawn placed in the room? Since the command is in a create event I could see how that would be the reason

EDIT: I think I finally fixed my problem. Instead of using obj_despawn, as it was solely there to initialize the variable, I instead put it in my initialization room's creation code. I don't seem to be having any issues yet, so I think it should be good! Thank you everyone for your help, I appreciate it :)
 
Last edited by a moderator:
Top