Page 1 of 1

Reset Lua variable on Checkpoint/Scene load

Posted: Tue Jun 11, 2024 6:16 am
by phoot
Hi,

I'm using the DS Standard Scene Transition Manager together with the DS save and inbuilt quest system. I have also my own custom autosave/load on scene Transition and checkpoint save/load within scenes.

Now I started trying to author a simple kill x mobs quest. The scene holds enemy game objects each holding their own IncrementOnDestroy component. These are set up to work on Disable and to up a kill count. The quest has 2 entries that will be flagged as success if a certain threshold on the kill count lua variable is achieved. the scene also has a generic quest handler game object with appropriate DS triggers to react to the lua variable increment. The enemy game objects use setActive(false) when they recieve fatal damage, and the increment happens every time.

I now try to have the following behaviour: let's say the player has killed 3 enemies, thus having a lua variable value of 3.
  • Whenever the player reloads the level, it should be 0 again and all 3 enemies present and active.
  • Whenever the player loads from a checkpoint both the lua variable should remain at the previous value of 3 and the already killed 3 enemies should stay inactive.
But currently I get the following behaviour instead:
  • Whenever the player reloads the level, the lua variable stays at 3 and the 3 enemies are active.
  • Whenever the player reloads the checkpoint, the lua variable adds 3 for total of 6 and the 3 enemies are inactive.
Now my questions:
Can I tell the DS to reset lua variables on scene load?
Can I tell the DS to ignore the setActive(false) calls after a checkpoint load? I've tried both SaveSystem.BeforeSceneChange() and PersistentDataManager.LevelWillBeUnloaded() but the doubling still happens, so it still recounts the enemies it shouldn't because they've already been disabled once.

I would be grateful for any hints.

Re: Reset Lua variable on Checkpoint/Scene load

Posted: Tue Jun 11, 2024 9:14 am
by Tony Li
Hi,

Gestalt: Steam & Cinder (which uses the Dialogue System) does something similar.
  • Each scene has enemies.
  • If you leave a scene and return, all of the enemies are alive again.
  • If you hit a checkpoint in the scene and then die, when you respawn in the scene the enemies you have already killed in the scene remain dead.
Here are two ways to handle this:

1. When the player dies in the scene, don't reload a saved game. Instead, just respawn the player at the checkpoint position.

2. Or keep two saved game data records. This is pretty much what Gestalt does, with some custom variations. For example:
  • When the player enters the scene, save to slot 0. In this save, the Lua variable should be 0 and all 3 enemies alive.
  • When the player hits a checkpoint, save to slot 1. In this save, the Lua variable should be equal to the number of enemies killed, and some number of enemies will be marked as killed (e.g., using DestructibleSaver components).
If the player dies, load slot 1. If there is no slot 1 save, load slot 0.
When the player leaves the scene, delete slot 1.

However, to answer your specific questions:

> Can I tell the DS to reset lua variables on scene load?

Yes. You can hook into the SaveSystem.saveDataApplied C# event to know when you can change Lua variables. You may want to reset specific variables, not the entire database. However, if you want to reset the entire database, use DialogueManager.ResetDatabase().

> Can I tell the DS to ignore the setActive(false) calls after a checkpoint load? I've tried both SaveSystem.BeforeSceneChange() and PersistentDataManager.LevelWillBeUnloaded() but the doubling still happens, so it still recounts the enemies it shouldn't because they've already been disabled once.

SaveSystem.BeforeSceneChange() calls Saver components' OnBeforeSceneChange() method on the savers in the outgoing scene -- that is, the scene that is being unloaded before loading the saved scene. You could record something in a static variable that survives the scene change if you need to remember this after loading the saved scene.

Re: Reset Lua variable on Checkpoint/Scene load

Posted: Wed Jun 12, 2024 12:16 pm
by phoot
Hello Tony,

thank you for your quick reply.
2. Or keep two saved game data records.
It's actually what I built. I use that approach to be able to have two data sets on record and being able to load either one according to given situations.
Yes. You can hook into the SaveSystem.saveDataApplied C# event to know when you can change Lua variables. You may want to reset specific variables, not the entire database. However, if you want to reset the entire database, use DialogueManager.ResetDatabase().
I've actually chosen this approach before posting here. I have not encountered unexpected behaviour so far but I wanted to check back with you if there was maybe another approach I was not aware of. I have to try out a few edge cases but I hope it will be robust enough.

One more question popped up though. Is there a setting that tells the DS save system to NOT save/load on scene transitions? I suspect I get inconsistent load data because I load data from my own system AND from

Code: Select all

SaveSystem.ApplySavedGameData() 
happening at scene transition. I want to see what happens if either system (mine or the DS' save system) is not running.

Thank you again for your time and explanation.

Re: Reset Lua variable on Checkpoint/Scene load

Posted: Wed Jun 12, 2024 1:22 pm
by Tony Li
Hi,

If you change scenes with your own code -- not using the save system as in How To: Change Scenes With Save System -- then the Pixel Crushers save data won't be applied when you enter the new scene.

Re: Reset Lua variable on Checkpoint/Scene load

Posted: Thu Jun 13, 2024 2:47 am
by phoot
Alright, I think I can work with the hints you gave me. Thank you again for your time.

Re: Reset Lua variable on Checkpoint/Scene load

Posted: Thu Jun 13, 2024 7:03 am
by Tony Li
Happy to help!