How to access an item in an asset layer?

Sam04

Member
So I created a sequence and added it to a room in an asset layer. Now I want to change some stuff in code during runtime... but I do not know how to reference it.

Well, mostly it is a question about instance's names. According to the manual, the name can be used to access a specific instance:
However it's worth noting that the name given here (whether it's one you give, or the default one that the IDE gives) is considered a constant and so must be unique to the instance. This also means that it can be used in code n your game to identify the instance, but only if you are in the same room as the instance.
I've used this before and it works as expected. The problem, however, lies in the assets layer (which is in the same link) that reads:
From here you can give the asset a unique name, set whether it is to inherit from the parent room, or change the sprite or sequence that you want it to display.
It doesn't say anything about using it as a constant to reference it later. Which seems to be for a reason. I tried to do some debugging with a sequence name but every time it would crash with an error about that name not existing (not that it is a valid reference to an invalid thing, but an invalid reference at all, i.e. an undeclared variable). I have tried accessing it through the room creation code and through an object within the room (inside a key press to make sure all the initialization is already completed) and in both cases it doesn't recognize the name at all.

I currently have the workaround in which I use "layer_get_all_elements()" and iterate through each of its elements to check with "layer_get_element_type()" if they are a sequence and, if they are, check if they have the name of the sequence I'm interested and only then I have the reference to modify the sequence I'm interested. But keep in mind this is only a workaround, not a solution; and definitely not ideal if assets names could be used as references in the same way instances names can.

Anyone has any idea about that? Is it an IDE bug?
Thanks.
 

chamaeleon

Member
From the Sequences reference page
To start with, at the top level, you have a sequence element. This is what you place on a layer in a room, either through the Room Editor or in code using the appropriate layer functions. The layer element has no real properties other than an element ID value, but this ID is required to use the above mentioned layer functions to change the sequence playback or to access the sequence data.
I'm not a heavy user of sequences so I may be overlooking something, but I don't really see why it should not be possible to use a specific name provided in the instance editor for the sequence instance placed in the room in order to reference the ID of a sequence. I tried creating a sequence, adding two in the room, changing their names to seq_one and seq_two, and was unable to use those name like I can for object instances.

I'd say it could warrant filing a bug report. Maybe there's some underlying reason why this is not possible, but if that is the case, it should be documented better.
 

Roldy

Member
Anyone has any idea about that? Is it an IDE bug?
Only instance names are are turned into constants. Asset names such as sprites or sequences are not. It is not a bug as no where in the manual does it claim you should be able too. However, it is most likely a half finished feature (seeing as asset names are colored red like a constant in gml even though they are not constants). It is undersandable why asset names are not constant ids like instances. Instance placed in the editor are assigned ids essentially at compile time and are static constant throughout the lifetime of the game and are relative to all other instances in all rooms. Layer elements however are assigned ids at runtime and are relative only to the single layer and its elements. So without a big work around it would be difficult to turn their names into constant ids like is done with instances.

Using the layer/layer_element functions are the only way to access editor placed assets. The names given to sprite assets can be accessed via the function layer_sprite_get_id. However this only works for sprite assets not sequences. If you want to file a suggestion then file a suggestion for a function similar to that. e.g. layer_sequence_get_id. That way you could access the specific sequence based on its name.


I have in the past filed suggestion to make asset name accessible at runtime beyond the single function layer_sprite_get_id. We need a general function to get the asset names... e.g. layer_asset_get_name
 

chamaeleon

Member
Only instance names are are turned into constants. Asset names such as sprites or sequences are not. It is not a bug as no where in the manual does it claim you should be able too. However, it is most likely a half finished feature (seeing as asset names are colored red like a constant in gml even though they are not constants). It is undersandable why asset names are not constant ids like instances. Instance placed in the editor are assigned ids essentially at compile time and are static constant throughout the lifetime of the game and are relative to all other instances in all rooms. Layer elements however are assigned ids at runtime and are relative only to the single layer and its elements. So without a big work around it would be difficult to turn their names into constant ids.

