diff --git a/Aetheria.State.Daemon.Smoke/Program.cs b/Aetheria.State.Daemon.Smoke/Program.cs index 33d1ad93a..70f4b5bcd 100644 --- a/Aetheria.State.Daemon.Smoke/Program.cs +++ b/Aetheria.State.Daemon.Smoke/Program.cs @@ -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" && diff --git a/Aetheria.Unity/Packages/manifest.json b/Aetheria.Unity/Packages/manifest.json index 9e430a81b..b734ec98b 100644 --- a/Aetheria.Unity/Packages/manifest.json +++ b/Aetheria.Unity/Packages/manifest.json @@ -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" } } diff --git a/Aetheria.Unity/Packages/packages-lock.json b/Aetheria.Unity/Packages/packages-lock.json index 5f8d35ae3..9c932b706 100644 --- a/Aetheria.Unity/Packages/packages-lock.json +++ b/Aetheria.Unity/Packages/packages-lock.json @@ -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", diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeDaemonGameSurfaceBuilder.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeDaemonGameSurfaceBuilder.cs index 2cd81bde9..328157b2b 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeDaemonGameSurfaceBuilder.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeDaemonGameSurfaceBuilder.cs @@ -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", diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index 30ac52b91..927042e6a 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -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 diff --git a/docs/original-game-migration-matrix.md b/docs/original-game-migration-matrix.md index 1062d14ba..c23f16cb7 100644 --- a/docs/original-game-migration-matrix.md +++ b/docs/original-game-migration-matrix.md @@ -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 |