Windows Question about creating and deleting ds_lists

Zuljaras

Member
I need some information from knowledgeable people :)

I have the following code:

Object with:

CREATE EVENT:
Code:
hit_by = ds_list_create();
ROOM END EVENT:
Code:
if room_persistent == false
    {
        hit_by = ds_list_create();
        ds_list_destroy(hit_by);
        show_debug_message("THE DS LIST IS DELETED!!!")
    }
So does the ds_list exist 2 times and I delete only one or the ds_list is overridden and there is ONLY ONE ds_list hit_by and it is cleared properly so I would not have memory leak?

Thanks in advance!
 

rIKmAN

Member
I need some information from knowledgeable people :)

I have the following code:

Object with:

CREATE EVENT:
Code:
hit_by = ds_list_create();
ROOM END EVENT:
Code:
if room_persistent == false
    {
        hit_by = ds_list_create();
        ds_list_destroy(hit_by);
        show_debug_message("THE DS LIST IS DELETED!!!")
    }
So does the ds_list exist 2 times and I delete only one or the ds_list is overridden and there is ONLY ONE ds_list hit_by and it is cleared properly so I would not have memory leak?

Thanks in advance!
You are losing the handle to the first list by overwriting it with the handle to the second list, meaning you now have no way of accessing the first list anymore and so will cause a memory leak as you now have no way of deleting that first list.

ie. The first list still exists in memory, but your "hit_by" variable doesn't point to it anymore as it now points to the second list you created and assigned to the same variable.
 

Zuljaras

Member
You are losing the handle to the first list by overwriting it with the handle to the second list, meaning you now have no way of accessing the first list anymore and so will cause a memory leak as you now have no way of deleting that first list.

ie. The first list still exists in memory, but your "hit_by" variable doesn't point to it anymore as it now points to the second list you created and assigned to the same variable.
Ok this is not good!

When I am loading a game I get a crash that my ds_list is NOT defined. Even if I try ds_exist(hit_by, ds_type_list) does NOT work.
I do not know how to make it so the ds list is deleted only if it is created. I get a crash either way.
 

Zuljaras

Member
If you want the list to go back to being empty, you use ds_list_clear(list_id), you don't create a new list.
The problem is that if I load the game the create event of the enemy is NOT executed and the ds_list is not existing. And in the room_end event I get the crash. Even if I use ds_exist(hit_by, ds_type_list) I still get a crash!
 
This depends on so many things. What do you mean by loading? Do you mean literally just running the game, or have you created a save/load system and the error occurs when you are loading from that system. The reason you are getting the error is because the variable itself hit_by has not been defined, so you cannot even check if it is a ds_list or not. We need a lot more info about what is going on before we can help. If you have a save load system, describe how it works and post some code from the loading section.
 

rIKmAN

Member
The problem is that if I load the game the create event of the enemy is NOT executed and the ds_list is not existing. And in the room_end event I get the crash. Even if I use ds_exist(hit_by, ds_type_list) I still get a crash!
Then you should check if the enemy exists before trying to delete a list it contains - you can't delete something that doesn't exist.
 

Zuljaras

Member
This depends on so many things. What do you mean by loading? Do you mean literally just running the game, or have you created a save/load system and the error occurs when you are loading from that system. The reason you are getting the error is because the variable itself hit_by has not been defined, so you cannot even check if it is a ds_list or not. We need a lot more info about what is going on before we can help. If you have a save load system, describe how it works and post some code from the loading section.
Yes I have load and save system using ini files.

The thing is that when I load the game I go to the first room of the game and if loading is true I go to the room that I am supposed to.

