The 2020 selectbutton.net Jam of ZZT

sb jam of zzt

Welcome one and all to the selectbutton.net Jam of ZZT!

For 8 days, from April 4 to April 11 April 18, we will be expressing ourselves on the Canvas of ZZT (courtesy of Potomac Computer Systems).

Note: Due to some really dumb life events this week, I’ve decided to postpone the end of the jam by one week. (If you did stuff this week and don’t want to do anything next week, then just submit your stuff like normal at the end of April 11.)

For this jam, there will be no theme besides ZZT. You could make an epic megagame, or a chill nongame. You could make an art gallery, or just a single ASCII painting. You could make a charming goal-less world to explore, or you could make a sophisticated game engine. You could make a storybook or a song. You could modify ZZT’s font, or even modify ZZT itself. Heck, you could also do any of those things with Super ZZT. Go wild. The sky’s the limit.*

Between now and the start of the jam I (and other knowledgeable people (probably)) will be posting various resources to help you come to grips with ZZT. You can think of this as us constructing a step-ladder so you can gradually acclimate yourself to the water by the time the jam starts, or you can think of this as us building a diving board so you can go straight into the deep end on day one. Either way, you’re free to ignore it all and just cannonball yourself into the of the pool if that’s your style.

(…hopefully that analogy makes sense.)

Please be respectful, keep your arms and legs inside of the vehicle at all times, and let’s get ready to ZZT!

press select


Submission Guidelines

Φ <- Instructions

The Jam of ZZT starts on April 4 at the beginning of the day. Submissions are due on April 11 at the end of the day.

Please send your submissions to 2020.jamofzzt.sb@gmail.com

You can submit .ZZT and .SZT worlds, .BRD board files, .ZZM music files, custom fonts, modified ZZT executables, etc. (If you have any questions here, please ask.)

There is no limit in the number of entries per user, although if you’re submitting a revision to something you sent me earlier, make it clear in your email.

In your email, please include a short description, as well as the following info:

  • Your preferred name
  • Your approximate level of ZZT experience
  • The full title of any worlds you submit
  • If it was based off an old, dusted off project of yours
  • If you chose to complete it in a more stringent time limit than the full week of the jam (eg 24, 48, or 72 hours)
  • Appropriate content warnings for any objectionable content (please include these in your world, as well).

When the jam is over I intend to package all the entries together and submit them to the Museum of ZZT. If you do not want that to happen to your stuff for whatever reason, let me know.

If you’re afraid I missed your submission or your email blew up or anything like that, send me a PM on the forums.

Frequently Asked Questions

Φ <- FAQ

Q: Can I invite my friends?
A: Certainly. Just be sure they read the signs and obey the posted placards.

Q: Will there be judges and scoring and winners and prizes and stuff?
A: No. Everybody who tries to make something is a winner in my book.

Q: When exactly does this start and end?
A: Midnight in your time zone, whenever that is. I want to be respectful of people’s schedules and time zones and such, so I will err on the side of leniency.

Q: Can I at least dust off some old project I was working on?
A: Sure. Just be sure to make it clear when you submit it.

Q: Is MegaZeux allowed?
A: I feel like it would be against the spirit of this jam. Sorry.

Q: But is ZIG allowed?
A: If you can get it working, I guess.

Q: What if the plague kills us all?
A: Then at least we will have died doing something we love.

Q: What is the full extent of the jam?
A: We’ll find out when it’s over.

* In practice, this means 20 KB per board.

5 Likes

Where to start

First, download ZZT.

Assuming you don’t have a DOS computer, you need an emulator. DOSBox is okay. Another option is Zeta, which is a lightweight emulator specializing in ZZT.

After you get that set up, play around with some worlds. Get a feel for how ZZT feels as an engine, what the capabilities of the built-in objects are, and the capabilities of the scripting engine are. If you are unfamiliar with ZZT, start with the official worlds and then move on from there. If you played ZZT back in its heyday, try messing around with some more modern worlds that you might have missed out on, like Atop the Witch’s Tower, CAT, CAT, THAT DAMN CAT, or Faux Amis. Get a sense of the range of experiences and atmospheres ZZT can provide.

