Gauntlet mode: Game state object (and some technical rambling)

Gauntlet tasks to do before initial release

Get local games fully working
Object for holding game state in Gauntlet mode
– Auto-repair system + vehicle swap ability
– Gauntlet game flow from menu to end
– Score system
– Level generation tweaks
– Update scrap drop system
– Item unlock system
– Update How To Play screens
– Test and balance gameplay
– Music?

“Object for holding game state in Gauntlet mode” is probably the most boring entry on the task list (wow what a great way to open a blog post), but let’s talk technical stuff.

Scraps and persistent state

The Unity engine that Scraps is written in has this concept of “Scenes.” You can put stuff in a scene, like make a level for your game. You can attach stuff to stuff in your scenes, like lights and physics and scripts that run code. A nice thing about Scenes is that when you go to a different one, everything you put in the first scene is unloaded, so you know you didn’t accidentally leave anything hanging around taking up memory[1].

But sometimes obviously you want stuff that doesn’t go away on scene change. Scraps Melee games need to remember who’s playing when the map changes, Gauntlet games need to remember the player’s scrap amount/score/etc when they move between levels, everything needs to remember which vehicle the player has selected and so on. You can create code that doesn’t get destroyed on scene changes, either by making it totally separate from the scene system, or by marking it in the scene with a special DontDestroyOnLoad flag.

Anyway, in the Scraps system:

(click for big)

Everything there except ServerStartupInit (which just gets things going on the server) is persistent between scenes. Server is an object on the server, sort of a master controller. Client (for multiplayer) or Local (for singleplayer) are its client-side equivalents. There’s a ScrapsPlayer for each player in a game – both AI or human. VehicleBase is a script on the vehicles themselves. It’s subclassed into Client and Server variants. Having a ScrapsPlayer rather than having a player be their vehicle means that a player can continue to exist and run code when they don’t have a vehicle, like between being destroyed and respawning. Whereas having VehicleBase on the vehicle means that vehicle-specific actions can still be done on the vehicle itself.

For instance say a ScrapsPlayer decided to set the health level on a vehicle in 1 second’s time, and within that time the player’s vehicle changed to a different one, it could end up setting that health level on the wrong vehicle. If the vehicle script decided to do the same thing and the vehicle got destroyed within that second, the command would get destroyed as well and never happen. OK that’s a pretty contrived example, but I do remember something somewhat like that being a real issue at one point. Network latency in particular makes everything need a bit more careful protection.

ANYWAY, I haven’t needed to update any of that very much, that’s just some random info about the whole system. What I have needed to do is add a new type of GameData, because GameDataServer/GameDataClient/GameDataLocal were more like MeleeModeGameData.

I mean look at this stuff in GameData:


Number of players, networking stuff, starting scrap and other melee game settings. None of that’s needed for a new singleplayer mode and adding Gauntlet mode stuff to it would just make it a big mess.

So anyway GameData is now MeleeGameData and there’s a new GauntletGameData too. It stores the player’s score, what level they’re on, etc. When a new game is started the appropriate GameData object is created based on the game type.

I’m not sure if the next item on the list completed will be “Auto-repair system + vehicle swap ability” or “Gauntlet game flow from menu to end”. The former is part of the latter but I might be able to do the game flow without having the new build screen systems totally ready.

[1] As with many things code-related, this is sadly true only in the most naïve, optimistic theoretical way. If you have anything that doesn’t get destroyed on a scene change (like a static class or a class with DontDestroyOnLoad), and it references something that should, the thing will still stay in memory until the reference is cleared.

Bookmark the permalink. Both comments and trackbacks are currently closed.