DOCS v0.1.13 github

@hatch:game v0.3.37

Game framework for Wren. Game.run(MyGame) and you're rendering — subclass Game, override setup / update / draw, get a window + GPU device + per-frame loop wired in. Composes with @hatch:ecs / @hatch:assets / @hatch:audio / @hatch:physics for the rest of a game. Same source drives a winit window on native and a page-attached canvas on web. Scene-level constructs: Transform / GlobalTransform, MeshRenderer, ParticleSystem, lights, physics bridges, SceneRenderer3D, Terrain, Foliage, Wind, Water mesh + wave-height sampler, and WaterPipeline — a self-contained render pipeline that displaces the water mesh on the GPU with the same wave field the CPU sampler uses, fresnel-blends to a sky colour, and adds Blinn-Phong specular on the wave crests.

stable system updated Jun 6, 2026 source ↗
$ hatch add @hatch:game

MOD decals

CL Decal

NEW Decal.new(opts: Map)

GET Decal.position

GET Decal.normal

GET Decal.texture

GET Decal.sizeX

GET Decal.sizeY

GET Decal.rotation

GET Decal.age

GET Decal.lifetime

GET Decal.fadeIn

GET Decal.fadeOut

GET Decal.r

GET Decal.g

GET Decal.b

GET Decal.a

SET Decal.tint=(rgba: List)

FN Decal.static requireVec3_(opts, key)

FN Decal.step(dt) → Bool

CL DecalLayer

NEW DecalLayer.new(device: Device, surfaceFormat: String, depthFormat: String, texture: Texture, capacity: Num)

GET DecalLayer.count → Num

GET DecalLayer.capacity

FN DecalLayer.static SHADER_WGSL_

FN DecalLayer.static FLOATS_PER_DECAL_

FN DecalLayer.static BYTES_PER_DECAL_

FN DecalLayer.static SCENE_UBO_BYTES_

FN DecalLayer.static DEFAULT_CAPACITY_

FN DecalLayer.add(decal: Decal)

FN DecalLayer.clear()

FN DecalLayer.update(dt: Num)

FN DecalLayer.draw(pass: RenderPass, camera: Camera3D)

FN DecalLayer.writeMat4_(arr, off, m)

CL Decals

FN Decals.static register(layer: DecalLayer)

FN Decals.static unregister(layer: DecalLayer)

FN Decals.static clear()

FN Decals.static count

FN Decals.static update(dt: Num)

MOD foliage

CL Foliage

FN Foliage.static scatter(opts: Map) → Map

FN Foliage.static poisson(opts: Map) → Map

FN Foliage.static fromHeightmap(opts: Map) → Map

MOD particles

CL Particle_

NEW Particle_.new_()

GET Particle_.alive

GET Particle_.x

GET Particle_.y

GET Particle_.vx

GET Particle_.vy

GET Particle_.age

GET Particle_.life

GET Particle_.t_

GET Particle_.size_

GET Particle_.red_

GET Particle_.green_

GET Particle_.blue_

GET Particle_.alpha_

FN Particle_.set_(x, y, vx, vy, life, s0, s1, r0, g0, b0, a0, r1, g1, b1, a1)

FN Particle_.step_(dt, gx, gy, drag)

CL ParticleSystem

NEW ParticleSystem.new(opts: Map)

GET ParticleSystem.playing → Bool

GET ParticleSystem.start

GET ParticleSystem.stop

GET ParticleSystem.liveCount → Num

GET ParticleSystem.capacity → Num

FN ParticleSystem.static numOr_(opts, key, fallback)

FN ParticleSystem.static intOr_(opts, key, fallback)

FN ParticleSystem.static pairOr_(opts, key, fallbackX, fallbackY)

FN ParticleSystem.position(x: Num, y: Num)

FN ParticleSystem.burst(n: Num) → Num

FN ParticleSystem.spawnOne_()

FN ParticleSystem.update(dt: Num)

