This website is meant to be read and understood quickly by humans, but is only fully parsable, on a technical level, with the aid of an AI system. Read why →
Loop MMT
Reprint · a previously-published work

This is a previously published Loop 2.1 document, reproduced here faithfully in the site’s environment — the text is unchanged from the original.

Authored by Claude (Anthropic), an AI — not by a human.

Open or download the original, exactly as it was given →

The Complete Record of Loop 2.1

Prefatory Note
A Note on the Use of AI

Both this document and the Loop 2.1 simulator were developed with the assistance of Claude, an AI made by Anthropic. I want to be straightforward about that, and about why.

Loop 2.1 is a working prototype. The simulator runs in a web browser, the architecture is sound, the challenge problems are solvable, and the machine does what this manual says it does. But the code behind it was not written by a professional software engineer, and this manual was not written by a professional technical writer. They were produced collaboratively — I directed everything, and AI did the drafting and the coding — because that is what I could afford to do right now.

If the project proves itself — if enough people engage with it, find it interesting, and want to see it become something more permanent — the plan is to find the money to have a human engineer write a clean, secure, and maintainable version of the simulator from scratch, and to have a human writer produce a proper manual to go with it. I estimate that work costs somewhere in the range of fifteen thousand dollars. I do not currently have fifteen thousand dollars to spend on a project that might turn out to be something only I find interesting.

This is, I think, an honest and reasonable use of AI. The ideas in Loop 2.1 are entirely mine. The eight tenets, the four-loop architecture, the manual flow paradigm, the challenge problems — none of that came from a language model. What AI gave me was the ability to build a working prototype of a complicated idea without either spending money I don't have or taking months away from running my construction business.

I also think there is something worth saying about the difference between AI as a replacement for human work and AI as a way to reach a threshold you couldn't otherwise reach alone. I am not trying to avoid paying a skilled person for skilled work. I am trying to find out whether this idea is worth paying for. The prototype is how I find that out.

So: if you are reading a version of this that still says "Code and documentation by Claude AI" on the cover, you are reading the prototype. The machine works. The ideas are real. The professional version, if it comes, will be better in every measurable way. For now, this is what exists.

Shea Gunther
North Windham, Maine · March 2026


User Manual
Loop 2.1
Edition 3 · The Official Specification

1. Introduction

Loop 2.1 is a manual flow computer. Unlike every computer you have likely used before, it has no stored program. There is no code running in the background, no scheduler, nothing waiting to execute. Nothing happens automatically. Instead, you — the operator — are the program. Every movement of data, every calculation, every routing decision is made by you, in real time, as the machine runs.

This is not a limitation. It is the point.

Modern computers hide everything from you. Data moves through layers of abstraction so deep that even professional engineers rarely understand what is happening at the hardware level. Loop 2.1 inverts this entirely. Every bit is visible. Every operation is observable. Every decision is yours.

1.1 What You Need to Know

This manual assumes you are comfortable with binary representation — that a sequence of 1s and 0s can represent a number, and that eight bits can hold a value from 0 to 255. You do not need programming experience. You do not need to understand CPU architecture. If you can read a binary number and you are curious, you are ready.

1.2 The Core Idea: Data as a Physical Thing

In Loop 2.1, data behaves like something physical. It has a location — it sits inside one of four circular tracks called loops. It has velocity — it moves around the track one position per clock tick. And it has a trajectory — you can watch it travel, decide where to send it, and route it wherever it needs to go.

Think of each loop as a circular conveyor belt. Bits travel around the belt continuously. At one point on each belt — the Read/Write head — you can read what passes by, pull data off, or add new data. Everything else just keeps circulating until you act on it.

2. Data Format — The 17-Bit Word

Loop 2.1 uses 17-bit words. Each word consists of 1 marker bit followed by 16 data bits:

[ M | b15 b14 b13 b12 · b11 b10 b9 b8 · b7 b6 b5 b4 · b3 b2 b1 b0 ]

The data range is 0 through 65,535. The marker bit is always 1 when a word is present and 0 for empty space. It is not part of the value — a word with marker=1 and data=0000000000000000 holds the value zero.

The top four bits (b15–b12) serve a dual purpose in Memory address-read mode: they can encode a 4-bit slot address (values 0–15), routing an incoming word to its own destination slot automatically.

3. The Four Loops

LoopCapacityBitsPurpose
Working12 words204Primary staging area. New data enters here via the Inject Channel.
ALU16 words272Connected to the ALU engine. Words captured from here into registers.
Memory16 words + 16 slots272Bulk storage loop plus 16 addressed fixed-storage slots.
Big32 words544Largest loop. Home of both Pattern Matchers and Threshold Gates.

3.1 The R/G/W Head

Each loop has three consecutive head positions:

  • R dot — the read position. Buses and the ALU capture data here, before the loop rotates.
  • G dot — the gate position. If the gate is closed, any bit here is zeroed on that tick.
  • W dot — the write position. Bus deliveries, ALU writebacks, and inject channel output all land here.

3.2 The Gate

Each loop has a GATE button. When OPEN (default), data passes freely. When CLOSED, data at the G dot is destroyed on every tick. Closing the gate does not stop circulation — it destroys only the bit that reaches the G dot each tick. Data injected from outside lands at the W dot after the gate and is not affected.

3.3 Pause and Step

The ⏸ button on each loop freezes that loop. The loop STEP button advances only that loop one position. The global STEP button advances the entire machine one tick.

4. The Control Bar

4.1 Operator Handle, Session Name, and Machine Identity

Two text fields in the header identify your session. The Operator Handle is your name or alias — it appears in the session log and, when you connect via P2P, is transmitted to your peer as your network identity. If left blank, a four-character machine ID (generated once and stored in your browser) is used instead. The Session Name labels the specific computation. Both are optional but useful.

4.2 Start, Stop, Step

ControlFunction
START / STOPStarts or halts the master clock.
STEPAdvances the entire machine by exactly one tick.
Tick displayNine-digit counter (000000000–999999999). Rolls over at one billion ticks. At 24 Hz, that is approximately 14 months of continuous operation. Press RESET to zero it.

4.3 Speed Control

The speed slider runs from 0.50 Hz to 144 Hz. A number input allows fractional speeds. Both stay in sync. The recommended operating speed is 24 Hz — the approximate threshold of human persistence of vision, where individual ticks become difficult to distinguish and data flow begins to appear continuous. The Clock % display in the header shows how accurately the machine is hitting its target speed.

4.4 Op Count

Set a target value, then link it to one or more loop counters using the W, A, M, B, and G buttons. When a linked counter reaches the target, that loop halts automatically. Op Count only fires if the linked counter is actually incrementing — counters only increment when triggers are configured in the Counter Triggers panel.

4.5 Status LEDs

Five indicators in the upper right of the control bar: CLOCK (pulses each tick), RUNNING (lit when clock is active), BUS (lit when Bus A is on), INJECT (lit while inject channel has bits in flight), and P2P (lit when either P2P inbound buffer contains words waiting to be delivered).

4.6 Skins

OG (default cool-grey industrial), WinAmp (dark, 1990s bevel aesthetic, green accents), Sunrise (warm amber and terracotta). Switching is instant and persists across sessions.

5. Loading Data — The Inject Channel

Sixteen toggle switches represent the 16 data bits. Flip a switch up for 1, down for 0. The display shows the value in decimal and hex as you set the levers. Press ▼ SEND to prepend the marker bit and load the word into the inject channel. The full word enters the Working Loop over the next 17 ticks. You cannot inject a second value while the channel still has bits in flight — the INJECT LED will be lit.

5.1 The RNG

The RNG button generates a random value within a configured range and injects it directly into the Working Loop. It is a linear feedback shift register (LFSR) seeded from Math.random() — balanced over large samples but capable of local clustering. Min defaults to 0, Max defaults to 65,535.

6. Moving Data — The Seven Buses

Each bus is a 24-slot pipeline. A complete word takes 41 ticks to travel across and land in the destination (24 pipeline slots + 17 write ticks). Set source and destination first, then turn the bus on.

BusColorTypeNotes
APurpleInternalAny loop, PM/TG outputs as source. Any loop, counters, TG thresholds as destination.
BVioletInternalIdentical to A. Full counter read/write access.
CTealInternalIdentical to A and B.
DAmberInternalIdentical to A, B, C. With all four active: mega-loop pipeline Working → ALU → Memory → Big → Working.
ECrimson/GreenExternalTwo-way. Connects to Challenge Module or Network endpoint.
FIndigo/CyanP2P Left (PL)Two-way. Connects to left chain neighbor via WebRTC.
GViolet/MagentaP2P Right (PR)Two-way. Connects to right chain neighbor via WebRTC.
Common Mistake
Setting source and destination is not enough. You must also press TURN BUS X ON. The bus does nothing until explicitly activated. Turn it off when the transfer is complete — if you leave it on, data keeps flowing continuously.

7. The ALU — Arithmetic and Logic

The ALU performs all calculations. It operates on operands drawn from four persistent registers (A, B, C, D) and maintains a live Answer register that updates whenever the register contents or operation selection changes.

7.1 Loading Registers

Set the Capture Route selector (HEAD →) to the desired register letter, then route a value into the ALU loop via a bus. When the word's marker bit arrives at the ALU loop's R head, capture begins automatically and completes after 17 ticks.

7.2 Operations

