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.52k stars 470 forks source link

Runtime Palette Changes are not stored in save games #1460

Open morphoice opened 3 months ago

morphoice commented 3 months ago

Describe the bug When a scene has pallete changes in a script, and the game state is saved, the changes are not represented when the game is loaded. As most of those changes happen in a scene init it isn't run again after the game is loaded. So saving during a "night" scene makes it go day colored when loading the game.

GBStudio 4.0.0-RC2

untoxa commented 3 months ago

just restore palettes in your code on load. you have to do the same with sprite sheets and the other complex objects.

chrismaltby commented 3 months ago

To expand upon this @morphoice in an effort to conserve the limited memory available it's not always possible to store all the possible run time changes when saving/loading and palettes is one of those things which doesn't get stored.

I believe what Toxa is suggesting is something like the following, if you add a script directly AFTER the "Data Save" event

Screenshot 2024-07-03 at 16 33 17

where the "Reload Palettes" script would do contain something like "If Nighttime Then Set Palettes To X/Y/Z". This works (ish) because when you load the game it will immediately resume from just after the "Data Save" event has finished.

Screenshot 2024-07-03 at 16 40 50

The problem is that the game will fade in the scene BEFORE the palette change would happen so you'll see a flash of the original palette.

What I'm considering adding is the ability to set an "On Load" script using a second tab on the "Data Save" event. This script will be called BEFORE the scene fades in, when it is loaded allowing you to initialise things like palette changes, sprite changes, tilemap changes etc. like this

Screenshot 2024-07-03 at 16 32 20

I've got this working locally I just need to do some testing to make sure it's not introducing any issues.

If you'd like to test this feature you can download a build containing it here: https://github.com/chrismaltby/gb-studio/actions/runs/9781032814

Though please only use this with test copies of your project (after making backups) as I may decide to change how this feature works before it is officially released.

morphoice commented 3 months ago

Brilliant! Thank you so much, i'm trying this right away

maxoakland commented 3 months ago

To expand upon this @morphoice in an effort to conserve the limited memory available it's not always possible to store all the possible run time changes when saving/loading and palettes is one of those things which doesn't get stored.

I believe what Toxa is suggesting is something like the following, if you add a script directly AFTER the "Data Save" event Screenshot 2024-07-03 at 16 33 17 where the "Reload Palettes" script would do contain something like "If Nighttime Then Set Palettes To X/Y/Z". This works (ish) because when you load the game it will immediately resume from just after the "Data Save" event has finished.

Screenshot 2024-07-03 at 16 40 50

The problem is that the game will fade in the scene BEFORE the palette change would happen so you'll see a flash of the original palette.

What I'm considering adding is the ability to set an "On Load" script using a second tab on the "Data Save" event. This script will be called BEFORE the scene fades in, when it is loaded allowing you to initialise things like palette changes, sprite changes, tilemap changes etc. like this

Screenshot 2024-07-03 at 16 32 20

I've got this working locally I just need to do some testing to make sure it's not introducing any issues.

If you'd like to test this feature you can download a build containing it here: https://github.com/chrismaltby/gb-studio/actions/runs/9781032814

Though please only use this with test copies of your project (after making backups) as I may decide to change how this feature works before it is officially released.

I think the On Load script is a great solution