FN ParticleSystem.draw(renderer: Renderer2D)

FN ParticleSystem.static lerp_(a, b, t)

FN ParticleSystem.static rand_()

CL Particles

FN Particles.static register(system: ParticleSystem)

FN Particles.static unregister(system: ParticleSystem)

FN Particles.static clear()

FN Particles.static count → Num

FN Particles.static update(dt: Num)

CL ParticleSystem3D

NEW ParticleSystem3D.new(device: Device, opts: Map)

GET ParticleSystem3D.isPlaying

SET ParticleSystem3D.isPlaying=(b)

GET ParticleSystem3D.emissionRate → Num

SET ParticleSystem3D.emissionRate=(v)

GET ParticleSystem3D.liveCount

GET ParticleSystem3D.capacity

GET ParticleSystem3D.rotation → Num

SET ParticleSystem3D.rotation=(v)

GET ParticleSystem3D.deathCount → Num

GET ParticleSystem3D.deathPositions → Float32Array

FN ParticleSystem3D.static triple_(opts, key, fx, fy, fz)

FN ParticleSystem3D.setPosition(x: Num, y: Num, z: Num)

FN ParticleSystem3D.setWindDrift(vx: Num, vz: Num)

FN ParticleSystem3D.setScreenSpaceWidth(refDistance: Num)

FN ParticleSystem3D.setCameraEye(x: Num, y: Num, z: Num)

FN ParticleSystem3D.setKillPlane(y_plane: Num)

FN ParticleSystem3D.clearKillPlane()

FN ParticleSystem3D.consumeDeaths(fn: Fn)

FN ParticleSystem3D.burst(n: Num)

FN ParticleSystem3D.update(dt: Num)

FN ParticleSystem3D.spawnOne_()

FN ParticleSystem3D.random_()

FN ParticleSystem3D.draw(renderer: Renderer3D)

CL ParticleSim3DCore

FN ParticleSim3DCore.static integrate(sim, liveCount, params, deaths)

FN ParticleSim3DCore.static pack(sim, inst, liveCount, params)

MOD game

CL Input

NEW Input.new_()

GET Input.beginFrame_

GET Input.gamepadAxisMap → Map

GET Input.mouseX → Num

GET Input.mouseY → Num

GET Input.scrollX → Num

GET Input.scrollY → Num

FN Input.applyEvent_(e)

FN Input.gamepadJustPressed(code: String) → Bool

FN Input.gamepadJustReleased(code: String) → Bool

FN Input.gamepadDown(code: String) → Bool

FN Input.static normalizeKey_(s)

FN Input.isDown(key: String) → Bool

FN Input.justPressed(key: String) → Bool

FN Input.justReleased(key: String) → Bool

FN Input.mouseDown(button: String) → Bool

FN Input.mouseJustPressed(button: String) → Bool

FN Input.mouseJustReleased(button: String) → Bool

CL Viewport

NEW Viewport.new_(w, h)

GET Viewport.width → Num

GET Viewport.height → Num

GET Viewport.aspect → Num

GET Viewport.toString

CL GameState

NEW GameState.new_(window, device, surfaceFormat)

GET GameState.input → Input

GET GameState.depthFormat → String

SET GameState.depthFormat=(v)

GET GameState.depthView

SET GameState.depthView=(v)

GET GameState.colorView

SET GameState.colorView=(v)

GET GameState.window

GET GameState.device

GET GameState.surface

SET GameState.surface=(s)

GET GameState.surfaceFormat → String

GET GameState.pass

SET GameState.pass=(p)

GET GameState.events → List

SET GameState.events=(e)

GET GameState.dt → Num

SET GameState.dt=(v)

GET GameState.elapsed → Num

SET GameState.elapsed=(v)

GET GameState.tick → Num

SET GameState.tick=(v)

GET GameState.width → Num

GET GameState.height → Num

GET GameState.viewport → Viewport

GET GameState.lastTime_

