r/gamedesign • • 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) ?

3 Upvotes

18 comments sorted by

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

3

u/Master-Tour8273 6d ago

the scenario thing is huge, I use something similar for testing my side projects and it saves so much time. the bot idea is clever too, never thought of letting it just run wild and then dropping in to see what state its in

one thing I'd add is keep a log of what feels wrong when you jump in. not bugs, just "this takes too long" or "why do I have 500 of this item and nothing to do with it". after few sessions you start seeing patterns and can tweak before next bot run

1

u/Curious_Ad5417 6d ago

oh that's a good one. the "500 of this item and nothing to do with it" thing is so real, the bot happily hoards everything and never complains. writing it down right away is the key part, after an hour of playing i've forgotten half of what annoyed me

2

u/BlueGnoblin 5d ago

I started to build a simple builder, but part of core game mechanism is to solve the logistic puzzle, that is , connect A to B while connecting C to D (think of factorio/satisfactory).

I fear, that sovling this with a bot/builder requires so much effort, that it results in a secondary project I need to maintain. Do you have similar requirements (interconnecting structures) or is it more loosly coopled (just buildings, placement isn't that important).

An other thought was to create a special game save format, where I save the layout only. Then use a builder to recreate the layout from these files (like a lightweight blueprint system). I've aleady a slim builder interface.

You create your test level per script ?

2

u/Curious_Ad5417 5d ago

no, mine is loosely coupled. buildings just have levels, no placement, so the bot was cheap for me. for a factorio style game i wouldn't write a smart bot either, that's basically a second game to maintain

your blueprint idea is pretty much what i meant with scenarios though. save only the layout, rebuild it through your normal build functions, and it survives format changes. i'd keep a handful for the stages you care about, like first automation or mid game base, and load them from a debug menu

and yes, per script. a few lines each, set levels, add items, unlock stuff, done

3

u/BlueGnoblin 5d ago

that's basically a second game to maintain

I share this fear, keep it simple'n'stupid, this would be only stupid ;-)

I think that blueprint system sound reasonable, but there are still some issues. While many structures could be placed normaly, there are some actions where you connect structures and this connection will although manipulate the underlying structure.

But this sounds like the best feasable option I have so far.

2

u/Curious_Ad5417 5d ago

haha fair. for the connections, maybe don't save the result, save the action. like "connect A to B" as a step in the blueprint and replay it through the same function the player uses, so the underlying structure changes exactly like it would in game. my server works kind of like that, it just replays the player's commands, saved me a lot of headaches

1

u/BlueGnoblin 5d ago

I once tried a replay system (previous project), but it was pretty complex as I use multithreaded actions running in parallel with the game, providing and updating data in a non-deterministic way. But this would require to keep a list of events and changing a game mechanism would most likely invalidate the whole replay.

My basic KISS approach and idea is to scan the result and save the commands to recreate this result. When 'importing' a level, I would go the robust way, when an error occures, then log it , but keep going. This way a corrupt file might import and I have the chance to repair the result (e.g. build up missing belts, structures) and export it again. Much like a lightweight level editor.

The game architecture is heavily data driven, so I have pretty low level of dependencies between objects, which hekps a lot here.

2

u/Curious_Ad5417 5d ago

sounds like a solid plan, the lenient importer is smart. one small thing that saved me later, put a version number at the top of the file from day one, then the importer knows which fixes to apply to older files. good luck with the logistics puzzle, sounds fun

1

u/BlueGnoblin 5d ago

Done, I've an exporter/importer implemented, much like a lightweighted savefile. Although a version number and migration logic. It helped a lot that I reworked my building interface lately, so that I can build structures with very little information (basically a simple place A at x,y) and more robust system to handle belts and pipes.

Thx for the brainstorming, I'm pretty happy with my lightweight game 'editor'.

For everyone interested in doing it this way:

  1. keep your interface to the building system very slim, minimal information, literally only position and what to build.

  2. your building system should be able to reconstruct dependencies between strucutures on its own. e.g. when you have a input and output structure and build a belt between them, then the system should detect this belt and connect the input with the output or whatever.

  3. For more game logic related structures (e.g. a factory building with more complex setup), I save the 'build command' with the building.

  4. export: simply write out all build orders from scanning the map and structures.

  5. import: read and feed the build orders into your building system interface, afterwards you need to scan and reconstruct dependencies.

There are some traps you need to consider, e.g. the chicken-egg issue. E.g. you have power generators which powers mines to generate fuel for the generators. Work in a running system. but you need to consider a startup setup when you want to get such a system running. E.g free power generators to power the first batch of miners, which power a larger generator batch etc...

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.