How to persist values between "game" and "shell" contexts

BobobUnicorn

Chieftain
Joined
Feb 17, 2025
Messages
2
It seems the entire JS context is destroyed when switching between "shell" and "game" contexts (i.e. between in-game and main menu). I've found that Automation.setParameter is able to persist data between these contexts:
JavaScript:
// set arbitrary strings to the specified key
Automation.setParameter('CurrentTest', <key: string>, <value: string>);

// get strings from the specified key
const value: string = Automation.getParameter('CurrentTest', <key: string>);

I've not been able to determine how Automation.setParameterSet works, but the above should be sufficient for all serializable data.
 
I did very little modding in Civ 6 but I figured out some basics. I have not tried Civ 7 yet, but this might be adaptable. Check this link out:
Storing Tables on Objects as Properties

Basically you can set the values from the gamescript side and read them from the UI side. My understanding is that the UI side is a data "view" so you can get vales from that side, you can only read them.

This isn't exactly what you need but is all I could think of.
 
Last edited:
It seems that works on a number of things, like Configuration.getUser().setValue(). The key here would be something that exists as is in both contexts. window and globalThis don't work because they're completely different documents. It's like two different tabs in a browser.
 
It seems that works on a number of things, like Configuration.getUser().setValue(). The key here would be something that exists as is in both contexts. window and globalThis don't work because they're completely different documents. It's like two different tabs in a browser.
Maybe you are on to something though. What types of values can you set with that? Is not Configuration in scope in all scripts?
 
Actually, thinking about it you could just set Configuration.myVal = "someVal". You don't really have to bother with setValue and getValue. I didn't test shell to game context, but in the game context you can certainly do it.
 
Actually, thinking about it you could just set Configuration.myVal = "someVal". You don't really have to bother with setValue and getValue. I didn't test shell to game context, but in the game context you can certainly do it.

But what types can be stored? Can it be anything? (Sorry, I am not to the point of experimentation)
 
JavaScript is pretty loosely typed. If you pass a parameter into a function it is up to that function to determine if the type is valid or not. It could be expecting an animal, but you pass a car. It only uses run() which both have though they mean totally different things. The function has to check that it's an object derived from animal. If it tries calling a function that does exists it's going to throw an error. Apparently that's the whole reason for TypeScript, enforce some types. Things can go all to hell because you can, pretty much, just do whatever you please. The runtime maintains a call stack so it can do a traceback on error. Sometimes I'm 8 calls deep by the time something actually threw an error because I passed the wrong type. Everything is really like a pointer in C that you claim is whatever you please whether it actually is or not.
 
JavaScript is pretty loosely typed. If you pass a parameter into a function it is up to that function to determine if the type is valid or not. It could be expecting an animal, but you pass a car. It only uses run() which both have though they mean totally different things. The function has to check that it's an object derived from animal. If it tries calling a function that does exists it's going to throw an error. Apparently that's the whole reason for TypeScript, enforce some types. Things can go all to hell because you can, pretty much, just do whatever you please. The runtime maintains a call stack so it can do a traceback on error. Sometimes I'm 8 calls deep by the time something actually threw an error because I passed the wrong type. Everything is really like a pointer in C that you claim is whatever you please whether it actually is or not.
That is great news. ISo, can we invent a custom type, then save it via Userconfig the way you showed and will persist between saves? After reloading, can the value be retrieved?
 
No. The way you persist across saves is you write what you need to the save game and reload it. Just to use an example if you wanted to do a zombie apocalypse, resurrect all dead units and make them hostile to everyone, you would need to record all the deaths of units. If the game is saved you need to write that data to the save file. When the game is loaded you need to read it back. Otherwise it's just the deaths since the game was loaded rather than since the start of the game or age. I seen some comments that persistence across age is a bit flaky. If someone saves the game, exits to desktop, goes to bed, and reloads the game when they get home from work the next day whatever you stuck in Configuration would be gone. If they return to the main menu and start a new game it might still be there. Configuration is present in both shell and game contexts. I see no reason for them to destroy and rebuild it. Game is a different story. That has data about the game so they might destroy it when you exit to the main menu and recreate it when you start a new game. They may just reinitialize it though. Either way it's gone when you exit to the desktop.

The way you get persistence between exiting to the desktop and restarting the game is localStorage. That's a database table. Regretably it's bugged. If the key you specify when you write isn't in the table it will create it. Regretably when you try to read it back it ignores the key and just returns the first row. Modders have come up with a convention to allow them to share that row. Conceptually it's a dictionary with a key of your mod and a value of whatever converts to and from JSON. If they find more than one row the empty the table and start over since the only way to guarantee you have the correct row is if there is only one row.

I'm a little hard pressed to see why you would need a shell script to talk to a game script. Mod options is about all I can think of. That's done using localStorage. A shell script displays and allows you to change the settings then a game script uses the settings. I can picture some limited cases for communication between scripts. Like using another mod if it's there and doing something else if not with having an actual defined dependency in modinfo. Some limited debugging is another. Each script has it's own context. So like CDC let's you explore stuff if it's in CDC context, but if it's not you're out of luck. If you could pass a string to be evaluated in another context and get a result back you could get around that. I haven't tried anything like that nor test just how persistent various objects are.
 
Back
Top Bottom