• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Bug or not? Object index problem in 2.3.1

Hello gamemaker experts!
Noob seeking some help here.
I've converted my project "Floria" from GMS 2.2 to GMS 2.3 and my game is practically destroyed now. I could go back to old version but first I'd like to see if there is a solution.

Game size as .aab is currently at 176MB in the 2.3 version (trying to get it down to 150MB ). Same project in 2.2..version is 45MB bigger ( no clue why).

I have total 738 objects in the old 2.2 version. When I converted it to 2.3.1 it looks like now I have 739 objects. It is not seen in the resource tree but it is shows up as "_YYinternalObject_739" when I draw_text object_get_name(739). What it does to my game is throwing everything out of order and other objects show up instead of what should be there. ( So, instead of creating object_index 137, now it creates object_index 138). The game is already published and it will shift a lot of objects that the users have saved so far. I use Json method to save.

Also, if i try to add completely new objects they are now indexed at random. At first, they were object_index 0, 1, 2 and so on, now its just random numbers like 530, 633, etc. It also completely throws the whole game off.
I would like to see if there is a way to get rid of mysterious object 739 so the old users are not affected.

Thank you guys!
 

Evanski

Raccoon Lord
Forum Staff
Moderator
Sounds like you duplicated a lot of objects then upgraded, I think the only fix without nuking the project would be to open the project file with notepad or such and edit the instances
 

kburkhart84

Firehammer Games
Your problem is that you should NEVER have counted on the object index in the first place. You should be using the object names only to refer to the objects. This means you can't directly save those to JSON or other files either. You need to map those constants to your own constants. It was always said not to count on the values working like they had been. Other people made the same mistake, but this is a prime example if depending on un-documented behavior, which is a big NONO.

When they made the asset browser better, allowing you to order things how you like, in folders/groups however you like, they made changes to the object index constants. As long as you only use the object names like you are supposed to, you won't have any issues. If you urgently need to release an update, you may be better off downgrading to 2.2.5. Then, you can take the time to re-code the parts where you are accessing objects by number instead of by name, and redo the save files. I'd recommend you release another version after that in 2.2.5 with the fixes, and have it update all the save files to use your new system as well. Hopefully, your players update fast enough that by the time you release with 2.3, they have already went through your other released with 2.2.5 that fix the issue so they don't lose the files.
 
Oh no...it looks like I have to nuke the project...pulling hair... Didn't know it was an issue at all before...my first game ever.
 
Geez, did you really do that?
GML:
object_get_name(739)
wow, dude...I don't know the scope of the project, maybe it's easier/quicker and cleaner to start form scratch, and learn a BIG one in the process...but...if you went in the old version, open excel and get the object names/id, and then change them in the new version...give it 30 seconds per thing on average, so 400 minutes...this is doable in a day, with lots of coffee and smokes (if you do smoke)
Search and replace would be your friends here...especially the "search" part
 

kburkhart84

Firehammer Games
if you went in the old version, open excel and get the object names/id
What needs done is to redo the thing in the old GM version, changing it to use a different system instead of saving object IDs into the files in the first place. Many people just have a massive array that converts from object indices to the array index, which can then be reliably saved in the files. It just takes some redoing of the thing. They can also add on a thing to detect the old file format and fix it before adding new objects. Hopefully, if the players upgrade often enough, they can go through using this updated version to fix their files, THEN after its all fixed, they can switch to 2.3, add objects, do whatever.
 
What needs done is to redo the thing in the old GM version, changing it to use a different system instead of saving object IDs into the files in the first place. Many people just have a massive array that converts from object indices to the array index, which can then be reliably saved in the files. It just takes some redoing of the thing. They can also add on a thing to detect the old file format and fix it before adding new objects. Hopefully, if the players upgrade often enough, they can go through using this updated version to fix their files, THEN after its all fixed, they can switch to 2.3, add objects, do whatever.
I didn't mean excel as using it in a "conversion" file system, but more like keeping track of object 453 is obj_wall, and so on, just to keep track of, but yeah definitly.
The laws of Murphy were just waiting to jump on this one at the first possible occasion, that's for sure.
 

kburkhart84

Firehammer Games
I didn't mean excel as using it in a "conversion" file system, but more like keeping track of object 453 is obj_wall, and so on, just to keep track of, but yeah definitly.
The laws of Murphy were just waiting to jump on this one at the first possible occasion, that's for sure.
Oh, gotcha. I guess that could help with at the least the creation of the array with object name to index matching.
 
@Slow_Fingers - I am a total noob ( and a dudette) so I don't even see where I can change the object id... I am willing to go line by line...but which line?

