EXAPUNKS

EXAPUNKS

129 ratings
(No Spoilers/Solutions) EXAPUNKS Code Snippets
By Wracketeer
This guide contains some techniques and examples to help improve your EXA skills.

These are NOT direct puzzle solutions, but concepts that will help you create your own solutions to puzzles.
4
   
Award
Favorite
Favorited
Unfavorite
For T Loop
The TJMP documentation in zine issue 1 contains an important but often-overlooked piece of information:

jump to the specified label if the T register equals 1 (or any value other than 0).

Using this, you can make a loop that runs an arbitrary number of times - either hard coded, or based on another value in the puzzle. Best of all, this loop only uses the T register, meaning you can use the X register for whatever you like during the loop.

Here's an example of a loop that adds 1 to the X register each time it runs:

COPY 16 T MARK LOOP SUBI T 1 T TJMP LOOP

The first line above sets the T register to 16. This is the number of times the code will loop. Each time the loop runs, we subtract 1 from the T register. Then we use TJMP to determine whether or not to run the loop again. As long as T register hasn't reached zero, the loop will continue running.

The above example uses 16 as the number to loop, but you can use any value you like. You can even use a value from another register, like something you've stored in X, or a value read from a file.

Be aware that performing any TEST commands will overwrite the value in the T register! Be careful not to run any TEST commands inside this loop.

Replication Instantiation
This is a fancy way of saying "pre-load an EXA with a value when using REPL".

Let's say you have five different links you want to enter (800-804). One of these links contains a file (200) that you want to read from, but you don't know which. You could create five EXAs and copy/paste the code between them. Or, you could create a single EXA and have it instantiate EXAs with the REPL command.

COPY X 800 REPL START COPY X 801 REPL START COPY X 802 REPL START COPY X 803 REPL START COPY X 804 REPL START HALT MARK START LINK X GRAB 200 COPY F M

When an EXA is replicated via REPL, it keeps everything in the registers from the creator EXA. By setting the X register before the REPL command, we can seed the EXA with whatever variable we like. Then when we call the LINK command, we give it the X register. Each replicated EXA shares the same code, meaning we can run this as many times as we need to without taking up additional size in our solution.

Think about how you could use this technique with other commands (like TEST or COPY), and how you could use the "For T Loop" to simplify replicating EXAs.
Synchronising EXAs
At times, you may need to have one EXA wait for another EXA to finish executing its code before continuing. This is simple enough to solve:

EXA A:
MARK LOOP TEST MRD FJMP LOOP VOID M

EXA B:
NOOP NOOP NOOP COPY 1 M

Replace the NOOP operations in EXA B's code with any other instructions you want to occur before EXA A acts. EXA B won't continue until something reads from M, and EXA A won't continue until it finds something in M, at which point it will clear the M registry.

This method will work with one EXA waiting for a signal, but what if you have multiple EXAs all performing different operations in different hosts, and you want to synchronise them with each other?
A lot of things can go wrong when using the M register to communicate between multiple EXAs; two EXAs could call TEST MRD at the same time, and since they both read the M register as empty, they could then write to it at the same time. Or another EXA could read from the M register before the EXA you intended to recieve the message gets a chance!

This is where the Local Mode on the M register can help. Consider the following code:

EXA A:
REPL SIGNAL MARK LOOP TEST MRD FJMP LOOP HALT MARK SIGNAL LINK -1 MODE COPY 1 M

EXA B:
COPY 0 X MODE MARK LOOP ADDI X M X TEST X = 6 FJMP LOOP MODE COPY 1 M

EXA A replicates a new EXA (A:0). EXA A:0 links to the host containing EXA B, switches to Local Mode, and copies the number 1 to the M register. EXA B, also in Local Mode, waits for the M register to contain a value, then adds that value to X.
If five other EXAs run the same code as EXA A, EXA B will eventually increase its X value to 6. When X reaches 6, the loop ends, and EXA B switches to Global Mode and writes to the M register. EXA A then reads the message in the Global M register, and is free to continue running code.

Essentially, we use the replicated EXA as a messenger which carries a signal by moving to the same host as EXA B and communicating it locally. Then, EXA B switches to Global Mode and sends the synchronisation message to all other EXAs.

Consider how this could work if it was not possible for EXA A to send a replicated EXA to the same host as EXA B (For example, some puzzles contain one-way paths). Remember that EXAs in Local Mode will ignore messages sent in Global Mode, and vice versa.
Escape from M
When coordinating multiple EXAs such as in the example above, it isn't always possible to call VOID M and unpause an EXA after it has written to the M register. If you call VOID M on multiple EXAs, only one will be able to actually execute the command, and all the others will be paused. Here's a tip to ensure you can always unpause an EXA that writes to the M register:

REPL UNPAUSE COPY 1 M HALT MARK UNPAUSE VOID M

This will replicate a new EXA, which will clear the M register once it reads something from it. This way, your other EXAs can carry on with their instructions without having to deal with clearing the M register.

If your EXA that writes to the M register doesn't need to execute any other code, can you think of a way to make it HALT even faster?
8 Comments
theomegacarrot 13 Jan, 2021 @ 9:10am 
Something I've used to avoid an exa getting stuck reading/writing M is just to let it get stuck, and just kill it when the time comes
Arinyes Cant'ari 2 Dec, 2020 @ 7:09am 
I know there's mention of stupid code is smarter code, but that would apply to single line commands that won't exceed the example of before where replication creates a multitude of lines.
Arinyes Cant'ari 2 Dec, 2020 @ 4:26am 
Personally, I saw a better way to set up a replication system, by using X as your LINK X and REPL L the clones to do their task, while checking whether X matches a number higher than the total amount of gates available. FJMP to your replication loop and HALT at the end of it.

Something like this:
MARK CLONE
REPL EXE
ADDI X 1 X
TEST X = 805
FJMP CLONE
HALT

MARK EXE
LINK X
etc....
Panterich 21 Aug, 2020 @ 11:22am 
Great guide in concept, execution and content. Shame it has so little.
I think it worth a mention that TEST MRD executes at the same cycle as writing to M for those who try timing their syncs.

@arcane you are correct

@landvaarder what is the point of copy/pasting info from the zine?
arcane 3 Jan, 2020 @ 4:23pm 
I think in "Replication Instantiation" the instruction is flipped? IE its COPY 800 X, not COPY X 800
catcraft 8 Oct, 2019 @ 12:03am 
The method for syncing exas works for 2 exas, but what about something like 10 exas?
landvaarder 26 Sep, 2019 @ 3:12pm 
Here is a fun one i learned from another user:
you can compact repeating instructions in the editor before runtime with @REP x and @END
and you can make incrementing values with @{x,y} with x being the initial value and y the amount to increment (or decrement with negative values) by
for example:
@REP 4
LINK 800
@END
results in
LINK 800
LINK 800
LINK 800
LINK 800
and
@REP 4
LINK @{800, 3}
@END
results in
LINK 800
LINK 803
LINK 806
LINK 809

hope this helps
CuddleKing 19 Aug, 2019 @ 3:51pm 
nice little guide, good work op.