Game restart clear lists

S

Stealthy Panda

Guest
My code has a game room, and one of the objects in it has two ds_lists.

In order to avoid memory leaks (correct me if I'm wrong), I'm deleting the lists when the room is left.

To avoid memory leaks, do I also have to delete these lists when I call room_restart and game_restart? Thanks.
 
You don't need to clear the lists for the same reason you don't need to delete variables when changing room.
Ah...if only this were true, unfortunately it doesn't apply to data structures (anything starting with ds_ )

The data structures in Game Maker are dynamically allocated and do not delete themselves.

So you should definitely make sure that you are always cleaning them up, even on room_restart and game_restart (generally speaking).

I would personally recommend not using room_restart and game_restart, you should control the flow of your game manually using room_goto() most of the time.

Depending on your game of course. If you have a global persistent object that you only create once at the start of the game in an initialisation room, and it is holding the ds_lists, you can probably get away with not having to delete them and re-create them on a room_restart.

On a game_restart, when everything is thrown away and started from the beginning, you definitely would have to destroy those lists because you game would be restarting from the original initialisation room (in my example above) and you would get memory leaks.
 

Dupletor

Member
Sorry, I was mislead by the Debug feature losing track of all the references... I assumed they were automatically freed, because their references and all the content disappear when I change room. Good to know they aren't.

Well, got some stuff to fix, then. :p

Edit:

OOOOH...
The way I use ds_lists is convenient for the case, they eventually get clean after use, and start waiting for more content. The ones that don't behave like this are the ones that are global. This is why I never noticed a difference from not leaking memory, I was leaking almost zero memory, no matter how much stuff I put into the lists. haha.


Destroyed all the references anyway. The game now consumes 30 bytes less RAM after accessing every room once. :p
 
Last edited:
Sorry, I was mislead by the Debug feature losing track of all the references... I assumed they were automatically freed, because their references and all the content disappear when I change room. Good to know they aren't.
The variable that was indexing the ds_list indeed disappears, however the content does not.

Yeah, so what happens is, when you create a ds_list for example, you get in return an integer id that you need to keep track of.

e.g. :

my_list = ds_list_create() // my_list now equals 0 ( for example ).

So now, we have a ds_list floating around in memory that GMS is keeping track of internally, and which you can access using the id/index of 0.

So you could now actually write:

ds_list_add(0, "some_data")

and it will add it to the list that you created above.

Let's say the variable my_list was in an instance that you created in room0, and then you moved to room1 and the instance was destroyed, along with its variable "my_list". It appears as if you have lost track of the DS...and maybe it has been destroyed....but wait...

NOTE : The important bit is, even if the variable holding the id of the data structure is destroyed, the data structure is still in memory, and can even be re-accessed if you still know what its id was.

The data structure still exists, and you can still access it with the id of 0.

You could even assign the number 0 to new variable, then use that new variable to access the list.

my_old_list = 0

ds_list_add(my_old_list, "some_more_data")

OR

my_old_list[| 0] = "replace some data at position 0 in list"

NOTE 2: Think of the data structure id that you get when you create a ds_list as an "index" ( a simple integer number ) as opposed to a pointer or a reference (if you are coming from a non-memory managed language like C/C++).

The DS exists independently of the variable that is holding the index.

It's like if I asked for your home address, and you wrote it down for me on a piece of paper. (The address is the index to the DS, the piece of paper is the variable holding that index)

If I throw that piece of paper away, your house still exists. The variable and the index have gone, but your house (the DS) is certainly still there.
 
I

icuurd12b42

Guest
the room end event is called when you leave the room, when quit, when you restart the room and when you restart the game so you dont need to catch any other event. creating the lists on room start (or in the create event) and freeing it on room end is perfect

there is also a clean up event which I think is also called when the instance is removed from memory which should also happen in those same scenarios...
 

Dupletor

Member
I always assumed there was a default Clean Up event that got rid of ds created by an instance. Which is true then?

The documentation does say it exists and what it is for, that does not mean there is a default one that does its job correctly. It could be a space for developers to make their own Clean Up event and that does nothing unless the code is created.

In that case, all dynamic structures must be destroyed nevertheless.

https://docs2.yoyogames.com/source/_build/2_interface/1_editors/events/index.html
Clean Up event:
"This event will be called after any event that removes an instance of the object from the room. So, it will be triggered if the instance is destroyed, if the room ends, or if the game ends, and is designed for you to use to "clean up" any dynamic resources that you may have in your game (like surfaces, data structures, etc...) or to perform any task that you need performed once when the instance is removed. Note that this event will be called only after every other event has been called, so it will always be the last event to run in any instance as it is removed from the room or the room/game is ended."
 
It could be a space for developers to make their own Clean Up event and that does nothing unless the code is created.
Yes, its just a blank event for us to use.

I read somewhere that the Destroy Event is not called in some situations (e.g., Room End), so it was inconsistent to use it for cleaning up objects.

Previously I would call instance_destroy() on Room End to insure that the Destroy Event was called, because all my clean up code was in the Destroy Event.

The Clean Up event was created because it is always called when the object is removed from memory, so you can safely put all the code for deleting lists etc... in it and be sure it will be run.
 

Dupletor

Member
Edit:

By the time I wrote this I was sure Destroy Event is called on every instance when you change rooms, at least when there are less than 40 objects in room.

HOWEVER, it is WRONG. It is NOT called.
 
Last edited:
Just to check, as I have not done this experiement for a while, I made a test project. GMS 2 v2.1.3.273, runtime v2.1.3.189

I created an object, and I put a show_debug_message() in the Room Start/Room End/Game Start/Game End/Destroy/Clean Up events.

I created two rooms, and placed a single instance of the object in both rooms.
Object is not persistent.

The object has debug keys for room_restart()/game_restart()/room_goto() and instance_destroy()

I'll list the Events that were called when I ran each function:
room_restart()
ROOM END
CLEANUP
ROOM START

room_goto()
ROOM END
CLEANUP
ROOM START

game_restart()
ROOM END
GAME END
CLEANUP
GAME START
ROOM START

instance_destroy()
DESTROY
CLEANUP

So from my tests, the Destroy Event is never called on the instance unless I have actually explicitly used the instance_destroy() function.

Cleanup was always called, hence its usefulness.

Please correct me if I'm mistaken! But this is the behaviour I'm seeing here.
 
I

icuurd12b42

Guest
Just to check, as I have not done this experiement for a while, I made a test project. GMS 2 v2.1.3.273, runtime v2.1.3.189
...
Cleanup was always called, hence its usefulness.

Please correct me if I'm mistaken! But this is the behaviour I'm seeing here.
Yes that sounds right as I mentioned. it is weird with the game end being called first though... not that it matters since you should not use this "windows only" event
Why having a destroy event and a clean up event now in GMS2? Legacy?
Yoyo found that having a dedicated clean up event would be useful because the destroy event is only called when an instance is destroyed... which does not happen unless you call instance destroy()

where as the cleanup event is called when the instance is cleaned up from the game. you could consider this equivalent to the ~destructor() function in c++. The name is misleading unless you consider the internals.
 

RangerX

Member
Yeah I see what you mean. But I was more where if I want to destroy something, I want that event to play anyways and the clean up to happen. Clean up was transparent before and now there's an event for it.
That doesn't change much things in the grand scheme of things and renders the destroy event quite useless. If I don't want something to happen when the instance is destroyed, I put nothing in the clean up event. If I want something to happen, I put something in the clean up event.
 
I

icuurd12b42

Guest
Problem is a lot of people naively put effects in the destroy event, turning the destroy event into more of a "on AI or Player dies" event... and in the long run such code would interfere with cleaning up data associated with the instance in a way that is not really obvious in most circumstances...

Such circonstance is when you make your own level editor with "In Editor" semi active instances, where you need to delete the instance from the the level, you can't have them show special effects when you edit the level. Such a feature (live instances in room editor) may actually become part of the Game Maker UI one day


So, they added a cleanup event and they changed instance_destroy to allow not calling the destroy event, see the Arguments section. that way you can have data management properly implemented while allowing the destroy event being used in the way many (mis)use it....
 

Dupletor

Member
Just to check, as I have not done this experiement for a while, I made a test project. GMS 2 v2.1.3.273, runtime v2.1.3.189

So from my tests, the Destroy Event is never called on the instance unless I have actually explicitly used the instance_destroy() function.
Edit:
I need to make a test, I forgot one line in my code that might be the source of the confusion.
If it works when I remove it, then the destruction event is called. If it doesn't, then it's not.
If it's there and I don't remember it, it probably doesn't work without it.
 
Last edited:

Dupletor

Member
Confirmed. There was a line of code that made the system independent from the Destructor when the room was swapped, and the Destructor is NOT called when room is changed.
Sorry, my mistake again. haha

It's funny how you can make systems work in GMS without even being sure of what events are being executed, as soon as you give enough redundance to global variables manipulation and independence to objects behavior.
 
Last edited:
Top