Instalează Steam
conectare
|
limbă
简体中文 (chineză simplificată)
繁體中文 (chineză tradițională)
日本語 (japoneză)
한국어 (coreeană)
ไทย (thailandeză)
български (bulgară)
Čeština (cehă)
Dansk (daneză)
Deutsch (germană)
English (engleză)
Español - España (spaniolă - Spania)
Español - Latinoamérica (spaniolă - America Latină)
Ελληνικά (greacă)
Français (franceză)
Italiano (italiană)
Bahasa Indonesia (indoneziană)
Magyar (maghiară)
Nederlands (neerlandeză)
Norsk (norvegiană)
Polski (poloneză)
Português (portugheză - Portugalia)
Português - Brasil (portugheză - Brazilia)
Русский (rusă)
Suomi (finlandeză)
Svenska (suedeză)
Türkçe (turcă)
Tiếng Việt (vietnameză)
Українська (ucraineană)
Raportează o problemă de traducere
Translation of how it reads:
No offense, of course....;)
pho: The issue is not, of course, saving every object in the file. (The previous commentor asked what the complexity was, so I answered.) And it's not even necessarily the case - most FPS games save a very minimal subset of what they need to from state to state, precisely because saving every object in the game is such a pain in the neck. (Shadowrun Returns did a checkpoint save for precisely this reason, which is why their saves are a little wonky.)
So, in case anybody's interested, here's the deal with what took/is taking so long for the saves:
1. Objects may reference other objects. If you save both objects, you need to make sure that, on load, you match the newly created version of the object with anything that expects it to point to it. For Dungeons of Dredmor, our previous title, this was a huge pain in the neck, but pretty much okay - Dredmor levels are pretty flat and generally don't tend to keep many references to other objects around. For Clockwork Empires, everything references everything else. We implemented what is known as a pointer-chasing scheme in order to ensure that we can save, and load, everything in the right order. Until recently, the data structures involved in tracking all of this had a rather nasty tendency to break the 2-gigabyte address limit that Clockwork Empires suffers from under Windows because it's a 32-bit application. We didn't find that out until about half way through adding all the stuff to saves.
2. Our saves are not totally binary - they are plain text (specifically XML) stored in ZIP files, along with binary files for some things (like terrain) that are stored as flat arrays. Dredmor used binary saves, and it was a terrible idea; if one byte is off, everything explodes. This necessitated writing a lot of code to work with ZIP files, streaming them to disk and so forth.
3. Clockwork Empires has three basic systems, which we will call "game", "renderer", and "script." Because of how we do multithreaded things, a given object (say a cabbage) has three different representations - how it's seen by the scripting language, how it's seen by the jobs system/pathfinding/networking ("game") and how it's seen by the renderer. This gives us three times as much stuff to mark up with save/load information, and about three times as many systems to make work. The benefits outweigh the negatives of this approach - the game actually runs deterministically in its own thread at about one tenth the speed of the renderer, and lets it know what's going on as it reaches decisions. The renderer can then focus on rendering the game as fast as possible. If we didn't do this, we couldn't do things like the replay system (which we use for debugging) or the networking (which depends on being deterministic for making the whole thing work - since we can't send the entire game state over the network, we send only the commands that players input, and let the determinism ensure that all player commands are carried out in the same order on everybody's computer. Fairly standard stuff for strategy games and RTS games.)
However, it does complicate saving and loading.
The script state of a cabbage lives in Lua, and everything else lives in C++ - so we end up writing a little Lua script for each cabbage that we execute in order to recreate it on load. (Believe it or not, this is the recommended way of doing things. Lua is weird.)
4. We also ended up doing a lot of nice stuff based on our experiences from Dredmor, where I basically just slapped things together furiously - we have nice little functions for everything, and a bunch of stuff to make saves stable and more better. Doing all of that infrastructure building up front took a certain amount of time before we could even begin writing saves, as opposed to just "bashing through everything in memory and dumping it to disk in great steaming chunks" (read: what we did for Dredmor, never again!)
In hindsight - yes, absolutely we should have had saves in our engine framework from day zero. This didn't happen for a number of reasons - mainly getting other things in the engine that needed to be there from day zero. :) Anyhow, the actual system to do the loading and saving is working, and all that is outstanding is a certain amount of bug-chasing and marking up the portions of the renderer code base that talk to the user interface. I have a big pot of coffee and I'm plugging away at finishing it. At this point the top men have gotten it done, and it's all just me.
I am pleased we didn't make any of the same mistakes that I made with the Dredmor save game system; however, we made up for this by making new ones. :) Anyhow, hopefully this status update is at least interesting and answers some questions. Back to work!
Hopefully it will help create some more appreciation over that it's not as straight forward as "Save all the objects to file". :)
Thanks for the write up explaination.