The problem is that the zombie create event is not initializing before the create event of the control object :(
 

rIKmAN

Member
Well it exists if the room_end event is executing in its code right?
Yes, but you also said...
The problem is that the zombie create event is not initializing before the create event of the control object
...which sounds like you are trying to access the zombie object from the control object before the zombie object has been created - in which case you should check if it exists before trying to access it.

If that isn't the case, then as RefresherTowel said you'd to explain it more clearly and post more code, along with the exact error message(s).
 

Zuljaras

Member
Yes, but you also said...

...which sounds like you are trying to access the zombie object from the control object before the zombie object has been created - in which case you should check if it exists before trying to access it.

If that isn't the case, then as RefresherTowel said you'd to explain it more clearly and post more code, along with the exact error message(s).
Yes this is the weird part. I am not trying to access the zombie object from another object. I am simply creating a DS list in the create event of the Zombie and then deleting the list in the room_end event.
In the control object I state that if the game is loading (I have a global.loading == true) to load all the variables and then go to the next room from the ini file.
Somehow the create event of the zombie is not initializing but its room_end is.
 

rIKmAN

Member
Yes this is the weird part. I am not trying to access the zombie object from another object. I am simply creating a DS list in the create event of the Zombie and then deleting the list in the room_end event.
In the control object I state that if the game is loading (I have a global.loading == true) to load all the variables and then go to the next room from the ini file.
Somehow the create event of the zombie is not initializing but its room_end is.
Are you sure the error message is coming from the zombie objects Room End Event?
That sounds more like you may be trying to access the zombie object during your loading code when it doesn't exist.

If you remove the loading code and just change rooms normally do you get the same error?
 

Zuljaras

Member
Are you sure the error message is coming from the zombie objects Room End Event?
That sounds more like you may be trying to access the zombie object during your loading code when it doesn't exist.

If you remove the loading code and just change rooms normally do you get the same error?
No. I do not get the error when I am just moving from room.
And I am sure because the crash code is telling me that it is from the room_end event of the Zombie object.

This issue is probably because some events are executed before others.
 
If you have created an instance, it's Create Event code will run, therefore it will have a ds_list tied to a variable called hit_by if you have that in the Create Event. Room End Event will not run before Create Event. What rIKmAN is saying is probably what is going on. You have made an error in the way you are handling your code, that's why I said we need to see it.
 

rIKmAN

Member
No. I do not get the error when I am just moving from room.
And I am sure because the crash code is telling me that it is from the room_end event of the Zombie object.

This issue is probably because some events are executed before others.
Try doing the actual room change in an alarm with a delay of a few steps.

Even if that works I would still look at organising your code a bit better to prevent issues like this from happening in future.
If it doesn't then you need to post more information and code so we can try and work out what might be happening as there isn't really a lot to go on.
 

Zuljaras

Member
If you have created an instance, it's Create Event code will run, therefore it will have a ds_list tied to a variable called hit_by if you have that in the Create Event. Room End Event will not run before Create Event. What rIKmAN is saying is probably what is going on. You have made an error in the way you are handling your code, that's why I said we need to see it.
So.

I have a control object that in its CREATE event has this:
Code:
if global.loading=true && global.saveslot=1 {script_execute(scr_load); };
This object is in the first PLAYABLE room with my main character.

In this room I have 2 zombies that must have ds lists:

Now their lists are creating in the Room start event like this:
Code:
if room_persistent == false
    {
        hit_by = ds_list_create();
    }
And it is deleted in their room_end event:
Code:
if room_persistent == false
    {
    
        if !ds_exists(hit_by, ds_type_list)
            {
                hit_by = ds_list_create();
            }
        ds_list_destroy(hit_by);
        show_debug_message("THE DS LIST IS DELETED!!!")
    }
I managed to fix the issue by changing in the control object create event to alarm[0]=1;
and in alarm[0] I put the loading of the load script.

I hope this is enough to continue working on the game :D
 

Zuljaras

Member
Try doing the actual room change in an alarm with a delay of a few steps.

Even if that works I would still look at organising your code a bit better to prevent issues like this from happening in future.
If it doesn't then you need to post more information and code so we can try and work out what might be happening as there isn't really a lot to go on.
The issue was that the create code of the loading script is executed before everything else. I guess script execute was the cause of the issue and that is why I am now creating it with 1 mil second delay.
 
Room Start Event and Create Event are not synonymous. If you are creating instances from another object that exists in the room, only the first object will have it's Room Start Event code run. This is because the room only starts once and it only takes 1 frame to do, so if an instance doesn't exist in that one frame, it will not trigger it's own Room Start Event.
 

Zuljaras

Member
Room Start Event and Create Event are not synonymous. If you are creating instances from another object that exists in the room, only the first object will have it's Room Start Event code run. This is because the room only starts once and it only takes 1 frame to do, so if an instance doesn't exist in that one frame, it will not trigger it's own Room Start Event.
I get it now.

I just changed the ds creation list in the zombie create event and it still works when loading because now I execute the load script with 1 mil second delay.

I don't even see the starting room but there are no errors.
 

rIKmAN

Member
The issue was that the create code of the loading script is executed before everything else. I guess script execute was the cause of the issue and that is why I am now creating it with 1 mil second delay.
I had a feeling a delay might solve the issue, but issues like this are why you should try to keep your code organised and try and understand the order things are going to be run in based on where and how you have created them.

A couple of other things:

Why do you start the first playable room before deciding whether to load or not?
This would be better in an init room or loading room before you get to the first playable level and would prevent having to worry about any existing instances in a level that won't even get played.

In the Room End code you posted, you create a list if it doesn't exist only to delete it again straight away?
Hopefully it's just a remnant of you trying to debug the error you were getting.

Glad you got it sorted anyway.
 

Zuljaras

Member
I had a feeling a delay might solve the issue, but issues like this are why you should try to keep your code organised and try and understand the order things are going to be run in based on where and how you have created them.

A couple of other things:

Why do you start the first playable room before deciding whether to load or not?
This would be better in an init room or loading room before you get to the first playable level and would prevent having to worry about any existing instances in a level that won't even get played.

In the Room End code you posted, you create a list if it doesn't exist only to delete it again straight away?
Hopefully it's just a remnant of you trying to debug the error you were getting.

Glad you got it sorted anyway.
Yes this is only to debug it.

However I must start the first room because otherwise I will get error that my room does not exist.

My loading ini file is the following:
Code:
if file_exists("zulcon.sav")
{
global.damage_max=true;
global.damage=true
global.manapoints_max=40
global.manapoints=40
global.doublejumppermission=false
global.potion_storage=0
global.mana_potion_storage=0
global.weapon=1
global.armor=0
global.enchantment=0
global.accessory=0
global.spell=0
global.playermove=true
global.paused=false
global.playerlevel=1
global.experience=0
global.experiencelvlup=100
global.souls=0
global.relic=0
ini_open("zulcon.sav");
playero.x=ini_read_real("data","x",playero.x);
playero.y=ini_read_real("data","y",playero.y);

global.damage_max=ini_read_real("h","p",global.damage_max);
global.damage=ini_read_real("hh","pp",global.damage);
global.doublejumppermission=ini_read_real("dd","jj",global.doublejumppermission);
for(i = 0;i < 1000;i += 1)
global.used[i] = ini_read_real("arr", "aray"+string(i) ,0);

for(i = 0;i < 1000;i += 1)
global.map[i] = ini_read_real("mpp", "ppm"+string(i) ,0);

global.player_position=ini_read_real("p","p",global.player_position);
global.playerlevel=ini_read_real("p","l",global.playerlevel);
global.experience=ini_read_real("e","x",global.experience);
global.experiencelvlup=ini_read_real("e","l",global.experiencelvlup);
global.souls=ini_read_real("s","l",global.souls);
global.potion_storage=ini_read_real("hp","s",global.potion_storage);
global.mana_potion_storage=ini_read_real("mn","s",global.mana_potion_storage);
global.weapon=ini_read_real("we","p",global.weapon);
global.armor=ini_read_real("a","r",global.armor);
global.accessory=ini_read_real("ac","c",global.accessory);
global.spell=ini_read_real("s","pe",global.spell);
global.manapoints_max=ini_read_real("ma","ps",global.manapoints_max);
global.manapoints=ini_read_real("ma","na",global.manapoints);
global.zombiebuttonactive=ini_read_real("zm","bt",global.zombiebuttonactive);
global.halfzombiebuttonactive=ini_read_real("hzm","bt",global.halfzombiebuttonactive);
global.skeletonbuttonactive=ini_read_real("sc","bt",global.skeletonbuttonactive);
global.axearmorbuttonactive=ini_read_real("ax","bt",global.axearmorbuttonactive);
global.skulltrapbuttonactive=ini_read_real("st","bt",global.skulltrapbuttonactive);
global.sludgefiendbuttonactive=ini_read_real("sl","bt",global.sludgefiendbuttonactive);
global.killerplantbuttonactive=ini_read_real("kp","bt",global.killerplantbuttonactive);
global.skeletonknightbuttonactive=ini_read_real("sck","bt",global.skeletonknightbuttonactive);
global.active_spectralblade=ini_read_real("sb","bt",global.active_spectralblade);
global.deathshop=ini_read_real("de","sh",global.deathshop);
global.boss1dead=ini_read_real("bs","1",global.boss1dead);
global.sword_active=ini_read_real("sw","ac",global.sword_active);
global.dagger_active=ini_read_real("dg","ac",global.dagger_active);
global.greatsword_active=ini_read_real("gs","ac",global.greatsword_active);
global.twilightsfang_active=ini_read_real("twf","ac",global.twilightsfang_active);
global.mace_active=ini_read_real("mc","ac",global.mace_active);
global.leatherarmor_active=ini_read_real("la","ac",global.leatherarmor_active);
global.gladiatorsarmor_active=ini_read_real("ga","ac",global.gladiatorsarmor_active);
global.skullring_active=ini_read_real("sr","ac",global.skullring_active);
global.dagger_active=ini_read_real("dg","ac",global.dagger_active);
global.gragbuttonactive=ini_read_real("grg","bt",global.gragbuttonactive);
global.towerbootstaken=ini_read_real("twr","bts",global.towerbootstaken);
global.relic=ini_read_real("rl","rll",global.relic);

global.new_game_plus=ini_read_real("nnn","ppp",global.new_game_plus);

room=ini_read_real("savrm","rm",room);
ini_close();
}
The last line before closing the ini is the room that I have saved in. I need my main character and the control objects to be created before moving to the room.
They are persistent and they are in the first playable room.

After I know that I will use the script I start the game go to the first playable room. Then if I have a load script file I load it in the alarm event of the control object that was in its create event before.

I know my system is not very good but it is working.

I also moved the initialization of my global variables to an object in the initialization room of the game before the logo/credits. That could save me some troubles.
 
Last edited:

rIKmAN

Member
I know my system is not very good but it is working.
Fair enough and as long as it's working sometimes that's the main thing.
We've all been through that stage where we look back at old code written when we were learning and now know how to rewrite it better, cleaner, more optimised etc.

Take it or leave it and this is very much an individual preference, but I would suggest you start using some spaces and indentation in your code.
It will make it so much more readable and help you catch bugs later just from being laid out in a visually cleaner and nicer way and is a good habit to get into along with semi-colons (which can cause issues with YYC if not used).

Good luck with your project!
 

Zuljaras

Member
Why have the ds_list_create in the Room Start Event? Why not literally have it in the Create Event?
I changed it back to the Create event of the Zombie instances.
I thought that the room_start event will be faster and that is why I got the error.

Now I know that if many objects have in their create event different things they could override each other and create a crash.

Just like I executed my script that literally moves my character and changes the room in its create event. In the mean time I create a ds_list in the zombie create event. Guess which create event did not execute :D

Now I am loading my script with 1 mil second delay so I do not get that error.

The easier workaround would be to remove the zombies from my first playable room so I would not have DS lists, but that helped me understand some things.
 
Top