SET GameState.lastTime_=(v)

GET GameState.startTime_

SET GameState.startTime_=(v)

GET GameState.encoder → CommandEncoder

SET GameState.encoder=(e)

GET GameState.postFX → PostFX

SET GameState.postFX=(p)

GET GameState.requestQuit

GET GameState.quitRequested → Bool

FN GameState.setViewport_(w, h)

FN GameState.set(key: String, value: Object)

FN GameState.get(key: String) → Object

FN GameState.has(key: String) → Bool

CL Game

NEW Game.new()

GET Game.config → Map

FN Game.setup(g: GameState)

FN Game.update(g: GameState)

FN Game.draw(g: GameState)

FN Game.resize(g: GameState, width: Num, height: Num)

FN Game.static DEFAULTS_

FN Game.static drainEvents_(events, g)

FN Game.static run(klass: Class)

MOD actions

CL Action_

NEW Action_.new_(name, bindings)

GET Action_.name

GET Action_.bindings

GET Action_.isDown

GET Action_.value

GET Action_.justPressed

GET Action_.justReleased

GET Action_.clearBindings

FN Action_.bind(codes)

FN Action_.addBinding(code)

FN Action_.evaluate_(input, axisMap)

FN Action_.bindingValue_(code, input, axisMap)

FN Action_.static mouseButton_(code)

CL Actions

FN Actions.static define(name: String, bindings: List<String>)

FN Actions.static bind(name: String, bindings: List<String>)

FN Actions.static addBinding(name: String, code: String)

FN Actions.static clearBindings(name: String)

FN Actions.static remove(name: String)

FN Actions.static reset()

FN Actions.static names → Sequence<String>

FN Actions.static bindings(name: String) → List<String>

FN Actions.static isDown(name: String) → Bool

FN Actions.static justPressed(name: String) → Bool

FN Actions.static justReleased(name: String) → Bool

FN Actions.static value(name: String) → Num

FN Actions.static emitter → EventEmitter

FN Actions.static on(name: String, fn: Fn) → Fn

FN Actions.static onReleased(name: String, fn: Fn) → Fn

FN Actions.static update_(input)

FN Actions.static update_(input, axisMap)

FN Actions.static ensureInit_()

FN Actions.static replaceEmitter_(em)

MOD sky

CL SkyboxPipeline

NEW SkyboxPipeline.new(device: Device, surfaceFormat: String, depthFormat: String | null)

GET SkyboxPipeline.destroy

FN SkyboxPipeline.static SCENE_UBO_BYTES_

FN SkyboxPipeline.setSun(direction: List, color: List, intensity: Num)

FN SkyboxPipeline.setSkyGradient(zenith: List, mid: List, horizon: List)

FN SkyboxPipeline.setClouds(coverage: Num, altitude: Num, softness: Num, tint: List)

FN SkyboxPipeline.setWind(windX: Num, windZ: Num)

FN SkyboxPipeline.setProjection(fovYDegrees: Num, aspect: Num)

FN SkyboxPipeline.beginFrame(pass: RenderPass, camera: Camera3D, time: Num)

FN SkyboxPipeline.draw()

FN SkyboxPipeline.endFrame()

FN SkyboxPipeline.putF_(arr, idx, label, v)

FN SkyboxPipeline.static SHADER_WGSL_

MOD weather

CL Wind

FN Wind.static sample(opts: Map, x: Num, y: Num, z: Num, t: Num) → List

FN Wind.static apply(opts: Map, x: Num, y: Num, z: Num, t: Num, dt: Num, velocity: List) → List

CL Weather

FN Weather.static rain(device: Device, opts: Map) → ParticleSystem3D | GpuParticleSystem3D

FN Weather.static snow(device: Device, opts: Map) → ParticleSystem3D

FN Weather.static fog(opts: Map) → Fog

MOD debug

CL FrameTimer

NEW FrameTimer.new(capacity: Num)

NEW FrameTimer.new()

