Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make object sorting position on screen deterministic in case of equal z-order #2627

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

ivan-mogilko
Copy link
Contributor

@ivan-mogilko ivan-mogilko commented Dec 21, 2024

Fix #2311

This is a quick solution for resolving objects with identical z-order, in which case we'd like to keep their relative sort persistent, and avoid random sorting "swaps".

This is achieved by a combined comparison in sort's "less" function:

  • first compare if (z1 < z2);
  • if (z1 == z2), then compare if (drawindex1 < drawindex2)

Global DrawIndex is allocated for each drawable object in game (except for gui controls that are sorted only among each other).
Static objects are reserved draw indexes at the game init.
Dynamic objects (currently only Overlays) have one assigned for them when they are drawn for the first time.

DrawIndex is ever incrementing counter. When it reaches max value (of uint32_t), it overflows and gets reset to the "base dynamic index", which is set once to the number of all the static game objects.
Also, DrawIndex is reset whenever all dynamic objects are removed; which in current engine happens when all overlays are removed either by command or when a room changes.

DrawIndex replaces use of GUI.ID and Overlay's "creation_id" for this purpose.

Walk-behinds always receive DrawIndex = 0, because
a) they cannot be sorted among themselves due to their nature (as cut-outs from room bg);
b) by classic AGS logic they must draw behind objects and characters when their baselines match walk-behind.

There's a side effect where, in case of equal z-order, objects always have lower position in sort compared to characters, and both objects and characters have lower position than room overlays. Similarly, guis will have lower position compared to screen overlays. I don't know if that matches original AGS behavior; but probably it was random, because neither objects nor chars were ever fixed for this problem.

This is a quick solution for resolving objects with identical z-order, in which case we'd like to keep their relative sort persistent, and avoid random sorting "swaps".

Global DrawIndex is allocated for each drawable object in game (except for gui controls that are sorted only among each other).
Static objects are reserved draw indexes at the game init.
Dynamic objects (currently only Overlays) have one assigned for them when they are *drawn for the first time*.

DrawIndex replaces use of GUI.ID and Overlay's "creation_id" for this purpose.
@ericoporto
Copy link
Member

I tested this by throwing a few games to run and seeing if something was in a different order and at least in the games I tried, nothing changed that I could notice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make object sorting position on screen always defined
2 participants