KVG Interact profile — interactive simulation, parametric lighting, walkable 2D→3D scenes

ratified

Status: ratified (owner, 2026-06-07). This RFC defines a fourth additive capability layer for the KVG format (specs/kvg/format.kmd, itself still proposal-v0.1). Ratification unblocks the Interact runtime (Koder Kad KAD-005) and the Live alias. Nothing here is normative until ratified. It exists to unblock the design of a new visual-design product (the "KVG editor" — Visio + draw.io + SketchUp + AutoCAD + Blender class) whose flagship scenarios require interactivity the current profile model cannot express.

1. Summary

KVG today defines three additive capability layers — Core (static 2D), Motion (timeline + animation state machine), Solid (3D meshmaterial camera/lighting) — combined into four declared aliases (Core, Animated, Spatial, Full). Motion's own spec scopes it as *"a cena é coreografada, não um jogo"* (format.kmd §2 / §3.2): its state machine drives animation interpolation, not arbitrary scene logic, and Solid's camera/lighting are authored constants, not runtime-mutable parameters.

This RFC proposes a fourth layer, Interact, that adds: (a) scene-scoped state variables; (b) event→action rules (input or signal mutates state / node properties / light & material parameters); (c) an interactive camera contract (free / first-person / orbit navigation); and (d) runtime-mutable parameters surfaced to the host (e.g. a light's origin and incidence angle a user drags live). It also defines the floorplan→solid generative direction (a kgen transform that extrudes a 2D plan into a walkable interior) as the canonical worked example.

Declared alias additions: the layer token is Interact; the canonical top alias Live = Core+Motion+Solid+Interact. The conformance rule is unchanged — a document opens in a renderer ⇔ profile_doc ⊆ profile_renderer.

2. Motivation

2.1 The product that needs it

The owner asked for a Koder product in the category of Visio + draw.io + SketchUp + AutoCAD + Blender: vector projects in KVG with selectable/editable objects, themed object libraries (BPMN, UML, ER, floor plans, furniture, civil/ mechanicalelectricalelectronic engineering, PCB/IC, signage, characters, devices, …), animated simulations, and a 2D→3D transform — the headline being *"a floor plan becomes a walkable, interactive 3D house: the user navigates the interior, flips a switch to turn a lamp on, and sets the sun's origin and incidence angle on the walls and windows to preview the finished home."*

The object-library half is kdef-native and needs no format change (covered by specs/kvg/stencils.kmd). The interaction + parametric-lighting + walkable-3D half does not fit any existing layer.

2.2 Why Motion is not enough

Capability the scenario needs Motion offers Gap
"Flip switch → lamp emissive turns on" pointer trigger → timeline/state transition (interpolate visual props) No write of arbitrary node/light parameters; no boolean scene state; no conditional logic
"Drag the sun: live origin + angle on walls" Solid directional/spot light with authored direction Light parameters are constants; no host-surfaced mutable parameter; no live re-light contract
"Walk through the interior" Solid camera is an authored perspective No interactive/first-person navigation contract; camera is not user-driven
"Wire BPMN/circuit and simulate flow" timeline choreography No data/logic propagation between nodes

Motion is deliberately animation-shaped (Rive/Lottie heritage). Stretching it to carry general interaction would overload one layer with two contracts (D1 — correct contracts; D2 — boundaries). A distinct, additive layer keeps each layer single-purpose and keeps AnimatedSpatialFull renderers conformant without implementing interaction.

2.3 Why this belongs in the format, not the product

If interactivity lived only in the editor product, a .kvg exported from it would be inert anywhere else — it would not reopen, re-simulate, or be embeddable in DokCinea landing page. KVG's premise is *"o documento é fechado, distribuído como bytes, executável offline"* (format.kmd §0). For the walkable house or the simulated circuit to travel with the file, the interaction model must be a profile of the format (D1, D9 — reversibility / no product lock-in).

3. Design — the Interact layer

Sketch-level, for ratification review. Exact KSS grammar lands in format.kmd §3.4 + §(new) once this RFC is accepted.

3.1 Scene state

A document may declare typed, scene-scoped variables:

state {
  lampOn   : bool    = false
  sunAzim  : angle   = 135deg
  sunElev  : angle   = 45deg
  occupants: int     = 0
}

State is declarative and sandboxed — values, not code. It is the only mutable surface; nodes and lights read from it via bindings.

3.2 Event→action rules

Rules bind a trigger (input event on a node, a state change, or a host signal) to one or more actions (assign state, set a nodelightmaterial parameter, start a Motion timeline, switch a Motion state, emit a signal):

on tap #switch        -> toggle lampOn
on change lampOn      -> set #lamp.emissive = lampOn ? "#FFE08A@4.0" : "#000000@0"
on drag #sun-gizmo    -> set sunAzim, sunElev from pointer.spherical
bind light #sun.direction <- spherical(sunAzim, sunElev)

Actions are a closed, declarative vocabulary (assign / set-param / timeline- control / emit) — no eval, no general scripting. Where procedural logic is unavoidable (e.g. a circuit solver, a BPMN token engine), it runs in the existing sandboxed Koda path the format already reserves for kgen (format.kmd §2: "sandboxed (Koder Koda restrito)"), never with network or file IO.

3.3 Interactive camera & navigation

Solid contributes the camera; Interact contributes the navigation contract:

camera #eye mode=first-person {
  bounds   = #floor          // collision/clamp volume
  height   = 1.6m            // eye height for walkthrough
  controls = wasd+drag | orbit | pan-zoom
}