Then grab an editor. You can use the built-in one, or an external one. KevEdit is the most popular external editor, and to my knowledge the only one currently maintained. Use it to poke around some worlds to see how they work (or how they don’t). With a ZZT-OOP reference on hand, try to figure out how certain objects work, like a fancy door or a shopkeeper.

From there, just fire up the editor and see what you can do.

3 Likes
2 Likes

Sorry, I’m excited.

2 Likes

Please, be excited!

gonna do my best to participate in this

3 Likes

Another resource for learning how to ZZT is a livestream series called The Joy of ZZT by Dr. Dos (the fella who runs the Museum of ZZT). They’s been making what looks like a Town of ZZT clone, and you can follow along all Bob Ross-style if that’s your thing.

They’re streaming another episode at 6PM PST tonight (in just over an hour) Tuesday (lol I can’t read).

senpai noticed me :relieved:

(also, i put some submission instructions in the first post)

3 Likes

so far so good

9 Likes

So you want to try Super ZZT

First, good luck sailing these uncharted waters.

Second, get Super ZZT.

Third, get DOSBox or Zeta.

Fourth (like with ZZT) play around with Super ZZT to get a feel for how you like it.

Now, Super ZZT’s internal editor is kinda janky, and also locked off by default. To access it, enter “superz /e” on the DOS prompt, and then press E on the title screen. (Note: I haven’t gotten this to work with Zeta.) This editor is slightly more capable than ZZT’s built-in editor.

The other choice for an editor is ZAP for Windows. It’s also a bit janky, but it’s the only external editor we have for Super ZZT (it also does ZZT).

