Skip to content

Overview

Example apps live in the engine repo under apps/. Run from the app directory: ./plume3d . (after building) or from repo root: plume3d path/to/app.

ExampleDescription
Aspect RatioDesign resolution (1280×720) and letterbox scaling; resize to see black bars
Window DemoDisplay window title, width, and height via the Window API
ExampleDescription
Audio BasicPlay a click (Space) and toggle looping music (M)
Audio 3D3D listener and moving source; A/D move listener, Space plays sound, source on sine path
Audio PlayerRadio-style tuner: tune with Left/Right, stations from channels.toml, static when off-frequency
Audio Player 3D3D radio with power button, knobs, and body rotate; blend-loaded model, raycast picking
Audio StreamingStreams a procedural 220 Hz sine tone via Audio.newStreamingSource; feed interleaved float PCM over time, poll queuedBuffers to pace refills
ExampleDescription
Physics SimpleAutomatic rigid bodies from Blender (floor + falling cube); toggle pause; shadow mapping
Physics StackTower of stacked cubes; onContactBegin logs each collision
Physics FrictionBoxes on an inclined ramp; R resets; compares Blender friction values
Physics Constraint HingeHinge-constrained door; Space applies impulse; FPS camera
Physics Particles DebrisTier 2 debris emitter: 64 physics-body particles bouncing off the ground
Particle FX DemoNon-physics sprite particle render modes (ADR 0102): SpriteGround rings laid flat on the water (burst one per beat → concentric ripple rings) + a camera-facing SpriteBillboard sparkle — pinned kinematic decals reusing the sprite pipeline, no renderer change
Physics GolfRestitution side by side: three spheres (0.0 / 0.5 / 0.9) dropped from the same height
Physics Mesh TerrainBall rolls into a procedural triangle-mesh trough; one grid drives both collider and render mesh
Physics HeightfieldBall settles into a heightfield-grid bowl; one grid drives both collider and render mesh
ExampleDescription
Character ControllerTop-down 3D: WASD/Shift/Space/C/E; mouse-aim; all CharacterState constants; shadows
ExampleDescription
Camera ShowcaseThe camera rig system end to end (ADR 0058): Cam.thirdPerson follows a moving player, Cam.blendTo eases to an orbit rig (with noise sway), Impulse.emit shakes — all with draw() = just scene.draw(), no camera plumbing
Camera TOML DemoCamera rigs authored as data (ADR 0104): Cam.loadAssets(scene, "cameras.toml") builds a third-person follow rig (active) + an overview orbit rig in one call, resolving each target by SceneNode id; mid-run it blends to the rig looked up by its TOML name via Cam.rig(scene, "overview"). The data-authored twin of Camera Showcase — same presets + field mapping as the fluent setters
Blend Camera DemoA camera authored in a .blend driving the rig system (ADR 0106): instantiate the .blend camera, then Cam.fromNode(scene, node) binds its authored world pose + lens as a static rig — scene.draw() renders from exactly the framing the artist set, through the same CameraDirector every code-created rig uses. The type = "static" cameras-TOML value is the data-authored twin
Per-Viewport SDF TextPer-viewport SDF text (ADR 0105): the same Graphics.perViewportOverlays(true) flag that replays the HUD now also replays SDF text into each split-screen cell — world-space nameplates re-projected by that cell’s own camera (each player’s name over their own cube) + a screen-space banner scaled into both cells. A 2-player horizontal split
ExampleDescription
Blend LoadLoad Cube.blend, instantiate Cube and camera/light from blend; FPS camera, raycast-drag cube
Blend Scatter DemoBlender foliage import (Block BLD): GrassField.blend bakes 196 grass-blade instances that BlendResult.instantiateScatter emits as one GPU-instanced draw — the baked geometry-nodes / particles scatter pipeline round-tripped through the loader
Foliage + Terrain DemoBlender level load end-to-end (Block BLD): one Scene.loadBlendScene call brings in a whole FoliageTerrain.blend — a plume3d_terrain-tagged mesh as a render node and an automatic static Jolt collider (dropped spheres rest on the hills), 256 baked blades as one instanced draw, and two static rock props — composing instantiateTerrain + instantiateScatter + instantiateUnits
Blend Water DemoThe Blender water tag (PLM-274, ADR 0092): a mesh tagged plume3d_water in Blender is auto-drawn as a stylized water surface by Scene.loadBlendScene — no Wren wiring, the artist-authoring on-ramp parallel to plume3d_terrain. The tag string names the water shader (toon/pbr/basename — the shader stays pack content); optional plume3d_water_shallow/_deep/_foam/_waves/_horizon float-array props tune the look. Adds BlendResult.instantiateWater (additive) + a SceneNode custom material, the engine filling the camera-position param each frame
Water BlenderBlender-authored water on a hand-authored .blend — the surface companion to Blend Water Demo (which authors a box volume). A scene modelled in Blender (Island + Seabed + a Water plane) renders its water purely from tags: the Water plane tagged plume3d_water="realistic" (+ a shallow/deep/foam/waves/horizon/caustic/crest param block) is drawn by Scene.loadBlendScene as engine water around the island (waves, depth colour, a shoreline foam ring, the seabed showing through via depth/refraction); the Seabed tagged plume3d_terrain; the Island an ordinary lit mesh — no water wiring in the Wren script. Pins down the authoring gotcha that a mesh tagged plume3d_water must be subdivided for the wave displacement (a plume3d_water_volume box auto-generates a subdivided surface instead)
ExampleDescription
GUI OverviewBasic Nuklear GUI: two windows, labels, buttons
GUI InputLive display of mouse, keys, modifiers, and window size
GUI CalculatorFull calculator built with GUI buttons and layout
GUI ConfiguratorSettings panel: quality, fullscreen, window size, design size, scale mode
GUI TerminalIn-game terminal: backtick to open; #!command methods
GUI ButtonsLabel, color, symbol, and symbol+label buttons; repeater mode
GUI SliderssliderFloat/sliderInt, knobFloat/knobInt, progress bar
GUI TogglesCheckboxes (independent), radio buttons (exclusive), selectables
GUI LabelsAll label variants: colored, aligned (L/C/R), wrapping, colored separators
GUI ComboLabel, color, and symbol combo/dropdowns; inline color picker
GUI ChartAnimated sine wave line chart and static column chart
GUI LayoutAll layout types: dynamic, static, row, template, space, groups
GUI TreeTree node and tab types; collapsible nested sections
GUI MenuMenubar (File/Edit) and right-click contextual menu
GUI PopupStatic/dynamic popups; simple and custom tooltips
GUI PropertypropertyFloat/propertyInt; filtered editString
GUI ThemeDark/light switch, accent color, rounding, alpha, font loading
GUI WindowWindow flags, bounds, show/hide, collapse, widget disable
GUI ShowcaseKitchen-sink: theme, sliders, checkboxes, radio, combos, menus, properties
ExampleDescription
Plume TriangleMinimal: load shader, create colored triangle mesh, draw
Mesh LinesLine list, line strip, and line loop draw modes
Mesh PointsPoint mesh with animated colors
Mesh IndexedIndexed cube (8 vertices, vertex map for 12 triangles)
Mesh Draw RangeAnimate draw range to reveal a grid of triangles over time
Mesh DynamicAnimated trianglestrip (circle with wave + color animation), setVertexAttribute + flush
Mesh AttributesAnimate per-vertex position and color via setVertexAttribute; GUI and terminal commands
Mesh PrimitivesThe MeshGen procedural factories (Block SPL): one of each primitive (box, cylinder, cone, plane, grid) in a row plus a sine-wave heightmap terrain, each returning a standard Mesh drawn with a lit N·L shader so the generated normals read correctly
Instanced Mesh GPUGPU-instanced rendering (SSBO): 1,000 animated cubes in a single draw call
Grass FieldEnhanced instancing (SSBO): 4,096 grass blades in one draw, each with its own colour + height + wind-phase (addInstanceColored/setInstanceParams), plus per-instance frustum culling (setCullingEnabled, visibleCount)
Material TexturesFull PBR material map set (base/metallic/roughness/normal/AO/emissive) assigned to a script mesh from Wren; derivative-TBN normal mapping
Custom Material PackA pack shader binds its own textures + params at set 5 (mesh.setCustomTexture/setCustomColor/setCustomParamFloat), read via #include "plume3d.slang" — no engine change
Wind SwayThe global frame-uniform block (set 0 binding 4): Graphics.setWind + the host frame clock drive a shader that sways and colour-pulses with plume3d_time()
RefractionOpaque colour capture (set 0 binding 6): Graphics.opaqueCaptureEnabled lets a transparent quad sample the captured opaque scene via plume3d_opaqueColor at a wobbled screen UV — colour bands bend through it
Sky DemoAtmosphere (A#6): a procedural gradient then an environment-cubemap sky (Graphics.setSky + Texture.loadCubemap/setEnvironmentMap), an ambient fill (setAmbient) and atmospheric distance fog (setFog) that dissolves a receding row of cubes
RTT MonitorScript render-to-texture (A#7): a picture-in-picture “monitor” panel shows the scene from a second camera, rendered into a persistent capture texture with Graphics.submitCapture and sampled through the set-5 material path (mesh.setCustomTexture) — a capture is just a Texture
Planar ReflectionPlanar reflection (A#4): a transparent water plane reflects a row of cubes floating above it — Graphics.setPlanarReflection(true, planeY) renders the scene mirrored across the plane into a half-res target (set 0 binding 7) that the water shader samples screen-space via plume3d_reflection
Scene DepthScene depth in the mesh ABI (PLM-263): a transparent quad reads the OPAQUE scene depth behind it at set 0 binding 5 — #include "plume3d.slang" → plume3d_sceneDepthLoad(int2(SV_Position.xy)) under the Graphics.opaqueCaptureEnabled(true) gate — and paints a shoreline that tracks four bands at four different depths (foam where geometry is close behind, blue where deep); the shoreline / foam / depth-tint primitive the Water pack is built on
Water Mask DemoWater masking (PLM-273): a transparent water plane discards fragments inside a boat’s world-XZ footprint so an open-hull boat sits dry (interior shows the seabed) instead of flooded — the footprint is a game-driven set-5 custom-param mask (setCustomColor at byte offsets 0/16), and arbitrary shapes drive the same discard from a mask texture. Plus a depth-based shoreline foam via the PLM-263 scene depth (binding 5). Zero engine change — composed from already-shipped surface
SplineThe Spline curve primitive (Block SPL): a 5-point Catmull-Rom curve drawn as a line strip at constant arc-length spacing (positionAtDistance), with sampleFrames(16) rotation-minimizing orientation frames drawn as gizmos (tangent red / normal green / binormal blue) — the 13-number frames a mesh extruder consumes
Spline Mesh DemoSpline mesh extrusion (Block SPL): a river MeshGen.ribbon swept along a spline and conformed onto a heightfield (each station snapped to the ground so the water hugs the hills) plus an arching MeshGen.tube, terrain built as one MeshGen.heightmap visual + a matching Jolt heightfield collider
Scatter DemoScatter / placement (Block SPL): ~10,600 foliage instances placed into one InstancedMesh two ways — Scatter.onSurface projects 8,000 blades onto a heightfield, Scatter.alongSpline lines 2,600 along a terrain-following path — one GPU-instanced draw with per-instance culling + wind sway
Scatter MultiTwo GPU-instanced meshes in one frame (PLM-257): green blades left, blue right — the per-draw instance-SSBO sub-allocation so multiple InstancedMeshes render independently (the prerequisite for multi-prototype scatter)
Toon Pack DemoThe Toon / Stylized-Shading content pack (PLM-261): a cel/toon surface shader (N·L quantized into hard bands + a Fresnel rim, tuned via set-5 params) plus a depth-edge ink outline post effect — a whole stylized look built with zero engine change, on only the mesh ABI, the post ABI, and Graphics.addPostEffect
Sky / Weather DemoThe Sky / Weather content pack (PLM-262): a pure-Wren TimeOfDay driver paints a full day/night cycle — sky, sun, ambient, fog — over the engine’s neutral A#6 atmosphere knobs (setSky / setAmbient / setFog + a directional sun Light) via apply(t), t in [0,1); the policy half of the engine-vs-pack boundary, with zero engine change. Steps sunrise → noon → sunset → night
Weather DemoThe Weather content pack (PLM-265): rain, snow, thunder, wind, dynamic clouds, height fog and rain-splash ripples, driven by a pure-Wren Weather state machine (clear/rain/snow/storm) over the engine’s neutral knobs, with zero engine change. Instanced rain/snow (GPU-animated fall via precip.slang, one draw each), a cloud sky shader on setSky (clouds.slang), a rain-ripple ground shader (wet_ground.slang) swapped in while raining, plus setAmbient/setFog/setFogHeight/setWind policy and a storm lightning flash. Combines the Toon pack’s shader half with the Sky pack’s policy half. Cycles clear → rain → snow → storm
Foliage Pack DemoThe Grass / Foliage / Trees content pack (PLM-266): instanced grass, foliage and trees with wind sway + back-light translucency (leaves glow when the sun is behind them), built with zero engine change — one foliage.slang on the enhanced-instancing path. A grass field + procedural trees (lit trunk + a canopy of instanced leaf cards), all foliage in one instanced draw. The demo proves the shader; the production path is Blender-authored — author → Bake Scatter (PLM-250) → Scene.loadBlendScene/instantiateScatter (Block BLD) → render with foliage.slang active. Authored-object colliders (PLM-267) and spawn masking (PLM-268 — a geometry-nodes density mask or the Bake-Scatter grayscale mask image) now ship; multi-part tree prototypes and LOD/billboards remain roadmap
Water DemoThe stylized Water content pack (PLM-273): stylized water in two variants side by side sharing one core — PBR (realistic) left, Toon (anime) right, over the same waves — built with zero engine change. The shared water_common.slangh (mesh ABI) does Gerstner waves + analytic/ripple normals, PLM-263 scene-depth colour + Beer–Lambert absorption, A#3 refraction (halo-guarded) and A#4 planar reflection + Schlick fresnel, and an infini-water horizon fade; each variant supplies only the style remap (PBR soft foam/spec vs Toon quantized bands + hard foam line + stepped glint + contact rim). Pure content on the set-5 custom params under the opaqueCaptureEnabled gate. Now also dips the camera below the surface for an underwater post (tint → deep, fog, wobble, caustic, vignette). The surface half; rivers and buoyancy have since shipped, while rain bloops, a masked buoyant hull, custom textures and per-bend flow remain follow-ups
River DemoA spline water mesh (PLM-273): a Catmull-Rom Spline swept into a MeshGen.ribbon with the shared stylized Toon water flowing downstream — the ripples and foam scroll along the global Graphics.setWind vector. Rocks in the channel make foam; the green banks give the PLM-263 depth-based shoreline. Zero engine change — the Block SPL spline/ribbon + the water pack. Per-bend flow is a follow-up
Water PlaygroundThe interactive water capstone (Block WTR2 — Water Fidelity, ADR 0094): free-fly and dive below the surface, toggle the Realistic ↔ Toon variant and the weather at runtime, and spawn buoyant crates/barrels that ride the same waves the surface renders. Composes the whole water program — the two surface variants, the new Graphics.setWaterPlane / Graphics.cameraWaterState camera-submersion API, an underwater post cross-faded on the submersion amount, a camera-facing waterline meniscus, and Water + Physics.applyBuoyancy buoyancy
Buoyancy DemoJolt buoyancy on the stylized water (PLM-270 / PLM-271, ADR 0091): the new Water class is the CPU mirror of the water shader’s Gerstner waves — one Water drives both the rendered surface (applyToMesh → set-5 p3) and the height query (heightAt), so floats bob on the waves you see. Physics.applyBuoyancy samples multiple probe points per body: rafts sampling their four corners visibly rock/tilt, while cubes at density 0.35 / 0.7 / 1.25 float at different heights (low = floats high + snappy, high = sits low + sluggish)
Water RaymarchA self-contained ray-marched stylized water scene — seabed, sky, foamy wave crests and turquoise caustic shallows — rendered entirely in one full-screen post shader with no scene geometry; the owner’s Slang-Playground shader (a gameidea.org stylized-water adaptation) ported to the Plume3D post ABI (#include "plume3d_post.slang", plume3d_time(), mouse via post param p0.xy, a can_draw trigger quad). Drag the mouse to orbit. A demo of the existing full-screen post path + Input, not a new engine feature
Toon WaterThe owner’s ray-marched TOON water ported onto a real mesh (water_toon.slang) — a banded depth palette, crisp cel foam at shorelines/crests, INK graphic marks, banded sun light and a toonSky rim reflection — over the same Alekseev octave waves as Water Raymarch’s seascape look, so buoyant floaters ride the visible swell. Sees the real scene (seabed + floaters) via the grab-pass + scene depth. Press 1 to compare the realistic Seascape look. A demo of the set-5 custom material + grab-pass + scene depth, not a new engine feature
Sprite DemoBillboarded sprites: one texture, four tinted camera-facing quads, depth-sorted by the engine
SDF Text DemoSDF text: world-space and screen-space labels, outline, wrapping, rich-text markup
UI DemoRetained-mode UI: a .ui card (title, subtitle, interactive button) loaded and rendered full-window
UI WidgetsRetained-UI interactive widgets: a toggle and a slider whose state the game polls to recolour a swatch
UI CanvasRetained-UI custom drawing: a game draws node boxes, bezier wires, and labels into a type="canvas" element
UI 9-Slice DemoRetained-UI textured 9-slice: two different-sized frames share one image-by-path PNG + a .ui.component sidecar, corners unstretched
UI Input DemoRetained-UI editable text input: a Name field (initial text) and a City field (placeholder), focus by click, read via elem.text
ExampleDescription
Save/Load DemoPersists a launch counter across runs with a typed, versioned SaveState + Save.write/Save.read
ExampleDescription
Coroutine DemoCooperative coroutines: a self-cycling traffic light (Async.wait) and a per-frame counter (Async.nextFrame), both engine-ticked each frame
ExampleDescription
TOML EditorGUI editor for game.toml (Game, Window, Physics layers, audio channels); runs standalone or against another app via --tool
UI EditorWYSIWYG visual editor for retained-UI .ui documents: element tree, inspector, live canvas, selection gizmo; runs standalone or against another app via --tool
Node EditorVisual node editor for animation-controller graphs: states as nodes, transitions as bezier wires; loads/edits/saves the controller TOML; runs standalone or via --tool