PulseCore

Chapter 7 · Section 10

The Language Reader: Alphabet, Words and the Drive

The BPT law

BPT Part 3.15 (The Physical as Executed Code) says what is written. The Cell Rule runs on every cell at once: "a pulser flips, a null cell bifurcates once its lit neighbours sum to one whole pulse, and a pulser whose eight neighbours all share its phase folds back to null". "Once a cell has pulsed it never stops", so "the field fills: nulls are exposed, bifurcate and light, until every cell is a pulser and no null is left. From then on nothing new is written." BPT calls the written field the Pulsecore Drive: "the data as written, which stays, while the physical is the copy that runs from it."

BPT Part 4.10 (The Language of a Universe) reads that writing as a text. "The data layer is written once, as the Pulsecore fills (Part 3.15), and that writing is a text." A pulser read against the clock, "its phase set against the pulse's own parity", holds still: "a 0 or a 1 for the whole life". "Between the pulsers lies the null, ∅, the Pre-Pulse Field that has never pulsed. The null is the silence between words. A Universe Word is a run of pulsers between two silences along a row of the torus, counted when it is written: on a pulse with births or folds, a run that was not there the pulse before. The first word of all is 0 → 1 → 0, the Prime Pulse." No dictionary is invented: "A universe writes its own spaces." The game implements these definitions directly. The 2026-10-27 ruling quoted at language.js:2 is Josh's: "lets add all of that! and start to attempt to let it speak to us".

The established physics

None: a game method, built on BPT's definitions. The linguistic and information-theory sources come with the tests (Part 7.11).

The game's math

Starting. On the first pulse of a field, or when the field size changes before anything is written, app.js makes a LanguageReader (app.js:4514). capture(lit, pulser) (language.js:104) then keeps the central W × W window of the starting field for the control (Part 7.12), with W = min(128, rows, cols). After each run of the cell rule, read() gets the new field and the numbers of cells born and folded (app.js:4516).

Rows read (language.js:97). k = max(1, ⌊rows / min(rows, 64)⌋), and every kth row is read. So at most 64 rows are read, or a few more when 64 does not divide the row count.

Words of a row (rowWords() language.js:58). The letter of a pulser is lit XOR (pulse mod 2), written '1' or '0'. Reading starts just after the row's first silence and wraps around the torus, so a word that crosses the seam is one word. A row with no silence at all is one word of cols letters.

Writing (read() language.js:111). A pulse writes when born + folded > 0. On such a pulse, in each row read, a run (start, word) that was not in that row on the previous pulse is a written word. For each written word:

  • Its dictionary key is the word itself if it has ≤ 24 letters. A longer word is keyed ⟨length⟩ plus an 8-hex FNV-1a hash, because long words are near-unique (wordKey() language.js:53).
  • Birth map. The first written word through each cell of a read row is remembered, by word id. Ids are given to at most MAX_TYPES = 200,000 distinct keys.
  • Counts. A key already counted keeps counting. A new key is counted only while fewer than 200,000 keys exist.
  • written += 1; letters += length; silences += 1.
  • Text. The word's letters and then a silence (2) are appended to text, until text reaches TEXT_CAP = 400,000 symbols. After that, no more text is kept.

The drive (snapshot() language.js:133). On the first pulse with no writing after a pulse with writing, the whole field is read into drive. The step is k = max(1, ⌈rows / ⌊2¹⁸ / cols⌋⌉) rows, and each cell becomes its letter, or 2 for silence. The drive therefore holds at most about 2¹⁸ = 262,144 symbols. Each pause replaces the last one, and if the summary is asked for while writing goes on, the current frame is used.

Worked case, level 8 (1024 × 1024). Rows read: k = ⌊1024/64⌋ = 16, so 64 rows. Drive: ⌊262,144/1024⌋ = 256 rows per drive, so k = ⌈1024/256⌉ = 4. The drive is 256 rows × 1024 = 262,144 symbols, a quarter of the field. The text stops at 400,000 symbols, about 200,000 words of mean length 1, or fewer longer ones.

driveWordAt() (language.js:146) is defined but not called anywhere in the game. wordAt() is used by the codebook (Part 7.13) and by the line shown when a child well is tapped (app.js:3135).

In the game

The writing happens in the first epoch the player sees. After Start, the cell rule fills the painted Pulsecore: nulls light, the fill spreads, and when no null is left the field only flips. That fill is the universe writing its text, and the reader takes every written pulse of it. In BPT's words, "in the game the writing runs while the Pulsecore fills and ends when it is full." Nothing is drawn for the words; the player sees the fill itself.

The reading comes back at the end. When the universe returns to the Source (app.js:2615) or decays to nothing (app.js:2705), the run summary shows the chip "✎ its language: grammar only · 76,396 words written", with the verdict and the count (app.js:2799), and the button "✎ Language Block" (index.php:427). The block's Alphabet section shows the reader's three symbols as the book gives them (app.js:2355–2359): "∅ silence, the Pre-Pulse Field, between words"; "0 off phase, a pulser read against the clock"; "1 on phase, a pulser read against the clock"; and the first word 010, "0→1→0, the Prime Pulse". Its first tile is "words written", with "N distinct · mean x letters" beneath, and its last is "writing pulses", "pulse a to b" (app.js:2348–2353).

A word can also appear on the field. When the player taps a child well after the return, the banner names the word that wrote the well's cell: "written by 1011 ·", or "a 37-letter word" for a hashed one (app.js:3135).

What the player paints is what is written. A painted Pulsecore, a drawn genesis or a child's inherited Pulsecore each give a different text, and the block's lede says which: its origin, its seed, and "child of #N" for a child.

The scale model

The reader reads the drawn field, and on large fields only part of it: 64 rows for words, and 2¹⁸ symbols for the drive. Every count it reports (written, distinct, letters) is a count over the rows read. None is scaled up to the whole field or to the true level.

Where the game and the theory differ

  • BPT counts every run of pulsers along every row of the torus. The game reads every kth row, at most 64 rows (4 of every 64 at level 8), so its word counts are a sample of the text.
  • BPT's drive is the whole written field. The game's drive is every kth row up to 2¹⁸ symbols (a quarter of the field at level 8).
  • Once 200,000 distinct words have been counted, a new word is still counted as written but gets no id and no count of its own. In a universe that writes more distinct words than that, the reported "distinct" stops at 200,000.

Fixed numbers

Number Where What it is Kind
64 (sampleRows) language.js:95, 97 Rows read for words. This limits how much of the field is read CAP
24 (LONG) language.js:49, 53 Longest word kept in full; longer words keyed by length and hash METHOD
200,000 (MAX_TYPES) language.js:49, 123, 125 Distinct words counted and given ids. Beyond it new words vanish from counts, Zipf and the codebook CAP
400,000 (TEXT_CAP) language.js:49, 127 Symbols of written text kept for the monkey test CAP
2¹⁸ (DRIVE_CAP) language.js:49, 134 Symbols in the drive: the text the predictability test reads CAP
128 (LISTEN_WINDOW) language.js:32, 106 The control's window (Part 7.12) CAP
2 (silence), 48 (char code) language.js:127, 135 The third symbol; '0' = 48 METHOD
1 (pulse & 1) language.js:115, 134 Parity of the clock: letters read against the pulse BPT
2166136261, 16777619, 8 (hex) language.js:51, 53 FNV-1a hash of a long word METHOD