Notes on Random Levels in ZZT
quick note: This is a page to tack notes on procedurally generated (ZZT generally lacking "seeds", this means "random") levels in ZZT. Random dungeons have been used in a lot of games to some degree or another, enjoying a brief fad in 2000-2003 or so, with a smaller piece or two besides.
Because ZZT is not advanced enough to generate things procedurally (as pure data) and then map them, either in board memory terms or in pure variable terms, you have to rely on what you do have: random directions, nine boolean flags, and a host of environmental contexts. There are therefore two lists of building blocks below: One pertaining primarily to objects (that run code), and the other pertaining primarily to environmental objects and enemies (boulders/sliders, slimes, etc.)
- 1 What do we want out of ZZT level generation?
- 2 Important coding blocks
- 3 Important environmental blocks
- 4 Known Procedural Level Generation Engines in ZZT
What do we want out of ZZT level generation?
For our purposes, we generally want something:
- Interesting (or at least kind of interesting-looking)
Generally, most games have shot for being actiony (DGN, Run-On, ED Gold) but some segments of Run-On and the more recent-ish backtrax are more puzzle-esque.
ZZT games have traditionally not been able to guarantee passability of generated levels, instead relying on nothing at all (especially egregious when it is more likely to occur, but more forgivable for most of these examples) or on a "cheat" provided by the creator to get players out of supremely bad generation RNG.
Rabbitboots who runs this wiki has provided some excellent starting points for solving this problem in terms of level layout that can be found in his 2018 Doodads world. KKairos has an idea or two as well, mostly for starting from "maze" level things and expanding that to something interesting.
This will be mostly about methods that are useful for quick levels for gameplay, but will acknowledge tangentially when things are really really cool despite being impractical as game level gen.
Important coding blocks
Obviously you'll need to do some coding; there are few if any situations where you can get the level to generate itself.
because they use ZZT-OOP to get the randomness and act on it. We need them. They come in two flavors:
- Objects outside of the area of the board doing generation are probably doing gamerunning tasks or dice-rolls for the objects that are acting on level generation
- Objects inside the area of the board doing generation are probably interacting with the environment before, after and during its generation. In a number of examples, these objects either #become (change type to) part of the environment or become (in their code) enemies for the player to fight. I'll have some more notes on environmental behaviors later on.
(see: almost every example of procedural ZZT level generation)
some variant of random directionality is used in basically all ZZT games with heavy procedural generation. I think possibly Ekso doesn't, but I'm still working on getting through the list.
really nearly all zzt randomness begins with the random directions in some way, shape, or form. it's the simplest way of getting randomness out of ZZT and the most environmentally predictable. Even in games that don't procedurally generate their levels, you frequently will see this used to round out RPG battle engines with a touch of the ol' RNG.
rndp <dir> (randomly perpendicular to the given direction) rndne (north or east) rndns (north or south)
rnd (n,s,e, or w, with the horizontal being twice as likely as the vertical, but e/w and n/s pairwise equally likely
and by extension:
rndp rndne (1 of 4 cardinal directions)
so if you need an object to do something at a 1/2 split, it can do rndne with block n and not e
if you need an object to do something with a 1/4 split, it can do rndp rndne with a block in each corner.
If you need to use rndne instead of rndp rndne, you can do it twice with a label that splits first into the "top" and "bottom" of a diceroll, then into the "top" and "bottom" of each split.
I haven't explored rnd yet much, but that's some interesting potential because it allows us to construct situations with likelinesses in 3rds and (at least partially) in 6ths. E.g. an object is 1/6th going to be this, 1/6th that, one 1/3rd thing 1 and 1/3rd thing 2.
(you have 9 of them, and they can help deliver information from one object to another, e.g. from an object in a dicerolling environment to a set of objects actually making the dungeon happen.
You generally need these to change your environmental blocks into something presentable and playable. Sometimes you even need them to help with generation to start with.
Whatever it is Rabbitboots did with that maze walker
Presumably using a combination of all of the above and in an attempt to make KKairos's brain explode in wonder, Rabbitboots built a mazegen that works with only one object to build a small, medium or large maze. It's not really good for a game at this point mainly because it takes a long while to get a maze, but it's a really cool thing. You can find it in his doodads, which is the same place his concept for a walkable house-gen is.
Important environmental blocks
Flag alternatives (if you plan your level generation carefully you can minimize or eliminate use of flags)
If you can ensure that only one object of a type and can be on screen, you can replace some flag use in your dicerolling robot with #put <acceptable dir> <color> <gem>. Heck, if you can get it down further you can even use things like gem, torch, ammo, water, door. But to do that you have to basically keep those objects from being used in generation (or existing on the board) until you're done or almost done with level gen. Sometimes that's not practical, and to be honest, it seems a little extreme to me.
Another thing to note about flag alternatives is how intense they can get on the kb/board limits. "#set c0" even accompanied by "#clear c0", is likely, though not guaranteed, to at LEAST break even with several red/blue/cyan gem checks. Yours truly was working on a generator wherein he was going to replace 4/4 flags a board was capable of using with flag alternatives, but wound up bringing two flags back and using them together to sort of "simulate" having 3 or 4 flags at a cost of uniform distribution.
Boulders and sliders
(see: DGN series 2+, Run-On, LOST)
They can push things and block things and they can be all 7 colors. That's very helpful for procedural generation if you only want to use a few objects, but you want the content to really shine in its scope.
(see: Ekso, Endless Dungeon Gold, one room of Kerfuffle!)
Slimes move erratically, and every turn you can #change the breakables they leave into one thing and leave the huge amoeba going, ready for the next #change. That makes them an interesting, if unpredictable, choice for low-cost level generation in terms of KB.
(see: Regeneer Caverns)
Bombs create (temporarily) "breakable" objects of various and sundry colors that aren't predictable even though they occur in a predictable oval pattern. This makes them ripe for generation potential, if you can grab them at the right time.
Invisible walls provide their own type and can be turned into other types of things, including space. This can make them helpful for helping objects environmentally map a dice-roll to an action.
Known Procedural Level Generation Engines in ZZT
This is just a list for now.
Dungeon Guru Nostalgia
Used objects in environment and also "rolling dice" to no great effect. Too many doors. Not even a proof-of-concept. many unpassable floors, none of them very interesting.
Dungeon Guru Nostalgia 2
Appears also in Maximum. Has a BenW variant in Ben There, Made This! and WiL's Ultimate variant in Run-On.
Minimal chance of unpassable floors, verified. Somewhat interesting level design.
Dungeon Guru Nostalgia Tower / 2.0
Minimal chance of unpassable floors, according to author.
Endless Dungeon GOLD
Slimes. Used object enemies. Multiple classes. Mildly interesting level design.
Run-On / v2.4
Very interesting, sliders'n'boulders, progression from left to right in most early levels. Very long game with multiple level gen engines.
Similar generation to Run-On, but allows running in all directions.
Only "pacifist" game in this list that is known. Neat puzzle/arcade feel.
Only appeared as a demo in a mini-magazine by Benco.