GET FrameTimer.count → Num

GET FrameTimer.capacity

GET FrameTimer.avg → Num

GET FrameTimer.avgMs → Num

GET FrameTimer.fps

GET FrameTimer.lowFps

GET FrameTimer.reset

FN FrameTimer.tick(dt: Num)

CL DebugOverlay

NEW DebugOverlay.new()

GET DebugOverlay.isEnabled → Bool

SET DebugOverlay.isEnabled=(b)

GET DebugOverlay.timer

FN DebugOverlay.tick(dt: Num)

FN DebugOverlay.setCounter(name: String, value: Num)

FN DebugOverlay.counter(name: String) → Num

FN DebugOverlay.clearCounters()

FN DebugOverlay.draw(hud: HUD, x: Num, y: Num)

CL EntityInspector

NEW EntityInspector.new()

GET EntityInspector.toggle

GET EntityInspector.visible → Bool

SET EntityInspector.visible=(v: Bool)

GET EntityInspector.rows

SET EntityInspector.rows=(n: Num)

GET EntityInspector.panelWidth

SET EntityInspector.panelWidth=(w)

GET EntityInspector.scrollUp

GET EntityInspector.scrollDown

GET EntityInspector.selectedEntity → Num|Null

FN EntityInspector.tick(world: World)

FN EntityInspector.draw(hud: HUD, x: Num, y: Num) → Num

CL PhysicsDebugDraw

FN PhysicsDebugDraw.static run(world: World, hud: HUD, projectFn: Fn)

FN PhysicsDebugDraw.static runWith(world, hud, projectFn, color)

FN PhysicsDebugDraw.static colliderClass_(world)

FN PhysicsDebugDraw.static transformClass_(world)

FN PhysicsDebugDraw.static drawBox_(hud, projectFn, t, shape, color)

FN PhysicsDebugDraw.static drawBall_(hud, projectFn, t, shape, color)

FN PhysicsDebugDraw.static drawCapsule_(hud, projectFn, t, shape, color)

CL InputRecorder

NEW InputRecorder.new()

GET InputRecorder.frames → List<Map>

GET InputRecorder.count → Num

GET InputRecorder.reset

FN InputRecorder.record(snapshot: Map)

CL InputReplayer

NEW InputReplayer.new(frames: List<Map>)

GET InputReplayer.hasNext → Bool

GET InputReplayer.next → Map|Null

GET InputReplayer.cursor

GET InputReplayer.reset

MOD scene

CL Transform

NEW Transform.new()

NEW Transform.new(position: Vec3, rotation: Quat, scale: Vec3)

GET Transform.position

SET Transform.position=(v)

GET Transform.rotation

SET Transform.rotation=(q)

GET Transform.scale

SET Transform.scale=(v)

GET Transform.localMatrix

GET Transform.invalidate

GET Transform.toString

FN Transform.static identity

FN Transform.static translation(x, y, z)

FN Transform.setPosition(x: Num, y: Num, z: Num)

FN Transform.setRotation(w: Num, x: Num, y: Num, z: Num)

FN Transform.static buildTrsInto_(m, position, rotation, scale)

CL GlobalTransform

NEW GlobalTransform.new_(matrix: Mat4)

GET GlobalTransform.matrix

SET GlobalTransform.matrix=(m)

GET GlobalTransform.toString

CL MeshRenderer

NEW MeshRenderer.new(mesh: Mesh, material: Material)

GET MeshRenderer.mesh

SET MeshRenderer.mesh=(m)

GET MeshRenderer.material

SET MeshRenderer.material=(m)

GET MeshRenderer.visible

SET MeshRenderer.visible=(v)

GET MeshRenderer.toString

CL RigidBody

NEW RigidBody.new()

NEW RigidBody.new(kind: String)

NEW RigidBody.new(kind: String, mass: Num)

GET RigidBody.kind → String

SET RigidBody.kind=(v)

GET RigidBody.mass → Num

