The ZZT Exploits/Tricks Thread

NOTE: I HATE A LOT OF YOUR ZZT GAMES, SO WATCH OUT!

Moderators: Commodore, Zenith Nadir

User avatar
Dr. Dos
OH YES! USE VINE WHIP! <3
Posts: 1772
Joined: Tue Mar 11, 2003 12:00 am
Location: Washington

Post by Dr. Dos »

because tim was goddamn lazy :zzt:
Visit the Museum of ZZT
Follow Worlds of ZZT on Twitter

Apologies for the old post you may have just read.
User avatar
Zenith Nadir
this is my hammer
Posts: 2767
Joined: Wed Mar 12, 2003 11:40 am
Location: between the black and white spiders

Post by Zenith Nadir »

Dr. Dos wrote:because tseng was goddamn lazy :zzt:
he looked upon the world and saw it was still depraved :fvkk:

Overall: Rotton egg for breakfast
User avatar
Scribbit
is keeping the new avatar, thanks.
Posts: 543
Joined: Tue Sep 18, 2007 8:06 pm

Post by Scribbit »

Nupanick has ass burgers because tim was goddamn lazy?

That is weird, though. It sometimes ends up with you sitting "on top of" the object, and sometimes it moves the object out of the way.
I'm nupanick.
User avatar
nps
so kawaii! so cute!
Posts: 810
Joined: Sun Jan 18, 2004 1:51 pm

Post by nps »

It's true, he was goddamn lazy, I was just being coy.

Here's another one: open your copy of ZZT.EXE in notepad, add and delete random characters, and then save the file and run it. Kooky things will happen! Wow! So random!
User avatar
Aplsos
ill make a meal of you
Posts: 429
Joined: Fri Jan 23, 2004 3:06 pm
Location: beautiful downtown joelville
Contact:

Post by Aplsos »

there was something like that a while ago, but with the super mario bros. rom
r
User avatar
Quantum P.
Level 17 Accordion Thief
Posts: 1433
Joined: Fri Sep 12, 2003 1:41 am
Location: Edmonds, WA
Contact:

Post by Quantum P. »

I know I'm committing thread necromancy again, but while making my Collabyrinth entry, I discovered a couple of tricks I thought I'd share...



Storing counters in board terrain
Difficulty: medium; hard if you're unfamiliar with binary


This trick empties a counter, converts the value that was in the counter to binary, and stores it as a pattern of terrain. At a later time, you can load that value back into the counter. This is useful if you need a counter for an engine but don't want to disturb any of the counters (which may be in use for other things).

For those unfamiliar with binary, the basic idea is that any non-negative integer can be written as a sum of different powers of two. For example, 19 is 16 + 2 + 1, or 2^4 + 2^1 + 2^0. We would normally write this as 10011:

Code: Select all

 1       0       0       1       1

add    don't   don't    add     add
16     add 8   add 4     2       1
We'll use invisibles and empties to represent 0s and 1s. That way, we'll be able to read the number later using #if blocked statements. The largest possible value for a ZZT counter is 32767, so we'll need powers of two up to 16384 (32767 = 16384 + 8192 + 4096 + 2048 + 1024 + 512 + 256 + 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1). Here's the excerpt:

Code: Select all

:store
#take score 16384 put n red invisible
#take score 8192 put w red invisible
#take score 4096 put s red invisible
Now, before we box ourselves in, we move one step east. This gives us room to store more bits:

Code: Select all

/e#take score 2048 put n red invisible
#take score 1024 put w red invisible
#take score 512 put s red invisible
'...
Repeat until you have #taken every power of two (including 1). At the end of this process, score is 0, and its previous contents are stored in a relatively compact 6x3 space. Now our engine can do whatever it wants with score. When we want to return score to its original value, we set it to 0, then do everything in reverse:

Code: Select all

:load
#if not blocked s give score 1
#if not blocked w give score 2
#if not blocked n give score 4
#put s empty
#put w empty
#put n empty
/w#if not blocked s give score 8
'...
That's the general idea, but it can be improved upon:
* This implementation takes up over a kilobyte of space; clever coding could lead to smaller code (see example).
* At #cycle 1, this implementation takes about half a second to load or store a counter value. With 4 objects, you could make a counter storage device which works instantly.
* Why use terrain? You could #zap and #restore labels to keep track of which bits are 0s and which bits are 1s.

There are tradeoffs here. The last two suggestions are faster and provide non-destructive loads (i.e., loading a value does not erase it from the board). However, the original implementation allows you to store multiple values, similar to how you would push values onto a stack in real programming. But I think I've gone on long enough about this subject.



