Wulfram II Reconstruction Progress
Progress metrics for a byte-exact reconstruction of the Wulfram II game client. This site publishes numbers, charts and prose only; the reconstruction itself is not published here.
Snapshot of 2026-10-17 · 268 measured commits since 2026-09-11
Progress over time
From 0.27% on 2026-09-11 to 38.03% now. The shaded area is verified code; the dashed line is the whole first-party target, which moves a little as the inventory is corrected.
Where the verified code is
Each box is a feature area, sized by how much code it holds and shaded by how much of it is verified.
Table: feature areas
| area | verified % | verified bytes | area bytes |
|---|---|---|---|
| third-party.bzip2 | 99.4% | 168 | 169 |
| platform.window | 92.2% | 6,842 | 7,418 |
| sim.clock | 79.4% | 2,257 | 2,843 |
| math.kernel | 75.1% | 11,743 | 15,641 |
| core.runtime | 74.8% | 8,988 | 12,024 |
| net.transport | 73.8% | 9,230 | 12,514 |
| net.protocol | 69.3% | 12,610 | 18,207 |
| net.session | 66.4% | 9,302 | 14,005 |
| audio.runtime | 66.3% | 4,412 | 6,656 |
| assets.formats | 65.2% | 9,966 | 15,278 |
| gfx.backend | 64.1% | 42,832 | 66,828 |
| app.bootstrap | 60.2% | 16,599 | 27,558 |
| input.devices | 57.7% | 7,633 | 13,219 |
| services.updater | 57.0% | 11,233 | 19,712 |
| sim.entities | 50.8% | 14,567 | 28,700 |
| sim.physics | 49.8% | 19,332 | 38,806 |
| core.debug | 42.0% | 24,010 | 57,121 |
| sim.collision | 40.9% | 15,715 | 38,411 |
| net.replication | 39.4% | 8,003 | 20,317 |
| audio.backend | 38.6% | 2,012 | 5,212 |
| core.io | 34.9% | 6,963 | 19,930 |
| gfx.texture | 33.5% | 8,037 | 23,996 |
| sim.world | 33.2% | 18,704 | 56,378 |
| session.lifecycle | 32.6% | 3,776 | 11,580 |
| view.screens | 30.8% | 18,018 | 58,444 |
| ui.widgets | 28.2% | 15,750 | 55,790 |
| gfx.raster | 25.5% | 14,232 | 55,913 |
| tools.editors | 24.6% | 14,248 | 57,988 |
| social | 24.2% | 8,581 | 35,515 |
| view.hud | 23.6% | 16,441 | 69,726 |
| input.bindings | 20.7% | 1,636 | 7,899 |
| view.comms | 20.4% | 1,072 | 5,244 |
| view.tactical | 12.8% | 4,935 | 38,434 |
| view.camera | 12.1% | 778 | 6,436 |
| view.fx | 7.4% | 2,283 | 30,657 |
| crypto.hash | 7.4% | 220 | 2,992 |
| core.concurrency | 7.1% | 2,044 | 28,893 |
What's left
The 559.1 KiB of first-party code not yet verified, grouped by what is blocking it. Buckets come from the dependency census of 2026-10-04, minus everything verified since, so they only shrink between census refreshes.
Why the interlinked code is split by area: it used to appear here as one very large block, which hid where the work is and how it moves. It is really many groups, each unlocked once a handful of shared helpers (hubs) are rebuilt, so each line names the feature area the code belongs to, matching the rows of the map below. The lines add up to the interlinked total exactly. "Done" is the share of the area's interlinked code at census time that has been verified since; "hubs" is how many distinct hubs that code still waits on, and one hub can serve several areas. "Loosened since the census" is code that no longer waits on any hub and will move to another bucket at the next census. The groups as the compiler tied them are in the deep dive further down.
Table and full definitions
| bucket | bytes | share | done since census | hubs |
|---|---|---|---|---|
| Plain singles | 98,688 | 17.2% | ||
| Closed clusters | 86,935 | 15.2% | ||
| Frame / alignment classes | 56,201 | 9.8% | ||
| Interlinked code | 326,732 | 57.1% | ||
| HUD & targeting | 35,400 | 6.2% | 5.7% | 41 |
| In-game editors | 30,122 | 5.3% | 6.0% | 62 |
| Map & tactical view | 25,708 | 4.5% | 1.4% | 38 |
| 3D rendering & camera | 24,449 | 4.3% | 12.1% | 43 |
| Visual effects | 24,368 | 4.3% | 0.9% | 37 |
| World, entities & game data | 23,251 | 4.1% | 7.1% | 42 |
| Game screens & states | 22,266 | 3.9% | 7.2% | 51 |
| UI widgets & menus | 21,985 | 3.8% | 5.9% | 51 |
| Social, chat & lobby | 20,686 | 3.6% | 0.9% | 22 |
| Networking | 11,380 | 2.0% | 1.7% | 15 |
| Debug tools & console | 10,420 | 1.8% | 3.6% | 12 |
| Textures & images | 8,659 | 1.5% | 24.1% | 15 |
| Startup & config | 8,328 | 1.4% | 3.7% | 10 |
| Input & controls | 6,852 | 1.2% | 6.7% | 22 |
| Audio & voice | 3,261 | 0.6% | 55.4% | 4 |
| Graphics drivers (DirectX/GDI) | 2,686 | 0.5% | 5.9% | 4 |
| Core runtime & platform | 2,223 | 0.4% | 18.2% | 10 |
| Unattributed (no TU yet) | 2,132 | 0.4% | 7 | |
| Physics & collision | 516 | 0.1% | 12.7% | |
| Updater (CSN) | 272 | 0.1% | ||
| Loosened since the census | 41,768 | 7.3% | ||
| Policy-held | 3,965 | 0.7% |
- Plain singles
- functions with a standard calling convention, no register inputs from callers and no compiler frame-alignment demand; each can be attempted on its own. Includes single-function units the census put on the plain-single track, the census single-candidate list (split into 'worth a singles wave' and the rest), and a residual of first-party bytes that the census did not place in any unit (large, x87-heavy, complex exception handling or otherwise outside its filters).
- Closed clusters
- groups of functions that whole-program optimisation tied together through custom register conventions, whose closure is complete (every member's callers are inside the group). Grouped by size class: number of members and bytes.
- Frame / alignment classes
- single functions or groups whose stack-frame shape (8- or 64-byte realignment, padding slots) depends on callers or callees; reproducing them needs the right neighbours compiled together. Includes groups whose frame chain went beyond the census pull limit.
- Interlinked code
- functions that call each other through calling conventions the compiler chose privately across the whole program, so a function can only be rebuilt once the shared helpers (hubs) it depends on are rebuilt and published. In the census these chain into one very large connected group of over a thousand functions; here it is split by feature area. Each subsection gives its bytes, the share of its census-time code verified since the census, and how many distinct hubs its code still waits on (a hub can serve several areas, so subsection hub counts overlap). 'Loosened since the census' is code the current work map no longer finds in the tangle because hubs it depended on were verified; it moves to another bucket at the next census refresh.
- Policy-held
- work that is held by a process rule rather than by difficulty: units reserved for another work lane, units that need an ownership ruling on a calling-convention contradiction, and results that are proven but not countable under the current counting rules.
Library code is measured on its own line: 174.7 KiB exact, 81.5 KiB pending.
Where the remaining work is
All 604.4 KiB of unverified target code (1,982 functions; this includes the 38.1 KiB of rows found to be library code that "What's left" leaves out), placed on two axes: the feature area it belongs to, and the structural kind of problem it is. A darker cell holds more code. Hover a cell for exact figures. The map was computed on 2026-10-14, when 365,153 bytes were verified; functions verified since then are still in it until the map is refreshed.
How ready it is
Compiler quirks behind the stuck code: floating-point stack order 14.4 KiB, register allocation 10.9 KiB, stack-slot order 9.5 KiB, instruction order 7.3 KiB, exception-handling state 2.2 KiB, other 0.4 KiB. Rule decisions: 38.1 KiB is library code counted as game code, 33.6 KiB other process decisions. 103.2 KiB has never been attempted by a porting wave (much of it was drafted automatically). 5.8 KiB already matches in the provisional draft link, which is not counted. Hub counts overlap between areas, because one hub can serve several.
Interlinked code: how it's being unlocked
The interlinked code is 978 functions (300.2 KiB) that pass values to each other in registers the compiler picked for the whole program, rather than in the standard way. A function can only be rebuilt once the shared helpers it calls, its hubs, are rebuilt with the same conventions, so the work goes hub by hub. There are 254 hubs in all. 372 functions (149.3 KiB) form a tightly meshed centre that no single hub cuts apart; the rest hangs off it, one hub away.
A standard community-detection method splits the interlinked code into the groups below. Each group is named after the feature area that holds most of its code, with letters when an area has several.
Groups
| group | functions | bytes | hubs inside | hubs waited on |
|---|---|---|---|---|
| Social, chat & lobby A | 98 | 47,011 | 24 | 31 |
| World, entities & game data A | 64 | 23,524 | 14 | 16 |
| Startup & config | 65 | 22,109 | 11 | 13 |
| In-game editors A | 59 | 19,074 | 12 | 15 |
| Map & tactical view A | 51 | 17,495 | 16 | 20 |
| Visual effects A | 57 | 16,980 | 18 | 19 |
| HUD & targeting A | 45 | 14,878 | 8 | 8 |
| In-game editors B | 48 | 13,473 | 17 | 20 |
| 3D rendering & camera A | 47 | 13,445 | 16 | 16 |
| In-game editors C | 53 | 13,389 | 17 | 19 |
| Debug tools & console | 32 | 12,585 | 9 | 9 |
| Game screens & states A | 26 | 11,522 | 6 | 9 |
| Networking | 39 | 10,265 | 13 | 15 |
| World, entities & game data B | 33 | 9,946 | 10 | 10 |
| Visual effects B | 24 | 8,477 | 6 | 7 |
| Game screens & states B | 28 | 8,333 | 7 | 8 |
| Map & tactical view B | 26 | 7,958 | 4 | 5 |
| Social, chat & lobby B | 36 | 6,810 | 7 | 7 |
| Audio & voice | 23 | 5,509 | 6 | 7 |
| 3D rendering & camera B | 21 | 5,304 | 6 | 9 |
| Visual effects C | 18 | 4,132 | 6 | 7 |
| HUD & targeting B | 22 | 3,644 | 4 | 5 |
| Textures & images | 11 | 2,466 | 4 | 4 |
| Map & tactical view C | 16 | 2,207 | 5 | 5 |
| In-game editors D | 11 | 2,039 | 4 | 4 |
| UI widgets & menus A | 8 | 1,924 | 0 | 0 |
| UI widgets & menus B | 8 | 1,863 | 3 | 3 |
| Game screens & states C | 8 | 1,047 | 1 | 1 |
Where the hubs are
| area | hubs | hub bytes |
|---|---|---|
| UI widgets & menus | 44 | 8,636 |
| Visual effects | 33 | 9,087 |
| 3D rendering & camera | 30 | 7,266 |
| World, entities & game data | 28 | 7,348 |
| In-game editors | 17 | 3,125 |
| HUD & targeting | 15 | 5,132 |
| Map & tactical view | 13 | 3,234 |
| Input & controls | 12 | 2,010 |
| Textures & images | 11 | 2,767 |
| Debug tools & console | 11 | 4,910 |
| Game screens & states | 10 | 2,750 |
| Social, chat & lobby | 7 | 1,783 |
| Core runtime & platform | 7 | 878 |
| Networking | 5 | 1,129 |
| Graphics drivers (DirectX/GDI) | 4 | 1,336 |
| Audio & voice | 4 | 978 |
| Unattributed (no TU yet) | 2 | 309 |
| Startup & config | 1 | 89 |
Hubs are counted by the area they belong to, not named.
Kinds and definitions
- Stand-alone functions
- Ordinary functions that can each be rebuilt on their own.
- Small groups (plain build)
- Small groups outside the whole-program-optimised part of the game, tied by private calling conventions inside one source file.
- Small optimiser-bound groups
- Up to 8 functions the whole-program optimiser bound together; rebuilt as one unit.
- Large optimiser-bound groups
- 9 to 99 functions bound together; rebuilt as one unit.
- Stack-layout groups
- Functions whose stack layout depends on their callers or callees, so neighbours are compiled together.
- Interlinked (hub-blocked)
- Functions tied to each other through compiler-chosen calling conventions; each waits on the shared helpers (hubs) it calls, and is unlocked hub by hub.
- Library code counted as game code
- Rows in the game's own count that turned out to be statically linked library code.
- Tiny stubs and data
- Jump stubs, tiny bodies and data-like rows.
- Hub
- a function in the interlinked code that takes register inputs and is called from two or more other interlinked functions. Hubs are counted, never named.
- Hubs waited on
- the number of distinct hubs a group's functions are or call directly. A hub can serve several groups or areas, so these counts overlap.
areas, kinds, readiness and communities are computed mechanically but rest on heuristics (area roll-up, core/fringe split, plateau classes, transcribed holds); treat them as a map, not a ledger.
How we count, and the exceptions
Every byte counted in the byte-exact tier is identical to the original. That is 372,653 bytes in 2,423 functions. Each one, recompiled with the period compiler (Microsoft Visual C++ 2005) and the original flags, gives exactly the original machine code. Every address reference agrees with the original, and a deliberate mutation of the source is shown to break the match.
The campaign headline is that tier plus 2,519 bytes (26 functions) verified by behaviour on a lower proof tier, 375,172 bytes in all. The flags below describe how a unit was admitted or attributed, meaning which evidence rules it relied on. Apart from the behaviour-verified row, they are not about bytes that fail to match. Each flag is listed so it can be revisited, and most are expected to be temporary.
| Category | Bytes | % of counted | Match | Nature | Plan / status |
|---|---|---|---|---|---|
| Shared-context rule (provisional) | 9,054 54 fn | 2.41% of counted | identical | Byte-identical. These functions sit in multi-function units whose only outside helpers are functions that were already verified; those helpers ride along unchanged as shared build context and are not counted a second time. The open question is the admission rule, not the bytes. | Gate rule under review. If it is tightened, the whole block can be taken out of the count in one step. |
| Behaviour-verified (lower tier) | 2,519 26 fn | 0.67% of counted | behaviour only | Not yet byte-proven. Each function was run side by side with the original on recorded inputs and gave the same results, with a control that is able to fail. Counted in the campaign figure on a lower proof tier; not part of the byte-exact tier. | Expected to be temporary: these are meant to be replaced by byte-exact versions as their units are rebuilt. |
| Chosen local-variable names | 1,955 6 fn | 0.52% of counted | identical | Byte-identical. The period compiler orders some stack slots by the spelling of local variable names. Where no evidence names the original variable, a name was chosen that reproduces the layout. | Evidence-quality flag; revisit if naming evidence turns up. |
| Invented helpers | 23,842 64 fn | 6.36% of counted | identical | Byte-identical. The source uses a small helper the original may not have had, for example a stand-in caller that gives the compiler the right surrounding context. The helper itself is never counted. | Evidence-quality flag; revisit and replace with the original structure where it can be identified. |
| References to not-yet-named globals | 99,954 412 fn | 26.64% of counted | identical | Byte-identical, and every reference lands on the same address as in the original. The referenced global or function simply has no independently backed name yet. | Naming work; the bytes and addresses already agree. |
| Older alignment annotation | 420 4 fn | 0.11% of counted | identical | Byte-identical, but the source reproduces the stack frame with an explicit alignment annotation. A later study of frame alignment suggests the original was written differently. | Grandfathered; due to be re-ported the newer way. |
| Other provisional rule | 998 3 fn | 0.27% of counted | identical | Byte-identical; admitted under a rule that is marked provisional. | Under review. |
| Other provisional rule | 2,211 4 fn | 0.59% of counted | identical | Byte-identical; admitted under a rule that is marked provisional. | Under review. |
| Other provisional rule | 4,130 11 fn | 1.10% of counted | identical | Byte-identical; admitted under a rule that is marked provisional. | Under review. |
| Other provisional rule | 1,167 2 fn | 0.31% of counted | identical | Byte-identical; admitted under a rule that is marked provisional. | Under review. |
| Other provisional rule | 298 1 fn | 0.08% of counted | identical | Byte-identical; admitted under a rule that is marked provisional. | Under review. |
| Other provisional rule | 1,733 1 fn | 0.46% of counted | identical | Byte-identical; admitted under a rule that is marked provisional. | Under review. |
| Other provisional rule | 141 1 fn | 0.04% of counted | identical | Byte-identical; admitted under a rule that is marked provisional. | Under review. |
| Replaced records (provisional) | 1,621 5 fn | 0.43% of counted | identical | Byte-identical. A newer proof replaced an older record: either a larger unit that contains the old one, or a fresh proof for a record whose source had gone out of date. The old records are kept verbatim in a separate file; every function is counted once. | Rule under review. Deleting that one file returns the count to what it was before the rule. |
Apart from the behaviour-verified row, these flags describe how a unit was admitted or attributed (the evidence rules), not bytes that fail to match. A function can carry more than one flag, so the rows overlap and do not add up.
- Library tier: provisional bss gap fit. Library tier only: library bytes admitted under an evidence rule marked provisional. Under review; never part of the first-party figure.
A draft-link tier also exists in the private workspace. It links drafted functions into a runnable program for testing. It is provisional and diagnostic, and it is not counted in any number here.
Milestones
- Campaign passed 35% verified
2,277 functions, 346,317 bytes - Campaign passed 30% verified
2,119 functions, 312,374 bytes - Campaign passed 25% verified
1,939 functions, 254,510 bytes - Campaign passed 20% verified
1,701 functions, 202,527 bytes - Library tier passed 50% exact
172,330 library bytes - Campaign passed 15% verified
1,424 functions, 149,366 bytes - Campaign passed 10% verified
1,130 functions, 100,103 bytes - Campaign passed 5% verified
546 functions, 49,405 bytes
Latest changes
- +934 bytes to 38.03%
Promote intake-6b: [fn] via chained vecctor-owner supersede (+1 fn / +934 B) - +141 bytes to 37.94%
Promote intake-20cr: [fn] under PROVISIONAL Amendment 20c-r (+1 fn / +141 B) - +1,733 bytes to 37.92%
Promote intake-20f: [fn] under PROVISIONAL Amendment 20f (+1 fn / +1,733 B) - +894 bytes to 37.75%
Promote intake-w3a: h09 re-certified in place with [fn] (+1 fn / +894 B) - +2,457 bytes to 37.66%
Promote intake-w4f: hub-wave4 mesh-triangles object unit (+7 fn / +2,457 B) - +2,313 bytes to 37.41%
Promote intake-m05 + intake-w4e: m05 strict recert with , and 16 published singles re-proven fresh (+17 fn / +2,313 B)
The full list is in CHANGELOG.md in the repository.
Work waves
Each wave is a batch of attempts. "Counted now" is the part of the wave that is in today's verified total.
Table: waves
| wave | result date | functions tried | bytes tried | bytes counted now |
|---|---|---|---|---|
| cluster wave 6 | 2026-09-30 | 44 | 10,199 | 4,321 |
| round 47 | 2026-10-01 | 14 | 4,001 | 96 |
| round 49 | 2026-10-04 | 49 | 12,987 | 3,905 |
| round 50 | 2026-10-04 | 34 | 8,990 | 5,075 |
| round 51 | 2026-10-04 | 20 | 3,334 | 2,788 |
| round 52 | 2026-10-04 | 20 | 2,230 | 1,698 |
| round 53 | 2026-10-04 | 20 | 1,480 | 981 |
| round 54 | 2026-10-04 | 20 | 2,181 | 1,449 |
| round 55 | 2026-10-04 | 20 | 1,976 | 1,349 |
| round 56 | 2026-10-04 | 20 | 2,415 | 1,746 |
| round 57 | 2026-10-04 | 20 | 3,072 | 1,767 |
| round 58 | 2026-10-04 | 20 | 6,530 | 1,899 |
| round 59 | 2026-10-04 | 20 | 3,004 | 2,167 |
| round 60 | 2026-10-04 | 20 | 2,819 | 1,651 |
| round 61 | 2026-10-05 | 20 | 4,552 | 1,675 |
| round 62 | 2026-10-05 | 19 | 2,429 | 1,360 |
| cluster wave 7 | 2026-10-06 | 49 | 6,887 | 3,516 |
| cluster wave 8 | 2026-10-06 | 56 | 20,042 | 5,465 |
| cluster wave 10 | 2026-10-07 | 59 | 12,901 | 2,997 |
| cluster wave 11 | 2026-10-07 | 80 | 29,833 | 19,625 |
| cluster wave 9 | 2026-10-07 | 73 | 21,447 | 6,411 |
| giant attack 1 | 2026-10-07 | 80 | 18,812 | 4,970 |
| giant attack 2 | 2026-10-07 | 62 | 12,277 | 911 |
| giant attack 3 | 2026-10-08 | 105 | 20,319 | 3,624 |
| ready wave 1 | 2026-10-08 | 43 | 41,446 | 12,461 |
| ready wave 2 | 2026-10-08 | 101 | 44,312 | 20,700 |
| ready wave 3 | 2026-10-09 | 124 | 40,131 | 17,807 |
| ready wave 4 | 2026-10-09 | 207 | 40,771 | 16,511 |
| ready wave 5 | 2026-10-10 | 122 | 30,982 | 15,868 |
| ready wave 6 | 2026-10-10 | 138 | 22,203 | 2,208 |
| hub wave 1 | 2026-10-13 | 60 | 17,480 | 7,376 |
| hub wave 2 | 2026-10-13 | 23 | 8,407 | 2,355 |
| ready wave 7 | 2026-10-13 | 198 | 31,906 | 6,583 |
| hub wave 3 | 2026-10-14 | 37 | 9,755 | 2,669 |
More charts: subsystems over time, feature areas as bars, percent over time
What the numbers mean
Byte-exact means a function's reconstructed source, compiled with the same period compiler (Visual C++ 2005) and flags, produces exactly the machine code of the original program, with every address reference checked and a deliberate mutation shown to break the match. A small number of functions are instead counted on a differential-execution test against the original; they are listed in the exceptions table above.
Campaign verified bytes is the headline: verified bytes over all first-party target bytes. First-party excluding library rows moves rows that turned out to be library code out of the denominator. Library-exact measures the statically linked libraries (C runtime, Speex, bzip2, libjpeg) on their own line; it is never added to the first-party figure.