chrismaltby / gb-studio

A quick and easy to use drag and drop retro game creator for your favourite handheld video game system
https://www.gbstudio.dev
MIT License
8.55k stars 470 forks source link

"Actor Start "On Update" Script" does not use "VM_ACTOR_BEGIN_UPDATE" #1550

Closed KirbyKing186 closed 1 month ago

KirbyKing186 commented 2 months ago

Describe the bug When making an actor, for instance, Actor 1, have its On Update script started through the "Actor Start "On Update" Script" event, this GBVM code will be executed:

    ; Actor Set Active
    VM_SET_CONST            .LOCAL_ACTOR, 1

    ; Actor Start Update Script
    VM_ACTOR_DEACTIVATE     .LOCAL_ACTOR
    VM_ACTOR_ACTIVATE       .LOCAL_ACTOR

It shows here that the actor is deactivated, and promptly reactivated. Although this technically works, due to the actor being deactivated, it is now sent back in terms of sprite priority (specifically for the Game Boy Color), causing a visual bug if any other actors intercept with the affected actor.

VM_ACTOR_BEGIN_UPDATE is GBVM command that allows an On Update script to be started, without needing to mess with any sprite ordering, and therefore cause a potential visual error. The test project below showcases this. By using VM_ACTOR_BEGIN_UPDATE over the current script, it can save on unnecessarily changing the sprite order.

To Reproduce Steps to reproduce the behavior, or just download the Test Project linked below:

  1. Have two actors laid over each other.
  2. On a button script, start the On Update script with the actor with the highest sprite priority. This will most likely be the first created actor, Actor 1.
  3. Click the button related to the button script.
  4. Before clicking the button, Actor 1 would display above Actor 2. Now that Actor 1's On Update script has been called by deactivating and reactivating instead of using VM_ACTOR_BEGIN_UPDATE, Actor 2 now displays above Actor 1.

Test Project On Update Test.zip

Platform (please complete the following information):

Additional context Link to VM_ACTOR_BEGIN_UPDATE's information on the "GBVM Operations" page of the GB Studio documentation: https://www.gbstudio.dev/docs/scripting/gbvm/gbvm-operations/#vm_actor_begin_update

Actor Stop On Update script does not have this issue, as it uses VM_ACTOR_TERMINATE_UPDATE.

Additional potential issue

Side note, GB Studio displays the opposite sprite priority in the editor than with a real or emulated Game Boy Color.

Emulated image: image GB Studio editor image: image

chrismaltby commented 2 months ago

Hi @KirbyKing186 good spot, I've updated the Actor Start "On Update" Script event to use VM_ACTOR_BEGIN_UPDATE I forgot to make that change when the command was added. So the order will stay consistent now. The actual order not matching the editor is a little bit more of a tricky one, from doing some testing now it seems to be based on the Y coordinate of the actor (with actors that are below others mostly appearing behind) I wonder if it's because of the order that actors get initialised as they appear on screen going from top to bottom? Probably best to leave this issue open until that can be investigated.

patrickmollohan commented 2 months ago

@chrismaltby I believe this might be relevant:

Sprite Priorities and Conflicts When sprites with different x coordinate values overlap, the one with the smaller x coordinate (closer to the left) will have priority and appear above any others. This applies in Non CGB Mode only. When sprites with the same x coordinate values overlap, they have priority according to table ordering. (i.e. $FE00 - highest, $FE04 - next highest, etc.) In CGB Mode priorities are always assigned like this.

chrismaltby commented 1 month ago

Thanks for the info @patrickmollohan I'm going to close this as the original issue is fixed in the latest releases but there's probably a new issue to create as an enhancement to add the ability to control sprite draw order (at least on CGB where it seems like it should be possible)