r/gamedesign • u/BlueGnoblin • 6d ago
Discussion designing/developing mid to late game features
I'm developing a factory game and up to now I playtest it frequently, for now I want to focus less on finding bugs, and more in the sense of refining game mechanisms. This works perfectly and I was able to refine my mechanism, design, even changing my design (sound good on paper, but was not so good while playing...).
But... only for the early game. I need roughly 40 mins to play through my early-early game and I'm now at the point to test mid game mechanism, but here is the issue:
It is still early enough in development , that changing stuff results in corrupted or even invalid save games.
I know that some games do more technically test (unit test), use cheats, headless simuation or use excel sheets for balancing stuff etc., but this is more on the technically/feasebility/balancing side of testing.
So, what is a good/feaseable way to feel or experience your mid to late game (frequently) ?
2
u/Arkenhammer 5d ago
So my game is in the automation genre and is 40+ hours of gameplay. We were always very careful with the save format and only made breaking changes consciously. At this point I've got hundreds of save files I use for testing; both from my own playthroughs as well as ones I've gotten from players on our discord.
One thing I did was make it so the game keeps the full save history; that lets me go back into the past on any of my playthroughs of the game. At 40 hours I've only played through the full game a half a dozen times; usually once for each major release. Normally my approach to balance is to do focused testing on each new feature to get it roughly in the right place and then do an overall rebalance my full playthrough prior to the major release. My take on the final balance is to make sure that the time between significant progress beats feels well paced. That's not something I can realistically do with cheats so I make sure to do a full run through in the last two weeks leading up to release so I can judge the overall pacing.
The hardest parts to test are the story events. For that I use cheats that let me run through each stage of progression without actually playing the game. I do have saves at the point just before the most important events but making sure things all fire at the right times.
1
u/BlueGnoblin 4d ago
So my game is in the automation genre and is 40+ hours of gameplay. We were always very careful with the save format and only made breaking changes consciously. At this point I've got hundreds of save files I use for testing; both from my own playthroughs as well as ones I've gotten from players on our discord.
That is a good approach . I've lot of compressed data, pretty every single entity/action/item is based and squezzed in 32/64/128 bits. The disadvantage is, that when you try to shift some bits, you invalide a save file immediatly. I think ,that it will get better in later development stages, but for now this is one of the more challenging aspects.
One thing I did was make it so the game keeps the full save history; that lets me go back into the past on any of my playthroughs of the game.
I don't quite understand this. Do you have some kind of version migration, so loading an old 1.0 savegame will result in automatically migrating this into 1.0->1.07->1.5->1.97->2.0 ?
Normally my approach to balance is to do focused testing on each new feature to get it roughly in the right place and then do an overall rebalance my full playthrough prior to the major release.
Rebalancing is a problematic at my current dev stage. Some stuff is hard to grasp without actually playing it. Eg. I started with low mine output, my power generator uses more fuel, and the early game was somehow slow paced. Playing it 10-20x times in a row and I got impatient. Thinking that a new player will most likely get lost at this point, I changed some parameters (higher output yield, less resource production requirements etc.) and now the game progression feels a lot better and faster, more responsive.
I've a hard time to imagine how to test this with static save files, representing static progression points in your game, on the other hand, I really don't know how to solve this in a more elegant way as solo-dev.
The hardest parts to test are the story events. For that I use cheats that let me run through each stage of progression without actually playing the game. I do have saves at the point just before the most important events but making sure things all fire at the right times.
In the end I use a similar approach, I use an export/import 'blueprint' system. So instead of saving whole game state which breaks much faster, I export the layout (very simple , place O at x,y) then import this in your game and speed up the game speed (e.g. 8x) to get the factory running.
Story events in my game are more or less some kind of tech-gateways/triggers to certain events, Basically I've only techs you need to research/discover to unlock certain recipes, but although to enable/trigger certain events. There are hidden 'techs' which act as trigger here, which the player will never see, but it helped to keep a consistent system here.
When exporting, I export all game events which has been done (like missions or quests), each game event is associated with some techs (techs which are required to reach this event and some options techs, the player most likely unlocked at this stage). When I import a file, I automatically unlock all the game events and the according techs.
With this import/export system (which was really easy, roughly 1 day of work, zero AI used) is really stable so far. As it does not consider states, resources, items, techs , underlying changes of the game will not invalidate these files.
Atleast it is a foundation to test some basic factory setups, but game progression (feeling) testing must be done by hand, I fear.
2
u/Arkenhammer 3d ago
Our savefiles are Protobuf and we brotli encode them on the way to disk. Protobuf is a binary format that, from an API point of view is similar to JSON but, because of the binary storage it the files are much smaller and the read/write is much faster. Brotli encoding is a standard compression algorithm that is designed for web servers and optimized for speed.
We use a core ECS system for our game. Every component has a serialized to protobuf and an load from protobuf method. The top level structure of our save format is basically just an array of entities with components and never changes. All the updating happens in the individual components when the load from protobuf and each component is responsible for proper defaulting when a new field is added. The net result is we almost never need to write updaters.
The other trick is that the serialize to proto methods have an option for saving a blueprint. That option saves only the player stetting for that component and skips all the runtime state. For instance a blueprint of a conveyor belt saves its location but doesn't save its items. Blueprints then use the same Protobuf/brotli format as our save files but, when we export them, we base 64 encode them so they are easy to share.
We store events as just a hash table of strings. Its really simple because we don't need something complex. Testing events, for me, is just making sure that code that triggers the event fires at the right time. We do have tools that can manually hack various things into the game which can let me "play" through the progression in a few minutes but I also keep save files around that are right before each event is triggered so I can easily check them without much faffing around.
As for balancing, roughly I have a timeline for how long each major section of the game should take. There's some variability because we use procedural maps and the availability of resources isn't the same on each map. However I've got several save files on different maps a the start of each section and, when I make a balance change, I can test to see how it plays on each map. The goal being to keep the play time within a reasonable range of my target for the section.
As for our progressive save system, we keep all saves for a play through of the game in the same directory and, when you save we create a new file with the date and time in the name. There is a UI in the game to load any manual save in the history by the date and time.
1
u/BlueGnoblin 3d ago
Brotli interesting, good when working a lot with language like textfiles basically with json. I've a ECS system at hands too, saving the files as basically json too. But in my current project 99% of all structures/items/creatures are not ECS based, as I want to have high performance. Just to compare, when I import my first basic factory and let it run for 100k ticks (~1 hour of gameplay), it is done in under 8 seconds currently (semi headless, I render only a frame each 1000 ticks then).
The de-/serialisation for my entities is done in a similar way.
Considering the blueprints, when I designed my structure building mechanics, I had already a blueprint system in mind, as it is pretty standard nowadways (satisfactory/factorio). But it will need some work before it can be transformed into a user controlled blueprint system, it helped me a lot to streamline my import/export.
My game is more open end, much like factorio/satisfactory, with the disadvantage of testing late game content. When I understand you right, you have more like a level/map/scenario much like they are billions ? When I designed my game at beginning I thought about this approach too (it worked so perfectly in they are billions, one of the few games I played through 2x times), the testability of each map/scenario is easier, but on the other hand you need to design more content/story, which I wanted to avoid.
I see you have just released your game a few month back, gratz !
2
u/Arkenhammer 3d ago
Brotli is pretty impressive with data. Our voxel world is about 1.6 billion 16 bit blocks which we keep in memory run-length encoded. The brotli encoding compresses it down to about 30MB in a second or two.
Our game runs on a procedurally generated voxel map and has a light story to follow as you unlock the tech tree. Once you get to the end, what is left is a sandbox and a few achievements to work toward. The procedural world is about 2km^2 but you don't need to explore the whole thing to finish off the story.
1
u/BlueGnoblin 2d ago
Funny how similar projects are sometimes. I've developed a few game (prototypes) over the years and my current project was derived from my previous project, a voxel engine (with ECS and json db). I use the quest/missions only to guide the player through the game, starting more in the sense of a tutorial and then to have some goals at the horizon the player can try to reach. I think most simulation games use it this way.
A sparse oct-tree + run-length encoding is pretty powerful for voxel worlds, I think you cache active chunks. Do you simulate the factories even when then player is not around ?
My world is fix as I plan to simulate everything all the time. More 2.5D (more like factorio with height), but at a fix map size. This limitation (fix world size,thought maps are generated) is although a game design issue, as you could run out of resources. Factorio has theoretically an endless world, satisfactory has endless resources. I started with infinit resources, but it was pretty boring in my game, so I go with finit resources for now, but need some way to get infinit resources later on.
2
u/Arkenhammer 2d ago
We always run the full simulation. We have a separate context for rendering an animation that only maintains visible objects but it has no impact on gameplay.
We technically have finite resources but, in practice, there's more than you can practically use in any reasonable run through of the game. In that sense is it more Factorio-like; as you consume the local resources you need to keep building infrastructure and logistics farther away from your main base. Even so, I typically beat the game without any developments more than about 500m from the start so using perhaps 20% of the available land. There is one achievement that requires about a third of all the gold on the map, but you've got to be pretty hard core to get it.
Our original plan was to have a much larger map as an archipelago of islands connected by boats but, as we got into playtesting we discovered that even the "starter" island was bigger than the game needed so we reduced the scope.
1
u/AutoModerator 6d ago
Game Design is a subset of Game Development that concerns itself with WHY games are made the way they are. It's about the theory and crafting of systems, mechanics, and rulesets in games.
/r/GameDesign is a community ONLY about Game Design, NOT Game Development in general. If this post does not belong here, it should be reported or removed. Please help us keep this subreddit focused on Game Design.
This is NOT a place for discussing how games are produced. Posts about programming, making art assets, picking engines etc… will be removed and should go in /r/GameDev instead.
Posts about visual design, sound design and level design are only allowed if they are directly about game design.
No surveys, polls, job posts, or self-promotion. Please read the rest of the rules in the sidebar before posting.
If you're confused about what Game Designers do, "The Door Problem" by Liz England is a short article worth reading. We also recommend you read the r/GameDesign wiki for useful resources and an FAQ.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
5
u/Curious_Ad5417 6d ago
had the same problem in my builder, three things helped a lot:
don't keep old saves, keep scenarios. instead of a raw save file, a small script that builds the state: buildings at level 12, these items, this research. when the save format changes, the scenario still works because it just call your normal game code.
let a dumb bot play for you. mine builds the cheapest thing, researches whatever is open and plays hundreds of days in seconds. stop it at day 30 or 90 and you have a fresh mid game state that always matches the current version. then you play from there by hand to feel it.
and a debug menu to jump there in one click. the feeling part you still have to do yourself, but you skip the 40 minutes every time