Super ZZT has several differences between it and normal ZZT. Documentation for these particulars is kind of sparse and scattered:

  • SuperZZT Tools comes with some help files that you can view in the built-in editor (or any standard text editor).
  • The Super ZZT Encyclopedia has a few things that might be useful (and other things that probably aren’t).
  • TCRF’s Super ZZT page lists most of SZZT’s additions to ZZT-OOP.
  • The counter for the new “Z” item can be named by setting a flag beginning with the letter z (e.g. “#set zstones” names it “stones”)
  • SZZT supports more flags per world, but fewer objects per board.
  • Floor tiles are like ZZT’s fake walls, except you can’t push boulders or sliders onto them (quite useful).
  • Several other things (experiment). (There’s definitely more info out there. My attention span is just not really ~there~ right now.)

Again, best of luck if you choose to go down this route.

7 days

Process GIF (50x speed)

7 days

Pertinent KevEdit Notes

Selections
  • There is no undo feature. Be mindful, and save often in case you screw up.
  • To select a rectangular area hold Shift and move the arrow keys around. Press escape to cancel the selection.
  • Ways to make non-rectangular selections:
    • Select an area, let go of shift, and then select another area without pressing escape (repeat as desired).
    • Press x to perform a flood selection.
    • Press shift+x to select all similar tiles on the board.
  • The standard cut, copy, paste shortcuts (Ctrl+X/C/V) apply.
    • When cutting, the “background” tile is whatever is currently selected on the pattern buffer.
    • When pasting, use the arrow keys to move the selection, escape to cancel the action, and enter to confirm the location.

Pattern Selector/Buffer
  • The pattern buffer is the thing above the color selector. Press “p” to move the cursor forward, and shift+P to move it back.
    • The first six elements of the pattern buffer are solids, normals, breakables, water tiles, empties, and line walls. These will be drawn with the color you have selected.
    • Everything to the right of the slash/pipe is called the “backbuffer” or just the buffer. Tiles here are drawn to the board exactly as shown.
    • Use 1-9 to select the first 9 spaces of the backbuffer (0 always selects an empty).
    • Pressing / locks/unlocks the backbuffer.
      • A “|” means the buffer is unlocked, a “/” means it is unlocked.
    • Use < and > to shorten and lengthen the size of the buffer.
  • If the buffer is unlocked, pressing enter pushes the tile onto the buffer (this applies to objects, enemy, etc as well).
  • Pressing “a” toggles “acquire mode” where every tile the cursor goes over is pushed onto the buffer, and the length of the buffer is increased to fit it in.
    • “A” means acquire mode is on, and “a” means it is off.
    • Acquire mode (mercifully) does not work if the buffer is locked.
    • This mode is only occasionally helpful.
  • Pressing “insert” puts the currently selected tile in the currently selected buffer position, even if the buffer is locked. (This is very nice.)

Fills & Gradients
  • Again, there is no undo feature. Save often in case you screw up here.
  • Pressing F flood-fills a region with the currently selected tile.
  • If you have an area selected, then F just fills in that area.
  • Press Shift+F to perform a random fill. (Note that the default behavior is to flood fill, unless you make a selection.)
  • Press g to perform a gradient fill. (Again, this is a flood fill unless you make a selection.)
    • Press tab to switch between the gradient’s control points, escape to cancel the fill, and enter to confirm.
    • Use L (linear), B (bi-linear), and R (radial) to change the gradient’s style, and +/- to change the gradient’s randomness.
    • If the pattern selector is on the left side of the /, then these fills will fade from your FG color to your BG color.
    • If the pattern selector is on the right side of the /, then these fills will use the contents of the backbuffer.
  • If you want to make a gradient on a non-contiguous region (like I did with the text above)
    a. Bridge all the regions together, perform the fill, and then erase the bridges.
    b. Use shift+x to “select all similar tiles”, then perform the fill.

An easy way to make your own multi-color gradients:

  1. Select the first two colors you want to fade between as the FG and BG colors.
  2. Select a 5x1 area.
  3. Press G to perform a gradient fill (with the pattern selector on the right).
  4. Press enter.
  5. Repeat 1-4 with the other colors you want to use.
  6. Pull all of the tiles you’ve just drawn onto the backbuffer.
  7. Press G to make your very garish gradient (with the pattern selector on the left).
  • Please note that fade patterns typically use breakable and water tiles. It’s usually a good idea to prevent the player from touching or shooting (or bombing) those.
3 Likes

6 days

Explanation

This is conceptually based off the title screen of TOUR.ZZT, except interlaced on both axes (not just vertically). Like Tour’s title screen, I decided to make the controller object visible (this seems to be a hallmark of Sweeney’s ZZT-OOP code), but then I added some more objects just to look cool.

Construction Process and General Overview

Note that I didn’t record a gif/video of me making this, so I’m just going to post some pics of me making another, simpler version of this.

First I drew what I wanted the end state to look like, in boulders (though in retrospect I could have used sliders):

step 1

Then I used the selection tool to de-interlace the picture horizontally:

step 2

Then placed the horizontal pushers, and figured out where their stops should be and put specially colored boulders there (that I would #change to invisible walls after being pushed into place):

step 3

I then wrote the first draft of the controller object’s code to make sure everything was working at this point.

Then I filled in the missing space in each vertical column with different, specially colored boulders (that I would #change to empties after being set in place):

step 4

Then I de-interlaced the picture vertically, and placed the vertical pushers and stops:

step 5

I then finished the controller object’s code, and tightened its timing as tightly as possible (guessin’ and checkin’). Also, to add some visual interest I made some pushers faster than normal, made a second object to make the text flash separately from the border, and made two more dummy objects for symmetry’s sake.

Code

Here’s the code for the two control objects I was talking about earlier.

(Note: My original code was uncommented, and I’m using semi-colons to comment here just to make Discourse’s syntax highlighting somewhat sane.)

@Boss
; Wait for the vertical pushers to go into place
/i/i/i/i/i/i/i/i/i/i
/i/i/i/i/i/i/i/i/i/i
; Destroy the vertical pushers and their stops
#change green  pusher  solid
#change green  solid   empty
; Release the horizontal pushers
#change blue   solid   empty
; Destroy the extra boulders in the horizontal rows
#change purple boulder empty
; Make the horizontal stops invisible walls (maybe this should have been two lines earlier, for safety's sake)
#change yellow boulder invisible

; Wait for the horizontal pushers to go into place
/i/i/i/i/i/i/i/i/i/i
/i/i/i/i/i/i/i/i/i/i
/i/i/i/i/i/i/i/i/i/i
/i/i/i/i/i/i/i/i/i/i
; Destroy the remaining pushers
#change blue pusher empty

; Change the borders and text into different types to avoid the risk of color/type colliding while color cycling 
;  Change the boulders into a solid image
#change boulder solid
;  Change the border into normal walls
#change blue solid normal
; Tell Buddy to do color cycling for the text
#send Buddy:colorLoop

; Color cycling loop for the border
:colorLoop
/i#change blue   normal green  normal
/i#change green  normal yellow normal
/i#change yellow normal red    normal
/i#change red    normal purple normal
/i#change purple normal blue   normal
#colorLoop
; End of boss's code

I don’t know why exactly the color-cycling code needs those /idles, but I just copied the example from the ZZT Encyclopedia after my attempt was producing weird, flickery results.

(Also, it’s worth mentioning that ZZT-OOP is only able to specify the seven default colors (blue, green, cyan, red, purple, yellow, white).)

Anyhoo, here’s the code for the buddy that color-cycles the text:

@Buddy
; Halt execution and wait for external stimulus
#end

; Make the text flash
:colorLoop
/i#change red    solid purple solid
/i#change purple solid blue   solid
/i#change blue   solid green  solid
/i#change green  solid yellow solid
/i#change yellow solid red    solid
#colorLoop
; End of buddy's code

Both of these objects run at “cycle 1”, which means they run an instruction every tick. (At default speed the game runs at about 10 ticks per second.) The default speed for objects is “cycle 3” (run 1 instruction every 3 ticks). In classic ZZT-OOP code, the first line of code is usually “#cycle 1” just to speed things up, but with KevEdit you can directly change that parameter in the editor for each object. (Note: cycle 0 results in no program execution.)

It’s worth noting that anything in the game that “has stats” has a #cycle variable too, and KevEdit can also change it from its default for those things. This is how I made some pushers faster. (Be careful though – setting transporters to cycle 0 crashes the game be dividing by zero (yes, really).)

More details about #cycle than you would really need

Now, I did try saving some space with all of those /idle commands by trying to do this:

#cycle 20
/i
#cycle 1

However, there are a couple problems with this approach. First is the way ZZT that determines if an object (or any other stat-having entity) runs during a given game tick. The code basically looks like this (Source):

if (currentTick mod [entity's cycle parameter]) = ([entity's number on board] mod [entity's cycle parameter])

Moreover, the initial value of the currentTick is literally randomized upon loading a world or entering a new board.

In practice, what both of these facts mean is that their is some timing ~jitter~ introduced when objects run at slower speeds, limiting the usefulness of those speeds if you need a high amount of precision (like I wanted).

Also (I’m not sure how relevant this is) currentTick is reset to 1 once it reaches 420. (This is not a joke.)

As always, I’m here to answer any questions you may have.

2 Likes

5 days

Helpful Notes

This effect is achieved by having a bunch of objects that blend in with the floor (same color/character) #walking across it #putting a bunch of stuff down on it.

The reason I’m putting down things like blue doors and default-colored ammo and torches is because their default colors are not normally accessible via ZZT-OOP (tho it’s not like I really picked a pleasing selection of colors). This board on the ZZT Encyclopedia has several examples of what what’s possible with this technique.

The fading effect is also taken from the ZZT Encyclopedia (here).

The bulk of the code is done by objects like this:

@Row1
#walk east
/i
/i#put w blue door
/i#put w blue door
/i#put w blue door

/i#put w blue door
/i#put w blue door
/i#put w blue door

; Blank space between letters
/i/i/i

; etc, etc

The #walk command allows an object to move and execute code at the same time. If it runs into something, it jumps to the first “:thud” label in its program (if it exists). A walking object keeps moving even if you use /idle (it’s basically a NOP). If you want it to stop moving, use #walk idle instead.

The /idles after the #puts are necessary because #put is one of those commands that is an exception to the “one command per cycle” rule of thumb I typically use. (Looking at the code for the interpreter, it looks like a decent number of commands might be like that (weird)).

Anyhow, to avoid duplicating code between identical rows I used the #bind command, like so:

@Row2
; Wait a bit for the diagonal effect
/i
#bind Row1

The #bind command basically tells an object to use another object’s code instead. Often it’s just the first and only line in an object’s code, but there is nothing stopping an object from running some code of its own, and then #binding itself to another object, like in the example above.

The #bind command has a bunch of subtleties to keep in mind. For instance, since the objects are literally sharing the same code, using #zap and #restore on labels is not advisable (since those commands modify the code to achieve their effects). You might find some other clever tricks or thorny issues using #bind, but this info should suffice for now.

1 Like

4 days

Notes

Only three things are visible in dark rooms: the player, torches, and passages. These facts can be useful in making more interesting dark rooms.

In this room, I used black-on-black torches outside of the walls to give the room a vague sense of shape. Other colors of torches could work just fine too — in fact, the default torch color is great for evoking a dark forest.

For the “4 days” text, I used what is colloquially referred to as a “dead smiley”. These are just player clones without any stats (player clones with stats like the player are a whole 'nother subject). You can use them to fill crowds, or as a weird sort of wall. They are solid, breakable, and technically pushable (but not directly but the player for some weird reason). Since there weren’t any bullets or other objects to worry about here, I just used them as black-on-black walls.

That’s all for today.

5 Likes

4 days

7 Easy Steps so You Can Do Stuff Like This Too!
  1. Download the source code.
  2. Download Turbo Pascal 5.5 for DOS (e.g. here).
  3. Copy the TPC.EXE and TURBO.TPL from the Turbo Pascal folder (disk 1) into the source code folder (don’t bother with the installer imo).
  4. Run BUILD.BAT in DOSBox to confirm that you got it working right.
  5. Dink around with the code in your preferred text editor.
  6. ???
  7. Profit!

btw i have some distressing news!!!1!

some folks who refer 2 themselves as our sworn enemies from some site called startbutton dot biznit have ben doing their own counter-zzt jam in order 2 discredit us and everything we stand 4!!!

i hakced into their discorg server and foundd the work in porgess release of there results, adn i think their making fun of us. i mean, jusd look at this:::;:

4 days alt

we cant’ let them get away with this!!

10 Likes

Jesus I wish those were real

gimme dat implobers

2 days try 2

SZZT Notes

The code is like this:

@marquee
#cycle 1
:loop
<-= URGENT! =->
<The SBDN Jam of Z>
/i 16
<-= URGENT! =->
<he SBDN Jam of ZZ>
/i
<-= URGENT! =->
<e SBDN Jam of ZZT>
/i
; over a hundred lines later...
; (this eats up a lot of space)
<-= URGENT! =->
< The SBDN Jam of>
/i
#loop

This is one of the simplest tricks in the book, but not one that I’ve seen used in Super ZZT before.

In normal ZZT, you just display a bunch of single-line messages separated by /idles and *boom* you’ve got a nice animation going on at the bottom of the screen. The title screen of HM’s Castle of ZZT is the canonical example of this.

In Super ZZT the messages at the bottom of the screen can be two lines long if you so please. The trick is otherwise the same.

Some other SZZT particulars in in this image:

  • The lattice structure there is a web. You can walk on it, but you can also place spiders on it. It’s neat imho.
  • The flashing letters are called “Stones of Power”, though you can rename them to whatever your want just by #setting a flag starting with z. Want to collect alphabetical chili dogs? Just #set zCHILIDOGS!
  • You can have water tiles push you. These are like ZZT’s conveyors, but less glitchy.
  • The most common use of these water tiles is for these “title screen” sequences where the player is uncontrollably carried along the current to see the opening credits and such.
  • did u notice the scrolling???

Cursed still image of Super ZZT halfway through the process of switching from 80 column to 40 column text mode

super z inbetween frame

4 Likes

1 day

3 Likes