Wildfire separates simulation authority from host integration. There is one authoritative GPU simulation path.
Wildfire.Coreowns packed cells, grid helpers, deterministic fixture hashing, change records, delta records, and GPU simulator contracts.Wildfire.Cliowns seeded scenario preview and fixture input inspection.Wildfire.Unityowns compute buffers, HLSL rule translation, shader dispatch, compact delta readback, and GPU visual fields.Wildfire.Timberbornowns terrain/building/resource/water adapters, event registration, overlay updates, pooled effects, alerts, burn damage, ash adapter services, beaver exposure, contamination interaction, persistence, and gameplay consequences.
- Hosts call
RegisterChange; they do not mutate cells directly. - Listeners may register changes, but those changes apply on the next tick.
Wildfire.Coredoes not reference Unity or Timberborn.- GPU visuals may be driven by simulation buffers, but gameplay changes flow through C# deltas.
- Fire spread rules live in compute shaders, not in a second C# execution path.
- Fire does not reduce contamination. Contamination-aware effects are Timberborn-side consequences of simulator fields and deltas.
- Ash is simulator-owned transport state; ash presentation and Timberborn gameplay adapters read or queue changes against that state.
- Fire and smoke visuals are field-based presentation, not one effect object per tile.
Wildfire.Timberborn owns release-facing compatibility probes for Timberborn APIs, Unity capabilities, and adapter-owned asset paths. The probe layer is evidence-only: it checks service/member availability, compute support, private compute/diagnostic bundles, native effect prefab availability, and quick-notification access, then logs whether each release-facing feature is compatible, degraded, or failed. It does not own fire rules, mutate the grid, or install a fake simulator fallback.
Required terrain and compute failures stop the real compute-backed runtime path and surface as compatibility_probe_status=failed; the runtime logs wildfire_timberborn_runtime_initialization_blocked, rejects initialization, and qa-readiness reports loaded_game_ready=false even if other status fields are present. Optional feature failures, including building-burnout consequence APIs, native visual-effect prefabs, quick notifications, and diagnostic bundles, surface as compatibility_probe_status=degraded with compatibility_probe_degraded_features=<tokens>, so QA can distinguish a playable-but-degraded adapter from a release failure state. Reflection belongs behind this probe boundary when Timberborn has no stable public surface for a version-sensitive member; gameplay code should consume public services directly after the probe evidence is logged.
Host map/events
-> FireSimChange queue
-> GPU fire sim dispatch
-> packed cells, visual fields, and CellDelta list
-> host listeners
-> overlays, effects, damage, ash fields, beaver exposure, alerts
The repository currently has a core simulation contract with:
PackedCellFireGridFireRandomIGpuFireSimulatorGpuFireStepResultCellDeltaFireSimChangeIFireSimListener
Unity owns the compute-facing execution path, and Timberborn owns adapter-facing runtime integration. For concept-to-file navigation, use source-map.md.
Wildfire.Unity owns ComputeBufferGrid, the first GPU-side allocation boundary. The grid records width, height, depth, and checked cell count, then allocates named buffers for current cells, next cells, queued changes, delta output, generation state, and visual fields.
Initial fixture-style ushort packed cells are uploaded to current and next cell buffers as uint values. The packed cell payload remains in the lower 16 bits, leaving the upper bits available for future GPU-side bookkeeping without changing the core PackedCell contract.
The grid also allocates material field buffers beside packed cells:
wildfire.material_target_idsstores one stable target id per cell for imported world ownership.wildfire.material_fieldsstores one packed 32-bit material state per cell: material class, burn capacity, burn history, ash strength, ash quality, and contamination behavior.
Default initialization uploads empty material state for every cell. Real importers replace that default with material and target data, while shader and renderer follow-up tickets decide which material fields are consumed on GPU. Shader property names may still use CompanionFields while asset bundles and harness fixtures keep their compatibility spellings.
FireSimParameters is the runtime tuning contract for the compute path. It lives in Wildfire.Core, is carried through FireSimComputeDispatch, is bound by the Timberborn compute simulator before each kernel dispatch, and has default values that preserve the accepted release-tuning behavior. The object covers visual field weights, ignition, spread, water suppression, burn pressure, fuel burn-down, deterministic burn-roll seed, and heat-loss cooling behavior. CPU mirrors such as FireVisualField consume the same contract so deterministic tests can prove a non-default preset changes field output before live Timberborn validation.
The plain solution build does not reference UnityEngine APIs yet. Buffer allocation therefore flows through IComputeBufferAllocator and IComputeBufferHandle, so Unity can later provide real compute-buffer handles while tests use deterministic recording handles. Fire-spread rules are still owned by future compute shaders, not by the C# scaffold.
Wildfire.Timberborn owns the first adapter-side mapping boundary through TimberbornFireCellMapper and narrow terrain, building, resource, and water source adapters. The mapper accepts Timberborn-facing observations, groups them by FireGrid index, and produces either initial packed cells or sorted FireSimChange records with SetCell populated.
The mapping is deterministic and intentionally rule-free:
- Empty cells pack as no terrain, no fuel, no water, and maximum heat loss.
- Terrain contributes solid material with no fuel, no flammability, and high heat loss.
- Resource adapters expose deterministic stockpile and vegetation fuel bands before packing.
- Building adapters expose deterministic wood-like and non-burnable material bands.
- Buildings have material priority over resources and terrain for the same cell; non-burnable buildings still occupy terrain cells but pack no fuel or flammability.
- Water and terrain wetness contribute only to the packed water field, clamp to the water field width, and do not overwrite material.
- Multi-cell and vertical occupancy expands through
TimberbornCellFootprint, emitting one source per coveredx,y, andzcell before the mapper sorts byFireGridindex. - Inputs are clamped to the packed-cell field widths before packing.
Timberborn systems should use this layer to translate game state, then register changes through IGpuFireSimulator.RegisterChange. The Timberborn project still does not own fire-spread rules or mutate Unity/GPU buffers directly.
Wildfire.Core owns the versioned material field contract used by both live Timberborn import and offline .timber snapshot export. The current v1 schema lives in code as WildfireMaterialFieldSchema and as the shared fixture src/Wildfire.Core/MaterialFieldSchema.v1.json.
The schema classifies observed map inputs into material classes before they become packed simulation cells or material fields:
- Empty.
- Terrain.
- Vegetation.
- Crop.
- Tree.
- Building.
- Storage.
- Infrastructure.
- Water.
- Badwater.
- Unknown.
Each profile defines the packed fuel, flammability, heat loss, terrain bit, water band, burn capacity, consequence target kind, ash quality, contamination behavior, and resource policy. Packed bands remain small and deterministic; resource-specific detail still flows through adapter catalogs such as TimberbornResourceFuelCatalog.
Unknown materials fail closed. They do not invent fuel, burn capacity, consequence targets, or clean aftermath. This is deliberate: importer gaps should become explicit telemetry and ticket failures instead of another layer of fake fuel.
Timberborn consequence services consume compact deltas and visual or exposure samples after a simulator tick. They may register follow-up FireSimChange records, but those changes apply on the next tick.
The field visual presentation service owns fire, smoke, steam, and ash presentation from simulator fields. It should use compact deltas to bound the regions that need updates, then sample neighboring field intensity to produce larger coherent effects.
Responsibilities:
- Cluster, blur, threshold, or otherwise aggregate adjacent fire and smoke intensity into convincing regions.
- Maintain bounded pooled anchors, meshes, particles, or material-driven volumes rather than one effect object per cell.
- Scale visual presentation by sampled intensity, spread, field shape, and region size.
- Keep visual presentation failures isolated from gameplay consequences.
- Render ash from simulator-owned ash state without creating, projecting, or mutating ash.
The burn damage service owns persisted burn state for live Timberborn entities. Static burn descriptors can be attached to spec-backed objects such as buildings, harvestables, and cuttables, but damage is per instance.
The foundation boundary is:
- Static
TimberbornBurnDamageDescriptorrecords describe target kind, material kind, yielded resources, and construction-resource investment for a spec-backed Timberborn object. TimberbornBurnDamageService.RegisterTargetsbinds stable target identities to owned simulation cells after the adapter resolves a Timberborn entity footprint. Multi-cell and vertical targets are rolled up to one target key.- The service resolves changed simulation cells from
TimberbornFireCellDeltaDecisionback to a single owner, suppresses duplicate hits from the same target footprint during one dispatch, and applies bounded per-instance damage. - Damage capacity is derived from known resource yield or construction investment through
TimberbornResourceFuelCatalog. Unknown resource ids are recorded as missing and contribute no capacity so downstream consequences fail closed. - State snapshots capture target key, spec id, capacity, resource-accounting fields (
FuelValue,Flammability, andAccountedResourceIds), damage taken, last damaged tick, owned cell indices, and unresolved resources. - Telemetry is emitted through
wildfire_timberborn_burn_damage_targets_registeredandwildfire_timberborn_burn_damage_applied, while the existing delta-consumer summary exposes optional burn-damage sink counts without making Timberborn own fire-spread rules.
Responsibilities:
- Resolve changed simulation cells back to owning buildings, plants, crops, trees, stockpiles, or resources.
- Roll up multi-cell and vertical footprints into one damage target without duplicate damage.
- Track damage capacity from resource yield or construction-resource investment.
- Apply resource-specific fuel and flammability tuning.
- Leave crop death, tree death, structure rollback, inventory destruction, explosive behavior, ash, fertility, beaver effects, and player feedback to downstream consumers of this state.
- Persist burn damage state across save/load once downstream tickets bind real Timberborn entity persistence.
The stored goods burn service owns inventory-content loss caused by fire. It is separate from the burn damage service because storage contents are goods, not construction state.
Responsibilities:
- Resolve stockpiles, warehouses, tanks, and other storage entities from changed simulation cells.
- Use the shared resource fuel and flammability catalog for burnable goods.
- Destroy stored items only through Timberborn inventory APIs.
- Keep inventory loss separate from structural damage to the storage building.
- Route explosives or volatile goods through a bounded hazardous-good behavior before broader blast mechanics are considered.
- Expose counters for item loss by resource, skipped non-burnable goods, and hazardous goods.
Ash adapter services consume simulator ash deltas and queue bounded ash mutations from Timberborn actions. They do not own a second ash source of truth.
Responsibilities:
- Keep CPU-side persistence, status, collection, and fertility consumers synchronized from simulator ash deltas or readback.
- Treat uncontaminated ash as fertile for gameplay purposes and contaminated ash as hazardous.
- Queue
FertileAshapplication and ash-removal actions for the next simulator cycle. - Prevent contaminated ash from producing a fertility bonus unless a future decontamination mechanic explicitly allows it.
- Fade tainted ash over time and wash it away through water-contact mutations only through simulator-owned ash state.
- Treat water tainting from washed tainted ash as a bounded Timberborn adapter mutation through the supported water-contamination mutation path.
- Preserve simulator ash state across save/load.
- Expose collection hooks so beavers can gather uncontaminated ash as
FertileAshand place it in fields.
The beaver exposure service translates fire, heat, smoke, clean steam, ash, and contamination-adjacent fields into beaver-facing effects. It should be built as an evidence ladder: exposure telemetry first, then debuffs, then incapacitation, then death.
The service reads sampled simulator fields and compact-delta-driven field summaries. It does not write packed cells and does not infer alternate spread rules. Timberborn-owned behavior adapters can cancel hazardous work, apply native status effects, and change path costs.
Respiratory progression:
- Coughing: slowdown and work inefficiency.
- Choking: sleep-like or incapacitated state.
- Death: sustained severe exposure after avoidance and status behavior are proven.
Burn progression:
- Singed: injury-style debuff.
- Burned: contamination-like severe injury that prevents work until healed.
- Death: sustained direct heat or flame.
The service should cancel or interrupt hazardous work, increase path costs or avoidance where Timberborn supports it, and aggregate danger telemetry for player feedback. It should reuse native injury, sleep, contamination, treatment, and death.
Release scope is telemetry, avoidance/work interruption, coughing, singed, burned behavior, and fertile ash collection. Choking, death, native badwater contamination coupling, and faction response.
Future faction fire-response services should translate staffed buildings, beaver actions, and player-built defenses into simulation inputs. They must not own fire rules or mutate the simulation grid directly.
Responsibilities:
- Convert Fire Warden sprayer output, bucket dumps, tail-stamping, fans, or berms into explicit water, suppression, airflow, or spread-resistance changes.
- Register those changes for the next simulator tick through the existing change path.
- Keep faction-specific labor, cost, equipment, and injury behavior in Timberborn adapter services.
- Reuse beaver exposure and player feedback services for injury risk, alerts, and telemetry.
- Keep future suppression visuals field-based where they overlap fire, smoke, steam, or ash fields.
Contamination stays a Timberborn-owned environmental and status concern. The simulator can consume contaminated fuel through ordinary packed fuel, water, heat, and flammability inputs, but it does not cleanse contamination or store contamination state in PackedCell.
Timberborn consequence services should apply these rules:
- Contaminated burnable material can burn and can produce toxic smoke or tainted ash.
- Contaminated water or badwater can suppress fire but does not become clean water.
- Contaminated soil remains contaminated after fire.
- Ash on contaminated soil is tainted rather than fertile.
- Tainted ash can fade or wash away, but washing it should slightly taint water.
- Contaminated beaver exposure can combine respiratory or burn progressions with native badwater contamination if the API path is validated.
Rare spontaneous ignition is adapter input, not a second fire rule in Timberborn. Timberborn-facing services can classify fire-using buildings, dead vegetation, and drought-dry vegetation as ignition candidates, then pass deterministic candidate data into the simulator or queued change path. Ordinary non-fire buildings must not become spontaneous ignition candidates.
Responsibilities:
- Use deterministic hash-based rolls keyed by cell, tick, seed, and drought or material state.
- Keep default ignition probability rare and settings-tunable.
- Increase risk only for eligible fire-using buildings or dry dead vegetation.
- Reduce or suppress risk for wet, irrigated, or water-suppressed cells.
- Report candidate, roll, ignition, and skipped-ineligible counters for player feedback and QA.
Feedback systems should aggregate world consequences instead of emitting one alert per affected cell or entity. The alert and status lane should separately report active fire, building damage, plant or resource loss, beaver danger, and ash aftermath when those states become gameplay-relevant.