Separate flight and dock camera contracts

This commit is contained in:
Meta Vens 2026-07-15 21:40:28 +01:00
commit bb502eb04a
6 changed files with 40 additions and 18 deletions

View file

@ -565,13 +565,15 @@ internal sealed class AetheriaDaemonYmirSmokeChecks
world.Props["lookModel"] == "planar-yaw.v1" &&
world.Props["lookSensitivityRadians"] == "-0.001",
"playable world must advertise the daemon-owned continuous look command and fossil pointer response");
Require(world.Props["cameraRig"] == "planar.top-down-follow.v1" &&
world.Props["cameraDistance"] == "70" &&
Require(world.Props["cameraRig"] == "perspective.entity-forward-follow.v1" &&
world.Props["cameraDistance"] == "30" &&
world.Props["cameraVerticalFieldOfViewDegrees"] == "60" &&
world.Props["cameraTargetScreenX"] == "0.66" &&
world.Props["cameraTargetScreenY"] == "0.55" &&
world.Props["cameraPositionDamping"] == "2",
"playable world must preserve the authored ARPG follow-camera composition rather than TestScene tuning");
world.Props["cameraTargetScreenX"] == "0.64" &&
world.Props["cameraTargetScreenY"] == "0.81" &&
world.Props["cameraPositionDamping"] == "0" &&
world.Props["cameraNearClipPlane"] == "1" &&
world.Props["cameraFarClipPlane"] == "4096",
"undocked world must preserve the authored ARPG Third Person Rig rather than the distinct Docked Rig");
Require(world.Props["skyboxAssetRef"] == "material.environment.skybox" &&
world.Props["reflectionAssetRef"] == "texture.environment.reflection" &&
world.Props["reflectionIntensity"] == "1" &&

View file

@ -9,6 +9,6 @@
"org.gamecult.cultlib": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.13",
"org.gamecult.eve.plugin-fields": "https://github.com/GameCult/EvePlugins.git?path=/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields#eve-plugin-fields-unity-v0.2.0",
"org.gamecult.eve.surface": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.surface#eveunity-surface-v0.2.2",
"org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.38"
"org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.39"
}
}

View file

