Repository navigation
collect_directions reads order, which is a doc index and not the direction value #83
Description
The claim, and why it is wrong
tools/trim-factorio-oracle.py:139-151 says this:
def collect_directions(doc_dir):
"""defines.direction is the authoritative answer to 'what number means east'.
Factorio 2.0 widened this from 8 to 16 values, which silently reinterpreted every
direction in every blueprint."""
...
return {v["name"]: v["order"] for v in define.get("values", [])}runtime-api.json does not publish the numeric value of any define. The fixture's
directions table is built from a documentation ordering index, not from the
game's actual numbers.
Verified against the installed 2.1.14 file
Measured directly on
.../Factorio/factorio.app/Contents/doc-html/runtime-api.json, application_version
2.1.14:
- 0 of 1,408 define values carry a
valuekey. The only keys present on a
define value arename,orderanddescription. There is no value field
anywhere in the file. orderis always a dense0..n-1index. Checked across all 137 define
tables in the file: every one has orders that are exactlyrange(len(values)).
Not one has a gap, a duplicate or a non-zero start.- Values are stored alphabetically by name.
defines.directionis stored as
east,eastnortheast,eastsoutheast, ... Soorderexists to restore
declaration order for display, which is what a documentation index is for. - The HTML docs do not publish values either.
doc-html/defines.htmlcontains
no numeric assignments fordefines.inventoryor anything else.
So there is no shipped file, JSON or HTML, that answers "what number is east".
Why the fixture is still correct today
Factorio declares directions clockwise starting at north = 0, and there are
exactly 16 of them with no gaps. For an enum like that, declaration order and
runtime value are the same number. The committed fixture holds exactly 0 through
15 with north=0, east=4, south=8, west=12, which is right.
So this is not a live defect in output. Nothing is currently wrong in a
blueprint. It is a wrong method that currently produces a right answer.
Why it is still worth fixing
Because order provably cannot represent a non-sequential enum. It is a dense
0..n-1 index by construction, so any define whose real values have a gap, a
duplicate, or a start other than zero would be read wrong and nothing here would
notice. Directions happen to be the friendly case.
Because the docstring makes a claim the file does not support. It says
defines.direction is "the authoritative answer". The authority is the running
game. What we read is a documentation artifact that agrees with the game by
coincidence of declaration order. Anyone extending collect_directions to a second
define - which is the obvious next step, and something the shared oracle CLI
proposal explicitly wants - would inherit a method that looks proven and is not.
Because of what this constant is. Direction encoding is the exact thing that
silently broke in 2.0, when 8-way widened to 16-way and every blueprint direction
was reinterpreted. #77 exists because of it. The oracle was built so that constant
would never again be taken on trust - and it is the one value in the fixture that
is inferred rather than read.
How to fix it
Read the values from the running game rather than from the docs. A probe mod dumps
them directly:
local out = {}
for name, value in pairs(defines.direction) do out[name] = value end
helpers.write_file("defines-dump.json", helpers.table_to_json(out))That is the same throwaway-mod technique already used in this repo to establish the
direction table, the mirror field and the Version bit layout - see 975e344 and
the notes in CLAUDE.md. The catch is that the mod was written, run and thrown away,
so there is nothing to re-run. Rebuilding it from the prose in CLAUDE.md is the
work here.
Two smaller changes go with it:
- Correct the docstring. Say what the source actually is and what it can and
cannot answer. - Add a guard while the current method stands. If
collect_directionskeeps
readingorder, assert that the resulting values are contiguous from zero and
that the count matches what the planner expects. That turns a silent wrong
answer into a failed capture for any future define that is not sequential.
Relationship to the shared oracle work
This is the strongest single argument for the probe-mod capability described in
#82, and it stands on its own regardless of whether that tool gets built. Filed
separately so it does not get lost inside a larger issue.
While in this file, CLAUDE.md also says the capture pulls four sources and lists
data/changelog.txt as one of them. It pulls three. There is no changelog handling
anywhere in tools/. Worth correcting in the same pass.
Activity
Plan: the trimmer and the byte-for-byte gate (plan 2 of 4)
Correct the capture's source count, and name its replacement
Spec and first two build plans for a shared factorio-oracle CLI (#84)