SET RigidBody.mass=(v)

GET RigidBody.linearVelocity → Vec3|Null

SET RigidBody.linearVelocity=(v)

GET RigidBody.bodyId → Num|Null

SET RigidBody.bodyId_=(id)

GET RigidBody.toString

CL Collider

NEW Collider.new(shape: Map)

GET Collider.shape → Map

SET Collider.shape=(s)

GET Collider.toString

CL PhysicsSystem3D

FN PhysicsSystem3D.static step(world: World, physicsWorld: Object, dt: Num)

FN PhysicsSystem3D.static spawnBody3d_(physicsWorld, kind, desc)

CL PhysicsSystem2D

FN PhysicsSystem2D.static step(world: World, physicsWorld: Object, dt: Num)

FN PhysicsSystem2D.static spawnBody2d_(physicsWorld, kind, desc)

CL AudioSource

NEW AudioSource.new()

NEW AudioSource.new(sound: Sound)

GET AudioSource.sound

SET AudioSource.sound=(s)

GET AudioSource.volume → Num

SET AudioSource.volume=(v)

GET AudioSource.loop → Bool

SET AudioSource.loop=(v)

GET AudioSource.spatial → Bool

SET AudioSource.spatial=(v)

GET AudioSource.toString

CL AudioListener

NEW AudioListener.new()

GET AudioListener.gain → Num

SET AudioListener.gain=(v)

GET AudioListener.toString

CL DirectionalLight

NEW DirectionalLight.new()

NEW DirectionalLight.new(color: Vec3, intensity: Num)

GET DirectionalLight.color → Vec3

SET DirectionalLight.color=(c)

GET DirectionalLight.intensity → Num

SET DirectionalLight.intensity=(v)

GET DirectionalLight.castsShadows → Bool

SET DirectionalLight.castsShadows=(v)

GET DirectionalLight.toString

CL PointLight

NEW PointLight.new()

NEW PointLight.new(color: Vec3, intensity: Num, range: Num)

GET PointLight.color

SET PointLight.color=(c)

GET PointLight.intensity

SET PointLight.intensity=(v)

GET PointLight.range → Num

SET PointLight.range=(v)

GET PointLight.toString

CL SpotLight

NEW SpotLight.new()

NEW SpotLight.new(color: Vec3, intensity: Num, range: Num, innerConeAngle: Num, outerConeAngle: Num)

GET SpotLight.color

SET SpotLight.color=(c)

GET SpotLight.intensity

SET SpotLight.intensity=(v)

GET SpotLight.range

SET SpotLight.range=(v)

GET SpotLight.innerConeAngle → Num

SET SpotLight.innerConeAngle=(v)

GET SpotLight.outerConeAngle → Num

SET SpotLight.outerConeAngle=(v)

GET SpotLight.toString

CL AmbientLight

NEW AmbientLight.new()

NEW AmbientLight.new(color: Vec3, intensity: Num)

GET AmbientLight.color

SET AmbientLight.color=(c)

GET AmbientLight.intensity

SET AmbientLight.intensity=(v)

GET AmbientLight.toString

CL TransformPropagation

FN TransformPropagation.static run(world)

FN TransformPropagation.static walk_(world, entity, parentMatrix)

CL SceneRenderer3D

FN SceneRenderer3D.static run(world: World, camera: Camera3D, renderer: Renderer3D, pass: RenderPass)

FN SceneRenderer3D.static runShadows(world: World, renderer: Renderer3D, encoder: CommandEncoder)

FN SceneRenderer3D.static runShadows(world: World, renderer: Renderer3D, encoder: CommandEncoder, center: Vec3)

MOD fog

CL Fog

NEW Fog.new()

GET Fog.color → List<Num>

SET Fog.color=(v: List<Num>)

GET Fog.start → Num

SET Fog.start=(v: Num)

GET Fog.end → Num

SET Fog.end=(v: Num)

GET Fog.density → Num