@ -144,7 +144,7 @@
"hash": "140e1bd963a0033e66777a3b2c5fe6e9c97dfe32"
},
"org.gamecult.eve.unity-scene": {
"version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.38",
"version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.39",
"depth": 0,
"source": "git",
"dependencies": {
@ -154,7 +154,7 @@
"com.unity.mathematics": "1.3.2",
"com.unity.modules.particlesystem": "1.0.0"
},
"hash": "de580fe88350f422e30f1e4b64ded5c33070b118"
"hash": "35ff288aabc03130a61228579f1b09bac4345b5c"
},
"com.unity.modules.assetbundle": {
"version": "1.0.0",

View file

@ -605,14 +605,16 @@ namespace GameCult.Aetheria.State.Verse
["assetManifest"] = AetheriaRuntimeVerseRecordKeys.EveAssetCatalog.ToString(),
["inputCapability"] = AetheriaRuntimeVerseRecordKeys.PilotInputCapability.ToString(),
["inputProfile"] = "arpg.pointer-keyboard.v1",
["cameraRig"] = "planar.top-down-follow.v1",
["cameraDistance"] = "70",
["cameraRig"] = isDocked
? "planar.top-down-follow.v1"
: "perspective.entity-forward-follow.v1",
["cameraDistance"] = isDocked ? "70" : "30",
["cameraVerticalFieldOfViewDegrees"] = "60",
["cameraTargetScreenX"] = "0.66",
["cameraTargetScreenY"] = "0.55",
["cameraPositionDamping"] = "2",
["cameraNearClipPlane"] = "0.3",
["cameraFarClipPlane"] = "4096",
["cameraTargetScreenX"] = isDocked ? "0.66" : "0.64",
["cameraTargetScreenY"] = isDocked ? "0.55" : "0.81",
["cameraPositionDamping"] = isDocked ? "2" : "0",
["cameraNearClipPlane"] = isDocked ? "0.3" : "1",
["cameraFarClipPlane"] = isDocked ? "2048" : "4096",
["ambientLightColor"] = "0.2,0.2,0.2",
["ambientLightIntensity"] = "1.46",
["skyboxAssetRef"] = "material.environment.skybox",

View file

@ -865,6 +865,24 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted.
height, and negative body splats. Released cold/warm witnesses exercise the
persisted daemon path.
### Pilot Camera Presentation Contract
- Owner: the Aetheria daemon selects camera semantics from authoritative dock
state and publishes the fossil framing and lens values. EveUnity owns only the
native camera projection.
- Inputs: controlled entity identity and rotation, dock parentage, presentation
mode, distance, field of view, target screen position, damping, and clip planes.
- Outputs: undocked flight uses `perspective.entity-forward-follow.v1` with the
fossil `Third Person Rig` values. Docked presentation remains a distinct mode
and cannot lend its framing to flight.
- Derived state: Unity camera position, rotation, matrices, culling mask, and
temporal fog history are presentation state.
- Forbidden writers: Unity cameras cannot choose dock state, alter entity look
direction, or infer an Aetheria camera from product types. The old scene and
Cinemachine components are reference evidence, not runtime authorities.
- Cut line: the unconditional `planar.top-down-follow.v1` projection no longer
collapses the fossil dock and flight cameras into one false top-down view.
### Gravity Fog Presentation Contract
- Owner: Aetheria owns the gravity/fog splat values, authored volume tuning, and

View file

@ -31,10 +31,10 @@ validation proves contract shape, not wiring, exclusivity, lowering, or parity.
| Inventory/equipment | inventory panels + ServerShared | daemon | inventory/equipment surfaces | generic UI | owner-exists; wired/projected in fragments; not proven | all transfer directions and rejection |
| Trade | trade UI/economy | daemon | stock, quote, purchase commands | generic UI | daemon derives station, stock row, catalog item, current price, quantity, credits, target capacity, and hull-vs-cargo result; Eve advertises only currently available stock actions; generic Unity live witness receives an authoritative purchase receipt while paused | sell flow, quote expiry, contested stock, and full trade surface parity |
| Action bar/input | input shell and rebinding UI | daemon advertises actions; client owns bindings | input capability and action descriptors | universal binding UI | contracts wired; cargo actions are catalog-filtered to consumables the current actor can actually activate, including suppression of active non-stackable items | dynamic equipment behavior validity and runtime action-bar quantity/fill proof |
| Pilot camera | ARPG follow/dock cameras | Eve view semantics + runtime | camera rig and semantic view id | EveUnity camera rig | authored ARPG follow distance, field of view, screen framing, and damping are provider-owned and generically lowered; dock/view transition parity remains absent | dock transition timeline and reconnect |
| Pilot camera | ARPG follow/dock cameras | Eve view semantics + runtime | camera rig and semantic view id | EveUnity camera rig | daemon dock state now selects distinct contracts instead of collapsing both fossil cameras: undocked flight advertises the entity-forward `Third Person Rig` framing (distance 30, screen 0.64/0.81, FOV 60, lens 1-4096), while the retained dock projection remains separate; EveUnity lowers entity-forward framing without provider types | reproduce the dock camera's separate follow/look-at subjects, blend timeline, noise, and reconnect state |
| Render channels | Unity layers/culling masks | provider surface policy + runtime asset variant | semantic channel exclusions | EveUnity native layer mapping | wired, exclusive, and lowered: the pilot surface excludes the semantic `map` channel; the Unity asset variant maps `map` to its authored native layer; EveUnity subtracts that layer from the configured camera mask; portable state contains no Unity layer or mask; package tests and the clean-client dependency verifier pass | live pilot capture proving no map glyphs while the map camera retains them |
| Minimap/tactical map | `ZoneRenderer`, map cameras | daemon world facts | explicit map projections | Unity and Electron | facts fragmented; generic lowerers absent | same state in both runtimes |
| Fields/fog/gravity | zone renderer and shaders | daemon/plugin semantics | Fields plugin documents | EveUnity fields lowerer | daemon publishes four canonical gravity/fog splat layers through `field.volume3d`; the provider asset variant owns the fossil shader, native ports, quality/features, and raymarch/temporal/composite pass graph; released EveUnity `0.3.38` lowers the optional temporal-history lifecycle generically and fails closed on partial native programs; the warm released witness executes the provider bundle, four layers, and repeated composites without importing Aetheria code; the current pilot capture remains nearly black/geometric rather than the authored blue fog sea, so visual composition parity is explicitly absent | diagnose field values, colour/exposure/composition and camera-depth behavior against the fossil, then capture temporal stability and visual parity |
| Fields/fog/gravity | zone renderer and shaders | daemon/plugin semantics | Fields plugin documents | EveUnity fields lowerer | daemon publishes four canonical gravity/fog splat layers through `field.volume3d`; the provider asset variant owns the fossil shader, native ports, quality/features, and raymarch/temporal/composite pass graph; released EveUnity `0.3.39` lowers the optional temporal-history lifecycle generically and fails closed on partial native programs; the warm released witness executes the provider bundle, four layers, and repeated composites without importing Aetheria code; correcting the fossil flight camera removed the false top-down disk, but the raymarch remains a nearly uniform saturated orange horizon rather than the authored blue fog sea, so visual composition parity is explicitly absent | derive the advertised dither sampling coordinates from render-target and texture dimensions, then inspect finite aim look-at and capture temporal visual parity |
| HUD/schematic | ARPG HUD and `SchematicDisplay` | Eve composition from daemon facts | semantic status/components | EveUnity UI | provider-authored transparent cockpit is wired, projected, and lowered through generic UI Toolkit panes, metrics, and progress components for hull, shield, capacitor, temperature, cargo, weapon cooldown/groups, selected target, target lock, target shield, and target hull; the original armor/equipment schematic and transient warning choreography remain reference-only | schematic topology, warning timelines, dynamic action state, and composited live capture |
| Hit/lock/warnings | `ActionGameManager` feedback | daemon event facts | transient feedback stream | VFX/UI/audio | bounded deduplicated game-event ledger and Eve `feedback.stream` wired for pickup outcomes, projectile launch/impact, entity damage, alive-to-dead destruction, authoritative weapon reload chronology, and episode-deduplicated `weapon.fire.refused` facts for insufficient energy or missing ammunition; refusal identity, authored weapon, target, reason, and remaining magazine state are runtime-independent cockpit inputs | add lock transitions, thermal and docking event families, negative transaction fixtures, and runtime effect consumption |
| Assets | `Assets/Resources` | Aetheria provider | asset catalog + CultMesh CDN | runtime cache/load | provider manifests name deterministic bundle-internal paths; the authoring build derives presentation-only prefabs, strips missing and non-Eve `MonoBehaviour` components, verifies both saved prefabs and the loaded bundle, and publishes the immutable bundle through CultMesh; released-client warm-cache loading, content verification, and rendered provider identity are proven, while cold transfer still times out because the 46.1 MB body travels through batched snapshot records | mapped/network body transport followed by empty-cache download, atomic promotion, and cache reuse proof |