GML:
{
  "spriteId": {
    "name": "newtag2",
    "path": "sprites/newtag2/newtag2.yy",
  },
  "solid": false,
  "visible": true,
  "spriteMaskId": null,
  "persistent": false,
  "parentObjectId": null,
  "physicsObject": false,
  "physicsSensor": false,
  "physicsShape": 1,
  "physicsGroup": 0,
  "physicsDensity": 0.5,
  "physicsRestitution": 0.1,
  "physicsLinearDamping": 0.1,
  "physicsAngularDamping": 0.1,
  "physicsFriction": 0.2,
  "physicsStartAwake": true,
  "physicsKinematic": false,
  "physicsShapePoints": [],
  "eventList": [
    {"isDnD":false,"eventNum":0,"eventType":0,"collisionObjectId":null,"parent":{"name":"tag_pink","path":"objects/tag_pink/tag_pink.yy",},"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMEvent",},
    {"isDnD":false,"eventNum":0,"eventType":8,"collisionObjectId":null,"parent":{"name":"tag_pink","path":"objects/tag_pink/tag_pink.yy",},"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMEvent",},
    {"isDnD":false,"eventNum":0,"eventType":13,"collisionObjectId":null,"parent":{"name":"tag_pink","path":"objects/tag_pink/tag_pink.yy",},"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMEvent",},
    {"isDnD":false,"eventNum":0,"eventType":2,"collisionObjectId":null,"parent":{"name":"tag_pink","path":"objects/tag_pink/tag_pink.yy",},"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMEvent",},
    {"isDnD":false,"eventNum":1,"eventType":2,"collisionObjectId":null,"parent":{"name":"tag_pink","path":"objects/tag_pink/tag_pink.yy",},"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMEvent",},
  ],
  "properties": [],
  "overriddenProperties": [],
  "parent": {
    "name": "PLANTING_PROCESS_________________",
    "path": "folders/Objects/PLANTING_PROCESS_________________.yy",
  },
  "resourceVersion": "1.0",
  "name": "tag_pink",
  "tags": [],
  "resourceType": "GMObject",
}
 

kburkhart84

Firehammer Games
It isn't about changing object IDs. It is about not using them for saving files. Object IDs are subject to change at any time and can't be counted on. You need something to link the object names to. You could create some kind of array or other data structure to store the crap, or you could have each object know it's "index."

Or, you could use object_get_name() to get the name of the object as a string. You can then use the string to be the thing you save into the file. And when you load the file back up, you can use asset_get_index to convert from the string to the same constant you get with the object name in code. This method would save some time so you don't have to mess with making a bunch of data to match IDs to objects. However, it will work slower, as strings are simply more bloated than numbers in files generally(maybe not for JSON since it's all a string anyway), and for each object you have to call the conversion function instead of doing a quick lookup. But the performance hit only applies to loading/saving files.
 
Thank you kburkhart84 for explaining it a little more in depth. This is how i am using as object_get_name in Json, but the that prickly object 739 that appeared out of nowhere is skews everything off.
GML:
var _root_list = ds_list_create();



with (Garden_flower_main_o)

