KVG Interact profile — interactive simulation, parametric lighting, walkable 2D→3D scenes
Status: ratified (owner, 2026-06-07). This RFC defines a fourth additive capability layer for the KVG format (
specs/kvg/format.kmd, itself stillproposal-v0.1). Ratification unblocks the Interact runtime (Koder Kad KAD-005) and theLivealias. 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) sunElevThis 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:
- Author draws wallsdoorswindows on a 2D plan using the
floorplanstencil(Core), each carrying semantic params (wall height, opening type).
kgen floorplan-extrudereads the plan and emits Solid geometry: extrudedwalls, framed openings, a floor
boundsvolume.- Interact adds a first-person
camerabound to the floor,@paramsunazimuth/elevation driving a
directionallight, andon tap #switch -> togglerules 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 withMotion and/or Solid). Standalone
Core+Interactis valid (e.g. an interactive BPMN diagram with no animation/3D). - New canonical alias:
Live=Core+Motion+Solid+Interact.kvg fmtnormalizes the concat form to the alias, mirroring the existing rule (
format.kmd§3.0). - Conformance unchanged:
profile_doc ⊆ profile_renderer. ASpatialrendereropens an
Interactdocument 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
kgenruntime — no evalnetworkfile IO (format.kmd§2;policies/self-hosted-first.kmd). - Multi-tenancy is a product concern, not a format concern:
.kvgdocuments 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" performat.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 (seekvg-RFC-002, forthcoming).products/horizontal/craft(graphic design, SVG-native today) andboard(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@paramhost-surfacing isthe 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 —
Livealias name.LivevsInteractivevsSim.Liveis shortand 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?
scene3dmotivation flags AR/VR as coming tablestakes.
8. Next steps
- Ratify this RFC (1 review round) — promotes Interact +
Liveintoformat.kmd§3.4 and a new actions/state section. specs/kvg/stencils.kmd— the Stack-level stencil/kdeflibrary system(themed object banks; Hub-distributed). (authored alongside this RFC.)
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).
/k-new-product— name + skeleton + backlog for the visual KVG editor(owner-decision: product name, gated separately).
- Engine tickets in
engines/lang/kvg/backlog/for Interact parservalidatorrenderer support and the
floorplan-extrudekgenpack.