14 JAN 2023:
Still on my business trip so no real Scrapship updates but I have been reading a couple books about procedural generation.
At a very high level, procedural generation works like Mad Libs. The human user comes up with the parts of speech to make the story (hopefully) hilarious. But coming up with the parts of speech could just as easily be generated by a computer program that generates random parts of speech.
Though most talk of procedural generation revolves around RPGs and roguelikes, I’ve been thinking about how procedural generation would apply to a shmup like Scrapship.
Your average shmup has pre-scripted waves of enemies. This is good if you want a predictable experience for people who like to chase high scores, but not very good if you are looking for replay value.
It’d be very easy to make Scrapship just throw random enemies at you from random spawn points, but that could all too easily turn chaotic. There could be too few enemies . . . or too many. Or maybe they all spawn from the same region and start overlapping each other. There’s a lot that can go wrong with procedural generation. So this is why the concept of “guardrails” is important. Procedural generation works best when a HUMAN sets limits on what is and isn’t allowable. Without these “guardrails” it is all too easy to run into the “10,000 bowls of oatmeal” problem — lots of variation, but not much meaningful variation — one bowl of oatmeal is not much different from the thousands of other bowls of oatmeal.
The ideal enemy generator for Scrapship needs to fulfill these requirements:
Spawns enemies appropriate to the player’s current performance.
Spawns enemies in such a way that there is little to no overlap.
Spawns enemies in quantities that won’t cause the game to lag.
Occasionally does something completely random to keep things interesting.
I already have a system in place that addresses most of these things, but another problem with procedural generation is that it is impractical from a human standpoint to vet every single possible combination. Some developers handle this by making an AI that plays the game and records data from each playthrough. This is a great way to see if some levels are too easy or too hard, especially if you don’t have a lot of human play testers.
Before going on my business trip, the biggest problem I was encountering was enemies vs. lag. As cool as it would be to spawn 3 battleships against the player, battleships are large images and take longer to draw to the screen than smaller enemies. And that’s before factoring in large background images.
Below are some possible ways to handle this problem:
- Limit the number of large objects that can be on screen at any given time.
- Spawn enemies relative to the current framerate or expected framerate.
- Scale down enemies and/or background objects so they draw to the screen faster.
- See if there are any ways to make the graphic files smaller (jpg vs png, cropping the image, deleting metadata, etc).
What are your experiences and thoughts about procedural generation? Does your game use it or have you played a game that made good use of it? Let me know in the comments below!
QUOTE OF THE WEEK:
“Always deliver more than expected.” — Larry Page
Thanks for reading and have a great rest of your week!