{
        var _map=ds_map_create();
        ds_list_add(_root_list, _map);
        ds_list_mark_as_map(_root_list, ds_list_size(_root_list)-1);
        
        var _obj =object_get_name(object_index);
        ds_map_replace  (_map, "obj", _obj);
        ds_map_replace  (_map,"x", x);
        ds_map_replace  (_map,"y", y);
        ds_map_replace  (_map,"direction", direction)
        ds_map_replace  (_map,"sprite_index", sprite_index)

        ds_map_replace  (_map,"image_xscale", image_xscale)
        ds_map_replace  (_map,"image_yscale", image_yscale)
        ds_map_replace  (_map,"depth", depth)
        ds_map_replace  (_map,"image_angle", image_angle)
        var _wrapper = ds_map_create();



ds_map_add_list(_wrapper, "ROOT", _root_list);


var  _string = json_encode (_wrapper);
buffering_save("SavegameX11.sav", _string);


ds_map_destroy(_wrapper);
 
@Slow_Fingers - I am a [...] dudette
Oops! Sorry about that!
But yeah, reading Kenneth's answer, getting the object name and using asset_get_index(asset_string) would probably be my choice.
I use that function all the time volountairly, and I've never hit a performance wall because of it.
 

chamaeleon

Member
I have no particular insight into why with (Garden_flower_main_o) would yield a object that is not that object or a child object of it when calling object_get_name(), but I just want to point out that you need to take the same kind of precautions with sprite_index, as there are no guarantees the asset if of a sprite will be identical between compiles of the program.
 

kburkhart84

Firehammer Games
I don't think that some object 739 or whatever is your problem, though you may have it and not know it. In any case it shouldn't be throwing you off at all if you don't have any instances of it. And if you are no longer using object IDs for the files then it really shouldn't have any affect. See your following code...

Code:
var _map=ds_map_create();

var _obj =object_get_name(object_index);
ds_map_replace (_map, "obj", _obj);
I see an issue here. The first line is created a temporary variable. Since it is inside the with statement, it is very possible that you are creating it over and over again as the with() statement goes through all the instances of your Garden_flower_main_o object. And therefore, you are also possibly recreating the the map over and over as you do that, and therefore losing the reference to them as you go.

I also don't see a closing bracket for the with() statement, so I'm unsure what part is happening for every instance.

Finally, the part where you are replacing the map key "obj" with the value in _obj is an issue as well as I'm seeing it. Even if you haven't somehow been creating a bunch of extra maps, you are overwriting the same map with the same thing. Each object is putting it's own values into the map, overwriting the ones from the instances that went before. I'm guessing your intention was to create a list of maps, but I see nothing that is adding each of the maps to a list so it isn't happening.

I'm not sure what changed between the working version and this version, but you either didn't copy the code right, or you somehow added some logic problems.
 

FrostyCat

Redemption Seeker
Saving volatile resource IDs instead of stable resource names is a big mistake in both 2.2.5 and 2.3.0 (the numeric ordering can shift in either version with ongoing work), but there is no reason to completely restart the project because of this. You can capture a snapshot of the ID situation before 2.3.0 migration, then use that to convert save files in the old format (resource IDs) to the new format (resource names).

Revert both your IDE and Runtime back to 2.2.5, and open the unconverted project that corresponds to the public release. Temporarily add this to the beginning of your game, then run it on Windows/Mac to produce a GML file listing all sprite and object names. Read it over and make sure everything you need is in the file, then delete this piece of code.
GML:
// Create GML file
var filename = get_save_filename("GML File|*.gml", "");
var f = file_text_open_write(filename);

// Capture sprite names in array
var i = 0;
file_text_write_string(f, "var v1_sprite_names = [");
file_text_writeln(f);
while (sprite_exists(i)) {
    file_text_write_string(f, "\"" + sprite_get_name(i) + "\",");
    file_text_writeln(f);
    ++i;
}
file_text_write_string(f, "];");
file_text_writeln(f);

// Capture object names in array
var j = 0;
file_text_write_string(f, "var v1_object_names = [");
file_text_writeln(f);
while (object_exists(j)) {
    file_text_write_string(f, "\"" + object_get_name(j) + "\",");
    file_text_writeln(f);
    ++j;
}
file_text_write_string(f, "];");
file_text_writeln(f);

// Close file
file_text_close(f);
You can then use the information above to create a script that converts the save file format (preferably at the beginning of the game), so that existing users can migrate their save files transparently:
GML:
///@func convert_v1_to_v2(filename)
///@param filename

var filename = argument0;

/* PASTE THE GENERATED GML FILE HERE */

var jsonstr = buffering_load(filename); //Replace this line with whatever you're using to load from a file
var json = json_decode(jsonstr);
    
// Sniff the file for raw resource IDs, and if found, convert them to resource names based on the snapshot
var root_list = json[? "ROOT"];
if (!ds_list_empty(root_list) && !is_string(ds_map_find_value(root_list[| 0], "sprite_index"))) {
    for (var i = ds_list_size(root_list)-1; i >= 0; --i) {
        var entry = root_list[| i];
        entry[? "obj"] = v1_object_names[entry[? "obj"]];
        entry[? "sprite_index"] = v1_sprite_names[entry[? "sprite_index"]];
    }
    var jsonstr_new = json_encode(json);
    buffering_save(filename, jsonstr_new);
}

ds_map_destroy(json);
Then convert your saving code to save object_get_name(object_index) and sprite_get_name(sprite_index), and the loading code to use asset_get_index for both object and sprite IDs.
 
Last edited:
I also don't see a closing bracket for the with() statement, so I'm unsure what part is happening for every instance.
I have a closing bracket after image_angle entry, i just deleted few lines with my variables ( I name my vars too silly sometimes to post here)...I have over 400 different flower instances created as one object Garden Main Flower, it seems to work fine in 2.3.



@FrostyCat...it seems like your solution will be the answer for my problem, I will work on implementing it today. Thank you so much!

The code that gave me first problem is rather simple:
create event:

if place_meeting(x, y, pot1)
{
mytag=tag_blue_o
}
if place_meeting(x, y, pot2)
{
mytag=tag_red_o
}
alarm[0]:
instance_create_depth(x, y, 1, mytag)



changed it to:



create event:
if place_meeting(x, y, pot1)
{
mytag=1
}
if place_meeting(x, y, pot2)
{
mytag=2
}
alarm[0]:
if mytag=1
{instance_create_depth(x, y, 1, tag_blue_o)
}
if mytag=2
{instance_create_depth(x, y, 1, tag_red_o)
}

Seems to work but I can't now tell if this will affect old users who already had the objects.

Thank you so much for helping! Great community here!
 
Top