SET Fog.density=(v: Num)

GET Fog.curve → Num

SET Fog.curve=(v: Num)

MOD terrain_chunks

CL TerrainChunk

NEW TerrainChunk.new(device: Device, ix: Num, iz: Num, size: Num, res: Num, heightSampler: Fn)

GET TerrainChunk.ix

GET TerrainChunk.iz

GET TerrainChunk.size

GET TerrainChunk.res

GET TerrainChunk.heights

GET TerrainChunk.mesh

GET TerrainChunk.isAlive

GET TerrainChunk.centreX

GET TerrainChunk.centreZ

GET TerrainChunk.destroy

GET TerrainChunk.toString

CL TerrainStreamer

NEW TerrainStreamer.new(device: Device, opts: Map)

GET TerrainStreamer.chunkSize

GET TerrainStreamer.resolution

GET TerrainStreamer.radius

GET TerrainStreamer.activeChunks

GET TerrainStreamer.count

FN TerrainStreamer.update(focusX: Num, focusZ: Num)

FN TerrainStreamer.insertionSort_(arr)

FN TerrainStreamer.clear()

MOD terrain

CL Terrain

FN Terrain.static meshFromHeightmap(device: Device, heights: Float32Array, width: Num, depth: Num, opts: Map) → Mesh

FN Terrain.static fromNoise(device: Device, opts: Map) → Mesh

FN Terrain.static vertexCount(width: Num, depth: Num) → Num

FN Terrain.static indexCount(width: Num, depth: Num) → Num

MOD animation

CL Tween

NEW Tween.new(opts: Map)

GET Tween.from

GET Tween.to

GET Tween.duration

GET Tween.done → Bool

GET Tween.next_

SET Tween.next_=(v)

GET Tween.parallel_

FN Tween.static numOr_(opts, key, fallback)

FN Tween.then(next: Tween) → Tween

FN Tween.also(other: Tween) → Tween

FN Tween.reset()

FN Tween.step_(dt)

FN Tween.applyEasing_(t)

FN Tween.static resolveEase_(name, t)

CL Clip

NEW Clip.new(name: String, duration: Num, tracks: Map)

NEW Clip.withInterpolations(name: String, duration: Num, tracks: Map, interps: Map)

GET Clip.name

GET Clip.duration

GET Clip.tracks

GET Clip.interpolations

FN Clip.sample(t: Num) → Map<String, Num>

CL AnimationPlayer

NEW AnimationPlayer.new()

SET AnimationPlayer.speed=(v: Num)

GET AnimationPlayer.speed

SET AnimationPlayer.loop=(v: Bool)

GET AnimationPlayer.loop → Bool

GET AnimationPlayer.current → Map<String, Num>

GET AnimationPlayer.events → EventEmitter

FN AnimationPlayer.add(clip: Clip)

FN AnimationPlayer.play(name: String)

FN AnimationPlayer.crossfade(name: String, duration: Num)

FN AnimationPlayer.onSample(fn: Fn)

FN AnimationPlayer.update(dt: Num)

FN AnimationPlayer.bindStateChart(chart: StateChart, stateToClip: Map<String, String>)

FN AnimationPlayer.bindStateChart(chart: StateChart, stateToClip: Map<String, String>, fadeDuration: Num)

FN AnimationPlayer.static lookupClip_(map, toPath)

CL Tweens

FN Tweens.static add(tween: Tween) → Tween

FN Tweens.static cancel(tween: Tween)

FN Tweens.static cancelAll()

FN Tweens.static count → Num

FN Tweens.static update(dt: Num)

CL Behaviors

FN Behaviors.static wire(opts: Map)

MOD ecs_components

CL ActiveCamera

NEW ActiveCamera.new()

CL SpriteRenderer

NEW SpriteRenderer.new(sprite: Sprite)

GET SpriteRenderer.sprite

SET SpriteRenderer.sprite=(v)

GET SpriteRenderer.visible