Using the layer/layer_element functions are the only way to access editor placed assets. The names given to sprite assets can be accessed via the function layer_sprite_get_id. However this only works for sprite assets not sequences. If you want to file a suggestion then file a suggestion for a function similar to that. e.g. layer_sequence_get_id. That way you could access the specific sequence based on its name.
Given the presence of the name field in the sequence instance editor for the room editor, I'd classify it as a bug if I can not use it like I can for instances. Fight me. :)
GML:
show_debug_message(graphic_63B4DA1);
show_debug_message(inst_46FD015B);
In the above, both names are color coded the same in GMS, which means it's picked up as a name of some sort for the sequence. I fail to see why it can't have an id associated with it.
 

Roldy

Member
Given the presence of the name field in the sequence instance editor for the room editor, I'd classify it as a bug if I can not use it like I can for instances. Fight me. :)
GML:
show_debug_message(graphic_63B4DA1);
show_debug_message(inst_46FD015B);
In the above, both names are color coded the same in GMS, which means it's picked up as a name of some sort for the sequence. I fail to see why it can't have an id associated with it.
This has been this way for a long time. Asset layers existed before sequences and assets placed on such a layer have had a name field, and the name will be colored like a constant in GML just like instances.

The bug is that asset elements names are colored like constants when they are not constants. The bug is NOT that assets don't have ids like instances.

The thing missing is a function equivalent to layer_sprite_get_id. We need a function like layer_sequence_get_id and in general more function to access element names.

GML:
// Instances have constant static ids that are MAPPED

100000.x = 100; // This works for accessing the instance with id 100000

// Objects have ids that are constant static that are MAPPED

1.x = 10;  // Set the x of all instances with object_index 1

// Elements on a layer have a random index into a list of elements associated with a specific layer on a specific room
// They can be access even when the room is not the current room (via layer_set_target_room)

// How would you access an element via a constant id?
// Each layer has its own list of elements.  There can be many elements with the same index, one on each layer, in each room
// This is why, even if once planned and intended, asset elements on an asset layer do not have ids nor are their names MAPPED into constants in GML
// It would require a big overhaul of... everything
The ONLY access to asset element names is via the function layer_sprite_get_id. There is no equivalent function for instances, because instances don't have names, they have ids. The name given to instances is only used for a compile time mapping to instance ids, the instance name is essentially thrown away. Instances do not have names.

Layer elements do have 'names' and are accessible at least for sprites via layer_sprite_get_id. Sequences placed at editor time do have names (even though currently not accessible like layer_sprite_get_id) and they have an sequence instance struct. But that struct does not have an id like instances do.

Maybe in GMS3 some of this can be unified. But in GMS2, how things are addressed is a bit of a mess. The easiest (and actually most consistent) fix for this issue is to add a function like layer_sequence_get_id. I have made this and similar suggestions to YoYo.

If you have your own suggestion for them then submit it. But if you actually want it implemented then I would advise you to think about how the current system works and make your suggestion accordingly. If your suggestion would require a big refactor of layers, layer elements, object ids or instance ids, then I doubt your suggestion will be implemented.
 
Last edited:

chamaeleon

Member
If you have your own suggestion for them then submit it. But if you actually want it implemented then I would advise you to think about how the current system works and make your suggestion accordingly.
My suggestion would be that the value for the name would be the same kind of value as returned by layer_sequence_create() (an integer element id).
 

Roldy

Member
My suggestion would be that the value for the name would be the same kind of value as returned by layer_sequence_create() (an integer element id).
You mean you want the name (a string) turned into a constant identifier that is equal to an element id.

This cannot work without refactoring layer elements in general.
  • Element ids are an index into a list/array.
  • If you remove an element from a layer at runtime then all the indices change.
For the element name to map to an element id it would require that the element ids be a mapping instead of an index. Maybe that would be an easy refactor for YoYo. Maybe there isn't anything internally that would make that a challenging refactor. Would it be a mapping per layer, per room, or per game (like instance ids) and do any of those choices cause unforeseen problems.

Make your suggestion, but I doubt you will see it implemented. I agree that would be a nice way for things to work.

I do think they could expose element names by adding a single function: layer_element_get_name

That is all that is required to identify a specific element on a layer, which is what OP wants.
 
Last edited:

Roldy

Member
@chamaeleon

Consider this:

If element names mapped to element IDs, then what do instance names map to?

And instance on a layer has an Instance ID (in the instance map) and it has an element ID (in the layer element map).

