Savegames as save points are wrong?

Discuss programming in the QuakeC language.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Savegames as save points are wrong?

Post by Baker »

I've never liked save games as "save points" within a map. I could never figure out why. But I can now.

Save games are a terrible way to save progress. The engine doesn't support it. The QuakeC doesn't support it. It is a hack.

The RIGHT way to do save points:

1. Delete the old info_player_start. (And info_player_coopages).
2. Make a new info_player_start where the save point is supposed to be. (Don't bother with making new info_player_coops .. you don't need them now. If you don't understand why, I'll explain).
3. Update the stats thing that stores information that preserves across level changes. (The parms guys).

Then when you die, you spawn in the right place with the right stuff. And this method is compatible with save games and compatible with reloading a map.

Save game files as save game points are like giving a small kid a jar of peanut butter and a knife.

[Oh yeah, how do save game files work with coop? Do you REALLY want the reload the .sav when 1 player dies? And if a player starts a map out of the blue, which save game file is supposed to be used? The auto-progress one or a fresh map? Do you want QuakeC or the engine to make that decision? No. The above correct method lets Quake's save game system work without interjecting gremlins in it. And you don't have a pointless autosave.sav file laying around. Furthermore for a system designed to only need to READ files off the hard drive, why interject the sole place in the engine that demands file write privileges for normal operation of gameplay? That's bad design.]
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Savegames as save points are wrong?

Post by Baker »

Logic fail. This would only work for coop.

In single player, the map actually reloads upon death. The only way to restore the entities to base, and "base" is not what is wanted with a save point.

So with single player the entities would still have to be written to file, barring an engine modification that worked in conjunction with a single player death.

Foiled again :(

[Rats! Kurok has save game points and I really wanted to be able to gut that stuff out of there.]
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Spirit
Posts: 1065
Joined: Sat Nov 20, 2004 9:00 pm
Contact:

Re: Savegames as save points are wrong?

Post by Spirit »

Is the death and reloading engine side?
Improve Quaddicted, send me a pull request: https://github.com/SpiritQuaddicted/Quaddicted-reviews
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Savegames as save points are wrong?

Post by Baker »

Spirit wrote:Is the death and reloading engine side?
Sigh. Yeah. Upon death, the progs and the BSP are reloaded if coop 0 (aka single player). I initially was thinking "ok ... stuff the parms" ... and you have your inventory back but I had too much of coop angle and the single player mechanics got lost in my train of thought.

Forgot about the saving of entity states.

Checkpoint save games are evil. It writes to disk when nothing else in the engine requires writing to disk. The progs interpreter has no decent way of knowing the nature of HOW it was loaded (I guess you could save some parm crap on natural map change to differentiate between a player typing "map whatever" in the console versus a natural level transition.

Still save games are virtually unworkable for coop. And I really think coop is something that sets Quake in its own league and has never really been "unlocked" for the masses (would require "good" peer-to-peer capability + prediction).

I mean it could be worked around by copying the progs memory and reloading upon single player (non-coop) death to avoid the write to disk (would have to run a couple of frames and the usual load game mechanics). I only care about the write to disk because I think Quake should be run-able from a read-only device like a CD, disk image mount, etc.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
qbism
Posts: 1236
Joined: Thu Nov 04, 2004 5:51 am
Contact:

Re: Savegames as save points are wrong?

Post by qbism »

Single-player save points can work. ne_ruins map/mod is an example that works. it still allows regular saves. But it's going to stutter, because everything stops while it saves. Save points should be in a "quiet" place, a narrow transitional corridor, not a big open room right before all the monsters jump out.

Some time ago I played with the idea of a saved player state "monument". The monument is an entity created at current player location that stores all info for that player and a password to unlock it later. Maybe someone has already created this. In coop example, each player could create a monument, leave the server, and the guy running the game does a savegame. I don't know if that would actually work. If it did, the server could be even be shut down and restarted later, and everyone could rejoin as "ghosts" (not spectators) and go activate their respective monuments.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Savegames as save points are wrong?

Post by Spike »

the nice thing about checkpoints is that you can reload them when you next start the engine.
many quake engines can work in linux where the main id1 dir is readonly, such engines use the user's homedir for any additional content like saved games, check points, downloaded maps.

in the context of quake, there's too many things that would like to be saved for it to be worth coming up with some way around checkpoints instead of just pointing it to save/load from some home or tmp dir.
Even on android, each app has some config directory, even if it doesn't have any sdcard access - ideal for your config.cfg and a couple of saved games.


FTE supports multiplayer(deathmatch/coop/dedicated servers/whatever) saved games by kicking all old players (stuffcmd("reconnect\n") sort of thing), loading the game, flagging the players as 'loadzombies'. players that join are matched by name to existing loadzombies and fill that zombie's slot and take its ent as-is when they do enter the game. If the zombie wasn't eaten by a joining player by 20 secs or so, it times out and the qc is finally told that they disconnected.
So its not really any different from single player, just you have multiple players instead of slot 0, players are given their slots as they join instead of the local player being force-spawned at loadtime, and the possibility that no client claims them with all the allowances to stop the engine from complaining about no client in that slot if the qc tries sending centerprints or whatever before they're actually there. The only difference is that you need to get your name to match (instead of slot number, which would otherwise always be 0)...
Obviously if a mod sends some stuffcmd to the client and expects the client to actually receive it, you may notice some issues... but there's no problem if the mod isn't interrogating any players when its saved or during the 20 secs after.
This is probably easier in QuakeWorld where the player's name is known right from the connect request...
necros
Posts: 77
Joined: Thu Dec 16, 2004 10:32 pm

Re: Savegames as save points are wrong?

Post by necros »

hey guys...
i don't really know what's going on here re: saving (i don't know much about the technical aspects of the engine except where they relate to qc or mapping directly), but i thought i'd just ask: why does saving in quake take so long? the files are tiny, usually half a megabyte. there can't be THAT much data going in there. other games like stalker or oblivion, which can potentially save huge amounts of data, take a fraction of the time to write out the files.
so what's the deal? :P

also, what exactly is the issue with using save games as save points? is it just because there is not "reload checkpoint" function in qc? in ne_ruins, instead of using an impulse, i should have just directly bound F8 to "load autosave" and just used a consistent filename. instead I used an impulse which would save the last used filename that the impulse would use which allowed more freedom, but was ultimately less elegant, because it meant if the map wasn't running, impulses couldn't be processed to load a map.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Savegames as save points are wrong?

Post by Baker »

necros wrote:also, what exactly is the issue with using save games as save points?
Necros ignore my thoughts except as they apply to coop. I was off-based and hadn't walked through all the steps and should have thought it through thoroughly before posting.

I've never felt save games take long to save (I press F6 quick save tons of time in single player). Do you mean long load times? Or do you mean with huge maps with tons of entities take a long time to save?
Spike wrote:Even on android, each app has some config directory, even if it doesn't have any sdcard access - ideal for your config.cfg and a couple of saved games.
Yeah true, but I still think of save game check point about the same as the /glquake directory mesh files :D
ers (stuffcmd("reconnect\n") sort of thing), loading the game, flagging the players as 'loadzombies'. players that join are matched by name to existing loadzombies and fill that zombie's slot and take its ent as-is when they do enter the game. If the zombie wasn't eaten by a joining player by 20 secs or so, it times out and the qc is finally told that they disconnected.
Well, Quake does need a "coop or die" mode with checkpoints :D And I do guess even with my dislike of save game files as checkpoint, the #ifdef Quake2 inter map travel ("hub system" or whatever) ... requires those too.

[Yes, I am super-obsessed with coop.]
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
necros
Posts: 77
Joined: Thu Dec 16, 2004 10:32 pm

Re: Savegames as save points are wrong?

Post by necros »

welllll... maybe i'm just a dork, but it seems like the 3/4 to 1 second save time is pretty long for how little there is.
oblivion saves 4-5mb files in about that long.

mostly, i'm thinking about it from an autosave viewpoint where even the smallest hitch is both a dead giveaway that a save took place and very distracting.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Savegames as save points are wrong?

Post by Baker »

I just bound "echo saving; save quick" to a key and loaded up the start map and pressed that key several times while moving nearly non-stop for several seconds. I didn't even notice it happening. But the start map has only 300-400 entities or so.

I'll have to try this with a big custom with 2000 entities or such.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Savegames as save points are wrong?

Post by Baker »

My funny haha autosave example: Let's say you have coop setup. Let's say server is dedicated.

1. You hit trigger_savespot guy.
2. QuakeC happens sends "savegame autosave.sav" to client with stuffcmd ("autosave.sav")

3. Client receives "savegame autosave.sav"

Client says "Uh ... now how exactly am I going to save the game? I'm just a client and not the server and have no clue what the entities are."

Of course this can be avoid by checking for coop 0 or 1 and simply not stuffing the command. I'm not even saying stuffcmd is right, it should be "localcmd" or whatever the local command is technically. But stuffcmd is used because it isn't useful for anything except single player.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Re: Savegames as save points are wrong?

Post by mh »

There's a definite and noticeable hitch when Quake saves for sure. RMQ has autosaves and you can feel it there for sure.

Even a simple map (like e3m7) needs about 25 ms to save - if that happened during runtime you'd feel a slight jerk as you dropped below 40 fps. Bigger maps would take longer.

The bottleneck is definitely in ED_Write - commenting out that call drops the time to 2 ms.

One of the things Quake does is an fflush after writing out each entity. That's going to make the save process I/O bound to begin with. I'm dubious about the value of this - normally the OS should be trusted to select the most optimal time to commit writes (but then again, Quake was a DOS program, so...) and the potential major advantage of fflush (you get something on disk even if you crash before closing the file) is not really relevant here. Then again, commenting out the fflush seems to do nothing for me, so maybe it's not that big an issue.

I've often wondered if building the save game file in memory and then writing it out in one single operation would be beneficial, but I couldn't be bothered coding it up - sounds like an awful lot of work for something that may turn out to be marginal. (OK, I changed ED_Write to buffer up in memory and it was slower - needs something better than stdio.h and string.h functions for sure as most of the measured time went into building the strings - 25 ms - actually writing them out only took 5).

Switching from a plain text to a binary format would make things faster too - no need to route data through varargs functions many many times while saving, for starters. You could just fwrite each edict_t and be done with it (you might not actually be able to do this as you'd need to collect all the string_ts, but in principle it would be faster).
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Re: Savegames as save points are wrong?

Post by mh »

More experiments.

Most of the bottleneck comes from PR_UglyValueString; commenting out the fprintf of that reduces times to 12 ms.

Using std::string for in-memory buffering-before-write brings no benefit; I would have thought it would have had a better concatenator than strcat, but there is also overhead from shuffling all that data around in memory, I suppose (and there is a lot more shuffling going on than just the 110-odd kb of an e3m7 save).

Making a version of PR_UglyValueString that writes directly to a FILE * (instead of copying to a temp buffer which is then written separately) only saves 2-3 ms - not really worth it.

Switching to binary and just fwriting out each edict_t (not caring about strings here) is about twice as much data but drops the time to 5 ms. I think we're looking at close to best-case there.

Best I can manage with plain text is by using the PR_WriteUglyValueString function and switching from a varargs fprintf to fputs where appropriate. That drops times to maybe 20 ms.

Disk I/O is like networks and gfx cards; a few large operations are always going to be many times faster than lots of small operations. And plain text is slow.

A hypothetical "fast save" format would therefore have these features:
  • It would be binary; each edict is a single fwrite.
  • It would need to include the strings table so that can be reconstructed (otherwise you lose the benefit), or:
  • It would use an in-game representation of edict_t that can be written out fast.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
necros
Posts: 77
Joined: Thu Dec 16, 2004 10:32 pm

Re: Savegames as save points are wrong?

Post by necros »

this is probably dumb, but, could you make some kind of extra copy in memory of the game state and then just slowly write out a save file while letting the engine continue to run?
so the save might take 500ms, but the game doesn't have to wait while it does it.
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Re: Savegames as save points are wrong?

Post by mh »

You could probably write the entities over multiple frames, but entity states would get out of sync - you've have entity 0 in the state that it was in during the 1st frame, and entity 99 in the state that it was in during the 100th frame. A lot can happen in 100 frames (say: 3 monsters infighting, one gets killed on frame 20, another on frame 75 - all 3 should be alive in your save and the monsters end up getting confused over who should be alive and who should be dead).

Even using the times I got as a guide and splitting them over 20 ms, there's still a possibility for these things to happen. You could pick up an armour after you're saved but before the armour is - now when you reload you haven't got the armour but it's no longer in the map.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
Post Reply