217 lines
13 KiB
Markdown
217 lines
13 KiB
Markdown
# Aetheria.State
|
|
|
|
`Aetheria.State` is the replacement owner for durable Aetheria game state.
|
|
|
|
It uses modern `GameCult.Caching`, `GameCult.Caching.MessagePack`, and
|
|
`GameCult.Mesh`. It does not reference the old `Assets/Scripts/ServerShared`
|
|
tree, RethinkDB, JsonKnownTypes, or Newtonsoft.Json.
|
|
|
|
The first live state file is `GameData/aetheria-world.cc`. It is generated by
|
|
`Aetheria.State.Import` from checked-in legacy catalog inputs without embedding
|
|
machine-local absolute paths. Legacy files such as `GameData/AetherDB.msgpack`
|
|
are migration inputs only.
|
|
|
|
The typed runtime state model is split into player settings, loadout templates,
|
|
run state, zone state, entity snapshots, item slots, weapon groups, action-bar
|
|
bindings, and stat grids. Player settings include player name, tutorial flag,
|
|
story-file hash cursors, gameplay formatting, graphics preferences, input
|
|
binding overrides, and action-bar inputs. Do not preserve `SavedGame`, Unity
|
|
runtime settings projections, or runtime entity blueprints as opaque payloads in
|
|
the new store; they are source shapes for projection, not portable state
|
|
authority.
|
|
|
|
The Unity client no longer writes `PlayerSettings.msgpack`, `.loadout`, or
|
|
`.zone` files. `AetheriaPlayerSettings` is the typed Verse replacement for
|
|
`PlayerSettings.msgpack`, and `AetheriaLoadoutTemplate` is the typed Verse
|
|
replacement for bespoke loadout files, with structured hull/equipment/cargo/
|
|
docking item slots, nested child-entity loadouts, and weapon groups.
|
|
`RuntimePlayerSettings` is the Unity session projection for menus, formatting,
|
|
and input binding edits; menu and input-screen changes queue typed
|
|
`.cc.pending` player-settings commits and are not portable state authority.
|
|
Unity settings, loadout templates, and run checkpoints now queue typed
|
|
`.cc.pending` runtime commit envelopes beside
|
|
`GameData/aetheria-world.cc`. `Aetheria.State` owns applying those envelopes
|
|
into canonical typed state through `AetheriaRuntimeCommitLogApplier`; the
|
|
Unity-side command log is command-only and cannot become durable truth by
|
|
itself.
|
|
Unity Eve surfaces also emit `gamecult.eve.command.v1` envelopes under
|
|
`GameData/aetheria-world.cc.eve.pending`. `AetheriaEveCommandBridge` is the
|
|
provider-owned acceptance organ for those commands: it validates the provider,
|
|
surface, and command template before running the narrow refresh handlers for
|
|
the catalog and operations surfaces. Renderer callbacks do not accept commands
|
|
or mutate game state locally.
|
|
The old `SavedGame`/`SavedZone` DTOs and `Galaxy` loader constructor have also
|
|
been deleted; the new document family is live Verse run/zone state, not a
|
|
bespoke save-file format.
|
|
The dead `SavedStory` JSON DTO is gone. `RuntimeZoneBlueprint` and
|
|
`RuntimeEntityBlueprint` remain in-memory construction/loadout projections for
|
|
Unity runtime code, with `RuntimeEntityBlueprintProjector` capturing and
|
|
instantiating those projections. They no longer carry save-file or serializer
|
|
vocabulary, and they do not declare MessagePack persistence attributes.
|
|
|
|
Keyboard layout rendering now builds the static ANSI-104 display as typed
|
|
`InputLayout` rows and columns. It no longer reads a checked-in JSON text asset
|
|
or uses `SimpleJson` for display geometry. The generated `AetheriaInput` wrapper
|
|
still calls Unity's `InputActionAsset.FromJson`; that is an engine-owned
|
|
lowering boundary under Aetheria's remapping layer, not a save format or state
|
|
owner. The old generated `GameData/KeyboardLayouts/*.msgpack` cache and the
|
|
checked-in `ansi104.json` display file are deleted. Remapping and action-bar
|
|
edits are owned by typed `AetheriaPlayerSettings` commits; keyboard display
|
|
layout edits remain runtime-only until Verse owns a typed layout document.
|
|
|
|
The old IMGUI CultCache database editor has been deleted, and `NameTools` no
|
|
longer exports `NameFile/*.msgpack`. `AetherDB.msgpack` and existing name files
|
|
remain legacy catalog inputs only; typed catalog records are the durable owner.
|
|
Dead legacy catalog roots for user records and galaxy map-layer resources have
|
|
been deleted from live Unity source. Surviving runtime DTOs no longer carry
|
|
legacy catalog group/table annotations; their remaining metadata is projection
|
|
and inspection metadata for the typed runtime bridge.
|
|
Item instances now carry `RuntimeItemReference`, a narrow item-definition id plus
|
|
optional hydrated projection cache. The old generic `RuntimeCatalogLink<T>`
|
|
abstraction has been deleted; item data projection is routed through
|
|
`ItemManager` and a runtime item projection reader over the typed catalog.
|
|
`Projection` is not durable state; it is a bridge for surviving simulation and
|
|
UI code. The remaining single-item bridge is named `GetRuntimeItemProjection<T>`,
|
|
not catalog entry access.
|
|
Loadout generation now applies typed catalog prefilters for item category,
|
|
hardpoint type, shape fit, hull type, and behavior kind before hydrating legacy
|
|
`ItemData` projections for final simulation compatibility.
|
|
The surviving trade menu also applies typed catalog prefilters for row size,
|
|
hardpoint type, and behavior kind before hydrating `ItemData` projections for
|
|
legacy commodity filters, columns, and buy actions.
|
|
Surviving item catalog Unity DTOs inherit `RuntimeItemProjectionEntry`; the old
|
|
`RuntimeCatalogEntry` base name no longer appears in live source. Temporary
|
|
faction/corporation projections and zone body/orbit DTOs keep local GUID fields
|
|
but no longer inherit the shared projection identity base.
|
|
The dead `InspectableRuntimeCatalogLinkAttribute` inspector metadata is gone;
|
|
typed runtime projection still uses `LegacyPayloadKeyAttribute` only where the
|
|
temporary mapper needs a deterministic field order.
|
|
Agent task DTOs no longer inherit the item projection base; they are local
|
|
runtime AI work orders until a typed Verse task document exists.
|
|
|
|
`Aetheria.State.Import` captures the legacy catalog files into typed quarantine
|
|
state: path, size, and SHA-256 fingerprint for `AetherDB.msgpack` plus
|
|
`NameFile/*.msgpack`, and a migration ledger update. It also performs a bounded
|
|
raw MessagePack union pass that maps stable catalog fields into typed
|
|
item/faction/name-file documents without compiling Unity's legacy domain model
|
|
into `Aetheria.State`. The current checked-in catalog maps to 115 item
|
|
definitions, 12 factions, and 12 name files. Typed item definitions include
|
|
legacy manufacturer IDs, price, shape dimensions, occupied cell counts, full
|
|
shape-cell masks, interior shape masks for hull/cargo equipment, hull hardpoint
|
|
definitions, behavior kind fingerprints, typed recursive behavior payloads, and
|
|
stable equipment facets: hardpoint type, hull type, stack size, durability, and
|
|
weapon range/caliber/type/fire/modifier classifications.
|
|
Typed corporation documents include the legacy short name, the true description
|
|
field from key 3, name-file and boss-hull legacy IDs, influence distance,
|
|
allegiance count, full allegiance edges, and music bank IDs. Corporation
|
|
documents are `aetheria.corporation.v2` records because runtime generation
|
|
needs actual allegiance weights, not only display counts. Runtime object graphs,
|
|
typed behavior factory construction, and simulation state remain legacy until
|
|
dedicated typed runtime documents exist.
|
|
Typed name-file documents are `aetheria.name_file.v2` records. They carry the
|
|
legacy ID, display name, count, compact sample names for surfaces, and the full
|
|
name array needed to move `Galaxy`/Markov name generation off legacy
|
|
`NameFile.Names`.
|
|
Legacy GUID references that are `Guid.Empty` are imported as absent references,
|
|
not as resolvable catalog links.
|
|
Before materializing state, the importer clears the generated `.cc`,
|
|
`.cc.records`, and `.cultmesh` outputs for the selected state path. Legacy
|
|
catalog inputs are captured first and are not deleted. This lets schema changes
|
|
rebuild the typed artifact instead of failing on a stale embedded schema catalog.
|
|
|
|
`AetheriaCatalogSnapshot` is the typed read surface over materialized catalog
|
|
documents. It exposes trade items, legacy-ID lookup, manufacturer lookup,
|
|
corporation prefix lookup, corporation name-file lookup, equipment items,
|
|
behavior lookup, and hardpoint lookup without reading runtime projection DTOs.
|
|
|
|
`AetheriaCatalogSurfaceProjector` publishes the first Eve-compatible provider
|
|
surface from typed catalog state. The importer materializes
|
|
`gamecult.eve.surface.v1` at `eve:surface:aetheria.catalog.operator` with
|
|
summary, trade-catalog, and corporation views. This is a typed CultCache
|
|
provider document and a local mirror of the Eve contract until the shared Eve
|
|
Unity UI Toolkit lowering package exists.
|
|
|
|
`Aetheria.State.Unity` is the Unity-facing runtime read facade over typed state.
|
|
It opens `aetheria-world.cc`, emits immutable catalog read models for trade,
|
|
equipment, behavior, hardpoint, manufacturer, corporation, and name-file
|
|
queries, exposes typed item shape masks for layout and fitting consumers, and
|
|
exposes typed interior masks and hardpoints for equipment/cargo layout
|
|
consumers, exposes typed behavior payload read models, can read typed player
|
|
settings for Unity boot, and can read the published Eve catalog surface. It
|
|
does not deserialize legacy runtime projection objects and does not write state.
|
|
Unity can use this as the first package boundary once CultLib/Eve runtime
|
|
packaging is available.
|
|
`Galaxy` now consumes this package-owned runtime catalog for faction selection
|
|
and name generation, so generated sectors use typed corporation v2 and
|
|
`aetheria.name_file.v2` records instead of legacy `Faction`/`NameFile`
|
|
catalog documents. It still projects typed corporations into temporary
|
|
`Faction` DTOs, including allegiance dictionaries and local GUID equality,
|
|
because the surrounding simulation has not yet been rebuilt around typed
|
|
corporation records.
|
|
|
|
`Aetheria.State.Smoke` writes and reopens full typed player settings plus a
|
|
typed loadout template in addition to world, catalog, run state, zone state, and
|
|
an entity snapshot. The run smoke proves a typed run can reference a typed zone,
|
|
the zone can reference typed entity snapshots, and entity snapshots can preserve
|
|
equipment slots, weapon groups, and stat grids without reviving
|
|
`PlayerSettings.msgpack`, `.loadout`, or `.zone` serialization.
|
|
|
|
`Aetheria.State.Verify` opens a materialized state file and checks that the
|
|
typed migration ledger matches the actual item, corporation, and name-file
|
|
records in the `.cc` store. It also verifies the canonical legacy-ID lookup API
|
|
for one migrated record of each catalog kind, checks that name-file v2 records
|
|
carry their full name arrays, and checks that expanded item and corporation
|
|
catalog facts survived materialization. The verifier also exercises the typed
|
|
catalog snapshot query surface, shape-mask invariants, the typed behavior
|
|
payload tree, and the published Eve catalog surface. The current catalog
|
|
materializes 65 behavior payloads, 661 behavior fields, and 18 behavior-side
|
|
legacy-ID references. Legacy content currently includes at least one overhanging
|
|
hardpoint; the verifier preserves the payload and checks hardpoint local masks
|
|
rather than silently converting content repair into migration.
|
|
Use it after import when `GameData/aetheria-world.cc` changes.
|
|
|
|
`Aetheria.State.Unity.Smoke` opens the materialized state through the runtime
|
|
facade and proves read-only Unity-facing catalog access without the legacy
|
|
catalog reader. It also proves runtime commit envelopes for settings and run
|
|
zone/entity snapshots can be queued, applied through `Aetheria.State`, and
|
|
cleared.
|
|
|
|
`Economy.Server` opens the CultMesh state host, applies pending runtime commits
|
|
and pending Eve surface commands on startup, and polls for new pending work
|
|
while running. For a bounded one-shot drain without leaving the host running:
|
|
|
|
```powershell
|
|
dotnet run --project .\Economy.Server\Economy.Server.csproj -- --apply-pending-once
|
|
```
|
|
|
|
The server publishes `AetheriaRuntimeCommitDrainStatus`,
|
|
`AetheriaEveCommandDrainStatus`, and the `aetheria.operations` Eve surface after
|
|
drain attempts, so pending depth, accepted/applied/rejected counts, failures,
|
|
and timestamps are typed state rather than console-only status. It also
|
|
publishes `gamecult.eve.provider_advertisement.v1` for the `aetheria` provider,
|
|
advertising the catalog and operations surfaces plus the typed schemas witnessed
|
|
by the local `.cc` state file.
|
|
|
|
`Aetheria.State.ApplyPending` is the smaller local operator applicator for
|
|
queued Unity runtime commits and Eve commands when the server host is not being
|
|
used. It also republishes the typed drain status, operations surface, and
|
|
provider advertisement after applying pending files:
|
|
|
|
```powershell
|
|
dotnet run --project .\Aetheria.State.ApplyPending\Aetheria.State.ApplyPending.csproj -- .
|
|
```
|
|
|
|
Pass an explicit state path as the second argument when applying a non-default
|
|
`.cc` file. Use `--keep` only for diagnostics; normal application deletes
|
|
successfully applied command files.
|
|
|
|
Current rebuild notes:
|
|
|
|
- `MessagePack` 3.1.4 is pulled transitively through CultLib and is currently
|
|
flagged by NuGet advisory `GHSA-hv8m-jj95-wg3x`; update CultLib's
|
|
`GameCult.Caching.MessagePack` package ownership rather than adding a local
|
|
Aetheria override.
|
|
- `CultRecordRef<T>` should become the persisted reference shape once the
|
|
MessagePack source-generator path handles the GameCult formatter cleanly.
|
|
Until then, v1 profile documents store explicit record-key strings at the
|
|
persistence boundary.
|