SET SpriteRenderer.visible=(v)

GET SpriteRenderer.tint

SET SpriteRenderer.tint=(v)

CL Animator

NEW Animator.new(player: AnimationPlayer)

GET Animator.player

GET Animator.speed

SET Animator.speed=(v)

GET Animator.paused

SET Animator.paused=(v)

CL CameraSystem

FN CameraSystem.static active3D(world: World)

FN CameraSystem.static active2D(world: World)

CL SpriteRenderSystem

FN SpriteRenderSystem.static run(world: World, renderer: Renderer2D)

FN SpriteRenderSystem.static posOf_(transform)

CL AnimationSystem

FN AnimationSystem.static run(world: World, dt: Num)

CL AudioSystem

FN AudioSystem.static run(world: World)

FN AudioSystem.static lastListenerPos

FN AudioSystem.static lastSpatialCount

MOD water

CL Water

FN Water.static makePlane(device: Device, opts: Map) → Mesh

FN Water.static waveHeight(opts: Map, x: Num, z: Num, t: Num) → Num

CL WaterPipeline

NEW WaterPipeline.new(device: Device, surfaceFormat: String, depthFormat: String)

GET WaterPipeline.destroy

FN WaterPipeline.static SHADER_WGSL_

FN WaterPipeline.static SCENE_UBO_BYTES_

FN WaterPipeline.static SCENE_UBO_FLOATS_

FN WaterPipeline.static DRAW_UBO_BYTES_

FN WaterPipeline.static IMPACT_CAP_

FN WaterPipeline.static IMPACT_BYTES_

FN WaterPipeline.setSun(direction: List, color: List, intensity: Num)

FN WaterPipeline.setWave(amplitude: Num, scale: Num, timeScale: Num)

FN WaterPipeline.setColors(baseColor: List, skyColor: List, fresnelPow: Num)

FN WaterPipeline.setAmbient(ambient: List)

FN WaterPipeline.setFlow(dirX: Num, dirZ: Num, strength: Num)

FN WaterPipeline.setFoam(color: List, threshold: Num)

FN WaterPipeline.setShore(depthView: TextureView | null, near: Num, far: Num, bandMeters: Num)

FN WaterPipeline.setReflectionEnabled(enabled: Bool)

FN WaterPipeline.setShoreBand(bandMeters: Num)

FN WaterPipeline.setRipple(strength: Num, density: Num, lifetime: Num, speed: Num)

FN WaterPipeline.setRippleStrength(strength: Num)

FN WaterPipeline.setRippleDensity(density: Num)

FN WaterPipeline.setRippleScale(cellSize: Num)

FN WaterPipeline.setImpactRipple(strength: Num, lifetime: Num, speed: Num)

FN WaterPipeline.setImpactStrength(strength: Num)

FN WaterPipeline.addRipple(x: Num, z: Num)

FN WaterPipeline.setFog(fog: Fog)

FN WaterPipeline.beginFrame(pass: RenderPass, camera: Camera3D, time: Num)

FN WaterPipeline.putF_(arr, idx, label, v)

FN WaterPipeline.writeMat4_(arr, off, m)

FN WaterPipeline.draw(mesh: Mesh, model: Mat4)

FN WaterPipeline.endFrame()

FN WaterPipeline.rebuildSceneBindGroup_()

FN WaterPipeline.resize(width: Num, height: Num)

FN WaterPipeline.beginReflectionPass(encoder: CommandEncoder, clearColor: List) → RenderPass

FN WaterPipeline.reserveDrawSlot_()

FN WaterPipeline.appendMat4_(out, m)

MOD chain

CL PostPass

NEW PostPass.new()

GET PostPass.name → String

GET PostPass.fragmentBody → String

GET PostPass.uniformWgsl → String

GET PostPass.uniformBytes → Num

GET PostPass.stepCount → Num

GET PostPass.wantsDepth → Bool

GET PostPass.pipelines_