Using a counter to address a single #bound object
Difficulty: somewhat hard


This is a somewhat general trick, so I'll just make up a simple example. You have 10 objects. The first object has the following code, and the other nine are #bound to it:

Code: Select all

@guy
#cycle 1
#end

:check
#take gems 1 doit
#end

:doit
#zap doit
#char 2
/n/s/n/s/n/s/n/s#char 1
#restore doit
:doit
So what's going on here? Picture what would happen if you ran the following code (starting with an empty gems counter):

Code: Select all

#give gems 3
#guy:check
The first three @guys each #take gem 1 and #end. The fourth @guy tries to #take a gem, but there are no gems left! So he jumps to the :doit label, #zaps doit, and does a happy little dance.

The other @guys also try to #take gems, but they also find that there are no more gems left. So they also jump to :doit, but because it has been #zapped, they do nothing. As a result, the only object which does anything is the third object. In summary, the gems counter determines which object is active.

But what's the point? Well, in my Collabyrinth entry, I have a lot of objects which do approximately the same thing, so I'd like to #bind them together. However, I want to be able to give different instructions to different subsets of those #bound objects. My code is slightly different, but it uses the same kind of trick I detailed here.

Also, a small modification could keep the counter from being emptied every time you #send guy:check...

Code: Select all

:check
#take gems 1 doit
/i#give gems 1
#end
Now #take and #give become "select previous object" and "select next object" commands.
User avatar
thematrixeatsyou
‮Ouch.
Posts: 44
Joined: Wed Sep 06, 2006 8:50 am

Post by thematrixeatsyou »

Old thread, second time in a row, but it should be worthwhile.

These are tricks which aren't listed in the ZZT encyclopædia. All of them require reasonably precise timing.

Rapid conveyor transport
Rating: Easy, though requires an external editor to change conveyor cycles OR you could order the conveyors appropriately

Create a conveyor, then change the cycle to 1, then duplicate in the correct direction. If you slip an appropriately timed duplicator in, you can make it duplicate quite well. Make a row of duplicators in the correct order, and you could, lets say, fire 5 lit bombs.

Note that each conveyor can make only one movement per cycle.

Conveyors cannot move objects. Which is a pity. But they CAN move the player. And inbuilt enemies. And scrolls.

Clearing all keys
Rating: Hard - requires objects to be placed in a certain order, also uses player clones BUT DOESN'T REQUIRE AN EXTERNAL EDITOR :D :D :D (although you probably should consider using one)

Letters show order of which objects must be placed. Every object is cycle 1.

Code: Select all

#A#
# #
Firstly (A), an object you need to press up against (although any other direction will do, just make sure you use the same direction for everything!) This should send a label, e.g "byekeys", to ALL objects (#send ALL:byekeys).

Code: Select all

#RSTUVWX######## #
B              # #
#              # #
#CDEFGHIJKLMNOP#Q#
Secondly (B), an object to spit sideways, 7 boulders (using one of every colour), then 7 keys (ditto), then change the boulders into doors.

Thirdly (C-Q), several objects to spit out player clones up, then idle 1 cycle, then shoot them. 14 for all keys/doors, and 1 for you to teleport afterwards.

Fourthly (R-X), some objects to, after idling for 1 cycle, #put an empty down. This will actually push the remaining keys down, but don't worry, if you've done it in the correct order, then if you go through again, the second set of keys will be placed before the player clones, and because there is a wall (of objects - well, there should be at least SOME form of wall!) at the end, the player clones will be placed *over* the old keys.

Replacing the player with a monitor
Rating: Easy, though requires an external editor to create a monitor and change conveyor cycles (I use KevEdit)

First thing you create must be a monitor.

Then create these things in the following order:

Code: Select all

# B#
#CA#
# ##
A = clockwise conveyor
B = counterclockwise conveyor
C = scroll

For some weird reason, you MUST go up for this trick to work.

It's kinda useless really, unless you REALLY want to catch the P key and want to remove the player entirely.

EDIT: One more.

Start on title screen without pressing P
Rating: Easy
If you don't mind people not seeing their score / ammo / whatever, just create an object with this command:
#change monitor player
Then put a passage somewhere.

Unlike the method explained on the ZZT Encyclopædia, you can actually leave the title screen.

Also unlike that method, you get hurt (10 damage). If you get hurt too much, you get stuck with the "Game over - Press ESCAPE" thing.

One more thing: you can actually be brought back out after you quit or something like that.
AKA GreaseMonkey. This is my old nick.
Unless someone sneakily changes it while I'm not looking.
Oh well.

Playing around with timing hacks.
Post Reply