GML:
// In the editor I placed an instance with name 'inst_AAFFGGEE'

inst_AAFFGGEE.x = 10;  // I move the instance

// In the editor I placed a sprite with element name 'graphic_AAFFGGEE'

layer_sprite_x(graphic_AAFFGGEE, 10); // I move the sprite

// I want to move an element to a differnet layer

layer_element_move(graphic_AAFFGGEE, some_other_layer);  // I move the sprite

layer_element_move(inst_AAFFGGEE, some_other_layer);  // I try to move the instance?????

// This would force 'inst_AAFFGGEE' to map both to the instance id and the element id
// So element ids and instance ids would have to have the same value or
// instance elements can't have a name?
 

Roldy

Member
Why would you attempt to use an instance id as an element id? Fix your code. :)
This is the point.

Elements placed on a layer have a name. Instances are elements on a layer.

You want those elements names to be mapped to element ids.

Instance only have ONE element name. Right now they are mapped to instance ids. So how would you map their element ids.

Instances ARE elements on a layer and they have element IDs. The fact you don't understand this is why you don't understand the problem with your suggestion. You are proposing more inconsistency to the system.

EDIT: this is also most likely the root of the bug that asset element names are colored like constants in GML. Because those name fields are the same to editor (and internally) but only instance names get mapped, because they are they only things that are mappable at compile time.
 
Last edited:

chamaeleon

Member
The fact you don't understand this is why you don't understand the problem with your suggestion.
And your father smells of elderberries. From your tone I am assuming we are moving towards insults. Correct me if I'm wrong.
You are proposing more inconsistency to the system.
I am proposing that instances are handled the way they are today (or all hell would break loose). Sequences (and possibly other assets that are not exposed this way by name during compile time when placed on an asset layer) would have their name be element ids. I'll take the inconsistency over not being able to do it at all.

Why do you have such a resistance to instance layers implying the name being a instance id constant, and names for an asset on an asset layer being an entity id constant? The obvious caveat to the practicality as far as I'm concerned is only related to internal workings of GMS which I have no insight into.

Here's an experiment for you (I did, because I like to experiment when I'm faced with brain twisters)

Create two rooms and jump between them using some means and output the result of layer_get_all_elements() for a bunch of sequences (and/or instances, I did both) in each room, and observe how the element ids are unique across all sequences.

Room start event
GML:
var arr = layer_get_all_elements("Instances");
show_debug_message("[Instances] " + room_get_name(room) + ": " + string(arr));
var arr = layer_get_all_elements("Assets_1");
show_debug_message("[Assets_1] " + room_get_name(room) + ": " + string(arr));
Code:
[Instances] Room1: [ 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27 ]
[Assets_1] Room1: [ 7,8,9,10 ]
[Instances] Room2: [ 29,3,4,5 ]
[Assets_1] Room2: [ 0,1,2 ]
[Instances] Room1: [ 30,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27 ]
[Assets_1] Room1: [ 7,8,9,10 ]
[Instances] Room2: [ 31,3,4,5 ]
[Assets_1] Room2: [ 0,1,2 ]
[Instances] Room1: [ 32,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27 ]
Room1 has a bunch of instances (one being a persistent instance that handles room switching) and 4 sequences. Room2 has 3 instances (plus the persistent controller) and 3 sequences.

I am arguing for the name in the room editor for my sequence assets to correspond to the element id which to my eyes appear to be constant (whether it's by accident because my test project isn't complex enough, I couldn't say, but I haven't seen evidence that it isn't).

It is a curious fact that the element id for my persistent instance is changing as I move between rooms. I kept click and it kept going up until I stopped. However, should it? Does it have to? Is it a bug? I have no idea. But that is a instance, not an "asset" on an asset layer (in contrast to an instance layer).
 
Last edited:

Roldy

Member
And your father smells of elderberries. From your tone I am assuming we are moving towards insults. Correct me if I'm wrong.
Submit your suggestion to YoYo. Good luck.

They will either:
  1. understand the complications and not implement it
  2. not understand the complications, implement it, and increase the buggy inconsistent mess we already have
  3. ignore your suggestion completely
Most likely going with option 1 as they have done for years. It has been a known problem long before sequences where introduced and they didn't fix it when introducing them.
 
Last edited:
Top