OpDescription
ADDOp A + Op B. Sets carry if result exceeds 65,535.
SUBOp A − Op B. Sets carry on borrow.
AND / OR / XORBitwise logic.
NOTBitwise complement of Op A.
SHL / SHRShift Op A left/right one bit. Shifted-out bit → carry.
NEG0 − Op A (two's complement negate).
INC / DECOp A ± 1.

7.3 ALU Flags

FlagMeaning
ZROResult is exactly zero.
CRYCarry out, borrow, or shifted-out bit.
OVFSigned overflow.
SGNTop bit of result is set.
PAREven parity: number of set bits in result is even.

7.4 The Comparator

Runs automatically on every compute. Sets six flags: GT, LT, EQ, GTE, LTE, NEQ. Flags inform the operator — they do not trigger any automatic action. The six flags can be packed into a single word and sent to the ALU loop as data.

8. Memory Slots

Sixteen addressed memory slots — fixed storage locations numbered 0 through 15 that hold 16-bit words independently of loop circulation.

  • ENABLE WRITE TO SLOTS — captures every complete word passing the Memory loop's read head into the current address.
  • Auto-Increment — advances the address on each capture, filling sequential slots.
  • BATCH WRITE ALL — outputs all 16 slots sequentially into the Memory loop.
  • ADDR-READ mode — top 4 bits of an incoming word specify its destination slot, overriding the manual address selector.
  • Destructive read — clears a slot after sending its value to the loop.

9. Counters and Triggers

Five counters: one per loop, one global. All start at zero. Counters are not automatic — by default every trigger is off and no counter increments. You must activate triggers in the Counter Triggers panel.

9.1 Universal Triggers

TriggerFires when…
Word WrittenMarker bit arrives at write position — start of a word entering the loop.
Word ReadFinal bit of a word passes the read position — one complete pass.
Bits Written / ReadAny data bit written to or sampled from the loop. Fires 16× per word.
Full CycleLoop completes one full rotation.

9.2 Sound Notifications

The Notifications panel (right sidebar) lets you assign audio alerts to loop events. Each loop has three triggerable events — Word Read, Word Written, and Full Cycle — with an independent sound selector choosing from eight synthesized sounds: Ding, Bell, Chime, Blip, Bloop, Soft Tone, Pop, and Pulse. All sounds are off by default. Press the ▶ button beside any sound selector to preview it. A separate entry handles P2P chat message notifications.

10. The Pattern Matcher

Two Pattern Matchers are positioned on the Big Loop in cascade. PM1 is encountered first; PM2 processes the words PM1 passes. Each uses a 16-bit mask register (which bits to check) and a 16-bit pattern register (value to match against).

Match condition: (data AND mask) == (pattern AND mask)

On a match: the MATCH flag lights, the match counter increments, and the word is loaded into the PM output bridge. With EJECT: COPY, the word remains in the Big loop and continues circulating. With EJECT: DESTRUCTIVE, the word is zeroed and removed. With REWRITE: ARMED, specified bits are modified in-place before any other action.

11. Threshold Gates

Two Threshold Gates are positioned on the Big Loop downstream of the Pattern Matchers. Each compares every passing value against a configured threshold. TG1 and TG2 can each operate independently or in cascade (TG2 processes only TG1's output). Comparison modes: greater than, less than, greater-or-equal, less-or-equal.

12. Working Scratch Registers

Four fast holding slots attached to the Working loop. Press ENABLE CAPTURE — the next complete word passing the Working loop's R-head is captured into slot 0, then slot 1, alternating. Press →W to inject a slot's value back into the Working loop. Useful for holding intermediate values without crossing a bus.

13. P2P Networking — The Chain

Loop 2.1 supports a chain network topology. Each machine has two P2P connections: a left neighbor (PL, carried by Bus F) and a right neighbor (PR, carried by Bus G). A two-machine connection uses only one side. A ring of three or more machines uses both, with each machine's right output feeding the next machine's left input.

All connections are direct peer-to-peer via WebRTC. No server touches data after the initial handshake. The connection uses a manual SDP exchange — three copy-paste operations between operators establishes a live link.

13.1 Establishing a Connection

  1. Open the P2P Connection panel. Find the PL or PR sub-panel for the side you are connecting.
  2. Operator A clicks CREATE OFFER. An OFFER: text blob appears. Copy it and send it to Operator B.
  3. Operator B pastes the offer into their panel and clicks ACCEPT. An ANSWER: blob appears. Send it back.
  4. Operator A pastes the answer and clicks ACCEPT. Both sides show CONNECTED. The peer's identity appears.

13.2 The 512-Word Inbound Buffer

Each P2P connection maintains a 512-word inbound buffer. Words received from the peer go into the buffer first. The buffer drains automatically — one word per delivery cycle — whenever the destination loop is not paused or halted. If the buffer fills to 512 words, additional incoming words are dropped. The current buffer count is shown in the P2P Connection panel for each side. The P2P LED in the control bar lights when either buffer contains words, so an operator can see at a glance that data is waiting even while the machine is stopped.

13.3 P2P Chat

Each connection has its own text chat panel (Left and Right), which activates when that side connects. Messages are text-only, timestamped, labeled with the sender's identity, and logged in the session file when recording is active. Chat uses the same WebRTC data channel as the data buses — no additional infrastructure is needed.

14. The Session Log — .loop Files

Loop 2.1 records sessions to a structured .loop file. Every operator action and machine event is captured in dual format: machine-parseable code to the left of ||, human-readable description to the right.

SectionContents
SPECMachine configuration: loop sizes, word format, clock speed, operator handle, session name.
INITFull machine state snapshot at session start. Includes complete loop bit contents.
OPSTick-by-tick log. T##### lines mark clock ticks. Operator actions (S##### lines) appear between tick lines.
NOTESFree-text operator notes written before ending the session.
FINALComplete machine state snapshot at session end, plus performance statistics.

15. The Challenge Module

The Challenge Module delivers structured computational problems via Bus E. It sends values into a loop and waits to receive a correct answer back. Four challenge types: Add Two Numbers, Multiply Two Numbers, Transform Every Nth Value, and Filter: Pass Back Matching Values.

Scoring is based on efficiency relative to par — the theoretical minimum ticks and operator actions for an optimal solution of your specific instance. A run matching par on both dimensions scores 1000. The score display shows tick efficiency and operator efficiency separately so you can see where points were lost.

16. The Eight Tenets

These eight tenets define what Loop 2.1 is and what it is not.

  1. The Operator Is the Program. No stored program exists. The human makes all routing, operational, and control-flow decisions in real time. The operator participates throughout execution — not just at setup.
  2. Explicit State — No Black Boxes. All data is visible at all times. All operations are observable. Nothing happens invisibly. Every effect has a traceable cause.
  3. Data as Physical Entity. Data has position, velocity, and trajectory. It moves at observable speeds, one bit per tick. It is conserved — it does not appear or disappear. Moving data costs time, and that cost is always visible.
  4. Circular Storage. Memory is circular, not indexed. Data flows past read points continuously. There is no absolute start or end — only circulation. This demands cyclical thinking rather than linear thinking.
  5. Manual Flow. The operator routes all data and triggers all operations. Flags inform the operator; they do not control execution. No automatic branching occurs.
  6. Bus as Programmable Structure. Buses connect components explicitly. Routing is configurable by the operator. Data paths are part of the computation, not infrastructure beneath it.
  7. Computation as Craft. Quality over speed. Understanding over efficiency. The operator is an artisan, not a user. Progress is measured by elegance — minimal waste, clear workflow, beautiful choreography.
  8. Operator-Scale Timing. The clock runs at human-observable speeds by default. Time is a resource for learning and for craft. Extensibility grows horizontally — more modules, not faster execution.

17. Operator Style

One of the most important distinctions in Loop 2.1 is where the intelligence lives during a computation. Three styles are recognized:

  • Formal style — the machine's hardware (ALU, Comparator, Pattern Matcher, Threshold Gates) does the computational work. The operator configures and coordinates.
  • Manual style — the operator's own cognition does the computational work. The machine holds and displays data. The operator observes and acts.
  • Craftsman style — a fluid mix, reaching for whichever tool serves the moment.

Neither formal nor manual style is superior. Formal is more reproducible; manual can be faster for small datasets and gives the operator direct contact with the data. The Craftsman style is what most experienced operators converge toward. Choosing a style consciously and executing it well is itself a form of craft. The scoring system tracks style, and separate leaderboards distinguish sessions by approach.

18. Troubleshooting

SymptomLikely cause and fix
Nothing is movingClock is stopped. Press START or use STEP.
A loop is frozenLoop is paused (⏸ is lit) or halted by Op Count. RESET the linked counter to release.
Counter not incrementingNo triggers active. Open Counter Triggers and enable at least one.
Bus active but nothing arrivesSource loop may be halted. Gate may be destroying data. Source and destination may be the same loop.
PM not firingMask register is all zeros. Set at least one mask bit.
P2P data not arrivingCheck PL or PR connection status — must show CONNECTED. Verify the bus is ON. Check P2P LED for buffered words.
P2P chat not activatingChat panel only activates when the corresponding side (PL or PR) is connected.
Peer shows machine ID instead of nameThe peer has not set an Operator Handle. Machine ID is the normal fallback.
P2P connection failingPage must be served over HTTP, not opened as a file:// URL. Use a local web server or any hosted URL.

Chapter One
The Origin
From a Minecraft throne room to a web simulator

A Throne Room in Minecraft

The first Loop computer was built inside a Minecraft world, in a structure Shea Gunther called the throne room. There were no buses, no pattern matchers, no ALU registers with flags. There was one loop, carrying 5-bit words — a single signal bit followed by four data bits — and a two-register arithmetic unit that could do exactly two operations. When a computation completed, the result pulsed back into the loop. That was it.

It worked. Not impressively, not quickly, not at any speed a modern programmer would find meaningful. The redstone circuits clicked at 1 Hz — one tick per second — and you could stand there in the Minecraft world and watch the data move. You could see each bit as a redstone pulse traveling through the loops. You could trace cause and effect with your eyes. That was the entire point.

Shea Gunther is 48 years old, lives in North Windham, Maine, and owns a construction business. He coaches ultimate frisbee. He is developing a wedding venue. He has a four-year computer science degree with a Java background. He is not, by any conventional measure, a computer scientist. But he has a particular obsession that drove him to spend hundreds of hours building computing machinery out of redstone blocks: a deep discomfort with the opacity of modern computers.

"Computers don't have to be black boxes." Behind the slogan is something more specific: a belief that the abstraction layers of modern computing have made it fundamentally unknowable to most of the people who use it. You interact with systems you cannot see, running code you cannot read, making decisions you cannot audit.

What the Minecraft Build Proved

After the throne room came a more serious effort — Loop 1.99999: the canonical Minecraft implementation. Four loops. A full pattern matcher. Multiple buses. The system occupied roughly six Minecraft chunks, something like ninety-six by ninety-six blocks, with a glass floor so you could stand underneath and watch the redstone signals traveling.

The Mandelbrot pixel took six hours. This is not a complaint. It is cited as evidence that the system works. To calculate a single pixel of the Mandelbrot set by hand — routing operands through the ALU, managing iteration counts, detecting convergence, handling all the intermediate state manually — and to do it in six hours without the machine crashing: that is a proof of concept. The architecture is sound. The paradigm is coherent. You can actually compute with this thing.

The Minecraft build also revealed the performance ceiling. At 1 Hz, with a human operator making every routing decision, even simple operations take tens of seconds. A bubble sort of eight values takes fifteen minutes. This is not a bug. The system is running exactly as designed. But it suggested that a web simulator — where the clock speed could be tuned, where the visual feedback could be richer, where anyone with a browser could sit down and try it — would be the right next step.

Chapter Two
The Simulator Begins

Handoff

The web simulator did not begin as a single clean project. It began in a Claude conversation that eventually grew large enough to become unwieldy, and when it crossed that threshold the work was handed off to a new session. This was the first of many such handoffs — the development of Loop 2.1 has been a relay race, with each session picking up the baton from the last and running until the context window filled again.

The first thing each new Claude instance does in a handoff session is read the file and take stock. By the first handoff, the simulator already had more than most projects achieve before being shelved: four loops rendered on HTML canvases, an injection channel with toggle switches, two buses, an ALU with four registers and eight operations, a comparator with flag writeback, a memory panel with addressable slots, a pattern matcher on the Big Loop, five counters, a step-back button, and a session logger.

24 Hz and the Eye

One of the first substantive decisions made in the web era was about the maximum clock speed. The formula chosen produced a maximum of 22.627 Hz — an artifact of the math. Shea noticed this and asked whether there was a more meaningful number nearby.

There was. 24 Hz is the cinema frame rate — the approximate threshold of human persistence of vision. At 23 Hz, you can see the individual ticks of the Loop computer. At 25, motion begins to feel continuous. 24 Hz sits exactly at the boundary between computation you can watch frame by frame and computation that begins to look like flow. The cap was set to 24 Hz. The 24 Hz threshold remains the recommended operating speed.

"At 24 Hz, the machine tips from 'you can watch individual ticks' to 'motion becomes continuous.' That boundary belongs in this system."

The Version Numbering

Loop 1.00001 is the throne room. Loop 1.99999 is the full Minecraft canonical build. Loop 2.0 is the Minecraft display build — the physical structure that currently exists in a Minecraft world with four loops and all the visual components, but no redstone circuitry yet. It does not compute. Loop 2.1 is the web simulator and the official spec. When someone says "Loop computing," they are describing the behavior of Loop 2.1.

The R/G/W Architecture and Several Days of Bugs

The most architecturally significant decision of the early web simulator period was the introduction of the three-position read/gate/write head. In the original design, each loop had a single head that served all purposes. The new model gave every loop three distinct positions: the Write dot, where incoming data enters the loop; the Gate dot, which can be opened or closed to control whether data exits; and the Read dot, where the bus samples the loop's current bit.

The R/G/W architecture made the system dramatically more expressive. An operator could now hold data in a loop, read it without consuming it, write to a specific position, and gate output independently. It also introduced a week's worth of bugs — direction problems, inverted gate labels, timing errors — all of which were found and fixed.

Chapter Three
Growing Up

Counters, Stats, and the Logger

The configurable counter system was a turning point. Early versions had simple loop counters that counted rotations. What the system needed was something much more expressive: counters that the operator could configure to respond to specific events — a word read, a bit written, an ALU operation completed, a pattern matcher match, a memory slot write.

Alongside the counters came the session logger — a system for recording complete computation sessions to a .loop file format that was both human-readable and machine-parseable. Every operator action, every clock tick, every bus transfer and ALU execution gets recorded in a dual-format line: a machine-legible prefix on the left, a prose description on the right, separated by ||. The distinction the format makes explicit — between automatic machine actions and operator decisions — is not incidental. It is one of the core design principles of the project made visible in the record.

The Skin System and the Grumpy Professor

The skin system arrived in a session that also included a roleplay in which Shea asked Claude to respond as a grumpy CS professor skeptical of the entire project. Three skins: OG (cool blue-grey industrial), WinAmp (dark mode with 1990s bevel aesthetic), and Sunrise (warm amber and terracotta). Each is implemented as CSS variable overrides plus a canvas color object — SK — that drawing functions consult for all colors. Switching is instant and complete.

The grumpy professor session is worth dwelling on. The response was the kind of honest engagement the project deserves:

"You came back. I'll give you that — most people who leave my office with a half-baked idea don't. The simulator runs. The buses transfer data. The pattern matcher works — or mostly works, you had a cooldown bug I'd have caught in a code review. You built the thing. That's not nothing. Most people who argue with me about paradigms can't point to a running implementation. But here's what I want to know: who is this actually for?"

The answer that emerged settled into three audiences: the pedagogical (students who need to see computation before they can reason about it), the precision people (a personality type deeply satisfied by procedures that punish sloppiness), and the streamers and speedrunners, for whom a fully visible machine state is not a liability but the entire appeal.

"You might have accidentally built an esport for people who find normal esports too chaotic."
Chapter Four
The 16-Bit Migration

Why 16 Bits

The jump from 11-bit to 16-bit data words was the largest single architectural change in the simulator's development. Sixteen bits gives a range of 0 through 65,535 — the full data range of a real 16-bit computer. More importantly, 16 bits allows the top four bits to serve as a 4-bit address, pointing to one of sixteen memory slots. This dual interpretation makes address-read mode possible: a word can carry its own destination slot encoded in its top four bits.

The migration itself was a major engineering effort. BPW — bits per word — went from 12 to 17. Every component in the system that knew the word length had to be updated: the bus canvases, the capture pipelines, the ALU writeback logic, the comparator writeback logic, the counter trigger timing, the logger format. A comprehensive audit after the fact found six categories of missed 12-bit assumptions left behind in the migration.

Bus D and the Mega-Loop

Bus D arrived alongside the 16-bit planning, justified by a specific vision: the mega-loop. With four independent buses, an operator can connect all four loops in a chain — Working to ALU, ALU to Memory, Memory to Big, Big back to Working — creating a single continuous data pathway that passes through every component in sequence. Bus D takes an amber-gold identity color, clearly distinct from Bus A's purple, Bus B's violet, and Bus C's teal.

Chapter Five
The Challenge Module

The Challenge Module is the simulator's formal problem-delivery system. It lives in the sidebar and connects to the machine via Bus E. A challenge sends values into one of the four loops and waits to receive a correct answer back via Bus E.

The module launched with a single challenge type — Add Two Numbers. Three additional types were then added deliberately, one at a time: Multiply Two Numbers (repeated addition, using one factor as a counter), Transform Every Nth Value (apply a unary operation to every Nth value in a stream), and Filter: Pass Back Matching Values (return only values satisfying a condition, using the Pattern Matcher as the natural tool).

Scoring

Challenge scoring went through three complete redesigns. The current version computes par values — a computed ideal tick count and operator action count for each challenge instance — and scores performance as efficiency against par. A run that matches par exactly on both dimensions scores 1000. The score display shows tick efficiency and operator efficiency separately. Ticks carry slightly more weight (55%) than operator actions (45%) because ticks are harder to game.

"Par is the theoretical minimum ticks and operator actions for an optimal operator solving the exact instance you were given. This means a hard challenge scored at par earns the same 1000 points as an easy one scored at par."
Chapter Six
The Replay Viewer

A standalone replay viewer was built as a companion tool. It is a separate HTML file that accepts .loop session files — via drag-and-drop or file picker — and plays them back with full visual fidelity. The viewer reconstructs machine state from the INIT section of the log, applies OPS entries as deltas tick by tick, and simulates loop bit rotation between events so data can be watched physically circulating toward the read head.

Playback controls include step back and forward, play/pause, a speed selector from 0.25× to 4×, and a seek slider. A baked-in demo log of an "Add Two Numbers" session (5 + 7 = 12) provides an immediate demonstration without requiring the user to have a session file of their own. Checkpoints every 40 events support efficient backward stepping.

The simulator was updated alongside the viewer to write INIT.LOOP.*.BITS and FINAL.LOOP.*.BITS lines at session start and end, so sessions recorded after the update carry full loop bit state for accurate replay.

Chapter Seven
180 Builds In

What Changed in the Final Sprint

The v.173 through v.180 builds were primarily a bug sweep combined with targeted feature additions.

The clock display had been frozen since the tick display element was never populated in the DOM cache. The global clock was also never incrementing because it only piggybacked on trigger events rather than ticking independently. Both were fixed together.

The Pattern Matcher eject was clearing 12 bits instead of the full BPW of 17, leaving residue from the pre-migration word length.

Working Scratch capture had an off-by-one termination condition, capturing one extra bit and producing shifted values.

The RNG was encoding only 11 data bits into generated words instead of the full 16, silently discarding the top 5 bits of every random value.

The Filter challenge was generating conditions using 8-bit-era thresholds applied to the 16-bit value range. A threshold of "≥ 200" is meaningful at 0–2047 but nearly trivial at 0–65535. The thresholds were recalibrated.

On the feature side: Bus B, C, and D were given sensible default destinations. Working Scratch was expanded from two registers to four. The scoring formula received its third and final redesign.

The Machine at v.180

Four loops. Five buses (A through D internal, E external). An ALU with four registers, eleven operations, and a comparator. Two Pattern Matchers in cascade. Sixteen addressable Memory Slots. Four Working Scratch Registers. A Challenge Module with four types and par-based scoring. A session logger. A standalone replay viewer. Three visual skins.

Loop 2.1 at 180 builds is not a different machine than it was at 116. The architecture is the same. The fundamental paradigm — the operator as the program, all data visible, no stored instructions, every decision made in real time — is the same. What changed is the depth.

"The grumpy professor, consulted again at v.172, gave qualified approval. The machine works. The ideas are real. The challenges are solvable. The architecture holds."
Chapter Eight
194 Builds In
The Machine That Grew Outward

The development between v.181 and v.194 is the story of Loop 2.1 turning outward. Everything before was about the machine itself — its internal architecture, its data paths, its challenge system, its recording apparatus. Beginning at v.181, the machine started connecting to other machines, speaking to its operators by name, alerting them with sound, and eventually forming chains with its neighbors.

Fourteen builds. Several of them among the most architecturally significant in the project's history. And at the end of them, a machine that had become something qualitatively different from what it was at v.180 — not in its philosophy, which has not moved an inch, but in its reach.

Peer-to-Peer Networking — Bus F

v.181–v.187

The first peer-to-peer implementation added Bus F as a seventh bus — though calling it a bus undersells what it is. Buses A through D move data between components within a single machine. Bus E connects the machine to the Challenge Module. Bus F connects one Loop 2.1 instance to another over the internet.

The implementation uses WebRTC. Two operators, two browser windows, one direct link. No server touches the data after the initial handshake. The connection negotiation is manual SDP exchange — one operator generates an offer, copies it as compressed text, sends it through any channel they like, and the other pastes it and generates an answer. Three copy-paste operations and the machines are connected.

This friction was a design choice. It matches the machine's philosophy: the operator understands every step of what is happening. There is no auto-connect button that hides the mechanics. You see the offer. You copy it. You send it. You understand that two machines are establishing a direct link.

Bus F carries 16-bit words in both directions simultaneously. The outbound channel samples bits from a configured source loop and transmits them to the peer. The inbound channel receives bits from the peer and delivers them into a configured destination loop. Both channels are fully independent. The SDP strings are compressed before exchange — unnecessary fields stripped, then base64 encoded — to produce strings short enough to copy through a chat window without truncation.

Operator Identity

v.192

With two operators connected, the question of who is who became immediately practical. Each machine generates a four-character identifier on first load — drawn from an unambiguous charset that excludes easily confused characters — and stores it in localStorage. It persists across browser sessions but remains unique per browser instance.

The Operator Handle takes priority. If an operator has filled in the handle field, that name is transmitted to the peer the moment the data channel opens. If the field is empty, the machine ID is used instead. Either way, within milliseconds of a connection opening, both operators know who they are talking to. The peer's identity appears in the connection panel and becomes the label in the P2P Chat log.

The Chain Topology — Bus G and the PL/PR Architecture

v.193

A two-machine connection is interesting. A chain of machines is compelling. Beginning at v.193, Loop 2.1 has the infrastructure for both.

Bus G arrives as an eighth bus — the P2P Right connection, carrying the violet-to-magenta color identity. Bus F becomes the Left connection (PL). Bus G is the Right connection (PR). Each machine in a chain has two independently maintained WebRTC connections: one to its left neighbor, one to its right. A two-machine connection uses only one side. A ring of three or more machines uses both, with each machine's right output feeding the next machine's left input, wrapping back to the first machine.

The P2P Connection panel was redesigned around this topology. It contains two sub-boxes — one in Bus F blue, one in Bus G violet — each with its own complete offer/answer/connect/disconnect flow. All P2P state is held in a side-keyed object, and every P2P function accepts a side parameter. The two connections are entirely independent.

Bus strips were reduced from 26px to 21px height to accommodate the additional strip without significantly reducing loop canvas space.

On Chain Networks and What They Teach
When eight students in a room each manually negotiate two connections and build a working ring network, they encounter — without being told — handshaking, flow control, broadcast storms, and the specific problem that made dynamic routing protocols necessary. The chain topology doesn't teach these concepts. It creates the conditions in which students discover them. A broadcast storm caused by an underspecified forwarding protocol and recovered from over forty minutes of coordinated manual intervention teaches more about networking than any textbook passage on the same subject.

P2P Chat

v.188

Each P2P connection has its own text chat channel. The chat panel for each side is grayed out and inert when that side is disconnected, and activates automatically the moment the connection opens. Messages are text-only, timestamped, labeled with the sender's handle or machine ID, and logged in the session file when recording is active.

Chat uses the same WebRTC data channel as the data buses — no additional infrastructure is needed. It was deliberately kept text-only and low-bandwidth, serving as a coordination channel between operators without becoming a distraction from the machine itself. The aesthetic of it matters: two operators communicating through a monospaced, timestamped interface while simultaneously routing 16-bit words between their machines is exactly the kind of environment Loop 2.1 should create.

The 512-Word Inbound Buffer

v.194

The original P2P implementation delivered incoming words directly into the bit queue — the same queue that feeds into the destination loop bit by bit. This was fine as long as the destination loop was running. But if the operator had their machine stopped, or if the destination loop was paused, incoming words had nowhere to go. They would pile up in the bit queue and eventually overwrite each other, or simply be lost.

The 512-word inbound buffer solved this. Each P2P connection (left and right) now maintains an independent word buffer. Words received from the peer are held in the buffer first. The buffer drains automatically — one word per delivery cycle — whenever the destination loop is not paused or halted. If the destination is stopped, the words wait. If the operator starts the machine, the buffer begins draining immediately.

The buffer holds up to 512 words per side. Words received beyond 512 are dropped. The current buffer count is displayed in the P2P Connection panel for each side. A new P2P LED in the control bar — alongside CLOCK, RUNNING, BUS, and INJECT — lights whenever either buffer contains words. An operator can stop their machine, see the P2P LED lit, and know that data is waiting before they decide whether to continue running.

At 24 Hz, a 512-word buffer represents roughly 350 seconds of continuous word delivery — nearly six minutes of incoming data that the machine can absorb before the buffer fills. This is far more headroom than most P2P operations will require.

Sound Notifications

v.189–v.190

The Notifications panel arrived as a quality-of-life feature with an unexpected amount of design depth. Eight synthesized sounds — Ding, Bell, Chime, Blip, Bloop, Soft Tone, Pop, and Pulse — all generated in the browser via the Web Audio API with no external files. Each loop can independently trigger any sound on Word Read, Word Written, or Full Cycle events. A separate notification entry handles incoming P2P chat messages from either side.

The sounds were designed for what the documentation calls "ear candy" — chosen specifically for their appeal as audio feedback rather than mere utility. None are harsh or startling. The goal was to make a running Loop 2.1 session something pleasant to inhabit as sound as well as vision, the way a physical machine has its own characteristic acoustic texture.

All notifications are off by default. The AudioContext is created lazily on first sound play to satisfy browser autoplay policy. The notification system is independent of counters and session logging — enabling a sound trigger does not affect counter increments or log entries.

The Nine-Digit Tick Counter

v.191

The master clock tick display was extended from six to nine digits — from 000000 to 000000000, rolling over at 999,999,999. At 24 Hz, that is just under 14 months of continuous operation before rollover. The previous six-digit counter rolled over at approximately 11.6 hours, which is technically reachable in a long session.

The change is small in code and significant in feel. A nine-digit counter signals that this machine is designed for sustained use, not demonstration. It is a number that will not run out during a semester.

The Eight Tenets — A Consolidation

v.194

The project had operated with fourteen tenets since early in its development. They were sound, but fourteen is a number that resists memorization. A consolidation reduced them to eight without removing any content — adjacent ideas were merged, consequences were absorbed into their causes, and each surviving tenet was rewritten to carry the full weight of what had been folded into it.

The consolidation also clarified a distinction that the fourteen tenets had left somewhat implicit: the difference between tenets that describe what the machine does (Explicit State, Circular Storage, Bus as Programmable Structure) and tenets that describe what the operator does (The Operator Is the Program, Manual Flow, Computation as Craft). The eight tenets are more clearly a description of a complete philosophy rather than a checklist of features.

The Machine at v.194

Seven buses. Two P2P connections with 512-word buffers each. A chain topology capable of connecting arbitrarily many machines in a ring. Sound notifications with eight synthesized sounds. A nine-digit tick counter. Operator identity transmitted automatically on connection. Dual P2P Chat panels. An updated manual reflecting all of it.

The machine at v.194 is not a different machine than it was at v.180, or at v.116, or at the first handoff. The operator is still the program. All data is still visible. Every decision is still made in real time by a human being who can see exactly what is happening. What changed is that the human being can now see what is happening on up to two other machines simultaneously, receive words from peers even when their machine is stopped, hear the sound of data arriving, and coordinate with their neighbors through a text channel that feels like it belongs to the same aesthetic world as the machine itself.

Loop 2.1 at 194 builds is a machine that has grown outward without losing what it was.

"Who is this for? How do you find them? What does loop2.computer look like as a place to go? And behind all of that, the room-scale installation in the far distance — the basement-sized landscape, the volcano that erupts when a pattern matches, the clock tower in the center valley that rings a bell on every tick. For now there is the simulator, running in any web browser, 194 builds deep, with a computing paradigm that someone designed in a Minecraft throne room in Maine."

Chapter Nine
237 Builds In
The Machine That Learned to Name Things

The development between v.195 and v.237 is the story of a machine learning the difference between having capabilities and understanding them. The networking infrastructure was in place at v.194 — the chain, the buses, the topology probe. What followed was the work of giving that infrastructure its correct vocabulary, building the layer above it that operators actually use, and making the whole apparatus legible to the people who need to understand it, not just the people who built it.

Forty-three builds. A protocol designed for multi-machine challenges. A virtual network layer with membership management and hub election. A naming system that finally distinguished physical topology from logical grouping. Two new buses for reaching anyone in any net. The machine at v.194 knew how to connect. The machine at v.237 knows what it's connecting to, and why, and what to call it.

The Challenge Bus Protocol — CBX

v.195–v.210

The first major build after v.194 was also the most architecturally complex thing Loop 2.1 had attempted: a coordination protocol for running challenges across multiple machines simultaneously, built on top of the existing WebRTC data channels, without a server, with all verification distributed among the participating operators.

The protocol is called CBX — Challenge Bus Exchange. It adds a coordination layer to the existing P2P connections that is entirely invisible to ordinary data routing. CBX packets travel over the same data channels as loop words but carry a type identifier that distinguishes them from data traffic. The two streams share the same wire and never interfere with each other. An operator watching their loops during a chain challenge will see the challenge unfold — values arriving via Bus E, the incoming sum appearing at the read head — without any of the underlying coordination traffic touching their machine's data paths.

The Chain Sum is the challenge CBX was built to support. The originating machine assigns each participant an integer value and a chain position. The first machine in the chain adds its value to zero and passes the running total to the next. Each subsequent machine adds its own value and passes it forward. The final sum returns to the originating machine for verification against the correct answer. Every submission is verified cryptographically — the origin knows the correct running sum at every position because it assigned all the values, so a machine cannot cheat by submitting a false sum without immediate detection.

The sum forwarding mechanism uses a deliberately different path from the control messages. Rather than JSON over the data channel, the running total arrives as a special two-word marker sequence in the raw P2P word stream: the reserved word 0xCB00 followed immediately by the sum value. The receiving machine's CBX layer intercepts the marker before it touches any loop. This design was intentional: the sum is real data entering the machine, not just a protocol event. An operator who routes Bus H — the Challenge Bus strip — into a loop can watch the sum arrive at the read head as words, the way any other data arrives. The protocol is observable at the level of the machine itself.

On the Two-Path Design
The decision to send the running sum through the raw word channel rather than as a JSON message was not obvious. JSON would have been simpler. But the running sum is the operator's incoming data — it is what they are waiting for, what they are adding their value to, what they need to verify has arrived. Making it arrive as a word at the read head means operators can watch it come in the same way they watch everything else come in. The protocol is not hidden. Transparency is not suspended when things get complicated.

The Technical Reference

v.215

By v.215 the machine had accumulated enough internal complexity — message types, state objects, architectural constants, protocol behavior, file format specifications — that a document above the manual was warranted. The technical reference is for people who need to understand how the machine works at the implementation level, not just how to operate it.

The document covers: all architecture constants (BPW, BUS_N, INJ_N, eject indices), the four-step tick model in precise order, the full bus inventory, naming conventions enforced by a 116-identifier audit, every state object and its fields, the complete .loop session log format including SPEC/INIT/OPS/NOTES/FINAL sections, Loopscript notation, all P2P and CBX message types, the chain/net networking state structures, hub election algorithm, and the variant registry number spaces.

Loopscript

v.213

Loopscript is a compact notation for describing Loop 2.1 algorithms at the level an operator thinks about them — not tick by tick, but the meaningful moves. A Loopscript program is human-readable prose that captures the structure of a session: what was configured, what was routed, what decisions were made. It uses symbols (→ for route, ← for inject, ↺ for circulate, ⊗ for close gate) and control constructs (UNTIL, repeat blocks, labels) to make algorithms shareable and comparable without requiring a session log.

The notation exists because sessions became complex enough that operators started describing them in natural language on the subreddit, and the natural language was inconsistent. Loopscript is the formalization of that natural language, designed to be writable in a text editor and readable by anyone familiar with the machine.

Chain and Net — A Naming

v.222

The networking infrastructure at v.194 mixed two concepts that needed to be separated: the physical topology formed by P2P connections, and the user-created virtual groupings that ride on top of it. Both were called variations of "network," which created confusion about which layer was being discussed at any given moment.

The distinction was formalized: a Chain is the physical topology — the actual WebRTC connections made through the left/right handshake. It exists whether operators think about it or not. It has real geometry: linear or ring, with measurable hop counts. You do not join a Chain; you are in one by virtue of having P2P connections. A Net is a user-created virtual overlay — a named group of machines within the Chain, with a hub, a membership list, a heartbeat, a routing table, and coordinated chat. You explicitly create or join a Net.

This distinction resolved a cluster of design questions that had been ambiguous. The scan button makes sense as "scan the Chain" — you're discovering your physical topology, not creating anything. Hub election, heartbeats, and routing tables belong to Net logic, not Chain logic. "I'm connected but not in any Net" is a valid and understandable state. The CBX challenge protocol rides on the Chain directly, independent of any Net.

The rename required 199 substitutions across the codebase: netState to chainState, netScan to chainScan, netSendToSide to chainSendToSide, wire values net_scan and net_scan_reply to chain_scan and chain_scan_reply, and all corresponding HTML element IDs. Net-layer functions retained the net prefix. The codebase now correctly narrates what each layer is responsible for.

Named Nets — The Full Protocol

v.211–v.215

The full Net layer arrived between v.211 and v.215: creation, invitation, join request, approval, hub election, heartbeat, watchdog timeout, routing table distribution, multi-net membership, and a unified chat that routes across both direct P2P neighbors and Net members in a single dropdown.

The hub is the machine that created the Net. It maintains the membership list, distributes the routing table via net_member_list messages, sends heartbeat signals every five seconds, and handles join requests from machines that weren't in the original invite. All of this is automatic. The hub operator does not need to do anything manually after the Net is formed.

Hub election was designed for resilience: if the hub disappears — three missed heartbeats, approximately fifteen seconds — the remaining members elect a new hub automatically using a deterministic rule (lowest machine ID wins). The winner broadcasts a claim, all members acknowledge, and normal operation resumes within seconds. From a member's perspective the election is invisible, with a brief routing gap while the new hub establishes itself.

Message routing uses each Net's routeTable, a per-member map from machine ID to 'l' or 'r' indicating which Chain side leads toward that machine. The hub selects shortest-path routes when distributing the table. Every routed message carries a destination ID and a TTL that decrements at each hop; a message with TTL zero is dropped. Intermediate machines relay transparently — their loops are unaffected.

Net Buses H and I

v.231

Buses F and G are Chain buses — they connect directly to immediate P2P neighbors. A word on Bus F exits from a source loop, travels over the WebRTC data channel, and arrives at the left neighbor's inbound channel. Both the sender and the recipient are directly connected. This is sufficient for many operations but leaves no path to a machine three hops away without manual relay coordination.

Bus H (Net0, amber) and Bus I (Net1, lime) are the Net buses. Each can be addressed to any machine in any Net the operator belongs to. Words sent on H or I travel as routed messages through the Chain at network speed — no tick consumption at intermediate nodes, no loop involvement on relaying machines. They arrive at the destination's H or I inbound channel and enter the destination loop normally. The operator selects their destination from the Net member list, and the machine handles the rest.

Two Net buses was a deliberate choice. With H and I independently addressable, an operator can simultaneously route data to two different remote machines, or receive from two different sources. More interestingly, an operator can act as a router: receive data on H from machine A, process it through a loop, and forward out on I to machine B. This is the operator-is-the-program paradigm extended to the network layer. The routing decision is a human decision, made in real time, visible to all participants.

PM and TG Repositioning

v.227–v.229

The inspection pipeline on the Big Loop — PM1, PM2, TG1, TG2 — was shifted downstream along the loop to make room for the new bus strips. The shift moved the inspection heads further along the bottom track (lower bit indices, which is downstream in the loop's flow direction), creating space between the bottom of the loop ring and the inspection graphics that could be reclaimed for the H and I bus strips.

The inspection heads were also flipped from drawing downward (outside the loop ring) to drawing upward (inside the ring). This freed the vertical space below the Big Loop entirely. The bracket graphics, labels, bridge dots, and cascade arcs all now render into the interior of the loop, anchored at the same physical bit positions on the track but visually contained within the ring rather than extending below it.

Current eject positions: PM1 at bit index 359, PM2 at 342, TG1 at 325, TG2 at 308. Each component is exactly one word (17 bits) downstream of the previous. The pipeline order and spacing are unchanged.

The UI Sprint

v.216–v.237

The final sprint of builds in this period was primarily typographic and interface work. Bus strips reduced again — from 21px to 16px for B through I, from 26px to 19px for Bus A — to accommodate the new H and I strips without significantly reducing loop canvas space. Collapsed sidebar sections shortened to roughly 65% of their previous height, allowing the full sidebar to fit on a typical screen without scrolling when most sections are closed. Sidebar section titles reduced to 10px, bus labels simplified from "Bus A Config" to "Bus A," notification group layouts standardized with sound controls at the bottom of each group.

The PM and TG bracket colors were darkened — active state from #00b8e0 cc to #0080a8 ff, matched state from #ff4050 cc to #cc1828 ff, inactive from #507090 66 to #304860 bb — to improve readability against the lighter interior of the loop ring where they now draw.

The Winamp skin received an overhaul pass for button readability. Several button classes (START/STOP, SEND, loop pause/resume, gate open/close) had been rendered with green text on light pastel backgrounds — the skin's lime-green foreground color on near-white button backgrounds. All were given dark-background overrides specific to the Winamp skin, replacing the inherited light backgrounds with dark-on-dark with appropriately colored text and borders.

The ALU received auto-writeback — a toggle that, when on, sets a flag at the moment the result changes, which the main tick loop checks at its next execution and fires the writeback immediately. Zero wall-clock delay, one-tick latency. The operator sets up a tracking relationship; the machine executes it faithfully every tick.

Bug Fixes That Mattered

v.223

A code review pass at v.223 found three real bugs: a function called cbxPresentInvitation that was called but never defined — it should have been cbxHandleChainInvite, meaning challenge invitations to available machines were silently failing; dead element update code in the PM and TG display functions trying to update removed HTML elements (null-guarded, no crash, but pointless execution on every render frame); and dstIsTG checks across all four bus delivery handlers that didn't include the newly added tg1-clamp and tg2-clamp destinations, meaning selecting TG Clamp as a bus destination would route to the wrong handler.

The third bug is the most instructive. The TG clamp destinations had been added to the HTML destination selectors — an operator could select them — but the delivery logic that routes a word to a TG register rather than a loop hadn't been updated. The feature appeared to exist. It didn't work. These are the bugs that sit quietly until someone tries the exact path that triggers them.

The Sidebar Reorder

v.224

The right sidebar had accumulated sections in roughly the order they were built, which was not the order in which they were used. The reorder placed Global Counter, Challenges, and Challenge Network at the top — the sections most operators interact with first — followed by Counter Triggers, Working Scratch, ALU, the buses in order (A through I), P2P Bus, P2P Connection, Networking, Chat, PM1, PM2, TG1, TG2, Notifications, and Session Log. The Expand All and Collapse All buttons at the top survived one reorder, were lost in another, and were restored in a third.

The Machine at v.237

Nine buses. Four Chain-aware: A through D for internal routing, E for the Challenge Module, F (Chain Left) and G (Chain Right) for direct P2P neighbors, H (Net0) and I (Net1) for routed Net connections to any machine in any group. Two P2P connections forming the physical Chain. A Net layer with hub/member topology, routing table distribution, hub election, heartbeat watchdog, and unified chat. The CBX challenge protocol with full multi-machine coordination and per-submission verification. Loopscript for recording and communicating algorithms. A technical reference covering all implementation details. Two Pattern Matchers and two Threshold Gates on the Big Loop, now rendering inside the ring. Three visual skins.

The machine at v.237 is not different in philosophy from the machine at v.194, or v.180, or v.116. The operator is still the program. All data is still visible. Every routing decision is still made in real time by a human who can see exactly what is happening. What has changed is the scale of "what is happening." The operator can now see the state of machines they are not sitting at, receive data from machines multiple hops away, form named groups with other operators and route messages to any member of those groups by ID, and participate in coordinated challenges across machines that have never directly exchanged a packet.

Loop 2.1 at 237 builds has grown from a machine that connected two browsers to a machine that connects communities. The philosophy hasn't moved. The reach has.

"The Chain is discovered, not created. You are in a Chain by virtue of having P2P connections. A Net is created intentionally. This distinction resolves a cluster of design questions that had been ambiguous for months. The right vocabulary is not decoration. It is load-bearing."

Chapter Ten
253 Builds In
The Machine That Learned to Remember

The development between v.238 and v.253 is the story of a machine consolidating what it had become and extending its reach inward — into its own data, its own history, its own network traffic. The large outward work was done by v.237. What followed was the work of giving operators better command over the machine they already had: a more honest challenge system, a transparent network layer, and — most significantly — a file system that saves and loads memory the way the machine computes, through observable bit movement.

Sixteen builds. A challenge architecture rebuilt from first principles. An availability model simplified to something elegant. A window into network traffic that nobody had before. And a file system whose save operation requires the operator to do what the machine has always required: move bits deliberately, in the open, where everyone can see.

The Challenge Migration

v.238–v.245

The challenge system at v.237 was a hybrid: nine built-in challenges implemented as large blocks of hardcoded functions, alongside an emerging custom challenge registry that allowed operators to register their own definitions as JavaScript objects. The two systems ran in parallel, with built-ins taking different code paths than customs. The migration unified them.

All nine built-in challenges — Add, Multiply, Transform Nth, Filter, Sort, Find Maximum, XOR Checksum, Count Matches, Accumulate to Threshold, and Chain Sum — were rewritten as script definition objects with builtin: true and registered in the same customChallengeRegistry that holds operator-defined challenges. The approximately 24,000 characters of hardcoded function code was removed. A single execution path through startCustomChallenge() now handles everything. Built-ins cannot be removed or overwritten, but they can be viewed and copied as a starting point for custom variants.

The custom challenge system received full support: a textarea and REGISTER button in the Challenges panel, a validator that runs eight structural checks and five dry runs of the generate() function with a 50ms timeout each, dynamic parameter rendering from the definition's params[] array, and a VIEW button that populates the textarea with the definition's source. The definition schema — generate(params), par(result, params), params[] — is the complete interface between an operator-written challenge and the machine's evaluation infrastructure.

On the Migration's Meaning
The migration was not just a refactor. It was a statement about what the challenge system is. Built-in challenges are not hardcoded special cases — they are examples of what the definition schema can express. When an operator views the source of the Add challenge and sees exactly how it generates values and calculates par, they understand the full contract. The system is not divided into things you can inspect and things you cannot.

The Availability Simplification

v.243

The CBX availability system at v.237 had three states: RELAY (default — machine does not join challenges but does not block the chain), OPEN (machine will accept invitations), and SOFT_DECLINE (machine returns a terminal response to all probes, making machines beyond it invisible). Operators had to explicitly set themselves to OPEN before participating in Chain Sum. SOFT_DECLINE existed for operators who wanted complete isolation.

All three states were removed in a single decision. The new rule: every machine always relays, and always accepts challenge invitations, unless a local challenge is currently active. When an invitation arrives at a busy machine, the machine sends a skip notice and forwards the invitation to the next machine in the chain. The challenge continues with whoever is available. No operator action required to participate. No Challenge Network sidebar panel. No availability buttons.

SOFT_DECLINE was the most deliberate removal. Its effect — making machines beyond you invisible to anyone trying to discover chain topology — was a significant power over your neighbors' experience. An operator could silently block a chain without the neighbor on the other side ever knowing why discovery stopped. The simplified model removes this: every machine is always part of the topology, always willing to relay, always available for challenges when not otherwise occupied. The network is more honest.

The Network Monitor

v.250

The network layer at v.237 was the one part of the machine that was opaque. Buses, loops, ALU registers, memory slots — all visible in real time on screen. But CBX packets traveling over the P2P data channels, chain sum values passing between machines, chat messages routing through the hub — these arrived at handler functions, got processed, and were gone. An operator watching a Chain Sum challenge could see their own machine's state but had no view into the protocol events that produced it.

The Network Monitor panel changes this. When enabled, it captures a rolling buffer of the last twenty interesting packets flowing through the machine — inbound and outbound. Every CBX challenge coordination message (INVITE, ASSIGN, GO, SUBMIT, SUM_OK, SUM_FAIL, ABORT, COMPLETE), every chain sum word value passing between machines, every chat message delivered to or sent from this machine. Each captured packet shows direction, type, a one-line payload summary, and timestamp. Click to expand the full fields.

The monitor extends the machine's transparency principle to the network layer — and then goes one step further. A captured packet can be staged for editing. An operator can modify the submitted sum in a CHAIN_SUM_SUBMIT packet and inject it back into the local handler, as if it had arrived from a neighbor. The origin's verification will catch it immediately. The value is not in observing the failure — it's in watching exactly how the verification catches it, in real time, with the specific values on screen. You learn the protocol by attempting to break it. The machine shows you why it didn't work.

On Making the Network Visible
There is something philosophically satisfying about an operator being able to watch their own machine relay a chain invite, see the challenge ID and machine count in the payload, observe the ASSIGN message arrive with their position and value, and then — if they choose — capture that ASSIGN and inject a modified version to see what happens. The machine was always supposed to be transparent. The network being opaque was an inconsistency, not a design choice. The monitor resolves it.

The File System

v.249–v.253

The file system was the largest single feature addition since the Net layer. It gives operators a persistent /local folder of up to eight named memory snapshots, exportable as human-readable text archives, importable from any computer, and transferable between machines. The technical work was non-trivial. The design question — how should saving a file feel on a machine like this — was harder.

The first implementation saved instantaneously: click SAVE, enter a name, the snapshot is taken from mem.slots[] directly with no bit movement. It worked. It was also wrong. Nothing about it was observable. Nothing about it required operator engagement with the machine. It happened to the machine rather than through it.

The redesign makes save require the movement of real bits. The operator presses NEW FILE, enters a name, and the system arms itself as a destination. Batch Write All — the operation that streams all sixteen memory slots through the Memory loop's write head in sequence — is then directed to the FILE SAVE destination on any of Buses A, B, C, or D. The system intercepts the stream bit by bit through the normal delivery path, assembles the arriving words, and saves when all sixteen have been received. The save is observable: the operator watches their memory stream through the bus, sees the word counter advance, and the system confirms completion.

Batch Write All was updated simultaneously. Previously, it skipped null (empty) slots. Now it always writes sixteen words — null slots as zero words with marker bit zero. This change was necessary for file integrity: a slot's position in the file is determined by its position in the stream, not by a separate index. If slot seven holds a value, it must be the eighth word in the stream, always, regardless of whether slots zero through six are populated. The new behavior makes this invariant absolute.

Loading works through the same writeback pipeline that individual slot sends and batch writes use. The sixteen words stream through the Memory loop's write head one per writeback cycle, at the clock rate the operator has set. The operator must have Write to Slots and Auto-Increment enabled to receive them. If they pause the memory loop mid-transfer, the stream pauses too — no bits are lost, because the same pipeline that the machine has always used for writeback handles both cases identically. Pausing the loop pauses the write. Starting the loop resumes it.

The .L21 format is the binary form: thirty-four bytes, sixteen 17-bit words packed contiguously big-endian, bit-for-bit identical to the stream that flows through the machine. The .l21x format is the archive: plain text, one file block per named snapshot, sixteen slot lines per block in four-digit uppercase hex. A .l21x file can be opened in any text editor, edited by hand, and imported. An instructor can create a starting memory state for a class without touching the machine at all — write the hex values in a text editor, import, done.

On What Save Should Feel Like
The instantaneous save felt wrong in the same way that an invisible background operation always feels wrong on this machine. Loop 2.1 has never done anything to you without you directing it. The file save redesign restores that: the operator performs the save. They do the batch write. They watch the words arrive. The file is the product of a deliberate act, not a button click that happens to produce a file as a side effect.

Bug Fixes That Mattered

v.238–v.253

Several bugs surfaced and were fixed across this period. The ALU auto-writeback had a secondary failure mode: when the machine was stopped, the writeback pipeline flag was set but could never drain because the pipeline only advances on clock ticks. Subsequent computations would find the pipeline still marked busy and silently fail. The fix resets the pipeline before firing a new writeback in the stopped-machine path.

Four functions were accidentally removed during the challenge migration — challOnTypeChange, ensureBusEIsActive, queueChallengeValuesForDelivery, and initializeChallengeState — because they lived inside the same code region that was removed as part of the hardcoded block. All four were restored. The View Script button on custom challenges was not storing the original source text on registered definitions, causing the button to silently do nothing. Fixed. The FILE SAVE destination on buses A through D was not routing bits to the file system because the bus delivery code checked LOOP_IDS_SET to determine whether a destination was valid, and 'file-save' was not in that set. The intercept existed; the routing condition that triggered it did not. Fixed.

The pattern is consistent: features that appeared to exist but did not work, because the path from user action to the new functionality had a gap in it. These are the bugs that confirm the importance of end-to-end testing on every code path, not just the happy paths.

The Machine at v.253

A unified challenge architecture where built-ins and customs are the same kind of thing. A network availability model that requires nothing of operators and deceives nobody. A window into network protocol traffic that makes the CBX layer as observable as the loops. A file system that saves through bit movement and loads through the writeback pipeline. An archive format readable in any text editor. The machine at v.253 knows how to remember what it was doing.

The philosophy has not moved. The operator is still the program. All data is still visible. Nothing happens invisibly. What changed is the definition of "all data" — it now includes the packets traveling through your machine, the files you have saved from previous sessions, and the ability to share that data with other machines and other operators. The circle of visibility is wider.

"The file save redesign restores something the instantaneous save had given up: the operator performs the save. They do the batch write. They watch the words arrive. The file is the product of a deliberate act, not a button click that happens to produce a file as a side effect."

Chapter Eleven
261 Builds In
The Machine Grows Outward Again

The development between v.254 and v.261 returned to the network. The file system was complete; the challenge architecture was unified; the internal machine was as coherent as it had ever been. What remained was the question of how machines relate to each other — not just through the chain and the named nets, but through the movement of data and files directly from one operator's workspace to another's.

Eight builds. Two net buses that finally worked. A file transfer protocol that arrived on the first try. A topology probe bug that had silently blocked Chain Sum for every two-machine test. And a sidebar reorganization that made nine buses feel like nine buses instead of seven buses plus a separate special thing.

The Zero-Word Fix

v.254–v.255

The Batch Write All null-slot behavior introduced in v.251 had a subtle failure mode. Null slots were written as marker=0, data=0 — a word with no marker bit. On the receiving side, the memory capture pipeline only starts when a marker bit arrives. A marker=0 word passed through silently, the address pointer never advanced, and the next populated word landed in the wrong slot. Values compressed together as if the empty slots between them didn't exist.

The fix was on the send side. Null slots now write marker=1, data=0 — a valid word with a zero payload. The capture pipeline starts, collects sixteen zero data bits, writes zero to the slot, and advances the address pointer exactly as for any populated word. The stream always produces sixteen words. Every slot position maps to exactly its stream position. The accepted tradeoff: a slot that was null and a slot that held the value zero are indistinguishable after a batch recall cycle. Shea reviewed and accepted this tradeoff.

Buses F and G Graduate

v.260

Since their introduction, Buses F and G had lived as sub-sections inside a parent section called "P2P Bus" — two buses nested inside a single collapsed panel, aesthetically separate from the A through E buses above them and the H and I buses that were about to arrive. The P2P Bus section was removed. Buses F and G each got their own independent sidebar panel, in order, between Bus E and Bus H. The sidebar now runs A through I in sequence with no interruptions, each bus with the same layout: source selector, destination selector, toggle button.

The functional change was purely cosmetic — no code was touched except the HTML. But the aesthetic change matters. Nine buses should look like nine buses. The nested layout implicitly argued that F and G were a different class of thing. They're not. They move bits across a strip. They have a source and a destination. They turn on and off. The same description applies to all nine.

Buses H and I — Fully Wired

v.258

Buses H and I had existed as infrastructure since v.231 — state variables, toggle functions, flash arrays, render code, inline canvas buttons. What they lacked was tick logic: the code inside executeOneTick() that actually moves bits. They were dark.

The implementation wires them as routed net buses. Where F and G send words directly to immediate P2P neighbors, H and I route through the chain toward any connected machine by machine ID. An operator selects a peer target from a selector that combines two sources: direct P2P neighbors (marked with ◀ and ▶ direction indicators) and any machines found by the last topology scan. The selector rebuilds automatically after every chain scan.

Outbound: bits exit the source loop, accumulate in the Bus H or I shift register bit by bit, assemble into a 17-bit word when complete, and route through chainForward() toward the target. Two new message types — bus_word_h and bus_word_i — carry the word through the chain, hopping through intermediate machines transparently until they arrive at the destination. Inbound: the word enters a dedicated receive buffer per bus, drains one word at a time into a bit queue when the destination loop is ready, and lands at the write head exactly as F and G words do.

If no peer target is set, outbound words drop silently with a log entry. If the destination loop is paused, inbound bits wait — no data is lost. Both behaviors are consistent with how the rest of the machine handles edge cases.

With H and I operational, an operator can simultaneously route data to two different remote machines, or hold two independent inbound streams from two different sources, or act as a router — receiving on H from machine A, transforming through a loop, forwarding on I to machine C. The operator-is-the-program paradigm now extends across the full network.

On What Four Network Buses Means
An operator connected to two neighbors now has four network buses: F to the left neighbor, G to the right, H to any machine by ID, I to any other machine by ID. They could direct H and I at the same neighbor as F or G, giving three simultaneous data streams between two machines. Or they could route all four toward four different machines. The routing topology is entirely in the operator's hands, decided in real time, visible to everyone. This is not a metaphor for how networks work. It is how networks work.

File Transfer

v.259

The file system at v.253 gave operators persistent local storage and archive export. The next logical step was direct machine-to-machine file transfer — not through .l21x archives copied out-of-band, but through the network the machines were already connected to.

The protocol is three messages. The sender selects a file, presses SEND TO PEER, picks a recipient from a peer selector, and confirms. A ftp_offer packet containing the file name, the 34-byte .L21 binary data, the slot count, and the save timestamp routes through chainForward() toward the destination. The offer packet is visible in the Network Monitor — the data blob is summarized as the byte count rather than the full base64, but it can be captured and injected like any other packet.

The recipient sees the incoming file panel appear in their Files section: file name, sender handle, slot count. ACCEPT saves the file immediately to /local and sends ftp_accept back to the sender. DECLINE sends ftp_decline and closes the panel. Both replies route back through the chain. The sender's Files status updates when either reply arrives.

If the recipient's /local folder is full, they are shown an overwrite selector — a list of their existing files — and must choose one to replace before the incoming file can be saved. The choice is theirs. The machine does not decide. Nothing is overwritten without explicit operator action.

Three file notifications were added to the Notifications panel: FILE OFFER (incoming transfer request), FILE RECEIVED (transfer accepted and saved), FILE DECLINED (your sent offer was turned down). Each independently toggleable, with a shared sound selector. The notification fires on the event the operator doesn't see coming — the one that requires their attention.

On Building a Network
By v.259, the machine has WebRTC connections, a chain topology with hop-count routing, named nets with hub election, net-routed buses, a challenge coordination protocol, a network chat system, and now file transfer. None of these were planned together. Each was built when the machine was ready for it, when the layer below was stable enough to support the layer above. The result is a networked computer system where every layer is visible and the humans are the control plane. That is not what was intended when someone built a computer in a Minecraft throne room. It is what the machine became.

The Chain Sum Bug

v.261

Chain Sum had not worked correctly in a two-machine configuration since the CBX probe system was built. The symptom: PING NETWORK would return one machine found, even with a neighbor connected. Chain Sum would then refuse to start, correctly reporting that it needed at least two machines.

The cause was a single missing + 1 in cbxHandleIncomingProbe(). The terminal node — the machine at the end of the chain with no forward connection — was returning the probe with hopCount: message.hopCount. For a two-machine chain, this was hopCount: 0. The origin received zero hops in that direction, computed totalNodes = 1 + 0 + 0 = 1, and concluded it was alone.

The fix: terminal nodes return hopCount: message.hopCount + 1, counting themselves. The origin now receives 1, computes totalNodes = 2, and Chain Sum starts correctly. The same logic was already correct in the parallel chain scan used by the Networking panel — only the CBX-specific probe had the error. The CBX probe was written separately and independently, which is how the same off-by-one ended up in one copy and not the other.

The Machine at v.261

Nine buses, all in order, all with equivalent sidebar layouts. Two net-routed buses that can reach any machine in the connected topology. File transfer that requires no out-of-band coordination. A working Chain Sum. A file notification system. A Network Monitor that now captures FTP packets alongside CBX and chat.

The machine at v.261 is connected in a way v.253 was not. Memory snapshots move between machines. Challenge coordination works at two machines. Net buses extend the data routing paradigm across the network. The philosophy is unchanged. The reach has grown again.

"By v.259, the machine has WebRTC connections, a chain topology, named nets, net-routed buses, a challenge protocol, a chat system, and file transfer. None of these were planned together. Each was built when the machine was ready for it. The result is a networked computer system where every layer is visible and the humans are the control plane."

Chapter Twelve
288 Builds In
The Restructuring

The development between v.262 and v.288 did not add a single feature. No new buses, no new peripherals, no new networking protocols, no new challenge types. The machine at v.288 does exactly what the machine at v.261 did. What changed is how the code is organized — and whether anyone other than the original conversation thread could safely modify it.

The codebase at v.261 was roughly 14,860 lines of JavaScript and HTML in a single file. It worked. Every feature functioned correctly. But it had been built iteratively over 261 versions in conversation between one human and one AI, and it had never been architected. Functions that should have been one function were three. State variables lived wherever they had first been declared. Duplicate code existed because the thing being duplicated had been written before the generic version. The machine worked, but the code was held together by the fact that one conversation thread remembered where everything was.

The restructuring happened in six phases across 27 builds. It was motivated by a simple concern: if the project is going to be handed to a human engineer for a production rewrite, that engineer needs to be able to read the code. And if the project continues to be developed by AI in the meantime, new conversation threads need to be able to modify it without breaking things they cannot see.

Phase 1 — Cleanup

v.267

The first pass was housekeeping. Duplicate functions removed, orphaned CSS deleted, duplicate comments cleaned up. Seven utility CSS classes were added and 121 inline style= attributes were replaced with class references. One real bug was found during the cleanup: BUS_B_COLOR.length-1 should have been BUS_N-1 — a variable referencing the wrong constant for the bus bit array length.

Phase 2 — Central State Object

v.268–v.270

The single most important architectural change of the restructuring. All simulation state was consolidated into a single namespace object called L21. Before this, bus state lived in nine separate top-level variables. ALU state, memory state, counter state, pattern matcher state — all top-level. Snapshot save and restore had to know where every piece of state lived and copy each one individually.

L21.buses was the largest migration: nine buses, roughly 1,000 mechanical renames from busABits to L21.buses.a.bits, busBActive to L21.buses.b.active, and so on. Every other subsystem followed: L21.alu, L21.cmp, L21.ctr, L21.pm, L21.pm2, L21.tg1, L21.tg2, L21.mem, L21.wscr, L21.logger, L21.stats. Backward-compatible aliases (const alu = L21.alu) were created so that existing code continued to work without modification.

A 55-test suite was established during this phase — the project's first automated tests.

Phase 3 — Bus Deduplication

v.271–v.274

The nine buses had been built one at a time. Each had its own direction function, its own selection function, its own toggle function, its own tick function, and its own rendering function. Many of these were identical except for the bus letter in variable names. Phase 3 introduced BUS_CONFIGS — a central data table describing all nine buses — and unified direction, selection, toggle, tick, and render functions that read from the config table instead of hardcoding bus identifiers.

The generated sidebar panels for buses E through I, which had been 323 lines of hand-coded HTML, were replaced by a single generateBusSidebarPanels() function. All original function names were preserved as one-liner delegates — zero HTML call-site changes required. Phase 3 removed 702 lines.

Phase 4 — Peripheral Consolidation

v.275–v.278

The same deduplication applied to peripherals. Pattern Matchers 1 and 2 had 16 paired functions — togglePMDestructive() and togglePMDestructive2(), refreshPatternMatcherDisplay() and refreshPatternMatcher2Display(), and so on. Eight unified PM helpers replaced the 16. Threshold Gates followed the same pattern: 11 unified TG helpers replaced 22 paired functions. Counter eject and drain functions were similarly consolidated. Phase 4 removed 193 lines.

Phase 5 — Tick Engine and State Migration

v.279–v.285

The tick engine — the function that executes one clock cycle of the machine — was a 294-line monolith called executeOneTick(). It mixed sampling, reading, gating, rotating, and writing into a single uninterruptible block. Phase 5 decomposed it into an 8-line coordinator calling six named sub-functions: tickPreamble, tickSampleBusSources, tickReadPhase, tickGatePhase, tickRotatePhase, tickWritePhase. Data flow between phases was made explicit through return values.

The remaining stray state variables — injection channel, clock timing, external buffers, operator action count — were migrated into L21 sub-objects. By v.281, every piece of simulation state lived inside L21. The pending-migration list from Phase 2 was empty.

Snapshot save was simplified from 194 lines to 30 using JSON.parse(JSON.stringify()) on the now-cleanly-organized L21 sub-objects. Snapshot restore went from 218 lines to 95 using a generic deepAssign helper. The render loop was decomposed from 384 lines into a 25-line coordinator plus seven named sub-functions. The test suite grew to 125 tests, including 19 integration tests running in a Node VM with a recursive proxy-based DOM mock.

Phase 6 — Session Logger, Display Sync, Event Delegation

v.286–v.288

The final phase addressed three remaining structural issues. The session logger's logWriteINIT and logWriteFINAL functions — 78 and 142 lines respectively — manually enumerated every piece of machine state in parallel. A shared logWriteMachineState(prefix, options) function replaced 130 lines of duplication. Three pre-existing bugs were found during the rewrite: the INIT section used the wrong marker bit for operator input (0x100 instead of 0x10000), PM binary padding was wrong, and the FINAL section truncated ALU results to 8 bits in the human-readable column.

The snapshot restore display sync — 80 lines manually poking every UI element after a state restore — was consolidated using a new syncBusSidebarButton(busId) helper driven by BUS_CONFIGS. The same helper was reused across all nine bus toggle functions.

The largest single change: 225 inline onclick= handlers were replaced with data-action attributes and a single top-level event delegation listener. Every button in the simulator — from ALU operations to bus toggles to challenge controls to file management — now routes through one 33-line delegate function that reads the action name from the clicked element's dataset and dispatches to the corresponding global function.

A code review pass found two additional bugs: the _anyFlash render gate was missing Buses H and I (flash glow popped off instantly instead of decaying), and toggleBusB was a standalone implementation missing both renderAllComponents() and the status bar log message. Both were fixed by delegating to the existing generic infrastructure.

The remaining pattern debt was cleaned up: standalone toggle functions for Buses E through I were replaced with one-liner delegates to toggleBusGeneric. Eight ternary dispatches in the net bus section (busId === 'h' ? L21.buses.h.property : L21.buses.i.property) were replaced with direct property access (L21.buses[busId].property). A flashProps field was added to every BUS_CONFIGS entry, and the flash decay loop and _anyFlash render gate were rewritten to iterate the config table instead of maintaining parallel hardcoded lists.

The Test Suite

v.268–v.288

The project had no automated tests before the restructuring. By v.288 it has 140, organized in six categories: structural tests (HTML validity, script/style blocks, version consistency, duplicate detection), logic tests (pure functions extracted and tested in Node), state verification (initial state shape of every subsystem), phase pre-flight tests (structure validation for consolidated peripherals), CSS tests (custom properties, utility classes, skins), and integration tests (full simulator running in a Node VM with a DOM mock, testing loop rotation, gate phase, injection, pattern matching, threshold gating, ALU arithmetic, snapshot round-trip, session logging, and event delegation).

The integration test harness deserves mention: the entire simulator JavaScript is evaluated in Node's vm module with a recursive proxy-based DOM mock that intercepts all property access and returns stub elements. A postamble exports key objects (L21, loops, alu, etc.) to the sandbox scope. Tests can call tick sub-functions, manipulate state, and verify results — full behavioral testing of a browser application without a browser.

What the Numbers Say

The machine at v.261 was 14,861 lines. The machine at v.288 is 14,752 — a net reduction of 109 lines despite adding 140 tests' worth of testable structure, a central state object, a unified bus configuration table, decomposed tick and render engines, and a complete event delegation system. The real metric is not lines saved but lines that can now be safely changed without understanding the entire file. The restructuring did not change what the machine does. It changed whether anyone else can work on it.

The Machine at v.288

The machine at v.288 is the same machine as v.261. Same buses, same loops, same peripherals, same networking, same challenges. An operator using v.288 would not notice any difference from v.261 — every button works, every display updates, every feature functions identically. What is different is invisible to the operator and visible to the developer: a central state namespace, a test suite, a unified configuration table, decomposed engines, and a single event delegation path. The machine was built for operators. The restructuring was built for the people who will build the next version of the machine.

"The restructuring did not add a single feature. It changed whether anyone else can work on it."

Chapter Thirteen
308 Builds In
The Machine Learns to Listen

The development between v.289 and v.308 is the story of a machine that had become structurally sound, finally turning its attention to the people operating it. The restructuring of v.288 had addressed the code. What followed was the work of addressing the interface — what the machine looks like while it runs, how it receives and keeps operator notes, and whether an operator who has used it for a hundred hours can finally put the mouse down.

Twenty builds. A sidebar rebuilt from first principles with a semantic color language. A complete annotation and scripting system that arrives at the machine's top position because that is where it belongs. And a full keyboard control system that makes Loop 2.1 operable with hands on the home row. The machine at v.288 was structurally the best version of the simulator that had been built. The machine at v.308 is the most operationally complete.

The Sidebar Restructure

v.291

The right sidebar had grown organically over 288 versions. Sections arrived in roughly the order they were built, which had never been the order in which they were used. By v.288 the sidebar had nine bus panels, four counter sections, two pattern matchers, two threshold gates, files, networking, chat, notifications, and a session log — and they sat in an order that reflected the history of the project rather than the workflow of an operator.

The restructure imposed a canonical order based on a single principle: the sections an operator needs first appear at the top, and related sections that share a visual language are grouped together. The new order runs: Annotate, Global Counter, Counter Triggers, Challenges, Buses, Working Scratch, ALU, Filters (PM1, PM2, TG1, TG2), Memory Slots, Files, Chain & Net (P2P Connection, Networking, Network Monitor), Chat, Notifications, Session Log.

Three new collapsible group containers were introduced: Buses wraps all nine bus panels (A through I) under a single expand/collapse toggle; Filters wraps the two Pattern Matchers and two Threshold Gates; Chain & Net wraps P2P Connection, Networking, and the Network Monitor. The parent groups collapse to a single header line, making a sidebar with nine buses and four filter components navigable without scrolling past things you are not currently using. All three groups are wired into the existing Expand All / Collapse All controls at the sidebar top.

The sidebar also widened from 260px to 270px, and the nested indent within group bodies was reduced by approximately 75% — groups no longer feel like sub-documents. Each level reads at the same density as the level above it.

On the Annotate Position
Annotate was placed at the very top of the sidebar — above Global Counter, above Challenges, above the buses. This is not the position it earned by importance alone. It is the position that makes the most sense for an operator who has started a session: notes go at the top because writing down what you are about to do is the first thing you do, not an afterthought. The sidebar order tells a story about how the machine is used.

The Sidebar Color System

v.294–v.298

The sidebar at v.293 had section colors inherited from whichever builds had set them, which was no one in particular — colors had accrued rather than been designed. Some sections were blue, some were grey, and the distinction carried no meaning. A complete audit replaced every hardcoded color value with a semantic CSS variable system organized into seven families.

Blue (--c-working) covers the working loop's extended family: Global Counter, Counter Triggers, Working Scratch, and Annotate. These sections are all primarily about data in motion through the Working loop, or about the operator's relationship with that data in time. Amber (--c-alu) covers the ALU, the one section unchanged. Magenta (--c-chall, new) is Challenges — a distinct operational mode deserving its own color. Teal (--c-big) covers Pattern Matchers 1 and 2, which operate on the Big loop. Violet (--c-tg, new) covers Threshold Gates 1 and 2. Green (--c-memory) is Memory Slots and Files. Indigo (--c-net, new) covers everything in the network layer: P2P Connection, Networking, Network Monitor, and Chat.

Bus sections E through I, previously colored via inline style= attributes set in JavaScript, were given proper CSS classes: sb-sec-buse through sb-sec-busi, each with a background tint derived from its bus color. The four internal buses (A through D) already had this structure. All three skins received matching dark and warm variable sets so the semantic language holds in Winamp and Sunrise as well as OG.

The Annotate System

v.299–v.307

The Annotate system is the most substantial feature addition since the file system at v.249. It gives operators a structured space for recording thoughts during a session — not a freeform text field bolted to the side, but a purposeful tool that knows what the machine is doing when the operator writes.

At its core: a multi-line textarea and a Take Note button. Press Take Note (or Ctrl+Enter with the textarea focused), and the text is recorded with the current tick count into the recent annotations list, written as a timestamped line to a .loopscript file held open by the File System Access API, and written to the session log as a TNNNN.ANNO.NOTE entry. Three destinations for one operator action. The note is stamped with the machine's moment — not a wall clock, but the tick count that places it precisely within the computation's own timeline.

Above the textarea sits a context bar that updates on a 100ms interval, showing the current tick count and the most recent status log entry. The operator doesn't need to watch the loop ring to know where the machine is — the context bar tells them. Notes written in response to machine events are automatically paired with the event in the record.

The Symbol Library provides five tab categories (Act, Ctrl, Comp, Flag, ALU) with drag-to-palette symbols. An operator can populate My Palette with the symbols they use in every session — the routing arrow (→), the gate close symbol (⊗), the comparator flag markers — and insert them with a single click. The palette persists in localStorage across sessions.

All JavaScript is wrapped in an IIFE. All functions exposed to HTML use the anno prefix, following the naming discipline the restructuring established. The collapse state is controlled via a window._annoSetLibraryCollapsed function, a deliberate design choice: an internal function exposed through the window namespace rather than a global, keeping the IIFE boundary clean while allowing the Expand All / Collapse All controls to reach it.

On Notes as First-Class Records
The Annotate system writes to three places because operator notes are not peripheral to a session — they are part of its record. A session log that captures every bus toggle and tick count but has no space for the operator's intent is a machine record, not an operator record. The annotation format was named .loopscript from the beginning, with a future in mind: a scripting layer for the machine that would use the same file, the same format, the same timestamping discipline. The notation and the annotations would coexist in one place, telling the story of both the setup and the computation.

The Keybinding System

v.308

Loop 2.1 had been operable entirely by mouse since its first version. The keybinding system gives operators a parallel path: every high-frequency action reachable from the home row, without touching the mouse. The system was designed with the same care as the rest of the machine — not as a convenience layer but as an ergonomic architecture that reflects how the machine is actually used.

Three layers. The flat layer is the workhorse: single-key commands for the most common actions. Space starts and stops the clock. Period steps one tick. S, D, F, G pause and resume Working, ALU, Memory, and Big in left-to-right visual order, matching the loops as they appear on screen. R sends the ALU answer to the loop. E injects. Q clears switches. The spatial logic is consistent: the four loop keys occupy the left-hand home row because four fingers rest there; every loop action is a one-hand operation.

The modifier layer uses Shift as a consistent prefix for secondary variants of flat-layer keys. Shift+S toggles the Working gate rather than pausing it. Shift+R sends the comparator rather than the ALU answer. Shift+V cycles ALU operations backward. The relationship is predictable: if you know what a key does, you can guess what Shift+key does.

The chord layer is the most original design in the keybinding system. Bus configuration — setting source and destination, the central routing act of operating Loop 2.1 — reduces to a three-keystroke grammar: bus key, source key, destination key. Press 1, then W, then A, and Bus A is configured Working → ALU. Press 2, then A, then M, and Bus B is configured ALU → Memory. Four buses, the complete four-loop pipeline, in twelve keystrokes total. A status display at the bottom of the screen shows chord progress in real time as each key is pressed.

The chord vocabulary maps eight component letters to machine endpoints: W (Working), A (ALU), M (Memory), B (Big), P (PM1 output, source only), T (TG1 output, source only), K (global counter), F (file save, destination only). Invalid combinations — attempting to use file save as a source, or TG1 as a destination — cancel cleanly with a displayed error. The bus configuration is unchanged. The chord system performs the same validation the mouse-based UI performs.

Double-tap detection on the digit keys provides the toggle shortcut: press 1 twice within 300ms and Bus A toggles on or off without entering chord mode. The threshold is generous. Shift+digit provides the same toggle for operators who find double-tap timing inconsistent. Both paths produce identical behavior. Net buses E through I follow the same toggle patterns on keys 5 through 9, without chord entry — their configuration remains click-only, but their on/off state is keyboard-reachable.

Chat, challenge, and context-sensitive Enter complete the system. T opens the chat input with a single keypress; Enter sends the message and returns focus to the machine; Escape cancels and returns. N starts a new challenge; Shift+N aborts; H toggles the spoiler display. Enter triggers challenge RELEASE when no input is focused and the button is active — a context-sensitive binding designed so it cannot fire accidentally while typing.

The entire system hangs on a single document.addEventListener('keydown', handleKeydown). The handler follows a strict decision tree: ignore all Ctrl/Alt/Meta events; suppress all bindings while inputs are focused; handle Escape universally; process active chords before anything else; check digit keys for chord or toggle entry; fall through to shift map, then flat map. Every matched key calls event.preventDefault(); unmatched keys pass through to the browser. The session log receives identical entries whether an action was triggered by a key, a mouse click, or — in the future — a script.

On the Keybinding System and What Comes Next
The keybinding system is the foundation of something larger. Every action it exposes is now a named, callable function with consistent behavior. That registry is the vocabulary a scripting layer needs. An operator who writes send_answer() in a script is calling the same function the R key calls. The work of the keybinding system was not only to give operators a faster path to actions they already had — it was to make the action registry explicit enough that a future system can address it by name.

The Machine at v.308

The machine at v.308 has everything the machine at v.288 had, plus a sidebar that narrates itself through color and order, an annotation system that places operator notes inside the machine's own timeline, and a keyboard architecture that makes the full machine operable without touching the mouse. None of these additions change what the machine computes. All of them change what it is like to be the person computing with it.

Three capabilities introduced in this period point outward toward what the machine could become. The .loopscript format is named for its future: an annotation file today, a scripting host tomorrow. The action registry made explicit by the keybinding system is the vocabulary a reactive scripting language would need. LPScript — the name chosen for the scripting layer in design — would let an operator write a rule that fires when the ALU answer exceeds a threshold, route it, and continue. The operator writes the rule once. The machine executes it faithfully every tick. The operator remains in control. The machine remains manual. What changes is the level of abstraction at which the operator works.

The machine at v.308 is 308 builds from a Minecraft throne room. It runs in any web browser. It supports nine buses, four loop peripherals, networked multi-machine challenges, file transfer, named operator groups, sound notifications, three visual skins, a complete annotation system, and now a keyboard architecture designed from ergonomic first principles. The philosophy has not moved. The operator is still the program. What has moved is everything it takes to be that program.

"The keybinding system is a foundation. Every action it exposes is now a named, callable function. That registry is exactly the vocabulary a scripting layer needs. The work of making actions keyboard-reachable was also the work of making them scriptable."

Advanced Problems
Challenge Problems
No posted solutions · Every problem is solvable with the tools in this manual

Finding a more elegant route — fewer total steps, fewer ticks, less operator intervention — is part of the challenge. Before each problem, confirm a clean state: counters at zero, no triggers active, buses off, Op Count unlinked, PM mask all zeros.

A · Find the Maximum

Demonstrates: Comparator, conditional routing, multiple register use

Load four values into the machine, one at a time. Find the largest using the comparator, and return it to the Working loop. Values: 91, 34, 117, 58.

  • You may use all four registers and perform as many comparisons as needed.
  • The correct answer must end up in the Working loop as a circulating word.
  • You may not compute the answer by inspection — work through the comparisons on the machine.
Hint
A comparison tells you which of two values is larger. Think about how many comparisons are necessary for four values. The GTE flag tells you which register holds the current maximum candidate at each step.

B · Measure Your Own Work

Demonstrates: Counter triggers, Op Count halt, Bus B, counter as data

Load five values into Working. Count how many words enter using the Word Written trigger. Use that count as a multiplier. Values: 10, 20, 30, 40, 50.

  • Activate Word Written trigger on the Working loop counter.
  • Inject all five values. Working counter should read 5.
  • Use Bus B to move the counter value (5) into the ALU loop. Capture into Register B.
  • Load 10 into Register A. Compute 10 × 5 = 50 via repeated addition.
  • Compare your result to the value 50 circulating in Working. The EQ flag should light.
Hint
The counter will continue firing during the computation phase as words arrive at Working from bus transfers. Think about how to manage this before you begin.

C · Rewrite in Place

Demonstrates: Pattern Matcher rewrite mode, selective bit modification

Load eight values into the Big loop. Use PM1's rewrite mode to zero out bit 7 of every value that has bit 7 set — without removing any values from the loop. Values: 200, 45, 180, 30, 128, 77, 160, 99.

  • Determine which values have bit 7 set (value ≥ 128).
  • Configure PM1 to match values with b7=1. Rewrite mode: set b7 to 0.
  • Use EJECT: COPY so modified words remain in the Big loop.
  • After one full rotation, verify all eight values are present with the correct modifications.
Hint
Rewrite Mask bit 7 = 1 (change this position); Rewrite Value bit 7 = 0 (set to zero). All other rewrite mask bits = 0 (leave unchanged).

D · Building Numbers from Nothing

Demonstrates: Inject channel timing, zero-pulse injection, bit placement precision

The inject channel fires a marker bit followed by data bits. By selectively pausing the Working loop during specific bit positions of a zero-word injection, you allow only that one bit position to land — and by repeating this over several cycles, you build up a value bit by bit.

Construct 420 and 247 in the Working loop using only zero-word injections and selective timing. Then route both to the ALU loop, add them, and confirm the result is 667.

ValueBinary (16 bits)
4200000000110100100
2470000000011110111
Sum = 6670000001010011011
Hint
420's 1-bits are at positions b8, b7, b5, b2. That's four pulses. 247's 1-bits are at b7, b6, b5, b4, b2, b1, b0. That's seven pulses. The values can also be entered directly using the switch levers — but where's the elegance in that?

E · How Random Is Random?

Demonstrates: RNG, Pattern Matcher parity sort, counter-based result read

The Loop 2.1 RNG is a linear feedback shift register. It feels random. But is it balanced across even and odd outputs?

Generate 100 values from the RNG and sort them into even and odd using PM1. Count each group. The two counts must sum to exactly 100.

QuestionMethod
How many even values in 100 RNG outputs?PM1 ejects evens → Memory loop → Memory counter tallies
How many odd values?Remaining words in Big → Big loop counter tallies
VerificationEven count + Odd count = 100
Hint
A well-seeded LFSR over 100 values typically produces between 45 and 55 of each parity. The interesting finding is not the specific numbers — it's the act of measuring. You built a parity sorter out of a loop, a gate, and a single-bit mask.

Variants: Sort by a different bit — b1, b2, or b15. Does the distribution change? Use PM2 in cascade for three groups. Run the test five times and compare distributions. Try 200 values — does the distribution converge closer to 50/50?