Lantern fuel — scope investigation, not implementation authorization #
Status: research complete; exact wiring plan pending. Baseline 757962b accepted Tinker. No runtime/config/content changes made. Full HEXWORK1.0 remains incomplete.
Problem #
Production stores/hashes item fuel and displays the lowest-ID carried lamp, but actual lighting uses an independent player light source. spend_fuel has no production caller. Refilling a number without burn/extinction would be cosmetic; do not ship it as functional oil use. Item prose is not an effects interpreter.
Source evidence (current investigation): core/light.rs:44–55 LightSource has position/radius/warm but no owner; core/state.rs:2262–2269 light phase consumes sources, not item fuel; cli/session.rs:1034–1047 creates standalone player light, :3222–3226 syncs lights[0] position. Item fuel, light sources and voxel light contribute to canonical state hashes. core/item.rs:411–426 spend_fuel changes final-unit condition to Spent. Full step and unattended Inn advancement differ (core/state.rs:1717–1735); any cadence must specify both.
Compatibility decision not yet made by operator #
Parent asked whether to introduce a new version rejecting old recordings, preserve v4 execution, or defer. The structured question could not reach the unavailable operator during unattended goal continuation. No answer/approval was received. Prior preference for current Rust over old-toolchain maintenance does not automatically authorize breaking player saves/replays.
Conservative planning assumption: preserve v4 while proposing new fuel semantics for new runs. This is a proposal, not an indefinite support promise or implementation handoff. An adversarial independent read-only review found it technically feasible; user absence is not itself a technical block. Do not falsely mark the entire goal blocked or complete.
Why a semantics contract is necessary #
Run/replay globals currently4 (save/protocol.rs:53–56), headers carry format/hash versions but gates accept only current values (:777–780,1428–1452). RunIdentity (:567–579) and StateImage (core/checkpoint.rs:46–91) have no semantics selector. Replay reconstructs via Session::from_identity; State::from_image recomputes hashes. A CLI-only flag would disappear across checkpoint/image/replay boundaries. Canonical v4 prefix/domains must remain byte-identical for legacy states, not gain an extra flag.
An explicit Refuel action does not solve automatic burn compatibility: old ticks would still change. First-refill implicit activation is a hidden semantics transition and leaves default lamps artificially infinite; reject that shortcut.
Candidate conservative architecture #
- Closed immutable runtime semantics enum LegacyV4/FuelV5, carried through State, StateImage, identity, checkpoints, resurrection, recovery and replay reconstruction.
- Preserve exact v4 wire layout/encoder/decoder and canonical hash stream. Validated v4 format/hash pair selects LegacyV4. Loaded v4 continues and exports as v4; no silent migration.
- New supported envelope/hash pair selects FuelV5. No redundant serialized selector required if header pair uniquely determines it, but all reconstructed runtime/image boundaries must retain and validate semantics consistency.
- Dispatch before initial kit/light creation, not only during ticks. Legacy keeps current source initialization/movement/no-burn/unattended behavior. New hash prefix and fields cover all future-affecting lamp state.
- Share unchanged code; explicitly branch only changed simulation behavior. This still adds permanent codec/selector/regression costs, not just an enum.
Exact decisions needed in the next wiring plan #
- Which carried instance owns light; multiple lamps, pickup/drop/death, whether dropped lamps stay lit, and treatment of non-lamp callings.
- Fuel units/capacity/rate and cadence ownership; full-step phase order and unattended sleep behavior. Define replenishment of Spent condition honestly.
- Light invalidation on movement/extinction/refuel; do not leave old voxel illumination or replace environmental sources via lights[0].
- Exact selected lamp+oil instance action, consumption/capacity/rejection and atomic save/event handling. No generic uses interpreter or oil sale without functioning effect.
- Header/version support table and selector flow through every constructor/wire conversion. No silent upgrade, mutation or deletion of old artifacts.
- New-run default and intended future support/migration policy must be stated as proposed choices, not alleged operator approval.
Required evidence before acceptance #
Separate compatibility plumbing and actual gameplay slices in the dependency graph. Inventory affected constructors/serializers first, then review exact plan before writers. Test genuine v4 decode/reencode/replay hashes plus resumed/exported continuity; unknown/mismatched version pairs rejected; new default fuel consumption, refill, depletion/extinction, multiple-lamp/drop/light-cache and sleep semantics deterministic; save/checkpoint/replay reconstruct same future behavior. Use ordinary starter content/process inputs, focused opt1 checks and one frozen checkpoint per development-validation.md. Preserve existing fixture files and provenance. No additional old-Rust matrix.
Constructor and wire inventory (read-only follow-up) #
These are current symbols, not implemented new APIs. Line anchors refer to gameplay baseline757962b and may shift. No LegacyV4/FuelV5 selector or RunIdentity constructor methods exist today; identity construction uses struct literals.
| Boundary | Current symbols / source anchors | Required consideration in proposed versioned design |
|---|---|---|
| Core construction | State, State::new(seed), state.rs147–176,401–451 |
Explicit immutable semantics before initialization; no silently changed existing caller defaults. |
| Full versus unattended time | State::step, phase_light, preflight_unattended, advance_unattended, spend_copper_and_advance_unattended, state.rs1717–1815,2262–2269 |
Separate specified burn behavior; retain legacy spatial omissions and paid-time atomicity. |
| Images | StateImage, checkpoint.rs46–87; State::to_image/from_image, state.rs2484–2693 |
Selector survives all reconstruction and is validated, not defaulted. |
| Hashing | CANONICAL_HASH_VERSION, try_hash_state, state.rs260–265,2696–2860 |
Exact legacy prefix/domain stream; new hash contract includes new future-affecting state. |
| Identity | RunIdentity, identity_to_wire/from_wire, protocol.rs567–579,1525–1560 |
Immutable reconstruction input, no CLI-only selector lost during replay. |
| Envelopes/wire | EnvelopeHeader, RunWire, ReplayWire, RunIdentityWire, protocol.rs774–814; version gates1409–1453 |
Preserve v4 layout; validated format/hash pair may infer selector, then materialize it in runtime/image boundaries. |
| Run codecs | encode_run/decode_run, protocol.rs1222–1283 |
Version-dispatch codec and validate identity/current/checkpoint consistency. |
| Replay codecs | encode_replay/decode_replay, protocol.rs1286–1336; entry.rs683–710 |
Replay has identity/events, no state snapshot; semantics must reach bootstrap before any tick. |
| Hashed images | HashedState, hashed_state_to_wire/from_wire, validate_hashed_image, protocol.rs581–620,1756–1819 |
Image→State recomputes hash; selector cannot live only on decoder. |
| Checkpoints | StoryCheckpoint, protocol.rs623–628,1788–1804; build_checkpoint, session.rs2335–2364 |
Same semantics throughout checkpoint creation, prefix proof and resurrection. |
| New/resumed sessions | app.rs372–419 identity literal; from_identity, session.rs995–1079; from_decoded,1917–1958 |
New bootstrap creates kit/standalone light; resume reconstructs decoded state directly. Both must be explicit. |
| Source movement/resurrection | sync_player_light*, session.rs3214–3227,4260–4268; resurrection2278–2297 |
Legacy index0 behavior versus new owned lamp source and invalidation. |
| Replay/time/lifecycle | session.rs2060–2341,3597–3647; Inn3481–3503; app budget1868–1872 | Full idle ticks, unattended Inn time and checkpoint restoration all preserve selector/timeline. |
| Durable artifacts | save/artifact/mod.rs1299–1324,1729–1737 codec consumers | Coordinate downstream save/replay identity construction and validation. |
Core owns State/image/light/item and must not gain a content dependency: content already depends on core. Save owns identities/hashed states/wire/codecs and depends on core/content. CLI owns startup/replay/lifecycle and presentation. Core and Save workers may only proceed with frozen shared signatures; CLI follows their interface checkpoint. Do not assign overlapping state/image/protocol/session constructor changes to independent workers.
Existing oracle targets (not rerun during this inventory): Save genuine_pretransfer_v4_fixtures_decode_and_reencode_identically and genuine_v3_run_replay_fixtures_reject_before_v4_body_parse; immutable Classic/Story v4 run fixtures and v4 replay plus provenance. Core same_seed_same_hash, full_tick_mutates_and_hashes, unattended_advance_matches_empty_world_clock_scope, unattended_advance_overflow_is_atomic. CLI exact_run_restore_retains_state_history_and_continuation, mixed_replay_reconstructs_same_tick_actions_idle_gaps_and_terminal_hash, inn_service_charges_unattended_work_before_dispatch, resume_resurrection_export_replay_matches, repeated_resurrection_keeps_ordered_history_and_active_checkpoint_reference, resurrection_continue_export_replay_matches, story_death_restores_town_checkpoint_and_can_repeat, deep_to_town_refreshes_checkpoint_after_transition_event, v4_replay_preserves_latest_story_checkpoint_reference. These existing tests do not certify a proposed selector or fuel system.
Research itself does not certify a fuel mechanic or authorize broad compatibility implementation. Next useful work is a bounded exact version/lantern wiring plan, then independent review and any remaining operator-owned decision.