The renderer maps host input (pointerkeyboardtouchgamepadXR controller) to camera motion within bounds. This is the "walk through the house" primitive.

3.4 Runtime-mutable parameters (host-surfaced)

A parameter marked @param is exported to the host (editor UI, embed API, or an LLM tool call) as a typed knob with range metadata:

@param("Sun azimuth", min=0deg, max=360deg) sunAzim
@param("Sun elevation", min=0deg, max=90deg) sunElev

This is how the editor renders the "drag the sun" gizmo and how an embed exposes sliders — without the host knowing the scene internals (D1, D3).

3.5 Worked example — floorplan→solid

The 2D→3D transform is not new core; it is a kgen pack (see specs/kvg/stencils.kmd) operating on the Spatial layer:

  1. Author draws wallsdoorswindows on a 2D plan using the floorplan stencil

    (Core), each carrying semantic params (wall height, opening type).

  2. kgen floorplan-extrude reads the plan and emits Solid geometry: extruded

    walls, framed openings, a floor bounds volume.

  3. Interact adds a first-person camera bound to the floor, @param sun

    azimuth/elevation driving a directional light, and on tap #switch -> toggle rules per fixture.

The same source .kvg opens in 2D (Core renderer ignores Solid+Interact) as the editable plan, and in Live as the walkable preview. One graph, both views — the founding promise of KVG (format.kmd §0).

4. Profile-model impact

  • New additive layer token: Interact (depends on Core; may combine with

    Motion and/or Solid). Standalone Core+Interact is valid (e.g. an interactive BPMN diagram with no animation/3D).

  • New canonical alias: Live = Core+Motion+Solid+Interact. kvg fmt

    normalizes the concat form to the alias, mirroring the existing rule (format.kmd §3.0).

  • Conformance unchanged: profile_doc ⊆ profile_renderer. A Spatial renderer

    opens an Interact document by rendering the static fallback (initial state, authored camera) and ignoring rules — the document must declare a sane initial state so the fallback is meaningful (validator rule).

  • Footprint: Interact is logic-light (declarative rules + a small bound-input

    loop). Target overhead over the host renderer: < 80 KB, 100% offline.

5. Self-hosted-first & multi-tenancy

  • No external dependency: rules and state are declarative; the optional Koda

    escape hatch is the already-sandboxed kgen runtime — no evalnetworkfile IO (format.kmd §2; policies/self-hosted-first.kmd).

  • Multi-tenancy is a product concern, not a format concern: .kvg

    documents and the stencil packs a user saves are tenant-scoped by the editor product per policies/multi-tenant-by-default.kmd (tenant resolved by auth, RLS / key-prefix at storage, cross-tenant → 404). The format itself carries no tenant identity.

6. Relation to existing components

  • services/ai/scene3d (scene3d-RFC-001): an AI 3D-generation service

    (text/image→mesh). Complementary — a source of assets the editor can drop into a Solid scene and a possible accelerator for floorplan→solid. Not an overlap (it generates meshes; it is not an editor or a format layer).

  • products/horizontal/dok (KVG "canonical editor" per format.kmd §15):

    remains the canonical textual KVG editor (edit kdef/blocks, live preview, autocomplete). The new product is the canonical visual / direct-manipulation editor. Both consume the same engine + the shared editing core (see kvg-RFC-002, forthcoming).

  • products/horizontal/craft (graphic design, SVG-native today) and

    board (whiteboard): candidate downstream consumers of the shared KVG editing core; out of scope for this RFC.

  • ai-RFC-001 (Generative UI via KVG): Interact's @param host-surfacing is

    the same seam an LLM would use to drive a generated interactive widget — the two RFCs should converge on one host-parameter contract.

7. Open questions

  • Q1 — layer vs Motion extension. Proposed here as a distinct layer

    (Interact). Alternative: fold a minimal "set-param action" into Motion. This RFC argues for a distinct layer (D2 boundaries); reviewers may push back if the walkable-3D/param-light use cases can be sufficiently served by extending Motion.

  • Q2 — logic ceiling. How far does the declarative action vocabulary go before

    a scene legitimately needs sandboxed Koda (circuit/BPMN simulation)? Draw the line explicitly so simple scenes stay logic-free and validatable.

  • Q3 — Live alias name. Live vs Interactive vs Sim. Live is short

    and reads well next to Core/Animated/Spatial/Full; confirm at ratification.

  • Q4 — XR. First-person navigation is one step from VR walkthrough. Keep the

    camera contract XR-shaped now (head pose as an input source) or defer? scene3d motivation flags AR/VR as coming tablestakes.

8. Next steps

  1. Ratify this RFC (1 review round) — promotes Interact + Live into

    format.kmd §3.4 and a new actions/state section.

  2. specs/kvg/stencils.kmd — the Stack-level stencil/kdef library system

    (themed object banks; Hub-distributed). (authored alongside this RFC.)

  3. kvg-RFC-002 — the new product's architecture: the three shared layers

    (KVG editing-core, stencil-registry client, 2D→3D pipeline) consumed by the product + Dok + Craft (reuse-first ≥3 consumers).

  4. /k-new-product — name + skeleton + backlog for the visual KVG editor

    (owner-decision: product name, gated separately).

  5. Engine tickets in engines/lang/kvg/backlog/ for Interact parservalidator

    renderer support and the floorplan-extrude kgen pack.