Aetheria/Aetheria.State
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-06-14 12:31:20 +01:00
..
Documents Publish runtime sessions as typed state 2026-06-14 12:31:20 +01:00
Migration Add typed Verse save documents 2026-06-13 04:00:10 +01:00
Aetheria.State.csproj Use typed documents for Eve pending commands 2026-06-14 08:47:06 +01:00
AetheriaCatalogKeys.cs Centralize typed catalog legacy keys 2026-06-13 07:46:28 +01:00
AetheriaCatalogSnapshot.cs Expand typed item equipment migration 2026-06-13 09:01:13 +01:00
AetheriaCatalogSurfaceProjector.cs Expand typed item equipment migration 2026-06-13 09:01:13 +01:00
AetheriaDocumentRegistry.cs Drain Eve commands through provider state 2026-06-13 17:02:52 +01:00
AetheriaEveCommandBridge.cs Use typed documents for Eve pending commands 2026-06-14 08:47:06 +01:00
AetheriaOperationsSurfaceProjector.cs Publish runtime sessions as typed state 2026-06-14 12:31:20 +01:00
AetheriaProviderAdvertisementProjector.cs Publish runtime sessions as typed state 2026-06-14 12:31:20 +01:00
AetheriaRuntimeCommitLogApplier.cs Persist faction relationships in run checkpoints 2026-06-14 12:02:47 +01:00
AetheriaStateNode.cs Publish runtime sessions as typed state 2026-06-14 12:31:20 +01:00
AetheriaStatePaths.cs Start typed state rebuild 2026-06-13 00:38:48 +01:00
README.md Publish runtime sessions as typed state 2026-06-14 12:31:20 +01:00

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, stat grids, and runtime session documents. Runtime checkpoints include current action-bar bindings as stable typed targets: input control path, binding kind, item definition reference, equipment index, behavior index, or weapon-group index. They also include current faction relationship rows as typed corporation references plus relationship tokens and numeric standings. 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 documents beside GameData/aetheria-world.cc. Aetheria.State owns applying those documents into canonical typed state through AetheriaRuntimeCommitLogApplier; the Unity-side command log is command-only and cannot become durable truth by itself. AetheriaRuntimeSession is the typed Verse signal for the running state host or one-shot pending drain. Economy.Server owns the long-running cultmesh-state-host heartbeat and publishes starting, running, and stopping states through Aetheria.State; drain status remains operation telemetry, not daemon-session ownership. Unity Eve surfaces also emit typed gamecult.eve.command.v1 documents 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 RuntimeItemDefinitionReference, a narrow item-definition id. The old generic RuntimeCatalogLink<T> abstraction, ItemManager.GetData hydration path, vague ItemInstance.Data identity field, and old RuntimeItemReference.Projection cache have been deleted; runtime item facts come from typed catalog rows. Loadout generation now applies typed catalog prefilters for item category, hardpoint type, shape fit, hull type, and behavior kind, then instantiates generated equipment directly from typed runtime rows. The surviving trade menu also applies typed catalog prefilters for row size, hardpoint type, and behavior kind before legacy buy actions. Surviving item catalog Unity DTOs keep local legacy GUID fields only where old simulation APIs still accept DTO objects. The old RuntimeCatalogEntry and RuntimeItemProjectionEntry base names no longer appear in live source. 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 checkpoints now persist session faction relationships into typed run state, and runtime sessions publish typed state-host liveness, but broader 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. It also writes and reopens AetheriaRuntimeSession and checks that the Eve provider advertises the runtime-session schema. 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:

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:

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.