You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tracking + recovery document for the eyes2 evolutionary-genome work. Captures the plan, decisions, current state, and how to resume in a fresh session. Last updated after addressing PR review comments — see "Session state" at the bottom for the live status.
Goal
eyes2 previously had only deterministic demo controllers (random, noop, looker) and never implemented the evolutionary logic of the original 1999 eyes C++ project. Add that as a drop-in Genotype plugin so creatures evolve, plus the original's code tooling (assembler/disassembler/inspector).
Placement: fill in the existing giles / sigil 'G' genotype stub.
Vision: use eyes2's existing single adjacent-cell Look vision (cached, refreshed after each move) — keep the change contained to the plugin. (Original read 4 cells deep per direction.)
Genome = 1000 random bytes interpreted as byte-code for a VM, one instruction per world tick().
12 instructions: LOADC, LOADV, ANDV, ORV, JZ, JNZ, MOVV, MOVC, NOP, SAVEV, ADDV, SUBV (values must match the original; see eyes/Engine.h).
State: accumulator r (u16, wrapping = original WORD), 5 I/O registers I1..I5, instruction pointer.
Readable variables (18): V1..V8 (8 cached Look cells, encoded empty=0/grass=1/entity=2/wall=4), E, X/Y (dead-reckoning, internal signal), B breed threshold, M mutation rate, I1..I5.
16-bit constants little-endian; JZ/JNZ targets relative to the instruction's own address; genome access wraps % CODE_SIZE.
Reproduction: world (Creature::reproduce) splits energy; genotype halves its own energy estimate (gates re-breed, like random.rs). Mutation probability = evolvable mutation_rate%; per-byte flips + roving copy point (gene duplication); breed_after/mutation_rate evolve and are clamped (rate ≥ 1).
Async Look: cache [Cell;8]; refresh by emitting Look the tick after each move (and first tick via pending_look).
PR #5 — the genome (branch claude/github-eyes-repos-tadi28)
VM unit tests; eyes2-lib/tests/evolution.rs headless experiment (#[ignore]d)
README / TODO / NOTES updated
Review fix: guard against samples == 0 division in the experiment (commit 7906431)
Tip: 7906431. CodeRabbit: no actionable comments (clean).
Headless result (40×40, 50 giles): grows ~50→106 at grass_rate=99, declines ~50→2 at grass_rate=80.
Run: cargo test --release -p eyes2-lib --test evolution -- --ignored --nocapture
PR #8 — the tooling (branch claude/giles-tooling, base = claude/github-eyes-repos-tadi28)
Stacked on #5. Discrete commits (current tip aa6d779):
37be56b Disassembler — refactor giles into a folder giles/{genotype,isa,asm}.rs; isa.rs is the single source of truth; asm::disassemble; GilesGenotype::disassemble(); public facade eyes2_lib::giles.
cdf81ee Assembler — asm::assemble (listing→bytes, comments/addresses/typed AssembleError); disassembler made boundary-safe so the two are exact inverses (property-tested); GilesGenotype::from_genome().
749527f TUI inspector — Genotype::inspect() (+ GenotypeInspect/InspectLine), Creature::inspect() → CreatureInspect on WorldGrid (serde-skip); World creature selection; GUI keys i (open/close), n/p (cycle), . (single-step); overlay shows registers + disassembly with active instruction marked.
aa6d779Review fix: restore genotype config after load — added set_config() to the Genotype trait (default no-op), forwarded from Creature::set_config (called per creature in store.rs load), implemented for giles/random/looker/noop, with a test. Fixes a project-wide latent bug (config was #[serde(skip)], reset to default on load).
Verification: cargo build --release ✅; cargo test ✅ (22 lib tests; 2 evolution tests ignored); clippy clean for all new code.
⚠️ The curses TUI can't run headless, so the inspector is build/clippy/test-verified only (not visually exercised). The asm/disasm core is unit tested.
Original features still not ported: carnivores/fighting, ranged (4-deep) vision, and an in-GUI genome editor + breakpoint debugger (the disassembler/inspector cover viewing; author/seed creatures via assemble + from_genome).
Tracking + recovery document for the eyes2 evolutionary-genome work. Captures the plan, decisions, current state, and how to resume in a fresh session. Last updated after addressing PR review comments — see "Session state" at the bottom for the live status.
Goal
eyes2 previously had only deterministic demo controllers (
random,noop,looker) and never implemented the evolutionary logic of the original 1999eyesC++ project. Add that as a drop-inGenotypeplugin so creatures evolve, plus the original's code tooling (assembler/disassembler/inspector).Decisions (locked)
giles/ sigil'G'genotype stub.Lookvision (cached, refreshed after each move) — keep the change contained to the plugin. (Original read 4 cells deep per direction.)gilescreature controller #5, as discrete commits (disassembler, then assembler, then TUI inspector).Design (how the port maps to eyes2)
tick().LOADC, LOADV, ANDV, ORV, JZ, JNZ, MOVV, MOVC, NOP, SAVEV, ADDV, SUBV(values must match the original; seeeyes/Engine.h).r(u16, wrapping = originalWORD), 5 I/O registersI1..I5, instruction pointer.V1..V8(8 cachedLookcells, encoded empty=0/grass=1/entity=2/wall=4),E,X/Y(dead-reckoning, internal signal),Bbreed threshold,Mmutation rate,I1..I5.JZ/JNZtargets relative to the instruction's own address; genome access wraps% CODE_SIZE.Creature::reproduce) splits energy; genotype halves its own energy estimate (gates re-breed, likerandom.rs). Mutation probability = evolvablemutation_rate%; per-byte flips + roving copy point (gene duplication);breed_after/mutation_rateevolve and are clamped (rate ≥ 1).Look: cache[Cell;8]; refresh by emittingLookthe tick after each move (and first tick viapending_look).PR #5 — the genome (branch
claude/github-eyes-repos-tadi28)eyes2-lib/src/entity/genotype/genotypes/giles/genotype.rs(wasgiles.rs; folder split happened in PR Add giles assembler, disassembler and a TUI inspector #8)eyes2-lib/tests/evolution.rsheadless experiment (#[ignore]d)samples == 0division in the experiment (commit7906431)7906431. CodeRabbit: no actionable comments (clean).grass_rate=99, declines ~50→2 atgrass_rate=80.Run:
cargo test --release -p eyes2-lib --test evolution -- --ignored --nocapturePR #8 — the tooling (branch
claude/giles-tooling, base =claude/github-eyes-repos-tadi28)Stacked on #5. Discrete commits (current tip
aa6d779):37be56bDisassembler — refactorgilesinto a foldergiles/{genotype,isa,asm}.rs;isa.rsis the single source of truth;asm::disassemble;GilesGenotype::disassemble(); public facadeeyes2_lib::giles.cdf81eeAssembler —asm::assemble(listing→bytes, comments/addresses/typedAssembleError); disassembler made boundary-safe so the two are exact inverses (property-tested);GilesGenotype::from_genome().749527fTUI inspector —Genotype::inspect()(+GenotypeInspect/InspectLine),Creature::inspect()→CreatureInspectonWorldGrid(serde-skip);Worldcreature selection; GUI keysi(open/close),n/p(cycle),.(single-step); overlay shows registers + disassembly with active instruction marked.aa6d779Review fix: restore genotypeconfigafter load — addedset_config()to theGenotypetrait (default no-op), forwarded fromCreature::set_config(called per creature instore.rsload), implemented for giles/random/looker/noop, with a test. Fixes a project-wide latent bug (config was#[serde(skip)], reset to default on load).cargo build --release✅;cargo test✅ (22 lib tests; 2 evolution tests ignored); clippy clean for all new code.main.How to resume in a fresh session
git fetch origin. Branches:claude/github-eyes-repos-tadi28(PR Add evolving RISC genome as thegilescreature controller #5, tip7906431) andclaude/giles-tooling(PR Add giles assembler, disassembler and a TUI inspector #8, tipaa6d779, stacked on Add evolving RISC genome as thegilescreature controller #5).gilescreature controller #5 first, then retarget Add giles assembler, disassembler and a TUI inspector #8 tomain(or merge Add evolving RISC genome as thegilescreature controller #5 into the stack first) and land Add giles assembler, disassembler and a TUI inspector #8.cargo testgreen on each.subscribe_pr_activityfor Add evolving RISC genome as thegilescreature controller #5 and Add giles assembler, disassembler and a TUI inspector #8. Notesend_lateris NOT available in this environment; use a background self-check (e.g. a persistent Monitor emitting hourly) to catch merges/conflicts that webhooks don't deliver. There is no GitHub Actions CI — CodeRabbit is the only check.Follow-up / not in scope
giles.assemble+from_genome).Key references
eyes2-lib/src/entity/genotype/genotypes/giles/(genotype.rs,isa.rs,asm.rs)eyes2-lib/src/entity/genotype/genotype.rs; creature driver +CreatureInspect:eyes2-lib/src/entity/creature.rs; selection/inspection + load:eyes2-lib/src/world/world.rs,eyes2-lib/src/world/store.rs; GUI:eyes2/src/gui.rs, loop:eyes2/src/main.rseyes/engine.cpp(VM +DisAssemble/Assemble),eyes/guts.cpp(MutateAnimal/BreedHerbivore),eyes/Engine.h+eyes/guts.h(defines),eyes/CodeEdit.cpp+eyes/Twiddle.cpp(original editor/debugger UI).Session state (as of last update)
gilescreature controller #5 (genome, tip7906431) and Add giles assembler, disassembler and a TUI inspector #8 (tooling, tipaa6d779). Both green, clean working tree, pushed.gilescreature controller #5; config-restoration on Add giles assembler, disassembler and a TUI inspector #8). CodeRabbit reports no actionable comments on Add evolving RISC genome as thegilescreature controller #5; Add giles assembler, disassembler and a TUI inspector #8 not auto-reviewed (stacked).gilescreature controller #5 and Add giles assembler, disassembler and a TUI inspector #8. A fresh session must re-subscribe_pr_activityto keep watching.gilescontroller #7 (recovery doc).gilescreature controller #5 then Add giles assembler, disassembler and a TUI inspector #8, or start Add a second, modernised evolvable genotype (non-byte-code design) #6. Nothing is blocked.