Snapshots in QB64?
#1
Recently I've been learning about saving data in games. It seems like most games only save the variables that have changed during the course of gameplay. But with this method you have to specify which variables get saved and that can be an extremely long list to keep track of.

So my question is: I've heard about some games using snapshots (hoping that's the right term), where instead of saving just a handful of variables, it saves the entire state of the entire game at that moment so it can be loaded later. Is there a way to do that in QB64? Though I've never used them before, I'm aware of all the _MEM commands and I imagine it can be done using those, but I have no clue how to do so and haven't seen any practical tutorials.
Reply
#2
(02-15-2023, 03:03 AM)40wattstudio Wrote: Recently I've been learning about saving data in games. It seems like most games only save the variables that have changed during the course of gameplay. But with this method you have to specify which variables get saved and that can be an extremely long list to keep track of.

So my question is: I've heard about some games using snapshots (hoping that's the right term), where instead of saving just a handful of variables, it saves the entire state of the entire game at that moment so it can be loaded later. Is there a way to do that in QB64? Though I've never used them before, I'm aware of all the _MEM commands and I imagine it can be done using those, but I have no clue how to do so and haven't seen any practical tutorials.

As a game writer the way I would approach this would be to create a global UDT that contains values relating to the current state of the game. Something like:

TYPE GAMESTATE
    CurrentScore AS LONG
    PlayerHealth AS INTEGER
    EnemiesRemain AS INTEGER
    PlayerLocationX AS INTEGER
    PlayerLocationY AS INTEGER
    etc..
    etc..
END TYPE

DIM GameState AS GAMESTATE

Then, if the player wished to load a saved gamed the values in GameState could be loaded from a file and the values distributed out where needed. In my opinion a game would need to be designed from the onset with saved game states in mind.

As far as snap shots? Well, you would still be doing the same thing, saving the states of all variables. I see what you are getting at though, sort of like saving the state of a VM in Virtualbox instead of shutting the virtual PC down. I would have no clue how to do that however with QB64.
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply
#3
Quote:In my opinion a game would need to be designed from the onset with saved game states in mind.


Totally agree! That's why I'm asking about this way ahead of time.  Smile I couldn't imagine trying to integrate a save system into a game after the fact. That would be a nightmare for sure.

Using a global User Defined Type would definitely work and would even be efficient if there were no more than a couple hundred variables . . . but a future project I have in mind is a "persistent world" game with potentially hundreds of NPC's, each with possibly dozens of variables being tracked. Not to mention location information, quest information, etc, etc. I would expect the variable count to be easily in the thousands.

So far my only experience with saving data in QB64 is with using commands like OPEN, CLOSE, WRITE, FOR BINARY, etc.
Reply
#4
(02-15-2023, 02:48 PM)40wattstudio Wrote:
Quote:In my opinion a game would need to be designed from the onset with saved game states in mind.


Totally agree! That's why I'm asking about this way ahead of time.  Smile I couldn't imagine trying to integrate a save system into a game after the fact. That would be a nightmare for sure.

Using a global User Defined Type would definitely work and would even be efficient if there were no more than a couple hundred variables . . . but a future project I have in mind is a "persistent world" game with potentially hundreds of NPC's, each with possibly dozens of variables being tracked. Not to mention location information, quest information, etc, etc. I would expect the variable count to be easily in the thousands.

So far my only experience with saving data in QB64 is with using commands like OPEN, CLOSE, WRITE, FOR BINARY, etc.

That still would be fairly manageable. Your NPCs could be held in an array with a common UDT:

TYPE NPC
    variable...
    variable...
   etc..
END TYPE

REDIM NPC(0) as NPC ' increase size as needed when adding NPCs

If would then be a simple matter of saving the state of each NPC:

Handle = 0
DO
    SaveNPCStates NPC(Handle) ' save the state of NPC to drive
    Handle = Handle + 1
LOOP UNTIL Handle > UBOUND(NPC)
SavePlayerState Player ' save the state of the player
SaveGameState GameState ' save the game's global variables

Just an idea off the top of my head.
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply
#5
Aside from the player data, I am wondering how you could reconstruct the scene so you can pickup from where you left off.

This is a mighty ambitious item on the wish list!
b = b + ...
Reply
#6
(02-16-2023, 01:50 AM)bplus Wrote: Aside from the player data, I am wondering how you could reconstruct the scene so you can pickup from where you left off.

This is a mighty ambitious item on the wish list!

Thankfully I plan on limiting my scope to that of a text adventure, so reconstructing a "scene" wouldn't be hard at all. But even if I used graphics, I imagine it wouldn't be too difficult. I saw a YT video that explained how AAA titles like Skyrim or Grand Theft Auto recreate their worlds after loading a saved game. Some data would have to be exact, like player position, health, inventory items, etc. but things outside the player's field of view or that region can just be placed in the general area. It's not critical for a skillet to be located at the PRECISE x, y, z and rotation as last time, it just needs to be there on the stove somewhere.
Reply
#7
(02-16-2023, 01:50 AM)bplus Wrote: Aside from the player data, I am wondering how you could reconstruct the scene so you can pickup from where you left off.

This is a mighty ambitious item on the wish list!

I would use a gathering subroutine when saving a game and then a populating subroutine when loading a saved game.

SUB GatherSavedValues() ' place all saved game values into their UDTs

SUB PopulateValues(FileName AS STRING) ' get UDT data from save file and populate game variables from UDTs

Or something along these lines, just spit-balling here.
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply
#8
If my goal was to save *everything*, then I'd use _MEMNEW to create a single block of memory, which is all I'd use in my program.  Smile
Reply
#9
(02-16-2023, 04:17 AM)SMcNeill Wrote: If my goal was to save *everything*, then I'd use _MEMNEW to create a single block of memory, which is all I'd use in my program.  Smile

I searched the forums for _MEMNEW and saw you had a MemFile System program. I haven't had a chance to try it out yet, but would something structured like that work for the purposes of saving large amounts of game data of different variable types?
Reply
#10
As the others have indicated here, you would do well with UDT. Because with the _MEM gang it could turn into a headache. You would have to keep track which data begins at what byte, and it has to be the right type or QB64 compiler complains.

UDT's are clunky to work with sometimes but the alternative is to keep one array for each type like LONG, DOUBLE, STRING etc., for specific data and then use clearly-labelled constants as subscripts to make programming documentation easier.

If it's important to you to have the data to store and then to recall in human readable format, might opt for strings and choose which delimeter. Then pick up a good parser there somewhere to distinguish words from numerals. This way is necessary if you require storing a data type which is beyond the limits of one supported by QB64(PE). For example, if you need a number larger than 18 trilliard. Rolleyes
Reply




Users browsing this thread: 9 Guest(s)