GET PostPass.bindGroups_

GET PostPass.uniformBuffer_

GET PostPass.intermediates_

FN PostPass.writeUniforms(scratch: List<Num>)

FN PostPass.requestTargets(width: Num, height: Num) → List<Map>

FN PostPass.onAdded_(orchestrator: PostFX)

FN PostPass.dispatchStep_(orchestrator: PostFX, encoder: CommandEncoder, ctx: Map)

FN PostPass.setIntermediates_(t)

CL PostFXShader_

FN PostFXShader_.static VERTEX_WGSL

FN PostFXShader_.static buildSource(pass)

CL PostFX

NEW PostFX.new(g: GameState)

NEW PostFX.new(g, opts)

GET PostFX.device_

GET PostFX.surfaceFormat_

GET PostFX.sampler_

GET PostFX.bglUniform_

GET PostFX.bglPlain_

GET PostFX.bglUniformDepth_

GET PostFX.bglPlainDepth_

GET PostFX.vertexWgsl_ → String

GET PostFX.count → Num

GET PostFX.sceneView_ → TextureView

GET PostFX.sceneDepthView_ → TextureView

GET PostFX.sceneNormalView_ → TextureView

GET PostFX.normalFormat_ → String

FN PostFX.init_(g, opts)

FN PostFX.add(pass: PostPass)

FN PostFX.clear()

FN PostFX.buildFragmentPipeline_(pass: PostPass) → RenderPipeline

FN PostFX.pickLayout_(pass)

FN PostFX.pickBindGroupLayout_(pass)

FN PostFX.runFragmentStep_(pass: PostPass, encoder: CommandEncoder, ctx: Map, pipelineIdx: Num)

FN PostFX.buildOrCacheBindGroup_(pass, pipelineIdx, inputView, depthView)

FN PostFX.resize_(width: Num, height: Num)

FN PostFX.destroyView_(v)

FN PostFX.destroyTex_(t)

FN PostFX.runChain(encoder: CommandEncoder, finalView: TextureView)

MOD gpu_particles

CL GpuParticleSystem3D

NEW GpuParticleSystem3D.new(device: Device, opts: Map)

GET GpuParticleSystem3D.capacity

GET GpuParticleSystem3D.emissionRate

SET GpuParticleSystem3D.emissionRate=(v)

GET GpuParticleSystem3D.isPlaying

SET GpuParticleSystem3D.isPlaying=(b)

GET GpuParticleSystem3D.rotation

SET GpuParticleSystem3D.rotation=(v)

FN GpuParticleSystem3D.static COMPUTE_WGSL_

FN GpuParticleSystem3D.static FLOATS_PER_STATE_

FN GpuParticleSystem3D.static FLOATS_PER_RENDER_

FN GpuParticleSystem3D.static FLOATS_PER_PARAMS_

FN GpuParticleSystem3D.static PARAMS_UBO_BYTES_

FN GpuParticleSystem3D.static numOr_(opts, key, fallback)

FN GpuParticleSystem3D.static intOr_(opts, key, fallback)

FN GpuParticleSystem3D.static pairOr_(opts, key, fx, fy)

FN GpuParticleSystem3D.static triple_(opts, key, fx, fy, fz)

FN GpuParticleSystem3D.setPosition(x, y, z)

FN GpuParticleSystem3D.setWindDrift(vx, vz)

FN GpuParticleSystem3D.setWind(dx: Num, dy: Num, dz: Num, strength: Num)

FN GpuParticleSystem3D.setWindNoise(scale: Num, timeScale: Num, amplitude: Num, align: Num)

FN GpuParticleSystem3D.update(dt: Num)

FN GpuParticleSystem3D.seedSpawns_(n)

FN GpuParticleSystem3D.compute(encoder: CommandEncoder)

FN GpuParticleSystem3D.writeParams_()

FN GpuParticleSystem3D.draw(renderer: Renderer3D)

FN GpuParticleSystem3D.random_()