Iterating on quick-and-dirty level gen in Bat Egg Who am I? My name is Cheese, and I wear many hats. The ones that are relevant today are: * Game developer * Egg You can find me on Twitter as @ValiantCheese or on irc.libera.chat as Cheeseness. I've worked on some games you might have heard of * Neverball http://neverball.org/ * Day of the Tentacle Remastered https://www.doublefine.com/games/day-of-the-tentacle-remastered * Full Throttle Remastered https://www.doublefine.com/games/full-throttle-remastered * The Fall http://store.steampowered.com/app/290770/ * Hand of Fate http://defiantdev.com/hof1.html * The Away Team http://awayteam.space/ And others you might not have heard of * Hive Time http://hivetime.twolofbees.com/ * In the Snowy Winter's Wake http://winterswake.com/ * Bonesweeper https://cheeseness.itch.io/bonesweeper/ * Supply Chain http://cheeseness.itch.io/supply-chain/ * Honeycomb CRUNCH http://cheeseness.itch.io/honeycomb-crunch/ * The Spicy Meatball Saves The Day http://cheeseness.itch.io/spicy-meatball/ * Voices of the Past https://cheeseness.itch.io/voices-of-the-past * Super Happy Fun Sun http://shfs.twolofbees.com/ * Robin's Rescue http://robinsrescue.twolofbees.com/ * Above The Waves http://atw.twolofbees.com/ * FLAT http://flat.jbushproductions.com/ * Grenades, Snarks & Teleporters http://www.moddb.com/mods/grenades-snarks-teleporters Today, we'll be talking about Bat Egg https://www.patreon.com/posts/yet-another-bat-53110154 Bat Egg is a small action game inspired by what I imagine Flappy Bird to be (I've never played it!) and based on characters I used to draw. A disclaimer As always, every developer and every project has its own context and identity. What's discussed here is not advice, but perspectives shared in the hopes that it can help you discover or navigate the best fit for your own work. Iterating on quick-and-dirty level gen in Bat Egg Today we'll be looking at creating and refining level generation across Bat Egg's development, going from a splatter of coloured blocks to something approaching release-ready levels. What do we need from level generation? Bat Egg levels should: * Be infinitely variable * Contain obstacles * Contain safe points in nests and rests * Contain collectable tokens What do we really need from level generation? All of this is in service of creating interesting spaces to navigate while managing ballistic momentum and stamina. Bat Egg's levels are about gaps. First steps * Place nests (green) at 40 unit intervals with vertical position at 9 ± 1 * Place branches (orange) at 40 unit intervals + 10 with vertical position at 13.5 ± 7.5 * Step through the playspace in increments of 4 units * Place obstacles (red) with lateral variation of increment * randi() % 20 * 25% chance for an obstacle to be placed low * 25% chance for an obstacle to be placed high * 50% chance for an obstacle to be placed in the middle * Track all used coordinates and shuffle anything within 2 units of another obstacle's lateral position up or down How's that look? This generates spaces that feel noisy and random. Obstacles sometimes spawn too close to nests and branches. It was good enough to switch dev focus to movement mechanics and building assets. Let's get a bit more focused * Step through the nest count and step through nestInterval between nests in increments of 6 * Place nest at nestInterval with vertical position at 12 ± 4 * Place a branch when increment crosses nestInterval / 2 ± a third * Track obstacles placed since last obstacle of each type, and give priority to anything > obstacleDelayThreshold * Place primary obstacle with priority type or equal chance of low, high, mid, or none (no secondary either) * 50% chance for secondary obstacle with recalculated priority type, excluding primary type How's that look now? This generates spaces with desired level of interestingness, but without consistency. Obstacles overlap nests and branches sometimes. It was good enough to start to consider game-scale pacing and balancing. Catching overlaps * Track every obstacle, nest, and branch in separate lists * After generation, increase the collision margin on every obstacle by player radius * 1.5 * Loop through every nest, branch, and token, and mark any overlapping obstacles for culling * Loop through every obstacle, and mark any that overlaps more than one obstacle not already marked for culling * Cull all marked obstacles * Reset all collision margins A little better, a little worse A screenshot showing a token overlapping a branch obstacles at commit 58f89e8a This generates slightly less interesting spaces. Sometimes there are long distances between obstacles. Obstacles are still sometimes placed a little too close to nests and rests. It's mostly good! A bit more refinement * Use proxy colliders for nest and branch overlp detection * Move obstacles that overlap nests or branches up or down depending on obstacle type (but still cull if that doesn't resolve overlap) * Move tokens that overlap branches down * Move tokens that overlap nests up * Minimum distance between tokens How's that look? This generates consistently interesting levels, with enough room for variety for that to not degrade over time. Nests and branches are safely approachable. A combination of near-naive generation and post-generation tweaking yields good results! A few extra bits and pieces * Lots of tweaking of threshold, max distance, and chance variables * Difficulty progression by increasing nest count and nest interval across levels and zones * Lost eggs provide a fun collectable and advanced challenge * Vertical levels give new context for familiar gameplay * Per-zone environments with their own backgrounds and obstacles increase variety and sense of progression * Per-obstacle mesh scaling and rotation options gives more variety * Culling margin size gives low-effort difficulty controls Further Reading I've written a little about, streamed, and otherwise documented some of Bat Egg's development. If you're hungry for more, read on. * Twitter progress thread * Bat Egg Pamtram posts * Bat Egg dev stream archives Thanks for listening to me waffle about Bat Egg's level generation! Bat Egg's not released yet, but some of my other games can be found on my Itch.io page http://cheeseness.itch.io/ More musings on development can be found on my Patreon page http://patreon.com/cheeseness More of my writing about games, and game-adjacent culture can be found at Cheese Talks http://cheesetalks.net/cheese