The pack
spriteShaders
function spriteShaders(): Pack<{ spriteShaders: SpriteShadersApi }>
The sprite shaders pack. Exposes game.spriteShaders; registers drawer 6 so the backend hands it every run of
sprites with a shader, in sorted order, and draws each with its own snippet (one draw call per sprite). Tweens and
fades run on the game clock. Headless it keeps every value and draws nothing. WebGPU and WebGL2.
Helpers
checkSpriteShader
function checkSpriteShader(def: SpriteShaderDef, opts: { maxCode?: number } = {}): string | null
Check a sprite shader definition the way add takes it, with no GPU: the name, the limits, reserved and redeclared
names, while/loop, texture calls, the margin, the length (default 8000 characters) and the WebGL2 translation. A
snippet the translator refuses would draw only on WebGPU, so add refuses it too. Returns the problem in one
sentence, or null.
SPRITE_SHADER_RECIPES
const SPRITE_SHADER_RECIPES: Readonly<Record<SpriteShaderRecipe, SpriteShaderDef>>
Eight ready sprite shaders, by name: a glow aura, burning (flames rising off the outline), frozen, electric arcs,
dissolve to embers (tween amount 0 → 1), hologram scanlines, golden shine, and a damage flash (tween hit; it never
strobes). Each is an ordinary definition: add it as it is, or copy it and change it.
spriteShaderEase
function spriteShaderEase(e: SpriteShaderEase | undefined): EaseFn
The curve an easing names: the maths pack's table by its own name (easeOutCubic, linear, sine) or by the
title screen file's spelling (cubicOut), or the function itself. Default easeInOutQuad. Unknown names throw.
Functions
checkSpriteShaderWith
function checkSpriteShaderWith(def: CheckedSpriteShader, translate: SnippetTranslator, opts: { maxCode?: number } = {}): string | null
Check a sprite shader definition the way the runtime takes it, with no GPU: the name, the sixteen-param and
four-colour limits, reserved and redeclared names, while/loop (a loop needs a constant bound or it can hang the
GPU), texture calls (the sprite is read with srcAt), the margin, the length (default 8000 characters) and the
WebGL2 translation (translate is render-webgl2's wgslSnippetToGLSL). Returns the problem in one sentence, or null.
ownsFade
function ownsFade(code: string): boolean
Does a snippet read fade (in its code, not its comments)? Then it fades itself: the template leaves color as the
snippet wrote it instead of mixing it with src by the fade, and the snippet must leave src at fade 0.
padProblem
function padProblem(pad: unknown): string | null
A margin's problem in one sentence, or null. A number is that fraction of the sprite's size on every side.
resolvePad
function resolvePad(pad: number | SpritePad | undefined, w: number, h: number): [number, number, number, number]
The margin in world units for a sprite of w × h world units: [left, top, right, bottom]. Assumes padProblem
found nothing; anything it would refuse reads as 0.
spriteShaderGLSL
function spriteShaderGLSL(code: string, keys: ReadonlyArray<string> = []): string
The GLSL fragment stage for a snippet: the WGSL translated (render-webgl2's wgslSnippetToGLSL, which throws naming
what it cannot translate) inside the same template. The dither and the blur's turn read the pixel from the top left,
as WebGPU's fragment position does, so both backends draw the same pixels.
spriteShaderScope
function spriteShaderScope(paramKeys: ReadonlyArray<string>): Record<string, string>
What a snippet can see, by GLSL type, as the WebGL2 translator is told it: the template's names and every param.
Constants
PAD_MAX_PX
const PAD_MAX_PX: 1024
The largest side a 'px' margin may take, in world units.
PAD_MAX_SIZE
const PAD_MAX_SIZE: 2
The largest side a 'size' margin may take: twice the sprite's own size.
SPRITE_FLOATS
const SPRITE_FLOATS: 60
Floats of uniform data one sprite draws with: fifteen vec4s, the same on both backends.
SPRITE_SHADER_HELPERS
const SPRITE_SHADER_HELPERS: Readonly<Record<string, { args: string[]; ret: string }>>
The helper functions the template declares beyond the shared hash21, noise2 and fbm2, as the translator is told them.
SPRITE_SHADER_RESERVED
const SPRITE_SHADER_RESERVED: ReadonlySet<string>
The names the sprite shader template declares itself: a param may not take one.
SPRITE_SHADERS_DRAWER_ID
const SPRITE_SHADERS_DRAWER_ID: 6
The drawBy id this pack registers its drawer under.
SPRITE_STRIDE
const SPRITE_STRIDE: 64
Floats between two sprites' data in the WebGPU uniform buffer: 256 bytes, the dynamic-offset alignment.
spriteShaderWGSL
const spriteShaderWGSL = (code: string, keys: ReadonlyArray<string> = []): string=> …
The whole WGSL a sprite shader runs as: the template around a definition's snippet (code), with its params named by
keys in order. A snippet that reads fade fades itself; any other is mixed with src by it. For tools and tests;
the runtime builds it once per snippet.
Types
CheckedSpriteShader
interface CheckedSpriteShader
The shape a check reads: a sprite shader definition.
name: string— Its name.code: string— The WGSL snippet.params?: Record<string, number>— Its params and defaults.colors?: Record<string, string>— Its colours.pad?: number | SpritePad— Its margin.
SnippetTranslator
type SnippetTranslator = (code: string, scope: Record<string, string>, helpers: Record<string, { args: string[]; ret: string }>) => string
The translator a check runs, as render-webgl2's wgslSnippetToGLSL: it throws naming what it cannot translate.
SpritePad
interface SpritePad
The margin a sprite shader draws into around the sprite, per side. unit 'size' (the default) reads each side as a
fraction of the sprite's own size on that axis (left and right of its width, top and bottom of its height), so the
effect scales with the sprite; 'px' reads them as world units (logical pixels at zoom 1). A side left out is 0.
top?: number— Above the sprite.right?: number— Right of it.bottom?: number— Below it.left?: number— Left of it.unit?: 'size' | 'px'— 'size' (default): fractions of the sprite's size; 'px': world units.
SpriteShaderDef
interface SpriteShaderDef
A sprite shader as data: a WGSL snippet run over one sprite and a margin around it. In scope: uv (0..1 over the
padded quad), suv (the sprite's own 0..1; outside it is the margin), size (the sprite's displayed size, world
units), px (suv * size), time (seconds), fade (the handle's show/hide, 0..1), TAU, hash21, noise2, fbm2, src and srcAt(p) (the sprite's
pixel, premultiplied and tinted; transparent outside it), alphaAt(p), edgeAt(p, r) (the most alpha within r
px), blurAt(p, r) (the alpha averaged over r px), c0..c3, p0..p15 and every param by name. It leaves the
sprite's whole new look, margin included, in color (premultiplied), which starts as src.
name: string— A name for messages and tools, e.g.'burning': a letter, then letters, digits,-or_.description?: string— One line: what it looks like.code: string— WGSL: the fragment body.colorstarts as the plain sprite (src); leave the premultiplied result in it. Light above alpha (rgb greater than a) adds to what is behind, for glows and flames. Nofn,while,loop,returnor texture calls: read the sprite withsrcAt,alphaAt,edgeAtandblurAt.params?: Record<string, number>— The params and their defaults, inp0..p15order, each also in scope by its name. At most sixteen.colors?: Record<string, string>— The colours and their default hex strings, inc0..c3order (straight rgba in the snippet). At most four.pad?: number | SpritePad— The margin the snippet may draw into around the sprite. A number is that fraction of the sprite's size on every side (0.25: a quarter of its width left and right, a quarter of its height above and below);{ top, right, bottom, left, unit }sets each side, in fractions of the size (unit: 'size', the default) or world units (unit: 'px'). Default 0: nothing outside the outline.
SpriteShaderEase
type SpriteShaderEase = EaseName | `${'sine' | 'quad' | 'cubic' | 'quart' | 'quint' | 'expo' | 'circ' | 'back' | 'elastic' | 'bounce'}${'In' | 'Out' | 'InOut'}` | EaseFn
An easing for tween, show and hide: a name from the maths pack's EASE table ('easeOutCubic', 'linear',
'sine'), the title screen file's spelling of the same curves ('cubicOut', 'sineInOut'), or a function of 0..1.
SpriteShaderHandle
interface SpriteShaderHandle
One sprite's shader, returned by game.spriteShaders.add(). Once removed it is inert: its calls do nothing.
readonly name: string— The definition's name.readonly sprite: Handle— The sprite it draws.readonly def: Readonly<SpriteShaderDef>— The definition, as it was added (a frozen copy).readonly removed: boolean— True once removed (byremove, by the sprite's death, by a lateraddon the same sprite, or by the scene's end).set(param: string, value: number): void— Set one param live. Throws on a name the definition does not declare, or a value that is not finite. Stops a tween of it. Set params and colours together, live. Throws on an unknown name, a non-finite number or a bad hex before changing anything. Stops tweens of the params it sets.set(values: SpriteShaderValues): void— Set one param live. Throws on a name the definition does not declare, or a value that is not finite. Stops a tween of it. Set params and colours together, live. Throws on an unknown name, a non-finite number or a bad hex before changing anything. Stops tweens of the params it sets.tween(params: Record<string, number>, opts?: SpriteShaderTweenOptions): Promise<void>— Ease params from where they are toparamsoverdurationseconds of game time (it pauses with the game). A param already tweening is taken over from where it is. Resolves when they arrive, or when replaced, set or removed. Throws on an unknown name or a non-finite number.show(opts?: SpriteShaderTweenOptions): Promise<void>— Ease the effect in over the plain sprite (fadeto 1), default 0.5 s. Resolves when shown, or when interrupted.hide(opts?: SpriteShaderTweenOptions): Promise<void>— Ease the effect out to the plain sprite (fadeto 0), default 0.5 s. Hidden, the sprite goes back to the plain sprite path and costs nothing;hide({ duration: 0 })right afteraddstarts it hidden, ready toshow.readonly fade: number— 0..1: how much of the effect is drawn now — 0 the plain sprite, 1 the effect, between them a mix; 1 unless shown or hidden.readonly params: Record<string, number>— Its params' values now, by name (a tween's current point); a fresh object each read.readonly colors: Record<string, string>— Its colours now, by name, as hex strings; a fresh object each read.time: number— The seconds its snippet'stimereads now: the game's clock plus this shader's own offset (0 atadd). Set it to jump (a tool's scrub, a restart from 0); it then runs on with the clock. Throws when not finite.remove(): void— Back to the plain sprite path. Idempotent; also run when the sprite dies, the scene ends, or another shader is added to the sprite. Its tweens end.
SpriteShaderOptions
interface SpriteShaderOptions extends SpriteShaderValues
What add takes beside the definition: values that override its defaults.
SpriteShaderRecipe
type SpriteShaderRecipe = 'glow' | 'burning' | 'frozen' | 'electric' | 'embers' | 'hologram' | 'gold' | 'damage'
The names of the ready looks in SPRITE_SHADER_RECIPES.
SpriteShadersApi
interface SpriteShadersApi
game.spriteShaders: custom shaders on single sprites.
add(sprite: Handle, def: SpriteShaderDef, opts?: SpriteShaderOptions): SpriteShaderHandle— Drawspritethroughdeffrom the next frame, in its sorted place, until removed.optsoverrides the definition's params and colours. One shader per sprite: adding another replaces it (the old handle is removed). Scene-scoped. Throws when the sprite is dead or an aggregate (a tilemap, a particle pool), when the definition failscheckSpriteShader(the message says why), or on an unknown param or colour name.of(sprite: Handle): SpriteShaderHandle | null— The shader on a sprite, or null.check(def: SpriteShaderDef): string | null—checkSpriteShader: a definition's problem in one sentence, or null.clear(): void— Remove every shader.failure(name: string): string | null— Why the shader namednamedraws as the plain sprite on this device: its compile error (WGSL on WebGPU, GLSL on WebGL2), or null. It arrives a frame or two after the shader is first drawn. For tools that show a shader's errors.readonly count: number— Sprites with a shader now.readonly drawn: number— Sprites drawn through a shader last frame.
SpriteShaderTweenOptions
interface SpriteShaderTweenOptions
How long a tween, show or hide takes and along which curve.
duration?: number— Seconds of game time; default 0.5. 0 is at once. Throws when negative or not finite.ease?: SpriteShaderEase— The curve; default'easeInOutQuad'(thetweenpack's). An unknown name throws.
SpriteShaderValues
interface SpriteShaderValues
Params and colours to set together: handle.set({ params: { heat: 2 }, colors: { flame: '#ff0' } }).
params?: Record<string, number>— Params by name.colors?: Record<string, string>— Colours by name, as hex strings (#rgb,#rgba,#rrggbb,#rrggbbaa; a missing alpha is opaque).

