YoYoGames / GameMaker-Bugs

Public tracking for GameMaker bugs
20 stars 8 forks source link

In Game - Make instance and sequence event ordering based on layer ordering. #2977

Open AtlaStar opened 11 months ago

AtlaStar commented 11 months ago

Is your feature request related to a problem?

Last I checked instances run their events in what I consider an arbitrary way, in that "younger" instances end up executing their non-draw and non-callback like events after "older" instances. While currently consistent, this is fully a result of internal implementation details that could change at any time. This behavior also makes it impossible to have any mechanism to change the event ordering instances have after the fact. For example, if you A runs its step event first due to being older, then B runs its step event, there isn't what I would consider a proper way to make B run its step event before A.

Describe the solution you'd like

For the engine to execute an instances events in an order defined by the layers order, just as is done for draw code. This means that if you have some class of object A, that needs to always run things like step event code before some class of object B, simply putting your instances of A in a layer that runs before the layer containing B will ensure that behavior. This also would allow you to change the ordering at runtime by simply changing the layer that an instance is on.

It may even be worth it to add a runtime preference that sets whether the code is ran in actual draw order (things which would be drawn behind other things run first) or reverse order (things which would be drawn on top run their code first).

Describe alternatives you've considered

Currently the only feasible way of having more fine grained control over ordering would require some extremely janky work arounds involving a data structure like a priority queue, dummy objects being used for all instances with some variable in the dummy that stores the actual type info, and a control object that iterates over the data structure and invokes event_perform_object per dummy via with based on the current event and subevent. The problem with this is that certain "callback" events can't be used with such a system without even more work by creating an object to delegate object pair where the delegate is responsible for invoking events. Then there are matters like not even having a proper answer for how things like event_inherited are supposed to work in the context of event_perform_object. Best guess is that it'd try to invoke the events inherited in the context of the non-delegate, which would make inheritance messier to work with in general.

Additional context

Just for extra clarification, this would not change the actual order events execute in...so begin step still would happen before step, which occurs before end step, it just would allow you to have further control over the order instances call those events. It also would make sense considering that layers act as a sort of container for references to those instances already

Gamer-XP commented 11 months ago

I've got similar issue already created quite some time ago. It's not about "ordering by layers", but more univeral one. https://github.com/YoYoGames/GameMaker-Bugs/issues/3221

AtlaStar commented 11 months ago

The idea for named custom events with some ordering system is nice too, but I don't know if such a system would really allow for easy reordering at runtime. Still would be a nice feature to have regardless. The alternatives could though depending on which one was selected.

I also feel that tying things to layers would be the most natural change since it is a system most are already familiar with, and it comes with the benefit that it is just using depth sorting to dictate execution order. The only caveat is that things within the same layer you wouldn't have as much control over...but as layers are already a container over instances and have the means to deactivate instances within them, using that container to iterate over the instances to call events seems like it wouldn't be the most intrusive change to make.

Gamer-XP commented 11 months ago

Ordering them by layers is, pretty much, same as ordering them by depth in the end. Thing is, before 2023.2 update events WERE ordered based on depth, but in opposite order to drawing. Though, it was "undocumented behaviour". I was using that to sort execution order of my global controller objects. Because it was change and I can't fix it - I'm stuck at older GM version now.