Aquarium/state/memory.json
2026-05-13 00:19:02 +01:00

96 lines
18 KiB
JSON

{
"identity": {
"name": "Aquarium Engine Self",
"role": "native C# engine steward for the Epiphany Aquarium client",
"desire": "Keep the renderer, state, and interaction grammar owned, legible, and useful."
},
"taste": [
"The default frame should feel like a field of living objects, not an editor viewport with a badge.",
"Cute earns its keep through affordance, spatial memory, and state legibility.",
"Fast iteration matters. Hot reload must protect the last good runtime and state.",
"Typed state beats sidecar soup.",
"Cut distracting renderer experiments once they stop serving the product."
],
"technical_memory": {
"native_engine": [
"Aquarium Engine lives at E:\\Projects\\Aquarium-Engine. Main is the live development branch.",
"Aquarium.Engine is the native engine layer: Win32 hosting, D3D12 rendering, input translation, reload transport, resource abstractions, and future render graph execution. It must not know Epiphany frontend roles, policy, or semantic client layout.",
"Aquarium.Epiphany is the Epiphany client layer behind Aquarium.Engine.Contracts. It owns client runtime state, CultCache documents, CultNet interpretation, camera intent, and future render graph configuration against engine abstractions.",
"The render API migration target is docs/epiphany-extraction-render-api-plan.md: clients declare render targets, cameras, shaders, passes, buffers, textures, and features through Vortice-free Aquarium contracts; Aquarium compiles that graph into D3D12 resources, descriptors, barriers, pipeline state, resize, shader reload, presentation, and debug inspection.",
"Epiphany declares its render plan, SDF shader manifest, SDF object table, SDF light table, height-field brush list, and cursor projection through Aquarium.Engine.Contracts. Aquarium.Engine consumes those as generic rendering data and must stay free of Epiphany client policy nouns; run scripts/verify-boundaries.ps1 to enforce that boundary.",
"D3D12Renderer now compiles an AquariumRenderPlan description and allocates non-legacy client-declared render targets through engine descriptor/resource machinery. Current legacy fixed pass execution still needs to be replaced by graph pass execution.",
"The host owns Win32 windowing, D3D12 rendering, input translation, and the client-runtime assembly boundary.",
"D3D12 descriptor ownership stays explicit: static descriptors for long-lived views, per-frame transient descriptors reset only after fence wait, and whole-arena rebuilds on resize until real descriptor churn demands free lists.",
"D3D12 previous-frame camera/view/time/cursor state is renderer-level temporal state, not per-swapchain-frame-resource state.",
"Height-field data is brush-rendered into one scalar R16_Float target. Height is one value; do not spend extra channels without a concrete pass contract.",
"Runtime volumetrics, cloud/fog research, medium/froxel render targets, medium history lanes, and the D3D11 renderer are shelved. Do not preserve compatibility husks for removed medium settings or dead shader paths."
],
"camera_and_grid": [
"The camera target is the Grid center on XY. Camera distance is clamped to [5, 40]. Grid radius derives from twice that distance and clamps to [20, 80]. Pitch, yaw, FOV, and screen aspect do not resize the Grid.",
"Body anchors are world-space simulation state. Moving the Grid visibility window must not drag bodies with it.",
"Grid texture, line, and future weather domains should sample world-space coordinates so panning reveals the field instead of sliding a texture under the camera.",
"Cursor and camera interactions should project onto the same XY surface used by the Grid contract."
],
"rendering": [
"Height-field shape is defined by brush data uploaded by the client. Epiphany currently supplies its gravity wells, CPU placement, and cursor projection; generic engine height-field and scene shaders consume the resulting brush constants.",
"The height-field surface is direct-traced as a terminating reflective surface over scalar height data. It writes the primary surface packet with FIELD_ID_HEIGHT_FIELD, terrain normal, full coverage, and Studio2 PMREM reflection; flat regions sample up to PMREM mip 3 while sloped/waved regions sharpen toward mip 0. Ray misses use a cone-averaged Studio2 PMREM mip 3 as the soft background so low-resolution mip texels do not become visible blocks.",
"Mouse/cursor-owned SDF bodies need object-motion reprojection. Carry current and previous cursor world anchors through frame constants and reproject cursor hits from current center to previous center.",
"The Epiphany cursor locator is currently a luminous five-petal hibiscus SDF in the body proxy pass. Its center stays at cursor XY with z equal to cursor radius, so its contact tip reaches Grid z=0 without sampling or projecting to the Grid surface. The previous MathWorld teardrop curve profile remains reusable SDF math for future objects: x=cos(t), y=sin(t)*sin^m(t/2), radius `sqrt(1 - x^2) * ((1 - x) / 2)^3`.",
"Role-specific Epiphany agent bodies should be driven by published CultNet surfaces, not private React projection folklore: identity and temperament from epiphany.agent_memory, motion from epiphany.agent_heartbeat, posture from epiphany.surface.roles/coordinator/role_result, and continuity pressure from epiphany.surface.pressure/reorient. The first durable renderer seam should be an AgentVisualState contract before adding per-role SDF organs. Orbit slots are home anchors, not cages: agents may wander a bounded distance for expression, and vertical motion should come from CPU-visible gravity-well pulses that also affect Grid placement.",
"Epiphany publishes semantic state, not Aquarium world anchors. AgentVisualState may derive local evidence, artifact, work, review, and continuity anchors, but those are Aquarium-owned diegetic layout rules. Do not require Epiphany graph nodes, jobs, or artifacts to publish spatial coordinates.",
"Realtime role SDFs must render through per-agent proxy bounds, not a scene-global mega-SDF. Sphere-trace only conservative distance bounds, select one role SDF after proxy hit, give every expensive feature a local bound, compute normals only after hit, and require LOD plus debug views for step count, proxy hits, material id, LOD tier, and SDF cost tier before adding full organ detail.",
"The fullscreen scene pass owns background and height-field surface only. Epiphany SDF shaders live under src/Aquarium.Epiphany/Shaders and render through client-declared proxy pipelines using AquariumSdfObject, conservative screen rectangles from center plus bound radius, and travel-derived depth writes for occlusion. Shared proxy mechanics may live in engine includes; client identity SDF and material code should not collapse back into a single engine shader.",
"Reusable SDF primitives and preserved formulas belong in engine D3D12SdfMath.hlsli. Current Epiphany role character organs belong in src/Aquarium.Epiphany/Shaders/D3D12AgentCharacters.hlsli. D3D12Renderer expands local shader includes before D3DCompile because the Vortice convenience path does not provide a working include handler here.",
"Shader include ownership should stay boring and strict: D3D12SdfMath.hlsli contains reusable SDF primitives and generic form helpers only; client-specific anatomy such as the cursor hibiscus lives in that object's shader; shared lighting equations live in D3D12SdfCommon.hlsli and take material parameters rather than being duplicated per object.",
"SDF proxy control flow is split by cost and authority: ray marching calls sdfDistance only, normals sample sdfDistance only, and sdfSurface is evaluated once at the refined hit to return only PBR material values: albedo, roughness, F0, and emission. Field identity is pass metadata for temporal ownership, not surface anatomy. Do not put distance, material ids, role ids, LOD tiers, cost tiers, or role-routing shaders back into the hot surface packet.",
"The first live visual-state slice uploads current center, previous center, and state scalars through AquariumSdfObject. Temporal reprojection must use those uploaded centers for SDF field ids; do not rederive moving centers separately in post. Do not add role, LOD, index, or flag lanes until a live pass consumes them.",
"Role SDF animation should avoid raw atan2 polar fields for lobe deformation unless the branch cut is explicitly handled. Use continuous harmonic polynomials over normalized XY directions for rotational lobes so sphere tracing does not open visible seams.",
"If a role SDF still shows cut-through gaps after removing angular branch cuts, stop using radial pseudo-distance deformation for that organ. Prefer smooth unions of analytic primitives with conservative bounds so the marcher sees connected surfaces instead of decorative distance fiction.",
"Chained smooth-union role organs need conservative tracing even when each primitive has a decent distance estimate. Keep petal overlaps substantial, union radii generous, hit epsilon tight, and step scale small enough that narrow joins are sampled instead of skipped.",
"All role bodies should be expected to contain thin structure. The shared body proxy marcher must default to conservative tracing that preserves stamens, petals, ribs, rings, filaments, and other narrow organs; faster tracing belongs behind explicit LOD policy, not private one-off body overrides.",
"Thin petal-like organs should be modeled as sheet/slab fields with explicit footprint bounds, not fat ellipsoids with decorative warps. If a transform or warp changes local metric, either scale the returned distance estimate conservatively like log-spherical SDF examples do, or cap the marcher step and refine sign crossings.",
"For pseudo-distance body composites, do not accept abs(distance) below epsilon as a surface hit. A ray that merely passes near a petal sheet can terminate before the real front intersection behind it. Body proxy tracing should enter solids by distance <= 0 and refine the positive-to-negative bracket.",
"Cursor hibiscus anatomy should use expressive primitives that match the organ: curved tapered sheet petals with lens footprints, curved tapered tubes for the staminal column, spheres for pollen beads, and a connected tapered stem plus calyx bulb. Do not default to ellipsoids when a lens, slab, tube, cone, sphere intersection, torus, superquadric, or profile revolution better describes the form.",
"The cursor hibiscus visual target is the pale pink five-petal hibiscus reference: broad translucent upward-cupped petals, folded pink throat, curved staminal column with a few pollen beads, and a green tapered calyx/stem connection ending at the XY contact point.",
"Cursor hibiscus petals should be modeled from one cheap longitudinal parameter: radial displacement grows quadratically from the vertical root, width and thickness grow toward the distal blade, and the first stable pass should avoid decorative ruffle/vein math. Do not build separate vertical panels plus horizontal blades; that creates rectangular fences and pulled-apart petal anatomy.",
"Agent role bodies should start from a small set of anatomical/form parameters that explain the whole silhouette before adding detail: a center curve, profile/width function, thickness function, repetition symmetry, and bounded material regions. If the SDF cannot be described as one coherent mapping from role state to form, stop and redesign instead of adding compensating organs.",
"For agent SDFs, prefer cheap structural math over decorative geometry. Veins, ribs, glitter, pollen, texturing, and fine state response should first be material/shading signals or LOD-gated overlays; do not put trigonometric ornament or filament swarms into the traced distance field until the base form is stable, readable, and measured fast.",
"Agent SDF iteration must separate form, evaluator, and ornament. First make the implicit form anatomically coherent from multiple views, then validate marcher behavior and cost, then add state-reactive detail. Screenshot-driven patches that only fix the current angle are a warning sign, not progress.",
"Imagination should read as distinct petals first, not as a fully merged blob. Keep the central seed small, make petal lobes narrow and visibly separated, and accept intentional negative space when it makes the role shape legible.",
"Heavy/specialized SDF evaluators should not live inside generic packed-id helpers when those helpers are called repeatedly; avoid shader compiler path cloning.",
"Lighting is diegetic. Self is the initial emitter; later other Selves should emit through an explicit body light lane, not generic field instances or ambient convenience fill.",
"Keep bundled blue-noise texture assets available for future dithering/noise work even when no current pass samples them.",
"Specular IBL uses the Studio2 PMREM cubemap baked at 512px per face: bake HDR latlong radiance into roughness-indexed cubemap mips, load it as a D3D12 TextureCube, and sample it by reflection direction plus roughness LOD. Convert Aquarium's Z-up world directions to cubemap Y-up directions before sampling: (x, z, y). Grid mirror reflection samples mip 0 directly; body material reflections use roughness LOD. Keep this as material reflection response, not a replacement for diegetic body light authority.",
"Diffuse IBL uses a separate Studio2 irradiance cubemap, not blurred GGX PMREM. Bake it by cosine-weighted hemisphere convolution storing irradiance integral Li*cos(theta) dOmega, then shade non-metal bodies with Fresnel-gated diffuse share times albedo/PI times irradiance.",
"HDR/PBR presentation follows research/rendering/hdr-pbr-presentation.md: scene-linear lighting, explicit exposure, pre-tonemap bloom/veil, then display transform.",
"Current temporal diagnostics are for inspection. With projection jitter disabled, final presentation should not blindly trust temporal color history until a real temporal contract earns authority. Do not preserve dormant full-frame event/history lanes without an active producer and consumer contract."
],
"text_and_ui": [
"Overlay text uses DirectWrite/Direct2D after scene rendering. It is crisp final-pixel UI for debug surfaces, terminals, inspectors, and splash/status text.",
"Aquarium UI controls follow the CultLib code-first binding style without Unity prefab assumptions: panels, sections, sliders, toggles, buttons, option rows, and text boxes bound by explicit read/write delegates.",
"Aquarium.Engine.Contracts exposes AquariumUiDocument as the client-facing debug composition surface. Client panels are tabs inside the single Aquarium debug panel, clients can register terminal commands through AquariumUiDocument.Command, and longer editable strings should use AquariumUiTextBox instead of pretending to be row values. Text boxes own caret/selection editing state, may opt into bundled Ubuntu Sans Mono and bottom alignment, and focused text boxes capture input so renderer debug hotkeys and client camera controls stay quiet while editing.",
"The unified F2 debug panel is titled Debug and owns engine controls, client tabs, and a bottom-aligned multiline command terminal. Tab navigation is panel chrome: a highlighted row of buttons below the title, not a content section made of ordinary controls. Do not reintroduce separate Aquarium/Epiphany debug panels fighting for the same hotkey.",
"Vortice.Mathematics.Rect uses x, y, width, height. UI code should use explicit RectFromEdges helpers when reasoning in edges.",
"Debug UI feedback needs honest element-specific states: base, hover, and active. Sliders respond on track/fill and handle separately, keep geometry stable, and brighten by lerping accent colors toward white.",
"Scene/diegetic labels should use renderer-owned MSDF/SDF billboards when they live in world space. Overlay text should not be shoved into HDR for convenience."
],
"audio": [
"Aquarium exposes an optional audio/synth hosting boundary through contracts; clients declare intent, Aquarium schedules playback and owns device/toolchain integration.",
"Aquarium consumes AquariumSynth.Dsl as a pinned repo-local NuGet package. AquariumSynthCSharp owns synth internals and tests; update the package only by deliberate version bump so visual/renderer work can continue while synth construction changes underneath."
],
"state_and_reload": [
"CultCache is the client memory organ. Runtime state, camera, renderer knobs, body state, UI state, and future Epiphany connection state should be typed Cult documents.",
"Global graphics presentation settings live in epiphany.aquarium.graphics_settings. The debug UI edits the renderer copy; the host syncs changed renderer settings back to the client runtime; the runtime flushes dirty settings through CultCache.",
"A truncated or unreadable single-file CultCache backing store is not a schema migration failure. Aquarium should quarantine the corrupt snapshot and boot fresh typed state.",
"dev-reload builds disposable apphost slots so a running window does not lock normal build output. Headless smoke runs use a separate CultCache from the visible dev window.",
"Live runtime reload is not successful just because dev-watch wrote live-current.txt. The watcher must see the host acknowledge the exact live DLL path in stdout.",
"Shader reload failure must keep the previous good shader objects bound. Live-runtime reload failure must keep the previous runtime alive."
]
},
"warnings": [
"A clean repo can still grow Jenga if state and docs lag behind code.",
"Do not add a framework-shaped dependency just to borrow one comfortable tool.",
"Do not let bloom or overlay debug output disguise a bad lighting equation.",
"Do not preserve historical branch scars in live docs unless they change a current decision."
]
}