hi Tim, i am an inexperienced game designer who loves your RPGs and your channel has helped me a lot. thank you for being so generous with the knowledge you have gained over the years
Here is a tip: implement load/save as early as possible. So you can figure it out as you go along + you don't have to stress about it + it will not be a huge task to do. (And the same is true for mod support for the game)
I think the most important thing is to implement saving and loading as early as possible in development. It makes testing everything so much easier if you can save a specific situation and load it later.
Here's a strange behaviour I found with the save system in the original Kings Quest III. I was save scumming my way up a mountain late in the game (you could very easily fall off the mountain trail and die). Save scumming was the only practical way of going up or down the mountains without magic. I had a single save game file and was using F5 and F7 to quickly load and save the game (IIRC they weren't quick save/load, but brought up the save/load interfaces). I walked off the mountain path and accidentally saved the game despite being dead. It was possible to save the game after you were dead. I had just discovered this the hard way. This was very frustrating to a quite young me. I never played that game again. This experience taught me to always use multiple rolling saves so I always had something to go back to. These days I always create multiple saves and typically will run up against the maximum save game limit if the game has one.
A bit off-topic: I know people nowadays use the term "save scumming" all over, even in news publications, but it's actually the derogatory form of the original term, "save scrumming". The term comes from a sport called rugby, where they would do something called a "scrum" or "scrummage" which is basically a way for them to __restart a play__. But since there are a ton of people that aren't familiar with rugby, they auto-correct in their minds to something more familiar... like scum which doesn't make as much sense, unless you're insulting someone. However, as you mentioned, in the age of Kings Quest, Command and Conquer, etc, save scrumming was almost a must, especially if we were younger at the time.
@@KeiNovakNo, it's not. The term originated with players of roguelike games. Since roguelikes are built around permadeath, reloading a save to escape a mistake or reroll a random event is considered “scummy.”
Its funny how often there is no real reason to limit saves, the only game that had bloated over 100mb on some levels was crysis1(and i think it shwowed the size in the menu) and effectively your save limit was disk space
I immediately knew where this story was going once I read "I had a single save game file and was using F5 and F7 to quickly load and save the game". We've all been there lmao
Oh my god this is so helpful. For the past month I'm learning how to do serialization for my unity project, and the moment I hear serialization my heart rate immediately went up :(
I don’t know how big of a feature it is, but I appreciate when RPG separate saves per-run, with manual saves, quick saves and auto saves being kept separate.
This video reminded me how nice it is that Rust is both a performant systems language, and has an *extremely* straightforward serialization system in the form of the Serde library. In all cases I've used it, serializing a structure only requires you to annotate the struct as (de/)serializable, and the code generation does the rest. Serializing and deserializing is just one function call. But also that serialization is only the starting point, and there's much more to this topic than just that.
Serialization is the worst form of creating a save game you can chose of. It is easy to use and comfortable from a developers perspective. But it is not a good form of a players perspective. Reason: Every memory can have a bit flip. This leads to incorrect data being stored and the serialization technology is particularly susceptible to this. Such errors can accumulate. It is therefore better to store the data in a structured manner using non-serialized technology. This allows the data to be checked for plausibility and errors have less of an impact. I once had a save game in Total War : ROME that was created via serialization. This save game was a late save game in the game and it always caused the game to crash on the next round.
@@OpenGL4ever Surely you could add error checking to the serialized version too? I've kinda thought that modern filesystems would deal with single bits being flipped, but evidently not. Still, I'd rather come up with a proper system that can recover from errors in the final serialized data. That honestly seems more robust and easier to me than fixing the issues in random save/load functions.
For loading I usually just read and parse the whole data from disk once and feed it into the load method for each class, and each class is responsible for picking the parts of the data that it cares about, so the method signature of all the load methods are basically the same. I like JSON (or whatever human readable format) as it makes it easier for people to go in and play around with the data, easier to debug/easier to get good bug reports as a tester can go in and look if some field has a bad value saved somehow, allows testers to modify their save manually to get themselves into a particular state they want to test (if you don't want to bother creating specific tools for that kind of thing), and it generally makes modding a lot easier.
It also provides better protection against a broken save due to a bit flip in memory. The data can not only be checked for plausibility during parsing, but can also be repaired at any time by the user. This type of savegame storage is therefore clearly preferable to serialization.
I know you said before you don't care about save-scumming, but as a player I was sometimes grateful to the designer when that choice was taken away from me. It's all too easy to optimize the fun out of your game when you press F5 every 10 seconds and reload after every setback. Of course I could just "not do it", but that's not how my brain is wired. In my game I have decided to lock the randomization in place before saving, so that save-scumming doesn't get you anything different. Some players hate it, some don't care, but there's no pleasing everyone I guess.
Sir i want to Thank you the way you explane the stuff. so everybody is able to understand, all so like you take your to explane. am lovin it. Thank you.
Such a great video (and channel). There aren't enough tutorials around that go through the important high-level game design problems in detail like this. I definitely feel like getting clear on what your problem is is halfway to solving it - whoever originally said that.
Once, I was working on a game where we implemented an auto-save feature on a background timer. Prior to that, we only had a quit-save, during which we deliberately broke AI, knowing that it would restore to mostly-the-same state on load. We ended up with some really weird AI behavior bugs, with the auto save regularly breaking the AI mid game. Most of these bugs surfaced long after we made the auto save update, making it a pretty hard bug to get to the root of.
You covered pretty much all of save/loading. I've never used saving raw memory using pointers myself though. But that does sound clever. The project I'm on now uses JSON with file versioning, so the loader knows what mods were installed at the time of save.
Versioning. IMHO, versioning your stored data is super important so that when you read data, you can verify that it's a version which you understand, and if it's an older version invoke different load-state code than for the latest version. Especially when writing out data serialized to a stream, based on my experience I think it's very important that each class/module that has its own custom write/read object code writes out a version number as very first thing for future use while reading back the data. Better to ignore a version number when you don't need it, then to need it and not have it! For data stored in a textual version this is also important but for raw data serialization it's even more important because often the stream will otherwise not contain any tags / markers to indicate what each value means, which field it maps to, and perhaps not even what type it is and how many bytes in size! (Of course if you use something like Protobuf for data serialization then the Protobuf framework takes on at least part of the responsibility of versioning your data and tagging the fields, types, and data sizes).
Keeping a couple of autosave or quicksave slots too, that way one 'bad save' is potentially recoverable. In a way that's kind of the point of autosaves (within the RPG genre the video seems to focus on). If the player forgets to save or the game suddenly crashes, they're not out an hour of progress.
Organization: I like a "player profile" option, to separate saves into character specific "folders". Its easier to abandon/pausing a character and switch to a new one, without getting a big messy list of old saves. Or if two people play on the same machine. And for a save slot, next to a screenshot, also showing some general state like level, location, maybe current active quest name.
I love when I can save a lot, not anytime anywhere, but at least before big battles and anytime when you are idle, on map etc. and I like quicksaves too, for instance in First Person RPGs. Not a big fan of checkpoints, but depends on game. For example Crash Bandicoot did it well. Edit: I used to be a fan of password saves which generated a code based on your statistics as well as level progress.
Kind of the same for me, though checkpoints can have a massive benefit. I remember at least two good examples for that: Alien vs predator 1, I remember running through corridors after hardly defeating a very hard enemy. With aliens on my heel. Shooting at every movement, panicking because I knew if I died I had to do all the fight again. It increased the stakes by a lot, compared to the typical save, die, reload... Similar experience was in Operation flashpoint. Dashing over a meadow to avoid a tank. Heart pumping, hearing the damn thing shot, explosion nearby, ducking running uphill into the cover of the trees, another close explosion. Then some shots, more running, sweating like I was running myself. Feeling more save after getting some more distance between me and the tank.. and then stumbling over a speznaz lying in a bush, reflex shooting, ducking, hiding... It's very hard to reproduce that with save/load everywhere... But also if you have to repeat that the 6th time because bad luck or, even worse, a have crash, then you start hating it again :D
@@Glimmlampe1982 That's why i didn't like Alien vs. Predator 1. They fixed this issue in Alien vs. Predator 2. It's no fun if you have to replay a level scene over and over again because you die before you finish each time. It's true that it increases the thrill, but the downside is more serious. So it is a big no no.
Thanks for the video, Tim. It came at just the right time! I've been troubled by file I/O and my save game system for months, and took a break to focus on other things. This video has given me the motivation to dive back into it.
@@Seanhmattsonit’s a bit overpunctuated but if I’m commenting shortly after upload you can bet imma say “Hi Tim, it’s us, everyone” or a similar variation 😊
Hey Tim! Question of the day: If you had to choose now, would you rather... Work on a game that becomes an instant cult classic and marks a generation but puts your studio at the edge of bankrupcy? Or... Make a basic bitch RPG that sells millions and your soul?
Now I know why I've put off save/load as a new Unity designer. My intuition was right. I'm almost ashamed that, when I was just a "gamer," my thinking was just "Yeah push F5, and it saves the game!" Thank you. This was one of the best.
Having worked in tech the last couple of millennia, I went the JSON route. It works really well at my early stage of development because when a test has had an issue on their machine, they can send me the file, and it's fairly easy to figure out what's gone wrong. The file size on my modest metroidvania is 30k, which isn't great (and i could probably get down by compressing), but save and load is actually still very fast. I save the game when you exit to the title screen, and I would say it's instantaneous, so if you're not writing out many megabytes of data, it will probably serve a lot of people's needs. Even better in c#, you get serialization basically for free so you just dump everything to a string and read write that (which has memory implications, but may be fine in a lot of applications). C# constructs my json into a series of structs, that each module knows how to hydrate into game state. It's really easy, flexible, trivial to add a subsystem, and human readable at the cost of memory and some efficiency which honestly you could even optimize out with a more efficient file writer if you really needed to, so would recommend.
JSON isn't the best (there are a few binary equivalent formats that would produce faster and smaller results while keeping the main benefits), but a save file that isn't 'fragile' is more important than maximum speed or space efficiency. If it comes down to it, you could always compress the result when you save it anyway.
@@GrandHighGamer Reading JSON is actually fairly optimised in .NET in terms of both speed and memory. It does come with certain assumptions, namely, its implementation is one of a depth-first and a single-pass forward-only reader. So even megabytes and megabytes of game state only need a few kilobytes at the JSON layer.
I'd be really interested in hearing more about save systems from a design point of view. I'm designing a game currently that I want to be dark and serious, and one where the player seriously considers their options due to consequence. However, I'm worried a game with no custom saves, and only auto-saves might not be fun at all to play. What do you see as the pros and cons to letting the player save when they want to. In other words is save-scumming something to worry about, or just let be?
Thanks for explaining the high level decisions you need to make for specific implementations with some examples. You explanation on how classes would implement save file IO is pretty much exactly how I was taught it.
Huh! I've always hated when games won't let me save more or less whenever I want. Never realized there was actuall coding issues behin it. I'll be more tollerent of save points in the future =)
Thank you this was thought provoking! I've worked on games that use fixed order save/load serializers and your description still made me really think. Hearing you describe them in this way made me think we should have written all the data into some hierarchical dynamic data structure in memory and then serialized that thing sequentially. Kind of like the memento pattern. You could add CRC checking to the end of each module entry which would hopefully make serialization issues more apparent. Also the actual file manipulation should be quite fast since you can blast through the whole map writing binary data.
In Eschalon the save anywhere feature allowed for an exploit to save after damaging an enemy but right before relinquishing your "turn", so basically you could do infinite damage by savescumming
It's important to consider not just the technical and implementation decisions, but also the impact your save system has on gameplay just by itself. You don't always even *want* the player to be able to save anywhere. Having to make risky choices without the safety net of a quicksave ten seconds can raise the tension and avoid encouraging savescumming, especially if the the game has a death mechanic beyond just "reload an earlier save", such as Dark Souls, Shadows of Mordor's nemesis orcs, or roguelite games with metaprogression between runs. The original Ori had a mechanic where you could spend a resource to create a save point anywhere, so you could pick and choose where you thought was tricky enough to be worth being able to reload from, Shovel Knight allowed you to break checkpoints in levels for bonus rewards, the N64 Majora's Mask only allowed permanent saves when you reset the three-day cycle, making each new loop feel like you really are restarting from the beginning, almost like a new roguelite run in itself, and of course Getting Over It is entirely based around the game always saving *everything* - even your mistakes. One of the major problems I had with Breath of the Wild's durability system was the fact that death had almost no consequence, because you could always just reload to moments before it happened, and so there was little reason to use up rare and powerful items when you could just do it in 2-3 tries with common ones. In areas where your progress isn't saved, such as the Master Sword trials and Eventide Island, you're much more inclined to make use of every tool at your disposal to avoid having to start again, rather than trying to save them for later. A related decision is save slots - can the player make multiple branching saves, allowing them to go back potentially hours to redo an earlier decision, or just one persistent slot per new game? There are also decisions to make not just about saving, but loading as well. Most "serious" CRPGs always want to save and reload the exact moment the save was made, but that's not the only option. In many Zelda games, while you can save anywhere, you always reload the game at a fixed point, such as Link's house in Ocarina of Time, or at the entrance of the current area rather than the exact spot you were in, and in Hollow Knight, the game constantly autosaves, but loading the game always places the PC at the last checkpoint they rested at. This provides a compromise between being able to save anywhere, ensuring that the player is always free to stop playing and resume later without losing progress, while also only needing to serialize key long-term variables rather than the entire state of the world at that exact moment. Of course, it's then up to you as a designer to ensure this can't break other parts of progression, perhaps bypassing a puzzle that required to you escape a room (just save and quit out!) or breaking a key sequence by saving and resetting all of the NPCs involved to their default positions. Another example from Dark Souls - the game lets you save and quit to the menu at any point, and while it does save your *position*, it only stores whether each NPC on the map is dead or alive and not their current state or position, so savvy players can charge through a whole horde of enemies towards some treasure, then quickly save and reload to reset and deaggro every one.
in modern games loading should not be too demanding, so if you have a cutscene that is supposed to be covering up a load, some how save that the player has seen the cutscene, and allow them to skip when the load is completed. or if the cutscene is not covering up a load/transition then have the scene be skippable.
I'm actually implementing Saving/Loading right now. For me, the extensive work is in the UI, as I made the decision to have "save rooms" like Castlevania: Symphony of the Night since my game is a open-world action JRPG with the same view point. And I love JSON.
I never even thought about things like this thanks this was very insightful and I had no idea I needed to learn about serialization to know where to start with saving and loading
The migration of files from a version to the next is always fun. Setting up a reeeeallly good testing suite is mandatory. Otherwise, the kind of esoteric bugs it can cause will drive you insane
Thanks for this overview, especially considering the depth of your experience. This is a topic that the theory seems simple on the surface, but still made my head spin when I thought of the details and what-ifs. I did get a little lost when you were talking about pointers but I figured it was a C++ thing. Thanks again.
I usually prefer save anywhere systems when I play games but checkpoints aren't always bad if they are not too far appart. They help with my obsession with saving every 5 minutes. What I absolutely hate is saving systems where you have to spend a resource to save. Luckily not many like that around.
Save slots were used especially in the past, when storage space was still tight and DOS limited you to 8 characters for the file name and 3 for its extension. The save slot allowed the player to assign a longer name internally and usually also showed the date if it was done correctly. At the file system level, everything was saved in the same folder as the program data. You then had a file for each of the available slots. Nowadays, of course, none of this is necessary anymore and slotless savegames are much better.
Wow. All the time during the video I was thinking about Bethesda games. Is it really possible to keep track of the precise position and orientation of every single interactable in-game-object present in each and every map of Skyrim, and still manage to have a usable save-load system both in terms of speed and file size? I mean, no wonder my Xbox360 couldn't manage it, back then, after one or two hundreds hours of world disarraying gameplay from my part! Thanks for your videos!
Their games are some of the few I had to purposely limit my saves for. Now it's become a habit to rotate through a handful of saves, even if they offer "unlimited" slots.
Bethesda games let you load the base game, and then layer 254 ESM/ESP formatted addons/mods on top. You might notice this is 1 short of 256: this is because mod slot FF is actually where Bethesda games store all mutated game state. Which is to say, a savegame in Skyrim is literally a mod that mutates the game state from default to whatever you've done and accomplished in game. Has many bugs, but IMO it's quite a clever approach.
@@billy65bob Yes, I guessed the save system for in-game-objects location and orientation had to be based on delta values of some sort vs the default initial state of the game world. At least that way the amount of data related to that aspect of the game world state, at any save, wouldn't reach its theoretical maximum until you've moved every single object you can move. I had no idea that, in order to implement such an approach, those games could use the same systems as mods, though: thanks for the info!
From memory the S.T.A.L.K.E.R. games had some weirdness with quick loading. The maps seem to dump as much data as possible between saves. So it could have been raining when a save was made, then be sunny on a load. NPCs also seemed to get dumped and respawned on a load, barring, but not always, those close to the player (at the least NPCs forget what they were doing before the load). There's a setting many mods for that game make viewable that determines this distance, and it is possible that on a reload the player could find themselves with NPCs spawning on top of them, where before the area was empty. Just interesting seeing that a developer presumably was doing what they could to cull memory on loading, and what effect that could have on gameplay. That seems an extreme example, and something that with older games modders try and fix where possible with engine rewrites (as how saving works is a baked in feature) - so long as source code gets leaked, or with porting games to work in other engines like Unity.
Hey Tim, I was wondering what your thoughts were on the increase in game industry layoffs lately. What does this mean for the future of games? What would you say to someone who wants to get into the industry? EA recently talked about incorporating generative AI right after firing hundreds of employees. I am worried game companies are looking for more and more ways to outsource and reduce employees in an already competitive industry. What are your thoughts on game unions? Thanks for all of the great videos!
I am working on a couple of videos, on both terrible things that happening in the game industry as well as changes that are happening (and yeah, there is overlap there). Keep in mind my perspective on things is very long term, and I have heard "doom and gloom" prophecies for literally DECADES...things like "consoles are dead", "PC gaming is dead", "turn based combat is dead", "RPGs are dead", "single player games are dead", "all artists are being replaced by 3D scanning and modeling", etc. So I breaking things into two videos...just how bad are things really...and people need to expect and adapt to change, because it is NOT going to stop. Expect them in a few weeks.
A very important point if you decide to have an auto-save only game, is to always save duplicates and a few previous saves. There's been some AA games that recently failed only because the saves had a chance to be corrupted with no way to recover even an older version.
Have you ever played Kingdom Come: Deliverance? I know you don't review games but would be interesting to know if you had an opinion about that game's saving.
This made me think about the Quicksave option in Skyrim. There's a persistent theory that they can absolutely break your saves, not just on that particular save but the whole game. The theory goes that the Quicksave massively bloats the save system, presumably saving far too much information, and that once the game has got to that point its basically impossible to load without a hard crash. Ive never actually seen any evidence of it (but with modding its not that hard to crash your game) but because i'm superstitious i never, ever have one or make one. A large portion of the modding community is the same. I know the original wasn't the most stable to start with tbf.
This may be helpful for someone. I defined a save system using polymorphism (a coding concept), with a base class called SaveableObject. So whenever I'd trigger an event saveRequested, it would make all saveable objects serialize themselves with a custom logic, allowing to serialize cherrypicked data for each object, and then each savew object woul dbe savec as a single file. This allowed me to reset the state of an object by simply deleting it's save file and debug certain things in my game. When load, all saveable objects would deserialize their save file and load their previous state. Now, having a million files is cool for debugging, but it sucks when youér already in production, so what you can do is have yoru save manager (the one that triggers the events) have a list of all saveable objects in the scene, and once all save triggers are completed, have him compress all save files in a single file, and remove the .zip extension to something like.sav, .doom, .yourGameEdgyAbreviation
Hi, Tim! You were talking about the technical aspect of loading and saving, I would love to hear your thoughts on the gameplay impact of different types of loading and saving.
for some reason I was expecting a video on Save scumming :D anyway, I personally found that Entity Component Systems are pretty handy when you need to serialize a state because they tend to stay very orderly and easy to read and write, as long as you don't use too many third party libraries that keep an internal states, like many AI libraries.
I would also add: "try to do it early"! I don't think a saving system is very fun to do. But it is easier if done early and to keep up with each new things you need to save/load. So you don't reach a point where you need to write the serialization function for hundreds of classes. It also helps a lot with testing to be able to load a save that will take you in the right conditions to test a bug/feature.
What I didn't realize when I started developing my game is that there's no point in development where you can "relax" about saving, it's constant consideration about what needs to be saved and how to save it. You might think your save system works well until you realize "Wait, can I actually save when X feature is active?" and often you realize the answer is "no" and you have to refactor stuff so it can. That's why I prefer the approach of disallowing saving during certain game states, save yourself hours of work, just make the player wait 10 seconds until they're back to a "normal" game state to save.
I'm recalling that the Elder Scrolls: Oblivion and Fallout 3/ New Vegas had the issue where Quick Saving would over time lead to the game crashing more. Modders created an alternative that had players Hard Save instead when they prompted the game. ...As somehow Quick Saves were coded vs Hard Saving (pressing Escape and clicking save) that was causing the problem.
Hey there! Great video as always! I have to say though: I disagree that text data is easier to handle compare to binary. If anything, I think it's the opposite: whether you convert your data to JSON or binary, you STILL have to serialize stuff, that hasn't changed. Now when you read the data, if you went for text, it means you have to parse it. It isn't just slower, it's also more difficult. If I'm loading a binary data, I just have to read bytes, and assuming I know the order my fields appear in, that's fairly easy to do. All of a sudden if you've got text you have to parse EVERYTHING, and in fact you don't even know how long your data is going to be, so you can't rely on fixed offsets to switch from a section to another. There's nothing text can do that binary can't, they both involve serialization and deserialization of some kind, but what it comes down to is: do you really need your data yo be human readable?
On rawdata-serialization that assumes to be on the right pointer I tend to optionally add (controlled with a define-flag) a checksum where it makes sense e.g. each section or even struct/class-type and assert for this checksum as part of the deserialization-process. Obviously you would need to put info about using checksum or not in your file-header along file-version and such so you know if you need to read the checksum as well. My advice epecially for the load-process: use as much asserts as possible to check if the data you use to recreate your state makes still sense....
I believe it's a good idea to use some sort of serialization framework. Some can generate load/save functions from class and field annotations; saves a lot of time and avoids a lot of bugs. Some frameworks allow to choose save format at runtime - so you can say use text format for development build and binary for release.
Save & Load is complicated! I learned a LOT more about CODING by trying to tackle Save & Load concepts! :D I made a test project, before starting my first big Unity game, that was just about working out Save & Load with some Rigid Body sphere balls, and a simple Player and AI characters. I still haven't decided how to handle Save & Load in my game. I love Quicksave / Quickload (where the full game state is snapshot/restored), but I think I'll avoid that for my first Unity game! We'll see. :D
Pro tip, if you're writing your own engine, and you want to do saving everywhere: A procedural or data-oriented programming paradigm is something to consider. Don't mix data and code, have a single monolithic program state, and your serialization will be easy peezy. This also makes bugs very reproducible. That is good for debugging. That is bad for the end user. Have tests
My favorite loading and saving state that is open world is Breath of the WIld's The Blood Moon rises which reset the world when the memory got to intense as far as I can speculate. So you could load in anywhere on the map but when the memory got too intense to crash the game, the blood moon rises cutscene would reset the memory so it doesn't have to remember the load state. I also liked Metroid Prime's loading system where you would have a bridge room that would do the loading and unloading of rooms. The problem with loading an open world is just that and I think BoTw solved the memory problem. But an unpopular opinion would be to have to pay for extra save slots or pay to autosave or quick save. People will hate it but as a publisher, I would push that on a studio to make more money. Jokes aside. At least, this will likely be stolen and then we will see these features done in games to increase revenue as pay to save becomes a thing. I would think that a basic flag system for what data is saved and what isn't like quests, etc and how many coins and items, etc that you have in your inventory and chests to be loaded in from a save. The save itself would be saving the flagged stuff and inventory and then it would reload at a point where you could easily test and run bugs. Autosave would simply save the game and then reload a fresh area when they reload. But if they want more than one save state, they will have to pay for each additional save state as well as maybe a monthly subscription to autosave. I am sorry if they steal this idea.
Much as I hate Bethesda, I think it's kind of cool that Save Games for Bethesda's games are literally just a mod. It's mod 255 (or FF) to be exact, if you ever wondered why you're restricted to 254 addons/mods of the ESP/ESM format. 10:40 The easy solution I used for this, was to put a EOF check inside every single loop or read of variable length (i.e. strings) - It's pretty obvious you messed up when the loop wants to read 1787571723 items (and EOFs) instead of say a more reasonable number like 206. Even if it doesn't bug out at the exact spot, it usually blows up close enough to the problem that I can quickly find the mismatched spot and fix it. That said, I don't think binary formats are very much in vogue anymore; quite likely that games these days would just serialise either a JSON file or a series of them, and then shove them into a compressed container if you're lucky. Which avoids the biggest problem with binary formats: inter-version compatibility.
Topic of the moment! I was wanting your opinion of the Subnautica load/save mechanic which is one of the most bizarre I've ever encountered. You can't save scum and you are more or less in semi- permanent Iron Man mode. Basically if you die you lose everything you got since you last were in a base, and that stuff is also gone from the world. This in a game where resources never respawn. There is no Load/Restore capability at all. Which makes me struggle to understand why they even have a Save option at all. "Save" seems to mean "Don't lose my progress when I Quit" - surely that should be the sane default??!
It is worth noting that until recently with super fast SSDs it was basically always faster to compress data and write that. The time saved on writes made up for the time spent on the compression, especially for verbose human readable things since they tend to compress well. I think now you'd have test. The downside is that the best compression means you can't really seek in the file. Modern systems have shifted a lot of these sorts of trade offs a fair bit with the changing performance characteristics of storage. These days it might be better to just allocate one big memory block that you don't expect save data to exceed, write to that then write it to disk in one go. You run the risk of bugs around handling data being larger than the buffer if that doesn't hapoen in testing, which it won't if you choose the buffer size right.
I now greatly appreciate all the old pc games that did have quicksaves everywhere. My save-scummiest games are Max Payne 1, Morrowind, and Blade of Darkness.
I remember reading the shocking file sizes in Crysis 1, the longer levels where I demolished a lot of things had over 100mb and I was like wtf. But if they never despawn everything and track a ton of high precision physics that's what you get. Maybe it could be shrunk more but for something that large it loaded quick too. Sometimes the type of game dictates what you save and when and you cannot save things in progress (basically all mission based or racing games)
I was a DBA for 25+ years, so I know saving across versions is a real pain. Most online games I've seen will just run an update and get everyone on the same version. But if you're running locally, or in an enterprise environment, you might have to be compatible for 3 or 4 versions back. I'm getting a headache just remembering some of the problems, so pardon me while I look for a bottle of aspirin. 😵💫
That was very interesting. I always wanted to hear about save/load from a developer. I wish you also made comments on how you deal with encryption or whatever else you use to protect save games against tampering when saving on local disk. Also, some comments on cloud saves / sync would be interesting.
Useless complexity for offline games where hacks/mods arent a problem. If youre going for online leaderbaords, I've seen a indie dev periodically check and ban records that arent posted on the speedrun site.
When Tim mentioned that he would add a save and load method on every pertinent class I immediately remembered a couple of programming design patterns I studied last month. Really good stuff!
I was making a game as a hobby a while back. First person horror game, simple I thought. Oh boy, why did i decide to add save game at the end of the development 😅. It delayed the project atleast 50%.
Its safer to have the save-file slit into some meta-data and general progression data (like level, inventory, story state etc) in some more robust text format, and then the concrete serialized world data of all objects in a binary format. In case the save system breaks with a patch, there is at least the fallback option to reset to some town, and have the main player progression restorable. A other objects and NPCs reset to some default state.
It occurs to me that a lot of these technical conveniences end up being QoL for players as well. Allowing saves during combat or physics events can easily cause a locked save. As a compulsive quick-saver I am quite glad if it doesn't work a second before death.
I took the easy way with my project, you can't save during combat and that cuts the effort in half instantly, I don't save anything related to AI because they would all be in Idle state, and they would be stationary or moving very slowly, so I could just store the location and rotation. (And health etc.)
Text vs. binary is orthogonal to how easy or hard it is to save stuff. Some of the serialization libraries let you select format, compression, and what not. What matters more is whether data types you need are supported and with the guarantees you expect. Are your lists ordered? It is guaranteed by JSON standard (and likely most implementations agree) but this doesn't have to be true for other data formats. One thing you didn't mention, Tim, is that per system involved you're also making conscious decisions about state not being preserved. Your interactable physics objects (boxes, crates, whatever) may need to be stored (if your emergent gameplay depends on them) but debris, even if it reacts to player walk, probably doesn't have to be stored. Players are unlikely to notice that some rocks returned to their default location after load. You may have to store open/closed state for door that maintain their state and are somehow critical for the story or gameplay. But door that aren't could return to default (likely closed) state. You can have other importance/relevancy criteria as well. Sometimes state far from the player can return to defaults under assumption that world lives and if you return to a tavern after a week it's likely someone closed the door you opened (and put a new lock on it for a good measure). But yeah, overall saving and loading especially with versioning (which is mandatory now that games have patches) is hard. Imagine your save contains quest state and quest had bug that needed to be fixed for a patch. Now your state no longer means what it did before and you need a custom patching/conversion happening on load. Madness.
I love it when saving is part of the game mechanic itself like the classic only save when you sleep or as Kingdom Come did it, it was a potion you drink to save , which also made it only possible to save during this 'low-change' situation or if you want to save in combat you have to be in a somewhat safe position to be able to finish the bottle of saving serum.
Question for you Tim: what are your thoughts on NPC vendor currency limits? Do you prefer an infinite vendor cash system, allowing players a one-stop-shop to sell all their loot and not worry about bleeding the vendor dry or do you think giving vendors a finite currency bank is a better option? Some other system? I've played so many games where the simple act of selling all your loot becomes a time-consuming struggle since the choice was made to use NPC vendors with small, finite banks and/or the loot item cost vs. vendor bank scale was out of balance. From a player's perspective, aside from maybe immersion reasons, it seems like using an infinite system would help the player stay focused on gameplay rather than getting bogged down with UI/system management.
I like when the currency is limited but selling to certain shops gives more money depending on what the shop is selling. (Sell armor to the armory, sell potions to the alchemist, etc) That way if you just dump everything into one shop you’ll rarely hit the currency limit, since the items have lesser value. But this also requires clean city design so walking between shops doesn’t take up too much time. I also like when there’s regional price mark ups like in Kenshi. That way when you’re doing long haul trades it incentivizes hitting up multiple cities for trade. (Again map design can make this overly tedious though)
NetHack had pretty simple solution I rather liked: Have the store give the player store credit they can redeem in the future. Of course Nethack players instead used this to 'pre-pay' because they often got afflictions that would make them teleport randomly, and if you were in a shop and left without settling your tab, the cops came after you.
I'm just going to point out that it's even harder than what you say. You didn't say anything about endianness and cross-platform saves. I mean, dumping an int in C is indeed fast and efficient, but it's also not cross-platform at all unless you think about the ordering of your bits. Some libraries offer binary and text save formats, which can be invaluable for debugging (stuff like protobuf and even C++ boost serialization if I remember well). However, saving pointers dumbly (like boost serialization did and maybe serde in Rust?) can easily lead to stack overflows, which means you may have to recompile your binary with larger stack space and hope. However, it would have been nice to speak a little bit about the design choices, not just the technical limitations around saving and loading. e.g. Why you would want to allow only save&quit, or why you don't want to allow save in combat. I know not being able to save in combat in Battle Brothers is a big plus for me because otherwise I could feel tempted to save and just savescum "bad luck" away, but that reason would vanish if the game didn't have any randomness (like chess).
While it's good to cater for endianness, you are extremely unlikely to encounter a Big Endian system in the wild these days. The last consumer product I know of that used Big-Endian were PowerPC based macs, and those were discontinued in 2006.
hi Tim, i am an inexperienced game designer who loves your RPGs and your channel has helped me a lot. thank you for being so generous with the knowledge you have gained over the years
Tim is definitely a generous teacher which is just another way to say he is a great teacher. Thanks Tim.
Here is a tip: implement load/save as early as possible. So you can figure it out as you go along + you don't have to stress about it + it will not be a huge task to do. (And the same is true for mod support for the game)
Second this and the same goes for networking. Retrofitting these is a huge headache.
you know its time to go to bed when you're still awake and tim uploaded
Lololol been there
unironically thats happened to me at least a couple time while Ive been up playing Temple
I think the most important thing is to implement saving and loading as early as possible in development. It makes testing everything so much easier if you can save a specific situation and load it later.
Here's a strange behaviour I found with the save system in the original Kings Quest III. I was save scumming my way up a mountain late in the game (you could very easily fall off the mountain trail and die). Save scumming was the only practical way of going up or down the mountains without magic. I had a single save game file and was using F5 and F7 to quickly load and save the game (IIRC they weren't quick save/load, but brought up the save/load interfaces). I walked off the mountain path and accidentally saved the game despite being dead. It was possible to save the game after you were dead. I had just discovered this the hard way. This was very frustrating to a quite young me. I never played that game again.
This experience taught me to always use multiple rolling saves so I always had something to go back to. These days I always create multiple saves and typically will run up against the maximum save game limit if the game has one.
A bit off-topic: I know people nowadays use the term "save scumming" all over, even in news publications, but it's actually the derogatory form of the original term, "save scrumming". The term comes from a sport called rugby, where they would do something called a "scrum" or "scrummage" which is basically a way for them to __restart a play__. But since there are a ton of people that aren't familiar with rugby, they auto-correct in their minds to something more familiar... like scum which doesn't make as much sense, unless you're insulting someone. However, as you mentioned, in the age of Kings Quest, Command and Conquer, etc, save scrumming was almost a must, especially if we were younger at the time.
@@KeiNovakNo, it's not. The term originated with players of roguelike games. Since roguelikes are built around permadeath, reloading a save to escape a mistake or reroll a random event is considered “scummy.”
Its funny how often there is no real reason to limit saves, the only game that had bloated over 100mb on some levels was crysis1(and i think it shwowed the size in the menu) and effectively your save limit was disk space
I immediately knew where this story was going once I read "I had a single save game file and was using F5 and F7 to quickly load and save the game".
We've all been there lmao
You got softlocked
This is why I favor passwords. Especially for games like Scrabble.
I find saving and loading to be one of the most challenging parts of my game dev process.
Every video that you make Tim, is absolute gold! We need more people like you that share the ancient tribal knowledge.
Oh my god this is so helpful. For the past month I'm learning how to do serialization for my unity project, and the moment I hear serialization my heart rate immediately went up :(
As a kid who had a daily half-hour time limit for video games, games that could save anytime anywhere blew my mind.
I don’t know how big of a feature it is, but I appreciate when RPG separate saves per-run, with manual saves, quick saves and auto saves being kept separate.
I just started to learn coding via Harvard's cs50 course online and I understood some of that! Int, string, double, float! How exciting!
Thanks, Tim!
Keep going!
CS50 is amazing!
This video reminded me how nice it is that Rust is both a performant systems language, and has an *extremely* straightforward serialization system in the form of the Serde library. In all cases I've used it, serializing a structure only requires you to annotate the struct as (de/)serializable, and the code generation does the rest. Serializing and deserializing is just one function call.
But also that serialization is only the starting point, and there's much more to this topic than just that.
Python and Java have similar systems. However, any change to the class can completely break it. I found it the hard way.
Serialization is the worst form of creating a save game you can chose of. It is easy to use and comfortable from a developers perspective. But it is not a good form of a players perspective.
Reason:
Every memory can have a bit flip. This leads to incorrect data being stored and the serialization technology is particularly susceptible to this. Such errors can accumulate. It is therefore better to store the data in a structured manner using non-serialized technology. This allows the data to be checked for plausibility and errors have less of an impact.
I once had a save game in Total War : ROME that was created via serialization. This save game was a late save game in the game and it always caused the game to crash on the next round.
@@OpenGL4ever Surely you could add error checking to the serialized version too? I've kinda thought that modern filesystems would deal with single bits being flipped, but evidently not. Still, I'd rather come up with a proper system that can recover from errors in the final serialized data. That honestly seems more robust and easier to me than fixing the issues in random save/load functions.
I cannot look at his T-shirt without hearing the Spacer's Choice jingle in my head. Damn you, Tim Cain!!!
It's not the best jingle it's Spacer's jingle!
For loading I usually just read and parse the whole data from disk once and feed it into the load method for each class, and each class is responsible for picking the parts of the data that it cares about, so the method signature of all the load methods are basically the same.
I like JSON (or whatever human readable format) as it makes it easier for people to go in and play around with the data, easier to debug/easier to get good bug reports as a tester can go in and look if some field has a bad value saved somehow, allows testers to modify their save manually to get themselves into a particular state they want to test (if you don't want to bother creating specific tools for that kind of thing), and it generally makes modding a lot easier.
It also provides better protection against a broken save due to a bit flip in memory. The data can not only be checked for plausibility during parsing, but can also be repaired at any time by the user. This type of savegame storage is therefore clearly preferable to serialization.
You're seriously a treasure trove of knowledge and wisdom. I enjoy your content so much!
I'm in the same place, he's the man.
I know you said before you don't care about save-scumming, but as a player I was sometimes grateful to the designer when that choice was taken away from me. It's all too easy to optimize the fun out of your game when you press F5 every 10 seconds and reload after every setback. Of course I could just "not do it", but that's not how my brain is wired.
In my game I have decided to lock the randomization in place before saving, so that save-scumming doesn't get you anything different. Some players hate it, some don't care, but there's no pleasing everyone I guess.
you got to save before you load, know when to hold em, and know when to quicksave
.. know when to walk away, know when to Ctrl Alt Tab...
@@gilgamecha And when the game intercepts Alt-F4 and it tells you "Hey friend, you didn't mean to do that." Then, it loops you back into the game.
You never counttttt yourrrrr pixels, when youre settingggg resssolution @@gilgamecha
😮You are bringing the hell talking about this matter
I really appreciate this channel and your pov. Even if im not pursuing game dev
Sir i want to Thank you the way you explane the stuff. so everybody is able to understand, all so like you take your to explane. am lovin it. Thank you.
Such a great video (and channel). There aren't enough tutorials around that go through the important high-level game design problems in detail like this. I definitely feel like getting clear on what your problem is is halfway to solving it - whoever originally said that.
Yea I really wish we had more channels like this.
Once, I was working on a game where we implemented an auto-save feature on a background timer. Prior to that, we only had a quit-save, during which we deliberately broke AI, knowing that it would restore to mostly-the-same state on load. We ended up with some really weird AI behavior bugs, with the auto save regularly breaking the AI mid game. Most of these bugs surfaced long after we made the auto save update, making it a pretty hard bug to get to the root of.
You covered pretty much all of save/loading. I've never used saving raw memory using pointers myself though. But that does sound clever.
The project I'm on now uses JSON with file versioning, so the loader knows what mods were installed at the time of save.
Versioning.
IMHO, versioning your stored data is super important so that when you read data, you can verify that it's a version which you understand, and if it's an older version invoke different load-state code than for the latest version.
Especially when writing out data serialized to a stream, based on my experience I think it's very important that each class/module that has its own custom write/read object code writes out a version number as very first thing for future use while reading back the data.
Better to ignore a version number when you don't need it, then to need it and not have it!
For data stored in a textual version this is also important but for raw data serialization it's even more important because often the stream will otherwise not contain any tags / markers to indicate what each value means, which field it maps to, and perhaps not even what type it is and how many bytes in size!
(Of course if you use something like Protobuf for data serialization then the Protobuf framework takes on at least part of the responsibility of versioning your data and tagging the fields, types, and data sizes).
Keeping a couple of autosave or quicksave slots too, that way one 'bad save' is potentially recoverable. In a way that's kind of the point of autosaves (within the RPG genre the video seems to focus on). If the player forgets to save or the game suddenly crashes, they're not out an hour of progress.
Great advice!
This has been a thorn in my side for all of the projects I have worked on so far. Glad that it’s not just me haha
Organization: I like a "player profile" option, to separate saves into character specific "folders". Its easier to abandon/pausing a character and switch to a new one, without getting a big messy list of old saves. Or if two people play on the same machine. And for a save slot, next to a screenshot, also showing some general state like level, location, maybe current active quest name.
I love when I can save a lot, not anytime anywhere, but at least before big battles and anytime when you are idle, on map etc. and I like quicksaves too, for instance in First Person RPGs. Not a big fan of checkpoints, but depends on game. For example Crash Bandicoot did it well.
Edit: I used to be a fan of password saves which generated a code based on your statistics as well as level progress.
Kind of the same for me, though checkpoints can have a massive benefit.
I remember at least two good examples for that:
Alien vs predator 1, I remember running through corridors after hardly defeating a very hard enemy. With aliens on my heel. Shooting at every movement, panicking because I knew if I died I had to do all the fight again. It increased the stakes by a lot, compared to the typical save, die, reload...
Similar experience was in Operation flashpoint. Dashing over a meadow to avoid a tank. Heart pumping, hearing the damn thing shot, explosion nearby, ducking running uphill into the cover of the trees, another close explosion. Then some shots, more running, sweating like I was running myself. Feeling more save after getting some more distance between me and the tank.. and then stumbling over a speznaz lying in a bush, reflex shooting, ducking, hiding...
It's very hard to reproduce that with save/load everywhere... But also if you have to repeat that the 6th time because bad luck or, even worse, a have crash, then you start hating it again :D
@@Glimmlampe1982 That's why i didn't like Alien vs. Predator 1. They fixed this issue in Alien vs. Predator 2. It's no fun if you have to replay a level scene over and over again because you die before you finish each time. It's true that it increases the thrill, but the downside is more serious. So it is a big no no.
Thanks for the video, Tim. It came at just the right time! I've been troubled by file I/O and my save game system for months, and took a break to focus on other things.
This video has given me the motivation to dive back into it.
Hi, Tim. It's us, everyone !
And me😊
This comment is amazing.
@@Seanhmattsonit’s a bit overpunctuated but if I’m commenting shortly after upload you can bet imma say “Hi Tim, it’s us, everyone” or a similar variation 😊
This has been one of those things I thought I would understand, but quickly was humbled by. Thank you so much for this video!
Hey Tim! Question of the day: If you had to choose now, would you rather...
Work on a game that becomes an instant cult classic and marks a generation but puts your studio at the edge of bankrupcy?
Or...
Make a basic bitch RPG that sells millions and your soul?
Hey Tim. Hope you're having a great day!
Now I know why I've put off save/load as a new Unity designer. My intuition was right. I'm almost ashamed that, when I was just a "gamer," my thinking was just "Yeah push F5, and it saves the game!" Thank you. This was one of the best.
Having worked in tech the last couple of millennia, I went the JSON route. It works really well at my early stage of development because when a test has had an issue on their machine, they can send me the file, and it's fairly easy to figure out what's gone wrong. The file size on my modest metroidvania is 30k, which isn't great (and i could probably get down by compressing), but save and load is actually still very fast. I save the game when you exit to the title screen, and I would say it's instantaneous, so if you're not writing out many megabytes of data, it will probably serve a lot of people's needs. Even better in c#, you get serialization basically for free so you just dump everything to a string and read write that (which has memory implications, but may be fine in a lot of applications). C# constructs my json into a series of structs, that each module knows how to hydrate into game state. It's really easy, flexible, trivial to add a subsystem, and human readable at the cost of memory and some efficiency which honestly you could even optimize out with a more efficient file writer if you really needed to, so would recommend.
JSON isn't the best (there are a few binary equivalent formats that would produce faster and smaller results while keeping the main benefits), but a save file that isn't 'fragile' is more important than maximum speed or space efficiency. If it comes down to it, you could always compress the result when you save it anyway.
@@GrandHighGamer Reading JSON is actually fairly optimised in .NET in terms of both speed and memory.
It does come with certain assumptions, namely, its implementation is one of a depth-first and a single-pass forward-only reader.
So even megabytes and megabytes of game state only need a few kilobytes at the JSON layer.
I'd be really interested in hearing more about save systems from a design point of view.
I'm designing a game currently that I want to be dark and serious, and one where the player seriously considers their options due to consequence. However, I'm worried a game with no custom saves, and only auto-saves might not be fun at all to play.
What do you see as the pros and cons to letting the player save when they want to. In other words is save-scumming something to worry about, or just let be?
Thanks for explaining the high level decisions you need to make for specific implementations with some examples. You explanation on how classes would implement save file IO is pretty much exactly how I was taught it.
Getting into some of the technical stuff is really helpful. Thanks for your insight
I sincerely, deeply appreciate you, Tim.
I could listen to you all day this is good stuff even if its obvious
some specific things/cases I've never thought about
This is a great topic. In my own game, I severely underestimated the work needed to code such a system.
I don't remember what game traumatized me but I have a superstition that I shouldn't save when my character is moving in an elevator 🙂
Probably Fallout 4 where elevators are often secret load screens.
Huh! I've always hated when games won't let me save more or less whenever I want. Never realized there was actuall coding issues behin it. I'll be more tollerent of save points in the future =)
Thank you this was thought provoking!
I've worked on games that use fixed order save/load serializers and your description still made me really think. Hearing you describe them in this way made me think we should have written all the data into some hierarchical dynamic data structure in memory and then serialized that thing sequentially. Kind of like the memento pattern. You could add CRC checking to the end of each module entry which would hopefully make serialization issues more apparent. Also the actual file manipulation should be quite fast since you can blast through the whole map writing binary data.
In Eschalon the save anywhere feature allowed for an exploit to save after damaging an enemy but right before relinquishing your "turn", so basically you could do infinite damage by savescumming
leave it to Tim to have a video on my feed right as I open youtube and it's an insightful take on something I literally never thought of
It's important to consider not just the technical and implementation decisions, but also the impact your save system has on gameplay just by itself. You don't always even *want* the player to be able to save anywhere. Having to make risky choices without the safety net of a quicksave ten seconds can raise the tension and avoid encouraging savescumming, especially if the the game has a death mechanic beyond just "reload an earlier save", such as Dark Souls, Shadows of Mordor's nemesis orcs, or roguelite games with metaprogression between runs. The original Ori had a mechanic where you could spend a resource to create a save point anywhere, so you could pick and choose where you thought was tricky enough to be worth being able to reload from, Shovel Knight allowed you to break checkpoints in levels for bonus rewards, the N64 Majora's Mask only allowed permanent saves when you reset the three-day cycle, making each new loop feel like you really are restarting from the beginning, almost like a new roguelite run in itself, and of course Getting Over It is entirely based around the game always saving *everything* - even your mistakes. One of the major problems I had with Breath of the Wild's durability system was the fact that death had almost no consequence, because you could always just reload to moments before it happened, and so there was little reason to use up rare and powerful items when you could just do it in 2-3 tries with common ones. In areas where your progress isn't saved, such as the Master Sword trials and Eventide Island, you're much more inclined to make use of every tool at your disposal to avoid having to start again, rather than trying to save them for later. A related decision is save slots - can the player make multiple branching saves, allowing them to go back potentially hours to redo an earlier decision, or just one persistent slot per new game?
There are also decisions to make not just about saving, but loading as well. Most "serious" CRPGs always want to save and reload the exact moment the save was made, but that's not the only option. In many Zelda games, while you can save anywhere, you always reload the game at a fixed point, such as Link's house in Ocarina of Time, or at the entrance of the current area rather than the exact spot you were in, and in Hollow Knight, the game constantly autosaves, but loading the game always places the PC at the last checkpoint they rested at.
This provides a compromise between being able to save anywhere, ensuring that the player is always free to stop playing and resume later without losing progress, while also only needing to serialize key long-term variables rather than the entire state of the world at that exact moment. Of course, it's then up to you as a designer to ensure this can't break other parts of progression, perhaps bypassing a puzzle that required to you escape a room (just save and quit out!) or breaking a key sequence by saving and resetting all of the NPCs involved to their default positions. Another example from Dark Souls - the game lets you save and quit to the menu at any point, and while it does save your *position*, it only stores whether each NPC on the map is dead or alive and not their current state or position, so savvy players can charge through a whole horde of enemies towards some treasure, then quickly save and reload to reset and deaggro every one.
in modern games loading should not be too demanding, so if you have a cutscene that is supposed to be covering up a load, some how save that the player has seen the cutscene, and allow them to skip when the load is completed.
or if the cutscene is not covering up a load/transition then have the scene be skippable.
I'm actually implementing Saving/Loading right now. For me, the extensive work is in the UI, as I made the decision to have "save rooms" like Castlevania: Symphony of the Night since my game is a open-world action JRPG with the same view point.
And I love JSON.
I never even thought about things like this thanks this was very insightful and I had no idea I needed to learn about serialization to know where to start with saving and loading
The migration of files from a version to the next is always fun. Setting up a reeeeallly good testing suite is mandatory. Otherwise, the kind of esoteric bugs it can cause will drive you insane
Thanks for this overview, especially considering the depth of your experience. This is a topic that the theory seems simple on the surface, but still made my head spin when I thought of the details and what-ifs. I did get a little lost when you were talking about pointers but I figured it was a C++ thing. Thanks again.
I usually prefer save anywhere systems when I play games but checkpoints aren't always bad if they are not too far appart. They help with my obsession with saving every 5 minutes. What I absolutely hate is saving systems where you have to spend a resource to save. Luckily not many like that around.
Save slots were used especially in the past, when storage space was still tight and DOS limited you to 8 characters for the file name and 3 for its extension. The save slot allowed the player to assign a longer name internally and usually also showed the date if it was done correctly. At the file system level, everything was saved in the same folder as the program data. You then had a file for each of the available slots.
Nowadays, of course, none of this is necessary anymore and slotless savegames are much better.
Wow.
All the time during the video I was thinking about Bethesda games.
Is it really possible to keep track of the precise position and orientation of every single interactable in-game-object present in each and every map of Skyrim, and still manage to have a usable save-load system both in terms of speed and file size?
I mean, no wonder my Xbox360 couldn't manage it, back then, after one or two hundreds hours of world disarraying gameplay from my part!
Thanks for your videos!
That is indeed impressive.
Their games are some of the few I had to purposely limit my saves for. Now it's become a habit to rotate through a handful of saves, even if they offer "unlimited" slots.
Bethesda games let you load the base game, and then layer 254 ESM/ESP formatted addons/mods on top.
You might notice this is 1 short of 256: this is because mod slot FF is actually where Bethesda games store all mutated game state.
Which is to say, a savegame in Skyrim is literally a mod that mutates the game state from default to whatever you've done and accomplished in game.
Has many bugs, but IMO it's quite a clever approach.
@@billy65bob
Yes, I guessed the save system for in-game-objects location and orientation had to be based on delta values of some sort vs the default initial state of the game world.
At least that way the amount of data related to that aspect of the game world state, at any save, wouldn't reach its theoretical maximum until you've moved every single object you can move.
I had no idea that, in order to implement such an approach,
those games could use the same systems as mods, though:
thanks for the info!
Always a new angle to consider. Thank you, sir!
7:35 games that let me name my saves are the best. I have so much fun describing what I was doing in excruciating detail.
This is a very informative video. Greatly appreciated 👏
I like saving, but I really like being able to load when I need to.
From memory the S.T.A.L.K.E.R. games had some weirdness with quick loading. The maps seem to dump as much data as possible between saves. So it could have been raining when a save was made, then be sunny on a load. NPCs also seemed to get dumped and respawned on a load, barring, but not always, those close to the player (at the least NPCs forget what they were doing before the load). There's a setting many mods for that game make viewable that determines this distance, and it is possible that on a reload the player could find themselves with NPCs spawning on top of them, where before the area was empty.
Just interesting seeing that a developer presumably was doing what they could to cull memory on loading, and what effect that could have on gameplay. That seems an extreme example, and something that with older games modders try and fix where possible with engine rewrites (as how saving works is a baked in feature) - so long as source code gets leaked, or with porting games to work in other engines like Unity.
Hey Tim, I was wondering what your thoughts were on the increase in game industry layoffs lately. What does this mean for the future of games? What would you say to someone who wants to get into the industry? EA recently talked about incorporating generative AI right after firing hundreds of employees. I am worried game companies are looking for more and more ways to outsource and reduce employees in an already competitive industry. What are your thoughts on game unions? Thanks for all of the great videos!
I am working on a couple of videos, on both terrible things that happening in the game industry as well as changes that are happening (and yeah, there is overlap there). Keep in mind my perspective on things is very long term, and I have heard "doom and gloom" prophecies for literally DECADES...things like "consoles are dead", "PC gaming is dead", "turn based combat is dead", "RPGs are dead", "single player games are dead", "all artists are being replaced by 3D scanning and modeling", etc. So I breaking things into two videos...just how bad are things really...and people need to expect and adapt to change, because it is NOT going to stop.
Expect them in a few weeks.
@@CainOnGames looking forward to it! I think the future of gaming is going to be exciting.
A very important point if you decide to have an auto-save only game, is to always save duplicates and a few previous saves. There's been some AA games that recently failed only because the saves had a chance to be corrupted with no way to recover even an older version.
Have you ever played Kingdom Come: Deliverance? I know you don't review games but would be interesting to know if you had an opinion about that game's saving.
I have reached a state where without audio and just subtitles I can hear Tim speak
Tim, thank you so much for every video you put out!
This made me think about the Quicksave option in Skyrim. There's a persistent theory that they can absolutely break your saves, not just on that particular save but the whole game. The theory goes that the Quicksave massively bloats the save system, presumably saving far too much information, and that once the game has got to that point its basically impossible to load without a hard crash. Ive never actually seen any evidence of it (but with modding its not that hard to crash your game) but because i'm superstitious i never, ever have one or make one. A large portion of the modding community is the same. I know the original wasn't the most stable to start with tbf.
This may be helpful for someone. I defined a save system using polymorphism (a coding concept), with a base class called SaveableObject. So whenever I'd trigger an event saveRequested, it would make all saveable objects serialize themselves with a custom logic, allowing to serialize cherrypicked data for each object, and then each savew object woul dbe savec as a single file. This allowed me to reset the state of an object by simply deleting it's save file and debug certain things in my game. When load, all saveable objects would deserialize their save file and load their previous state. Now, having a million files is cool for debugging, but it sucks when youér already in production, so what you can do is have yoru save manager (the one that triggers the events) have a list of all saveable objects in the scene, and once all save triggers are completed, have him compress all save files in a single file, and remove the .zip extension to something like.sav, .doom, .yourGameEdgyAbreviation
Hi, Tim! You were talking about the technical aspect of loading and saving, I would love to hear your thoughts on the gameplay impact of different types of loading and saving.
for some reason I was expecting a video on Save scumming :D anyway, I personally found that Entity Component Systems are pretty handy when you need to serialize a state because they tend to stay very orderly and easy to read and write, as long as you don't use too many third party libraries that keep an internal states, like many AI libraries.
I would also add: "try to do it early"! I don't think a saving system is very fun to do. But it is easier if done early and to keep up with each new things you need to save/load. So you don't reach a point where you need to write the serialization function for hundreds of classes. It also helps a lot with testing to be able to load a save that will take you in the right conditions to test a bug/feature.
For a moment I thought this will be about save scumming 😅
I remember in both Fallout 1 and Fallout 2 when they were major patches early on that the patches broke the save games and I had to start over again
What I didn't realize when I started developing my game is that there's no point in development where you can "relax" about saving, it's constant consideration about what needs to be saved and how to save it. You might think your save system works well until you realize "Wait, can I actually save when X feature is active?" and often you realize the answer is "no" and you have to refactor stuff so it can. That's why I prefer the approach of disallowing saving during certain game states, save yourself hours of work, just make the player wait 10 seconds until they're back to a "normal" game state to save.
I'm recalling that the Elder Scrolls: Oblivion and Fallout 3/ New Vegas had the issue where Quick Saving would over time lead to the game crashing more. Modders created an alternative that had players Hard Save instead when they prompted the game. ...As somehow Quick Saves were coded vs Hard Saving (pressing Escape and clicking save) that was causing the problem.
Hey there! Great video as always! I have to say though: I disagree that text data is easier to handle compare to binary. If anything, I think it's the opposite: whether you convert your data to JSON or binary, you STILL have to serialize stuff, that hasn't changed. Now when you read the data, if you went for text, it means you have to parse it. It isn't just slower, it's also more difficult. If I'm loading a binary data, I just have to read bytes, and assuming I know the order my fields appear in, that's fairly easy to do. All of a sudden if you've got text you have to parse EVERYTHING, and in fact you don't even know how long your data is going to be, so you can't rely on fixed offsets to switch from a section to another.
There's nothing text can do that binary can't, they both involve serialization and deserialization of some kind, but what it comes down to is: do you really need your data yo be human readable?
"You cannot save while jumping or Falling" makes so much sense now lol
On rawdata-serialization that assumes to be on the right pointer I tend to optionally add (controlled with a define-flag) a checksum where it makes sense e.g. each section or even struct/class-type and assert for this checksum as part of the deserialization-process. Obviously you would need to put info about using checksum or not in your file-header along file-version and such so you know if you need to read the checksum as well.
My advice epecially for the load-process: use as much asserts as possible to check if the data you use to recreate your state makes still sense....
I believe it's a good idea to use some sort of serialization framework. Some can generate load/save functions from class and field annotations; saves a lot of time and avoids a lot of bugs. Some frameworks allow to choose save format at runtime - so you can say use text format for development build and binary for release.
Save & Load is complicated! I learned a LOT more about CODING by trying to tackle Save & Load concepts! :D
I made a test project, before starting my first big Unity game, that was just about working out Save & Load with some Rigid Body sphere balls, and a simple Player and AI characters.
I still haven't decided how to handle Save & Load in my game. I love Quicksave / Quickload (where the full game state is snapshot/restored), but I think I'll avoid that for my first Unity game!
We'll see. :D
Pro tip, if you're writing your own engine, and you want to do saving everywhere: A procedural or data-oriented programming paradigm is something to consider. Don't mix data and code, have a single monolithic program state, and your serialization will be easy peezy.
This also makes bugs very reproducible. That is good for debugging. That is bad for the end user. Have tests
My favorite loading and saving state that is open world is Breath of the WIld's The Blood Moon rises which reset the world when the memory got to intense as far as I can speculate. So you could load in anywhere on the map but when the memory got too intense to crash the game, the blood moon rises cutscene would reset the memory so it doesn't have to remember the load state. I also liked Metroid Prime's loading system where you would have a bridge room that would do the loading and unloading of rooms. The problem with loading an open world is just that and I think BoTw solved the memory problem. But an unpopular opinion would be to have to pay for extra save slots or pay to autosave or quick save. People will hate it but as a publisher, I would push that on a studio to make more money. Jokes aside. At least, this will likely be stolen and then we will see these features done in games to increase revenue as pay to save becomes a thing. I would think that a basic flag system for what data is saved and what isn't like quests, etc and how many coins and items, etc that you have in your inventory and chests to be loaded in from a save. The save itself would be saving the flagged stuff and inventory and then it would reload at a point where you could easily test and run bugs. Autosave would simply save the game and then reload a fresh area when they reload. But if they want more than one save state, they will have to pay for each additional save state as well as maybe a monthly subscription to autosave. I am sorry if they steal this idea.
Much as I hate Bethesda, I think it's kind of cool that Save Games for Bethesda's games are literally just a mod.
It's mod 255 (or FF) to be exact, if you ever wondered why you're restricted to 254 addons/mods of the ESP/ESM format.
10:40 The easy solution I used for this, was to put a EOF check inside every single loop or read of variable length (i.e. strings) - It's pretty obvious you messed up when the loop wants to read 1787571723 items (and EOFs) instead of say a more reasonable number like 206.
Even if it doesn't bug out at the exact spot, it usually blows up close enough to the problem that I can quickly find the mismatched spot and fix it.
That said, I don't think binary formats are very much in vogue anymore; quite likely that games these days would just serialise either a JSON file or a series of them, and then shove them into a compressed container if you're lucky. Which avoids the biggest problem with binary formats: inter-version compatibility.
Diablo 2 "Save and quit" is great for the grinding nature of the game
Topic of the moment! I was wanting your opinion of the Subnautica load/save mechanic which is one of the most bizarre I've ever encountered. You can't save scum and you are more or less in semi- permanent Iron Man mode. Basically if you die you lose everything you got since you last were in a base, and that stuff is also gone from the world. This in a game where resources never respawn. There is no Load/Restore capability at all. Which makes me struggle to understand why they even have a Save option at all. "Save" seems to mean "Don't lose my progress when I Quit" - surely that should be the sane default??!
It is worth noting that until recently with super fast SSDs it was basically always faster to compress data and write that. The time saved on writes made up for the time spent on the compression, especially for verbose human readable things since they tend to compress well.
I think now you'd have test. The downside is that the best compression means you can't really seek in the file.
Modern systems have shifted a lot of these sorts of trade offs a fair bit with the changing performance characteristics of storage. These days it might be better to just allocate one big memory block that you don't expect save data to exceed, write to that then write it to disk in one go. You run the risk of bugs around handling data being larger than the buffer if that doesn't hapoen in testing, which it won't if you choose the buffer size right.
I now greatly appreciate all the old pc games that did have quicksaves everywhere. My save-scummiest games are Max Payne 1, Morrowind, and Blade of Darkness.
I remember reading the shocking file sizes in Crysis 1, the longer levels where I demolished a lot of things had over 100mb and I was like wtf. But if they never despawn everything and track a ton of high precision physics that's what you get. Maybe it could be shrunk more but for something that large it loaded quick too.
Sometimes the type of game dictates what you save and when and you cannot save things in progress (basically all mission based or racing games)
I was a DBA for 25+ years, so I know saving across versions is a real pain. Most online games I've seen will just run an update and get everyone on the same version. But if you're running locally, or in an enterprise environment, you might have to be compatible for 3 or 4 versions back. I'm getting a headache just remembering some of the problems, so pardon me while I look for a bottle of aspirin. 😵💫
I didn’t know there were so many variables that we into saving a game.
I was going to ask this as well, thanks for the video 👍
That was very interesting. I always wanted to hear about save/load from a developer. I wish you also made comments on how you deal with encryption or whatever else you use to protect save games against tampering when saving on local disk. Also, some comments on cloud saves / sync would be interesting.
In my opinion it is totally unnecessary for a single player game. If they can HexEd binary data let them have fun with it
Useless complexity for offline games where hacks/mods arent a problem. If youre going for online leaderbaords, I've seen a indie dev periodically check and ban records that arent posted on the speedrun site.
When Tim mentioned that he would add a save and load method on every pertinent class I immediately remembered a couple of programming design patterns I studied last month. Really good stuff!
I was making a game as a hobby a while back. First person horror game, simple I thought.
Oh boy, why did i decide to add save game at the end of the development 😅. It delayed the project atleast 50%.
Its safer to have the save-file slit into some meta-data and general progression data (like level, inventory, story state etc) in some more robust text format, and then the concrete serialized world data of all objects in a binary format. In case the save system breaks with a patch, there is at least the fallback option to reset to some town, and have the main player progression restorable. A other objects and NPCs reset to some default state.
It occurs to me that a lot of these technical conveniences end up being QoL for players as well. Allowing saves during combat or physics events can easily cause a locked save. As a compulsive quick-saver I am quite glad if it doesn't work a second before death.
I took the easy way with my project, you can't save during combat and that cuts the effort in half instantly, I don't save anything related to AI because they would all be in Idle state, and they would be stationary or moving very slowly, so I could just store the location and rotation. (And health etc.)
Text vs. binary is orthogonal to how easy or hard it is to save stuff. Some of the serialization libraries let you select format, compression, and what not. What matters more is whether data types you need are supported and with the guarantees you expect. Are your lists ordered? It is guaranteed by JSON standard (and likely most implementations agree) but this doesn't have to be true for other data formats.
One thing you didn't mention, Tim, is that per system involved you're also making conscious decisions about state not being preserved. Your interactable physics objects (boxes, crates, whatever) may need to be stored (if your emergent gameplay depends on them) but debris, even if it reacts to player walk, probably doesn't have to be stored. Players are unlikely to notice that some rocks returned to their default location after load.
You may have to store open/closed state for door that maintain their state and are somehow critical for the story or gameplay. But door that aren't could return to default (likely closed) state. You can have other importance/relevancy criteria as well. Sometimes state far from the player can return to defaults under assumption that world lives and if you return to a tavern after a week it's likely someone closed the door you opened (and put a new lock on it for a good measure).
But yeah, overall saving and loading especially with versioning (which is mandatory now that games have patches) is hard. Imagine your save contains quest state and quest had bug that needed to be fixed for a patch. Now your state no longer means what it did before and you need a custom patching/conversion happening on load. Madness.
Saving and networking is sometimes similar.
Something that can be replicated well, can be saved in the same matter.
I love it when saving is part of the game mechanic itself like the classic only save when you sleep or as Kingdom Come did it, it was a potion you drink to save , which also made it only possible to save during this 'low-change' situation or if you want to save in combat you have to be in a somewhat safe position to be able to finish the bottle of saving serum.
No,.. Maybe. In some games, it's maybe OK, but I prefer good old "you should be able to save anytime."
Question for you Tim: what are your thoughts on NPC vendor currency limits? Do you prefer an infinite vendor cash system, allowing players a one-stop-shop to sell all their loot and not worry about bleeding the vendor dry or do you think giving vendors a finite currency bank is a better option? Some other system?
I've played so many games where the simple act of selling all your loot becomes a time-consuming struggle since the choice was made to use NPC vendors with small, finite banks and/or the loot item cost vs. vendor bank scale was out of balance. From a player's perspective, aside from maybe immersion reasons, it seems like using an infinite system would help the player stay focused on gameplay rather than getting bogged down with UI/system management.
I like when the currency is limited but selling to certain shops gives more money depending on what the shop is selling.
(Sell armor to the armory, sell potions to the alchemist, etc)
That way if you just dump everything into one shop you’ll rarely hit the currency limit, since the items have lesser value.
But this also requires clean city design so walking between shops doesn’t take up too much time.
I also like when there’s regional price mark ups like in Kenshi. That way when you’re doing long haul trades it incentivizes hitting up multiple cities for trade.
(Again map design can make this overly tedious though)
NetHack had pretty simple solution I rather liked: Have the store give the player store credit they can redeem in the future.
Of course Nethack players instead used this to 'pre-pay' because they often got afflictions that would make them teleport randomly, and if you were in a shop and left without settling your tab, the cops came after you.
quicksaves are so important
I'm just going to point out that it's even harder than what you say.
You didn't say anything about endianness and cross-platform saves.
I mean, dumping an int in C is indeed fast and efficient, but it's also not cross-platform at all unless you think about the ordering of your bits.
Some libraries offer binary and text save formats, which can be invaluable for debugging (stuff like protobuf and even C++ boost serialization if I remember well). However, saving pointers dumbly (like boost serialization did and maybe serde in Rust?) can easily lead to stack overflows, which means you may have to recompile your binary with larger stack space and hope.
However, it would have been nice to speak a little bit about the design choices, not just the technical limitations around saving and loading.
e.g. Why you would want to allow only save&quit, or why you don't want to allow save in combat. I know not being able to save in combat in Battle Brothers is a big plus for me because otherwise I could feel tempted to save and just savescum "bad luck" away, but that reason would vanish if the game didn't have any randomness (like chess).
While it's good to cater for endianness, you are extremely unlikely to encounter a Big Endian system in the wild these days.
The last consumer product I know of that used Big-Endian were PowerPC based macs, and those were discontinued in 2006.