with one click
fs-skia-scene
Build pure scene descriptions in a generated FS.Skia.UI product.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Build pure scene descriptions in a generated FS.Skia.UI product.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Consumer-facing guide to hosting an interactive FS.Skia.UI app — the keyboard/pointer input surface, the preview-vs-tree render distinction, and the windowed-fullscreen blur caveat.
Build Skia-rendered FS.Skia.UI Controls, rich text, chart controls, graph controls, DataGrid, custom wrappers, and generated product examples.
Generated product guidance for Skia-rendered FS.Skia.UI Controls, rich text, chart controls, graph controls, DataGrid, and custom wrappers.
Wire a generated FS.Skia.UI product to the desktop viewer host.
Understand and work with the internal keyed VDOM diff over the lowered Control<'msg> IR (feature 067) — its key-first-then-positional matching, the NodePatch/ChildOp operation set, the totality/determinism/identity-at-rest/round-trip invariants, and the module's disposition (internal, property-tested, wired onto the live render path via RetainedRender in feature 091 and current through feature 103 — layout/bounds cache, injected-delta animation clock, visual-state cross-fade). Use when reading the diff invariants, extending the property tests, or working on the wired retained render path.
Maintainer-facing guide to the FS.Skia.UI.Controls.Elmish interactive-host seam — how runInteractiveApp drives the retained render structure each frame (RetainedRender.step over the keyed diff), advances per-identity animation clocks from an injected Tick delta, stamps runtime visual state pre-reconcile, routes keys focus-first through routeFocusedKey, and resolves pointer hits to a stable identity via retainedHitTest. Use when reading or extending the live controls host loop, the per-frame retained-state/clock/visual-state wiring, or the key/pointer routing seam.
| name | fs-skia-scene |
| description | Build pure scene descriptions in a generated FS.Skia.UI product. |
Use this skill for product code that builds pure Scene / SceneNode
descriptions: HUD regions, gameplay geometry, markers, and text. Scene values are
plain data — they perform no window, render, or screenshot I/O themselves.
The signatures you consume are bundled with this product at
docs/api-surface/Scene/Scene.fsi. Read them to confirm any union case's exact
field order locally — no DLL reflection needed. Prefer the self-describing
constructors (Scene.filledRectangle, Scene.textAt, Scene.circle) over the
positional tuple cases to avoid an arity slip.
open FS.Skia.UI.Scene
let panel = { Red = 40uy; Green = 90uy; Blue = 200uy; Alpha = 255uy }
let ink = { Red = 255uy; Green = 255uy; Blue = 255uy; Alpha = 255uy }
// A pure scene: a HUD bar plus a label. No I/O happens here.
let hud : Scene =
Scene.group
[ Scene.filledRectangle { X = 0.0; Y = 0.0; Width = 320.0; Height = 48.0 } panel
Scene.textAt { X = 12.0; Y = 30.0 } "tally: 0" ink ]
Point/Rect. Scene exposes
Point = { X: float; Y: float } and Rect = { X: float; Y: float; Width: float; Height: float }. If your product also defines a geometry record with the same field
names (a common type Vec2 = { X: float; Y: float }), F# label resolution binds a
bare { X = ...; Y = ... } to whichever record type is in scope last, which
produces a misleading error cascade at unrelated call sites. Disambiguate explicitly
at the boundary — annotate the type or qualify the fields — and convert your record
into the framework type when you call Scene:
type Vec2 = { X: float; Y: float } // product geometry
let toPoint (v: Vec2) : Point = { X = v.X; Y = v.Y } // explicit conversion
let p : Point = { Point.X = 0.0; Point.Y = 0.0 } // or qualify fields inline
Run ./fake.sh build -t Dev then ./fake.sh build -t Verify in this product.
Run ./fake.sh build -t Test to exercise product-owned scene examples.
Record scene and bounds evidence under this product's readiness/ paths. Do not
copy framework readiness reports into the product.
Scene must not reference Elmish, the viewer host, layout, or widgets. Keep host
wiring in fs-skia-skiaviewer and control authoring in fs-skia-ui-widgets.
Scene is the base capability in every profile; build product geometry from these
primitives and feed the resulting SceneNode to your View.
When a problem outlasts reasonable in-repo attempts, extensive external research is
mandatory — consult official online docs first (the F#/.NET docs and the driven
library's own documentation/API reference), then community sources (forums, Reddit, Q&A
sites, issue trackers and changelogs). Record the findings and resolving links in the
feature's specs/<feature>/feedback/ folder and, for durable lessons, in this skill's
Sources line. Offline, the mandate degrades to recording "research blocked — "
rather than hard-failing the phase.
SceneNode this skill builds at the host boundary.