lantern-engine 0.0.0-stage → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/LICENSE +21 -0
  3. package/README.md +113 -2
  4. package/dist/assets/takeCleanerWorker-DTcI_Jqr.js +31 -0
  5. package/dist/assets/takeCleanerWorker-DTcI_Jqr.js.map +1 -0
  6. package/dist/constants-CjYVdFid.js +252 -0
  7. package/dist/constants-CjYVdFid.js.map +1 -0
  8. package/dist/lantern-engine.js +3473 -0
  9. package/dist/lantern-engine.js.map +1 -0
  10. package/dist/pixel.js +1404 -0
  11. package/dist/pixel.js.map +1 -0
  12. package/dist/types/anim/Animator.d.ts +50 -0
  13. package/dist/types/anim/Animator.d.ts.map +1 -0
  14. package/dist/types/anim/animationSystem.d.ts +13 -0
  15. package/dist/types/anim/animationSystem.d.ts.map +1 -0
  16. package/dist/types/assets/AssetLoader.d.ts +85 -0
  17. package/dist/types/assets/AssetLoader.d.ts.map +1 -0
  18. package/dist/types/audio/MusicPlayer.d.ts +57 -0
  19. package/dist/types/audio/MusicPlayer.d.ts.map +1 -0
  20. package/dist/types/audio/SoundEngine.d.ts +42 -0
  21. package/dist/types/audio/SoundEngine.d.ts.map +1 -0
  22. package/dist/types/audio/cleanTake.d.ts +3 -0
  23. package/dist/types/audio/cleanTake.d.ts.map +1 -0
  24. package/dist/types/audio/sampleBank.d.ts +27 -0
  25. package/dist/types/audio/sampleBank.d.ts.map +1 -0
  26. package/dist/types/audio/soundTable.d.ts +14 -0
  27. package/dist/types/audio/soundTable.d.ts.map +1 -0
  28. package/dist/types/audio/synth.d.ts +34 -0
  29. package/dist/types/audio/synth.d.ts.map +1 -0
  30. package/dist/types/audio/takeCleanerWorker.d.ts +2 -0
  31. package/dist/types/audio/takeCleanerWorker.d.ts.map +1 -0
  32. package/dist/types/core/BitmapLabel.d.ts +26 -0
  33. package/dist/types/core/BitmapLabel.d.ts.map +1 -0
  34. package/dist/types/core/Camera.d.ts +90 -0
  35. package/dist/types/core/Camera.d.ts.map +1 -0
  36. package/dist/types/core/Clock.d.ts +11 -0
  37. package/dist/types/core/Clock.d.ts.map +1 -0
  38. package/dist/types/core/Graphics.d.ts +37 -0
  39. package/dist/types/core/Graphics.d.ts.map +1 -0
  40. package/dist/types/core/Group.d.ts +15 -0
  41. package/dist/types/core/Group.d.ts.map +1 -0
  42. package/dist/types/core/Image.d.ts +25 -0
  43. package/dist/types/core/Image.d.ts.map +1 -0
  44. package/dist/types/core/ObjectFactory.d.ts +34 -0
  45. package/dist/types/core/ObjectFactory.d.ts.map +1 -0
  46. package/dist/types/core/Pointer.d.ts +27 -0
  47. package/dist/types/core/Pointer.d.ts.map +1 -0
  48. package/dist/types/core/Rectangle.d.ts +26 -0
  49. package/dist/types/core/Rectangle.d.ts.map +1 -0
  50. package/dist/types/core/Stage.d.ts +58 -0
  51. package/dist/types/core/Stage.d.ts.map +1 -0
  52. package/dist/types/core/Text.d.ts +22 -0
  53. package/dist/types/core/Text.d.ts.map +1 -0
  54. package/dist/types/core/TextureRegistry.d.ts +51 -0
  55. package/dist/types/core/TextureRegistry.d.ts.map +1 -0
  56. package/dist/types/core/Tweener.d.ts +53 -0
  57. package/dist/types/core/Tweener.d.ts.map +1 -0
  58. package/dist/types/core/atlas.d.ts +16 -0
  59. package/dist/types/core/atlas.d.ts.map +1 -0
  60. package/dist/types/core/atlasPlan.d.ts +34 -0
  61. package/dist/types/core/atlasPlan.d.ts.map +1 -0
  62. package/dist/types/core/eases.d.ts +3 -0
  63. package/dist/types/core/eases.d.ts.map +1 -0
  64. package/dist/types/core/gameObject.d.ts +42 -0
  65. package/dist/types/core/gameObject.d.ts.map +1 -0
  66. package/dist/types/core/pixiPatches.d.ts +9 -0
  67. package/dist/types/core/pixiPatches.d.ts.map +1 -0
  68. package/dist/types/core/types.d.ts +4 -0
  69. package/dist/types/core/types.d.ts.map +1 -0
  70. package/dist/types/ecs/SparseSet.d.ts +25 -0
  71. package/dist/types/ecs/SparseSet.d.ts.map +1 -0
  72. package/dist/types/ecs/World.d.ts +133 -0
  73. package/dist/types/ecs/World.d.ts.map +1 -0
  74. package/dist/types/ecs/fields.d.ts +34 -0
  75. package/dist/types/ecs/fields.d.ts.map +1 -0
  76. package/dist/types/engine/Engine.d.ts +80 -0
  77. package/dist/types/engine/Engine.d.ts.map +1 -0
  78. package/dist/types/engine/FixedLoop.d.ts +32 -0
  79. package/dist/types/engine/FixedLoop.d.ts.map +1 -0
  80. package/dist/types/engine/Scene.d.ts +37 -0
  81. package/dist/types/engine/Scene.d.ts.map +1 -0
  82. package/dist/types/engine/SceneManager.d.ts +31 -0
  83. package/dist/types/engine/SceneManager.d.ts.map +1 -0
  84. package/dist/types/events/EventBus.d.ts +20 -0
  85. package/dist/types/events/EventBus.d.ts.map +1 -0
  86. package/dist/types/fx/hitStop.d.ts +20 -0
  87. package/dist/types/fx/hitStop.d.ts.map +1 -0
  88. package/dist/types/fx/viewCull.d.ts +14 -0
  89. package/dist/types/fx/viewCull.d.ts.map +1 -0
  90. package/dist/types/index.d.ts +68 -0
  91. package/dist/types/index.d.ts.map +1 -0
  92. package/dist/types/input/Actions.d.ts +75 -0
  93. package/dist/types/input/Actions.d.ts.map +1 -0
  94. package/dist/types/input/Keyboard.d.ts +25 -0
  95. package/dist/types/input/Keyboard.d.ts.map +1 -0
  96. package/dist/types/input/aimAxis.d.ts +9 -0
  97. package/dist/types/input/aimAxis.d.ts.map +1 -0
  98. package/dist/types/input/longPress.d.ts +21 -0
  99. package/dist/types/input/longPress.d.ts.map +1 -0
  100. package/dist/types/input/stickAxis.d.ts +26 -0
  101. package/dist/types/input/stickAxis.d.ts.map +1 -0
  102. package/dist/types/input/touchDetect.d.ts +18 -0
  103. package/dist/types/input/touchDetect.d.ts.map +1 -0
  104. package/dist/types/light/LightLayer.d.ts +65 -0
  105. package/dist/types/light/LightLayer.d.ts.map +1 -0
  106. package/dist/types/net/Connection.d.ts +66 -0
  107. package/dist/types/net/Connection.d.ts.map +1 -0
  108. package/dist/types/net/InterpolationBuffer.d.ts +36 -0
  109. package/dist/types/net/InterpolationBuffer.d.ts.map +1 -0
  110. package/dist/types/net/PredictedMover.d.ts +43 -0
  111. package/dist/types/net/PredictedMover.d.ts.map +1 -0
  112. package/dist/types/net/Room.d.ts +69 -0
  113. package/dist/types/net/Room.d.ts.map +1 -0
  114. package/dist/types/net/RoomHost.d.ts +74 -0
  115. package/dist/types/net/RoomHost.d.ts.map +1 -0
  116. package/dist/types/net/cadence.d.ts +22 -0
  117. package/dist/types/net/cadence.d.ts.map +1 -0
  118. package/dist/types/net/constants.d.ts +24 -0
  119. package/dist/types/net/constants.d.ts.map +1 -0
  120. package/dist/types/net/movement.d.ts +50 -0
  121. package/dist/types/net/movement.d.ts.map +1 -0
  122. package/dist/types/net/protocol.d.ts +59 -0
  123. package/dist/types/net/protocol.d.ts.map +1 -0
  124. package/dist/types/net/serverClock.d.ts +14 -0
  125. package/dist/types/net/serverClock.d.ts.map +1 -0
  126. package/dist/types/net/snapshotCodec.d.ts +55 -0
  127. package/dist/types/net/snapshotCodec.d.ts.map +1 -0
  128. package/dist/types/pixel/Darkness.d.ts +78 -0
  129. package/dist/types/pixel/Darkness.d.ts.map +1 -0
  130. package/dist/types/pixel/Evaporation.d.ts +30 -0
  131. package/dist/types/pixel/Evaporation.d.ts.map +1 -0
  132. package/dist/types/pixel/PixelLayer.d.ts +85 -0
  133. package/dist/types/pixel/PixelLayer.d.ts.map +1 -0
  134. package/dist/types/pixel/index.d.ts +22 -0
  135. package/dist/types/pixel/index.d.ts.map +1 -0
  136. package/dist/types/pixel/lights.d.ts +34 -0
  137. package/dist/types/pixel/lights.d.ts.map +1 -0
  138. package/dist/types/pixel/palette.d.ts +54 -0
  139. package/dist/types/pixel/palette.d.ts.map +1 -0
  140. package/dist/types/pixel/pixel.d.ts +80 -0
  141. package/dist/types/pixel/pixel.d.ts.map +1 -0
  142. package/dist/types/pixel/pixelPaint.d.ts +43 -0
  143. package/dist/types/pixel/pixelPaint.d.ts.map +1 -0
  144. package/dist/types/pixel/pixelTone.d.ts +49 -0
  145. package/dist/types/pixel/pixelTone.d.ts.map +1 -0
  146. package/dist/types/pixel/propKit.d.ts +26 -0
  147. package/dist/types/pixel/propKit.d.ts.map +1 -0
  148. package/dist/types/pixel/ramp.d.ts +31 -0
  149. package/dist/types/pixel/ramp.d.ts.map +1 -0
  150. package/dist/types/pixel/selout.d.ts +3 -0
  151. package/dist/types/pixel/selout.d.ts.map +1 -0
  152. package/dist/types/pixel/spritePixels.d.ts +29 -0
  153. package/dist/types/pixel/spritePixels.d.ts.map +1 -0
  154. package/dist/types/platform/touch.d.ts +5 -0
  155. package/dist/types/platform/touch.d.ts.map +1 -0
  156. package/dist/types/rig/PosePlayer.d.ts +64 -0
  157. package/dist/types/rig/PosePlayer.d.ts.map +1 -0
  158. package/dist/types/rig/RigView.d.ts +68 -0
  159. package/dist/types/rig/RigView.d.ts.map +1 -0
  160. package/dist/types/rig/Skeleton.d.ts +14 -0
  161. package/dist/types/rig/Skeleton.d.ts.map +1 -0
  162. package/dist/types/rig/humanoid.d.ts +4 -0
  163. package/dist/types/rig/humanoid.d.ts.map +1 -0
  164. package/dist/types/rig/humanoidPoses.d.ts +117 -0
  165. package/dist/types/rig/humanoidPoses.d.ts.map +1 -0
  166. package/dist/types/rig/poseMath.d.ts +14 -0
  167. package/dist/types/rig/poseMath.d.ts.map +1 -0
  168. package/dist/types/rig/rigTypes.d.ts +82 -0
  169. package/dist/types/rig/rigTypes.d.ts.map +1 -0
  170. package/dist/types/settings.d.ts +25 -0
  171. package/dist/types/settings.d.ts.map +1 -0
  172. package/dist/types/tilemap/TilemapView.d.ts +42 -0
  173. package/dist/types/tilemap/TilemapView.d.ts.map +1 -0
  174. package/dist/types/tilemap/collision.d.ts +16 -0
  175. package/dist/types/tilemap/collision.d.ts.map +1 -0
  176. package/dist/types/tilemap/tiled.d.ts +104 -0
  177. package/dist/types/tilemap/tiled.d.ts.map +1 -0
  178. package/package.json +82 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pixel.js","sources":["../src/pixel/PixelLayer.ts","../src/pixel/pixel.ts","../src/pixel/palette.ts","../src/pixel/ramp.ts","../src/pixel/propKit.ts","../src/pixel/selout.ts","../src/pixel/pixelTone.ts","../src/pixel/pixelPaint.ts","../src/pixel/Evaporation.ts","../src/pixel/spritePixels.ts","../src/pixel/lights.ts","../src/pixel/Darkness.ts"],"sourcesContent":["import { BufferImageSource, Sprite, Texture } from 'pixi.js';\nimport { Graphics } from '../core/Graphics';\nimport { patchPixi } from '../core/pixiPatches';\nimport type { Stage } from '../core/Stage';\n\npatchPixi();\n\n/** Larger than this a frame is laid as rects after all: a texture that size is no saving. */\nconst MAX_SIDE = 1024;\n/**\n * The sides a buffer is made in, each about a third to a half over the last: a layer that swells frame by frame\n * crosses a handful of them, not one every 32 px, and a spent buffer fits the next layer of its class (`POOL`).\n */\nconst SIDES = [16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024];\n/** Spent buffers kept per size class, and in all, for the next layers to take instead of making a texture. */\nconst POOL_PER_CLASS = 24;\nconst POOL_MAX_BYTES = 24 * 1024 * 1024;\n/** A layer whose frames have stayed this many presents well inside a quarter of its buffer trades it for a smaller one. */\nconst SHRINK_AFTER = 60;\n\n/** One buffer, the texture over it, and its size: what a layer holds and the pool keeps. */\ninterface Surface {\n pixels: Uint8Array;\n words: Uint32Array;\n source: BufferImageSource;\n texture: Texture;\n capW: number;\n capH: number;\n}\n\nconst POOL = new Map<number, Surface[]>();\nlet pooledBytes = 0;\n/** Textures made since boot (`PixelLayer.stats`): the pool is working when this stops climbing. */\nlet made = 0;\n\nconst sideFor = (n: number): number => {\n for (const s of SIDES) if (s >= n) return s;\n return Math.ceil(n / 256) * 256;\n};\nconst classOf = (w: number, h: number) => w * 4096 + h;\n\nfunction takeSurface(capW: number, capH: number): Surface {\n // the exact class, else the smallest pooled one that holds it within twice its area: a 48×24 frame takes a spent\n // 48×32 rather than making a texture of its own\n let list = POOL.get(classOf(capW, capH));\n if (!list?.length) {\n let best = Infinity;\n for (const [k, l] of POOL) {\n if (!l.length) continue;\n const w = Math.floor(k / 4096);\n const h = k % 4096;\n const area = w * h;\n if (w >= capW && h >= capH && area <= capW * capH * 2 && area < best) {\n best = area;\n list = l;\n }\n }\n }\n const hit = list?.pop();\n if (hit) {\n pooledBytes -= hit.pixels.byteLength;\n return hit;\n }\n made++;\n const pixels = new Uint8Array(capW * capH * 4);\n const source = new BufferImageSource({\n resource: pixels,\n width: capW,\n height: capH,\n format: 'rgba8unorm',\n alphaMode: 'premultiplied-alpha',\n scaleMode: 'nearest',\n });\n return { pixels, words: new Uint32Array(pixels.buffer), source, texture: new Texture({ source }), capW, capH };\n}\n\nfunction giveSurface(s: Surface): void {\n const key = classOf(s.capW, s.capH);\n let list = POOL.get(key);\n if (!list) POOL.set(key, (list = []));\n if (list.length >= POOL_PER_CLASS || pooledBytes + s.pixels.byteLength > POOL_MAX_BYTES) {\n s.texture.destroy(true);\n return;\n }\n list.push(s);\n pooledBytes += s.pixels.byteLength;\n}\n\n/**\n * A `Graphics` for the pixel effects: every `fillRect` of a frame is written into a small RGBA buffer\n * and shown as **one** sprite, instead of becoming a rect Pixi must tessellate, batch and upload. An effect's frame is\n * hundreds to thousands of one-pixel runs (a poison cloud, a status mark round every body in a pack), and as rects they\n * were most of a fight's CPU on a phone (profiled). The pixels are the same: whole\n * world pixels, a translucent fill blended over what was painted before it in the same frame, as a Graphics did.\n *\n * Paint between `clear()` and `present()`; anything other than `fillStyle`/`fillRect` still draws through the\n * Graphics underneath, so a painter using another shape keeps working. Solid pixels may also be **staged**\n * (`stage`, from `pixelTone`'s batch) and laid in one go by `commit`, which is what a batch's flush does.\n *\n * Buffers and their textures are pooled by size class (a texture per effect ran to ~114 a second in a busy fight,\n * and each one stayed in Pixi's batch tables), so a destroyed layer hands its texture\n * to the next one; `PixelLayer.drainPool` lets them all go when the map changes.\n */\n/** A new `PixelLayer` on the stage's world layer. */\nexport function addPixelLayer(stage: Stage): PixelLayer {\n return stage.add.existing(new PixelLayer());\n}\n\nexport class PixelLayer extends Graphics {\n /** This frame's rects: x, y, w, h, colour, alpha — six numbers each. */\n private readonly rects: number[] = [];\n /** Staged solid runs not yet committed: x, y, w, colour — four numbers each; later ones win. */\n private readonly staged: number[] = [];\n private ink = 0xffffff;\n private inkAlpha = 1;\n private readonly sprite = new Sprite(Texture.EMPTY);\n private surface: Surface | null = null;\n /** Where the buffer's first pixel sits in the layer, as of the last `present`. */\n private originX = 0;\n private originY = 0;\n /** The last frame's size, and how many presents in a row it stayed well inside a quarter of the buffer. */\n private lastW = 0;\n private lastH = 0;\n private small = 0;\n\n constructor() {\n super();\n this.sprite.visible = false;\n this.addChild(this.sprite);\n }\n\n /** Textures made, spent buffers waiting in the pool and their bytes (the leak tools read it). */\n static stats(): { made: number; pooled: number; pooledBytes: number } {\n let pooled = 0;\n for (const l of POOL.values()) pooled += l.length;\n return { made, pooled, pooledBytes };\n }\n\n /** Lets every pooled buffer go (the world changed map): the next map's effects start a pool of their own. */\n static drainPool(): void {\n for (const list of POOL.values()) for (const s of list) s.texture.destroy(true);\n POOL.clear();\n pooledBytes = 0;\n }\n\n override fillStyle(color: number, alpha = 1): this {\n this.ink = color;\n this.inkAlpha = alpha;\n return super.fillStyle(color, alpha);\n }\n\n override fillRect(x: number, y: number, w: number, h: number): this {\n const x0 = Math.round(x);\n const y0 = Math.round(y);\n const rw = Math.round(x + w) - x0;\n const rh = Math.round(y + h) - y0;\n if (rw > 0 && rh > 0 && this.inkAlpha > 0) this.rects.push(x0, y0, rw, rh, this.ink, this.inkAlpha);\n return this;\n }\n\n /** `fillStyle` + `fillRect` on whole pixels in one call, leaving the fill style alone (a hot loop's way in). */\n rect(x: number, y: number, w: number, h: number, color: number, alpha = 1): void {\n // a coordinate off to Infinity or NaN would make the frame's box endless (`present`), so it is dropped here\n if (w > 0 && h > 0 && alpha > 0 && Number.isFinite(x) && Number.isFinite(y) && Number.isFinite(w) && Number.isFinite(h)) this.rects.push(x, y, w, h, color, alpha);\n }\n\n /**\n * A solid run of `w` whole pixels at (x, y) in `color`, held until `commit` lays every staged run in the order given\n * (the later winning where they cross), after whatever was drawn before the commit. What `pixelTone`'s batch writes\n * instead of filing each pixel in a map and sorting it into rects.\n */\n stage(x: number, y: number, w: number, color: number): void {\n if (Number.isFinite(x) && Number.isFinite(y) && Number.isFinite(w)) this.staged.push(x, y, w, color);\n }\n\n /** Lays the staged runs, as opaque rects, after everything drawn so far. */\n commit(): void {\n const s = this.staged;\n const n = s.length;\n if (n === 0) return;\n const r = this.rects;\n for (let i = 0; i < n; i += 4) r.push(s[i]!, s[i + 1]!, s[i + 2]!, 1, s[i + 3]!, 1);\n s.length = 0;\n }\n\n override clear(): this {\n this.rects.length = 0;\n this.staged.length = 0;\n return super.clear();\n }\n\n /** How far the last frame reached from the layer's origin, in world pixels (0 when nothing showed). */\n reach(): number {\n if (!this.sprite.visible) return 0;\n return Math.max(Math.abs(this.originX), Math.abs(this.originY), Math.abs(this.originX + this.lastW), Math.abs(this.originY + this.lastH));\n }\n\n /** Writes this frame's rects into the texture and shows it; call once the frame is painted. */\n present(): void {\n this.commit();\n const r = this.rects;\n if (r.length === 0) {\n this.sprite.visible = false;\n return;\n }\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (let i = 0; i < r.length; i += 6) {\n if (r[i]! < minX) minX = r[i]!;\n if (r[i + 1]! < minY) minY = r[i + 1]!;\n if (r[i]! + r[i + 2]! > maxX) maxX = r[i]! + r[i + 2]!;\n if (r[i + 1]! + r[i + 3]! > maxY) maxY = r[i + 1]! + r[i + 3]!;\n }\n const w = maxX - minX;\n const h = maxY - minY;\n if (w > MAX_SIDE || h > MAX_SIDE) {\n this.sprite.visible = false;\n // the Graphics' own fillRect, never chained off `super.fillStyle(…)`: that returns `this`, so `.fillRect` was this\n // class's, which pushed every rect back onto `r` while it was walked — the loop never ended and grew the array to\n // a gigabyte (a body evaporating far across the screen froze PCs for seconds and killed mobile web views)\n const n = r.length;\n for (let i = 0; i < n; i += 6) {\n super.fillStyle(r[i + 4]!, r[i + 5]!);\n super.fillRect(r[i]!, r[i + 1]!, r[i + 2]!, r[i + 3]!);\n }\n return;\n }\n const surface = this.fit(w, h);\n const { words, pixels, capW: cap } = surface;\n // the whole buffer: the sprite always shows all of it at one texel a world pixel. Cropping the texture's frame to\n // this frame's size instead stretched it to the old size (a Pixi sprite is sized by `orig`), and an effect that\n // shrank — a falling column — came down as blocks blown up several times over\n words.fill(0);\n for (let i = 0; i < r.length; i += 6) {\n const x0 = r[i]! - minX;\n const y0 = r[i + 1]! - minY;\n const rw = r[i + 2]!;\n const rh = r[i + 3]!;\n const c = r[i + 4]!;\n const a = r[i + 5]!;\n const cr = (c >> 16) & 255;\n const cg = (c >> 8) & 255;\n const cb = c & 255;\n if (a >= 1) {\n // little-endian RGBA bytes, opaque: no blend\n const word = (0xff000000 | (cb << 16) | (cg << 8) | cr) >>> 0;\n if (rw === 1 && rh === 1) {\n words[y0 * cap + x0] = word;\n continue;\n }\n for (let y = y0; y < y0 + rh; y++) {\n const row = y * cap + x0;\n if (rw < 8) for (let p = row, end = row + rw; p < end; p++) words[p] = word;\n else words.fill(word, row, row + rw);\n }\n continue;\n }\n // premultiplied source-over, what a translucent Graphics fill did over the pixels under it\n const keep = 1 - a;\n const pr = cr * a;\n const pg = cg * a;\n const pb = cb * a;\n const pa = 255 * a;\n for (let y = y0; y < y0 + rh; y++) {\n for (let p = (y * cap + x0) * 4, end = p + rw * 4; p < end; p += 4) {\n pixels[p] = pr + pixels[p]! * keep;\n pixels[p + 1] = pg + pixels[p + 1]! * keep;\n pixels[p + 2] = pb + pixels[p + 2]! * keep;\n pixels[p + 3] = pa + pixels[p + 3]! * keep;\n }\n }\n }\n surface.source.update();\n this.sprite.texture = surface.texture;\n this.sprite.position.set(minX, minY);\n this.sprite.visible = true;\n this.originX = minX;\n this.originY = minY;\n this.lastW = w;\n this.lastH = h;\n }\n\n /**\n * Shows `other`'s last frame instead of painting one: its texture, placed where it placed it. A frame shared by\n * several bodies (the same aura on two bodies) is painted once and shown by each of their layers.\n */\n mirror(other: PixelLayer): void {\n const s = other.surface;\n if (!s || !other.sprite.visible) {\n this.hideMirror();\n return;\n }\n this.sprite.texture = s.texture;\n this.sprite.position.set(other.originX, other.originY);\n this.sprite.visible = true;\n this.originX = other.originX;\n this.originY = other.originY;\n this.lastW = other.lastW;\n this.lastH = other.lastH;\n }\n\n /** Shows nothing and lets go of the texture a `mirror` showed. */\n hideMirror(): void {\n this.sprite.visible = false;\n this.sprite.texture = this.surface?.texture ?? Texture.EMPTY;\n }\n\n /** The premultiplied [r, g, b, a] last presented at layer pixel (x, y); zeros where nothing was (tests read it). */\n pixelAt(x: number, y: number): [number, number, number, number] {\n const s = this.surface;\n const capW = s?.capW ?? 0;\n const capH = s?.capH ?? 0;\n // the sprite must show the buffer one texel to a world pixel, or every pixel read here lands somewhere else\n if (this.sprite.width !== capW || this.sprite.height !== capH) throw new Error('PixelLayer sprite is scaled');\n const px = x - this.originX;\n const py = y - this.originY;\n if (!s || !this.sprite.visible || px < 0 || py < 0 || px >= capW || py >= capH) return [0, 0, 0, 0];\n const p = (py * capW + px) * 4;\n return [s.pixels[p]!, s.pixels[p + 1]!, s.pixels[p + 2]!, s.pixels[p + 3]!];\n }\n\n /** The buffer's size (tests read it). */\n capacity(): { w: number; h: number } {\n return { w: this.surface?.capW ?? 0, h: this.surface?.capH ?? 0 };\n }\n\n /**\n * A buffer at least `w` × `h`: grown a size class at a time and kept while it fits, traded back to the pool for a\n * smaller one only once the frames have stayed well inside it for `SHRINK_AFTER` presents (a long-lived layer — an\n * aura, a status mark — that once swelled would otherwise hold and upload its largest buffer for good).\n */\n private fit(w: number, h: number): Surface {\n const s = this.surface;\n if (s && w <= s.capW && h <= s.capH) {\n const roomy = s.capW * s.capH >= 128 * 128 && w * 4 <= s.capW && h * 4 <= s.capH;\n this.small = roomy ? this.small + 1 : 0;\n if (this.small < SHRINK_AFTER) return s;\n }\n this.small = 0;\n // growing keeps the larger side it had, so a frame that swells one way and then the other is not traded each time\n const grow = !!s && (w > s.capW || h > s.capH);\n const capW = sideFor(Math.max(1, w, grow ? s!.capW : 0));\n const capH = sideFor(Math.max(1, h, grow ? s!.capH : 0));\n this.dropSurface();\n const next = takeSurface(capW, capH);\n this.surface = next;\n this.sprite.texture = next.texture;\n return next;\n }\n\n private dropSurface(): void {\n this.sprite.texture = Texture.EMPTY;\n if (this.surface) giveSurface(this.surface);\n this.surface = null;\n }\n\n override destroy(): void {\n if (this.destroyed) return;\n this.dropSurface();\n super.destroy();\n }\n}\n","/*\n * Minimal pixel-art canvas. All game art is painted procedurally with these primitives\n * (no external/copyrighted assets). Colors are packed little-endian RGBA (ImageData layout).\n */\n\nexport type Color = number;\n\nexport const CLEAR: Color = 0;\n\nexport function rgba(r: number, g: number, b: number, a = 255): Color {\n const R = Math.max(0, Math.min(255, Math.round(r)));\n const G = Math.max(0, Math.min(255, Math.round(g)));\n const B = Math.max(0, Math.min(255, Math.round(b)));\n const A = Math.max(0, Math.min(255, Math.round(a)));\n return ((A << 24) | (B << 16) | (G << 8) | R) >>> 0;\n}\n\nexport function hex(s: string): Color {\n let h = s.startsWith('#') ? s.slice(1) : s;\n if (h.length === 3) h = [...h].map((c) => c + c).join('');\n const r = parseInt(h.slice(0, 2), 16);\n const g = parseInt(h.slice(2, 4), 16);\n const b = parseInt(h.slice(4, 6), 16);\n const a = h.length >= 8 ? parseInt(h.slice(6, 8), 16) : 255;\n return rgba(r, g, b, a);\n}\n\nexport function channels(c: Color): [number, number, number, number] {\n return [c & 255, (c >>> 8) & 255, (c >>> 16) & 255, (c >>> 24) & 255];\n}\n\n/** f < 1 darkens, f > 1 lightens toward white. */\nexport function shade(c: Color, f: number): Color {\n const [r, g, b, a] = channels(c);\n if (f >= 1) {\n const t = Math.min(1, f - 1);\n return rgba(r + (255 - r) * t, g + (255 - g) * t, b + (255 - b) * t, a);\n }\n return rgba(r * f, g * f, b * f, a);\n}\n\nexport function mix(c1: Color, c2: Color, t: number): Color {\n const a = channels(c1);\n const b = channels(c2);\n return rgba(a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t, a[3] + (b[3] - a[3]) * t);\n}\n\nexport function withAlpha(c: Color, alpha: number): Color {\n const [r, g, b] = channels(c);\n return rgba(r, g, b, alpha);\n}\n\nexport function toCss(c: Color): string {\n const [r, g, b, a] = channels(c);\n return `rgba(${r},${g},${b},${(a / 255).toFixed(3)})`;\n}\n\nexport function hash2(x: number, y: number, seed = 0): number {\n let h = (x * 374761393 + y * 668265263 + seed * 2147483647) | 0;\n h = Math.imul(h ^ (h >>> 13), 1274126177);\n return ((h ^ (h >>> 16)) >>> 0) / 4294967296;\n}\n\nexport function mulberry32(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x6d2b79f5) >>> 0;\n let t = a;\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\nexport function valueNoise(x: number, y: number, scale: number, seed: number): number {\n const fx = x / scale;\n const fy = y / scale;\n const x0 = Math.floor(fx);\n const y0 = Math.floor(fy);\n const tx = fx - x0;\n const ty = fy - y0;\n const sx = tx * tx * (3 - 2 * tx);\n const sy = ty * ty * (3 - 2 * ty);\n const a = hash2(x0, y0, seed);\n const b = hash2(x0 + 1, y0, seed);\n const c = hash2(x0, y0 + 1, seed);\n const d = hash2(x0 + 1, y0 + 1, seed);\n return a + (b - a) * sx + (c - a) * sy + (a - b - c + d) * sx * sy;\n}\n\n\n\n\nexport class PixelGrid {\n readonly data: Uint32Array;\n\n constructor(\n readonly w: number,\n readonly h: number,\n ) {\n this.data = new Uint32Array(w * h);\n }\n\n inBounds(x: number, y: number): boolean {\n return x >= 0 && y >= 0 && x < this.w && y < this.h;\n }\n\n px(x: number, y: number, c: Color): void {\n x = Math.floor(x);\n y = Math.floor(y);\n if (x >= 0 && y >= 0 && x < this.w && y < this.h) this.data[y * this.w + x] = c;\n }\n\n get(x: number, y: number): Color {\n if (x < 0 || y < 0 || x >= this.w || y >= this.h) return CLEAR;\n return this.data[y * this.w + x] ?? CLEAR;\n }\n\n alphaAt(x: number, y: number): number {\n return this.get(x, y) >>> 24;\n }\n\n rect(x: number, y: number, w: number, h: number, c: Color): void {\n for (let yy = Math.floor(y); yy < y + h; yy++) for (let xx = Math.floor(x); xx < x + w; xx++) this.px(xx, yy, c);\n }\n\n hline(x0: number, x1: number, y: number, c: Color): void {\n for (let x = Math.min(x0, x1); x <= Math.max(x0, x1); x++) this.px(x, y, c);\n }\n\n vline(x: number, y0: number, y1: number, c: Color): void {\n for (let y = Math.min(y0, y1); y <= Math.max(y0, y1); y++) this.px(x, y, c);\n }\n\n /** Filled ellipse; a pixel is inside when its center lies inside the ellipse. */\n ellipse(cx: number, cy: number, rx: number, ry: number, c: Color): void {\n if (rx <= 0 || ry <= 0) return;\n for (let y = Math.floor(cy - ry); y <= Math.ceil(cy + ry); y++)\n for (let x = Math.floor(cx - rx); x <= Math.ceil(cx + rx); x++) {\n const dx = (x + 0.5 - cx) / rx;\n const dy = (y + 0.5 - cy) / ry;\n if (dx * dx + dy * dy <= 1) this.px(x, y, c);\n }\n }\n\n circle(cx: number, cy: number, r: number, c: Color): void {\n this.ellipse(cx, cy, r, r, c);\n }\n\n ring(cx: number, cy: number, r: number, thickness: number, c: Color): void {\n for (let y = Math.floor(cy - r - 1); y <= Math.ceil(cy + r + 1); y++)\n for (let x = Math.floor(cx - r - 1); x <= Math.ceil(cx + r + 1); x++) {\n const d = Math.hypot(x + 0.5 - cx, y + 0.5 - cy);\n if (d <= r && d >= r - thickness) this.px(x, y, c);\n }\n }\n\n line(x0: number, y0: number, x1: number, y1: number, c: Color, thickness = 1): void {\n x0 = Math.round(x0);\n y0 = Math.round(y0);\n x1 = Math.round(x1);\n y1 = Math.round(y1);\n const dx = Math.abs(x1 - x0);\n const dy = -Math.abs(y1 - y0);\n const sx = x0 < x1 ? 1 : -1;\n const sy = y0 < y1 ? 1 : -1;\n let err = dx + dy;\n for (;;) {\n if (thickness <= 1) this.px(x0, y0, c);\n else this.rect(x0 - Math.floor((thickness - 1) / 2), y0 - Math.floor((thickness - 1) / 2), thickness, thickness, c);\n if (x0 === x1 && y0 === y1) break;\n const e2 = 2 * err;\n if (e2 >= dy) {\n err += dy;\n x0 += sx;\n }\n if (e2 <= dx) {\n err += dx;\n y0 += sy;\n }\n }\n }\n\n /** Filled polygon (even-odd scanline on pixel centers). */\n poly(points: [number, number][], c: Color): void {\n if (points.length < 3) return;\n const minY = Math.floor(Math.min(...points.map((p) => p[1])));\n const maxY = Math.ceil(Math.max(...points.map((p) => p[1])));\n for (let y = minY; y <= maxY; y++) {\n const sy = y + 0.5;\n const xs: number[] = [];\n for (let i = 0; i < points.length; i++) {\n const a = points[i]!;\n const b = points[(i + 1) % points.length]!;\n if ((a[1] <= sy && b[1] > sy) || (b[1] <= sy && a[1] > sy)) {\n xs.push(a[0] + ((sy - a[1]) / (b[1] - a[1])) * (b[0] - a[0]));\n }\n }\n xs.sort((p, q) => p - q);\n for (let i = 0; i + 1 < xs.length; i += 2) {\n for (let x = Math.ceil(xs[i]! - 0.5); x <= Math.floor(xs[i + 1]! - 0.5); x++) this.px(x, y, c);\n }\n }\n }\n\n /**\n * Adds `width` pixels of outline around all opaque pixels, one ring at a time — the same result as calling it\n * `width` times, but each ring only visits the neighbours of the ring before it instead of the whole grid again.\n * (A pixel next to ring `k` is always filled by ring `k+1`, so nothing further back can still be waiting.)\n */\n outline(c: Color, diagonal = false, width = 1): void {\n const w = this.w;\n const h = this.h;\n const solid = new Uint8Array(this.data.length);\n let x0 = w, y0 = h, x1 = -1, y1 = -1;\n for (let y = 0; y < h; y++)\n for (let x = 0; x < w; x++) {\n const i = y * w + x;\n if ((this.data[i]! >>> 24) === 0) continue;\n solid[i] = 1;\n if (x < x0) x0 = x;\n if (x > x1) x1 = x;\n if (y < y0) y0 = y;\n y1 = y;\n }\n if (x1 < 0) return;\n const has = (x: number, y: number, i: number) => x >= 0 && y >= 0 && x < w && y < h && solid[i] === 1;\n // The first ring is one sweep of the box the body actually fills, so its interior never reaches a frontier list.\n let frontier: number[] = [];\n for (let y = Math.max(0, y0 - 1); y <= Math.min(h - 1, y1 + 1); y++)\n for (let x = Math.max(0, x0 - 1); x <= Math.min(w - 1, x1 + 1); x++) {\n const i = y * w + x;\n if (solid[i]) continue;\n let hit = has(x - 1, y, i - 1) || has(x + 1, y, i + 1) || has(x, y - 1, i - w) || has(x, y + 1, i + w);\n if (!hit && diagonal)\n hit = has(x - 1, y - 1, i - w - 1) || has(x + 1, y - 1, i - w + 1) || has(x - 1, y + 1, i + w - 1) || has(x + 1, y + 1, i + w + 1);\n if (hit) {\n this.data[i] = c;\n frontier.push(i);\n }\n }\n for (const i of frontier) solid[i] = 1;\n // Later rings only visit the neighbours of the ring before them.\n for (let step = 1; step < width && frontier.length; step++) {\n const next: number[] = [];\n for (const i of frontier) {\n const x = i % w;\n const y = (i / w) | 0;\n const grow = (nx: number, ny: number, k: number) => {\n if (nx < 0 || ny < 0 || nx >= w || ny >= h || solid[k]) return;\n solid[k] = 1;\n this.data[k] = c;\n next.push(k);\n };\n grow(x - 1, y, i - 1);\n grow(x + 1, y, i + 1);\n grow(x, y - 1, i - w);\n grow(x, y + 1, i + w);\n if (diagonal) {\n grow(x - 1, y - 1, i - w - 1);\n grow(x + 1, y - 1, i - w + 1);\n grow(x - 1, y + 1, i + w - 1);\n grow(x + 1, y + 1, i + w + 1);\n }\n }\n frontier = next;\n }\n }\n\n /** Replaces every pixel whose color matches `from`. */\n recolor(from: Color, to: Color): void {\n for (let i = 0; i < this.data.length; i++) if (this.data[i] === from) this.data[i] = to;\n }\n\n /** Multiplies brightness of opaque pixels matching `pred`. */\n tint(f: number, pred: (x: number, y: number) => boolean): void {\n for (let y = 0; y < this.h; y++)\n for (let x = 0; x < this.w; x++) {\n const i = y * this.w + x;\n const c = this.data[i] ?? 0;\n if (c >>> 24 && pred(x, y)) this.data[i] = shade(c, f);\n }\n }\n\n blit(src: PixelGrid, dx: number, dy: number, flipX = false): void {\n for (let y = 0; y < src.h; y++)\n for (let x = 0; x < src.w; x++) {\n const c = src.data[y * src.w + x] ?? 0;\n if (c >>> 24 === 0) continue;\n this.px(dx + (flipX ? src.w - 1 - x : x), dy + y, c);\n }\n }\n\n /** Alpha-blends a color onto an existing pixel. */\n blend(x: number, y: number, c: Color): void {\n if (!this.inBounds(x, y)) return;\n const i = y * this.w + x;\n const dst = this.data[i] ?? 0;\n const [r, g, b, a] = channels(c);\n const t = a / 255;\n const d = channels(dst);\n this.data[i] = rgba(d[0] + (r - d[0]) * t, d[1] + (g - d[1]) * t, d[2] + (b - d[2]) * t, Math.max(d[3], a));\n }\n\n /** Reads a canvas back into a grid (a PNG layer of the paper doll joining the painted ones). */\n static from(canvas: HTMLCanvasElement): PixelGrid {\n const g = new PixelGrid(canvas.width, canvas.height);\n const img = canvas.getContext('2d')!.getImageData(0, 0, canvas.width, canvas.height);\n g.data.set(new Uint32Array(img.data.buffer, img.data.byteOffset, canvas.width * canvas.height));\n return g;\n }\n\n /** The same picture on a grid `factor` times as fine, each pixel becoming a square block. */\n upscaled(factor: number): PixelGrid {\n if (factor === 1) return this;\n const g = new PixelGrid(this.w * factor, this.h * factor);\n for (let y = 0; y < this.h; y++)\n for (let x = 0; x < this.w; x++) {\n const c = this.data[y * this.w + x] ?? 0;\n if (c >>> 24 === 0) continue;\n g.rect(x * factor, y * factor, factor, factor, c);\n }\n return g;\n }\n\n /** Same size and same pixels. */\n equals(other: PixelGrid): boolean {\n if (other.w !== this.w || other.h !== this.h) return false;\n for (let i = 0; i < this.data.length; i++) if (this.data[i] !== other.data[i]) return false;\n return true;\n }\n\n /** Cheap hash of the pixels, for grouping identical frames before comparing them. */\n key(): number {\n let h = 2166136261 >>> 0;\n for (let i = 0; i < this.data.length; i++) {\n h ^= this.data[i]!;\n h = Math.imul(h, 16777619) >>> 0;\n }\n return h >>> 0;\n }\n\n clone(): PixelGrid {\n const g = new PixelGrid(this.w, this.h);\n g.data.set(this.data);\n return g;\n }\n\n toCanvas(): HTMLCanvasElement {\n const canvas = document.createElement('canvas');\n canvas.width = this.w;\n canvas.height = this.h;\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('2D canvas not supported');\n const bytes = new Uint8ClampedArray(this.w * this.h * 4);\n bytes.set(new Uint8Array(this.data.buffer, this.data.byteOffset, this.data.byteLength));\n const img = new ImageData(bytes, this.w, this.h);\n ctx.putImageData(img, 0, 0);\n return canvas;\n }\n}\n\n/**\n * A grid that stands for one window of a larger picture: it is drawn on in the larger picture's coordinates and\n * keeps only what falls inside `[x0, x0 + w) × [y0, y0 + h)`. A ground painter can paint a crop of a map into one, so the\n * login screen does not paint the whole of two maps to show 17 tiles of each. Every drawing method goes through\n * `px`/`get`/`inBounds`/`blend`; `outline`, `tint` and the whole-grid helpers work in window coordinates.\n */\nexport class PixelWindow extends PixelGrid {\n constructor(\n readonly x0: number,\n readonly y0: number,\n w: number,\n h: number,\n ) {\n super(w, h);\n }\n\n override inBounds(x: number, y: number): boolean {\n return super.inBounds(x - this.x0, y - this.y0);\n }\n\n override px(x: number, y: number, c: Color): void {\n super.px(Math.floor(x) - this.x0, Math.floor(y) - this.y0, c);\n }\n\n override get(x: number, y: number): Color {\n return super.get(x - this.x0, y - this.y0);\n }\n\n override blend(x: number, y: number, c: Color): void {\n // not through super.blend: it asks `this.inBounds`, which would move the point a second time\n const lx = x - this.x0;\n const ly = y - this.y0;\n if (!super.inBounds(lx, ly)) return;\n const i = ly * this.w + lx;\n const dst = this.data[i] ?? 0;\n const [r, g, b, a] = channels(c);\n const t = a / 255;\n const d = channels(dst);\n this.data[i] = rgba(d[0] + (r - d[0]) * t, d[1] + (g - d[1]) * t, d[2] + (b - d[2]) * t, Math.max(d[3], a));\n }\n}\n\n/**\n * Packs same-sized frames into rows no wider than `maxWidth`. A browser refuses a canvas past about 16k pixels\n * on a side and hands back a blank one, and a player sheet of six hundred frames at twice the detail is wider\n * than that, so it wraps. Readers work the row out from the canvas width.\n */\nexport function makeSheet(frames: PixelGrid[], maxWidth = 16384): HTMLCanvasElement {\n const first = frames[0];\n if (!first) throw new Error('makeSheet: no frames');\n const cols = Math.max(1, Math.min(frames.length, Math.floor(maxWidth / first.w)));\n const rows = Math.ceil(frames.length / cols);\n const sheet = new PixelGrid(first.w * cols, first.h * rows);\n frames.forEach((f, i) => sheet.blit(f, (i % cols) * first.w, Math.floor(i / cols) * first.h));\n return sheet.toCanvas();\n}\n\n/** Scales a canvas by an integer factor with nearest-neighbour filtering (for UI icons). */\nexport function upscale(src: HTMLCanvasElement, factor: number): HTMLCanvasElement {\n const c = document.createElement('canvas');\n c.width = src.width * factor;\n c.height = src.height * factor;\n const ctx = c.getContext('2d');\n if (!ctx) throw new Error('2D canvas not supported');\n ctx.imageSmoothingEnabled = false;\n ctx.drawImage(src, 0, 0, c.width, c.height);\n return c;\n}\n","import { hex } from './pixel';\n\n/** Shared colour palette: warm medieval fantasy tones, readable on green ground. */\nexport const P = {\n outline: hex('#1a1220'),\n outlineSoft: hex('#2e2233'),\n black: hex('#0e0b12'),\n white: hex('#f4f0e8'),\n offWhite: hex('#e2dccf'),\n\n skin: hex('#f2c59a'),\n skinShade: hex('#d99d74'),\n skinTan: hex('#cf9468'),\n skinTanShade: hex('#a86c48'),\n blush: hex('#e88c80'),\n\n hairBlack: hex('#2a2230'),\n hairBrown: hex('#5b3a29'),\n hairAuburn: hex('#7a3b2a'),\n hairWhite: hex('#e8e4dc'),\n hairGrey: hex('#9a96a0'),\n\n red: hex('#c8373a'),\n redDark: hex('#8e2331'),\n crimson: hex('#a3243b'),\n orange: hex('#e07a36'),\n gold: hex('#f2c84b'),\n goldDark: hex('#b88a2a'),\n yellow: hex('#f5e06a'),\n green: hex('#5aa04a'),\n greenDark: hex('#2f6b3a'),\n jade: hex('#4fbf8f'),\n jadeDark: hex('#2d8466'),\n teal: hex('#3aa6a0'),\n sky: hex('#7ec4f0'),\n azure: hex('#4a8ad4'),\n blue: hex('#3560b0'),\n navy: hex('#27335e'),\n indigo: hex('#3b2f6e'),\n purple: hex('#7a4bb0'),\n pink: hex('#e89aaa'),\n brown: hex('#7a5234'),\n brownDark: hex('#4e3222'),\n brownLight: hex('#a6784a'),\n tan: hex('#c9a26e'),\n cream: hex('#efe2c0'),\n grey: hex('#8a8690'),\n greyDark: hex('#57535e'),\n greyLight: hex('#bdb9c2'),\n steel: hex('#c8d2dc'),\n steelDark: hex('#7f8a98'),\n iron: hex('#9aa0a8'),\n wood: hex('#9a6a3c'),\n woodDark: hex('#6a4426'),\n woodLight: hex('#bd8c56'),\n straw: hex('#d8b060'),\n strawDark: hex('#a8823e'),\n} as const;\n","import { type Color, channels, mix, rgba, shade } from './pixel';\n\n/*\n * Hue-shifted ramps: the one place a character's colours get their shadows and lights. At 20x24 a body cannot get\n * detail from extra pixels, so it gets it from colour — a shadow that only darkens reads as dirt, a light that only\n * whitens reads as chalk. Here a shadow drifts toward its material's cool (or, for skin and leather, warm red) hue\n * and gains a little saturation; a light drifts toward warm yellow and loses a little. Everything the rig paints\n * goes through `hueShade`.\n */\n\nexport type Material = 'cloth' | 'leather' | 'mail' | 'plate' | 'dragon' | 'fur' | 'skin' | 'hair' | 'gold' | 'gem' | 'shadow';\n\nexport const MATERIALS: readonly Material[] = ['cloth', 'leather', 'mail', 'plate', 'dragon', 'fur', 'skin', 'hair', 'gold', 'gem', 'shadow'];\n\ninterface Light {\n /** Hue (degrees) a shadow drifts toward, and how far it drifts at a factor of 0.5. */\n cool: number;\n coolDeg: number;\n /** Saturation a shadow gains at a factor of 0.5. */\n coolSat: number;\n /** Hue a light drifts toward, and how far it drifts at a factor of 1.3. */\n warm: number;\n warmDeg: number;\n}\n\nconst LIGHT: Record<Material, Light> = {\n // wool and linen: violet shadows, faintly warm lights\n cloth: { cool: 255, coolDeg: 14, coolSat: 0.06, warm: 50, warmDeg: 6 },\n // hide: its shadows go red-brown, never grey\n leather: { cool: 8, coolDeg: 12, coolSat: 0.08, warm: 45, warmDeg: 8 },\n // steel: blue shadows, lights close to white\n mail: { cool: 232, coolDeg: 16, coolSat: 0.07, warm: 52, warmDeg: 4 },\n plate: { cool: 235, coolDeg: 18, coolSat: 0.08, warm: 50, warmDeg: 6 },\n // scale: crimson-violet shadows, ember-orange lights\n dragon: { cool: 330, coolDeg: 16, coolSat: 0.06, warm: 36, warmDeg: 12 },\n fur: { cool: 262, coolDeg: 10, coolSat: 0.04, warm: 48, warmDeg: 6 },\n // skin: shadows go to blood-red, never to grey or green\n skin: { cool: 350, coolDeg: 14, coolSat: 0.09, warm: 42, warmDeg: 5 },\n hair: { cool: 262, coolDeg: 14, coolSat: 0.05, warm: 46, warmDeg: 10 },\n gold: { cool: 14, coolDeg: 14, coolSat: 0.05, warm: 58, warmDeg: 8 },\n gem: { cool: 262, coolDeg: 8, coolSat: 0.02, warm: 50, warmDeg: 2 },\n // the side turned away from the light, whatever it is made of (the far limbs)\n shadow: { cool: 255, coolDeg: 12, coolSat: 0.04, warm: 50, warmDeg: 0 },\n};\n\n/** Tones of one colour in one material, darkest to brightest. `base` is the colour itself. */\nexport interface Ramp {\n /** Under-edges, rivets, seams: the darkest tone that is still the material. */\n deep: Color;\n dark: Color;\n mid: Color;\n base: Color;\n light: Color;\n /** One specular pixel: a plate's glint, a strand of hair, a buckle. */\n glint: Color;\n}\n\n/** The factors each material's ramp is built from: metal is contrasty, fur and skin are soft. */\nconst RAMP_FACTORS: Record<Material, [number, number, number, number, number]> = {\n cloth: [0.5, 0.66, 0.82, 1.12, 1.25],\n leather: [0.46, 0.62, 0.8, 1.16, 1.3],\n mail: [0.44, 0.6, 0.78, 1.22, 1.42],\n plate: [0.44, 0.56, 0.72, 1.2, 1.45],\n dragon: [0.42, 0.56, 0.74, 1.14, 1.32],\n fur: [0.56, 0.7, 0.84, 1.15, 1.26],\n skin: [0.6, 0.72, 0.86, 1.12, 1.24],\n hair: [0.5, 0.66, 0.8, 1.2, 1.36],\n gold: [0.42, 0.62, 0.8, 1.3, 1.5],\n gem: [0.32, 0.5, 0.78, 1.45, 1.65],\n shadow: [0.5, 0.66, 0.82, 1.12, 1.25],\n};\n\n/** Every factor a ramp or a painter shades by — what a recolour or a fine-pass mask has to recognise. */\nexport const RAMP_FACTOR_SET: readonly number[] = [...new Set(Object.values(RAMP_FACTORS).flat())];\n\nfunction toHsv(c: Color): [number, number, number] {\n const [r, g, b] = channels(c);\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const d = max - min;\n let h = 0;\n if (d > 0) {\n if (max === r) h = ((g - b) / d + 6) % 6;\n else if (max === g) h = (b - r) / d + 2;\n else h = (r - g) / d + 4;\n }\n return [h * 60, max === 0 ? 0 : d / max, max / 255];\n}\n\nfunction fromHsv(h: number, s: number, v: number, a: number): Color {\n const hh = (((h % 360) + 360) % 360) / 60;\n const i = Math.floor(hh);\n const f = hh - i;\n const p = v * (1 - s);\n const q = v * (1 - s * f);\n const t = v * (1 - s * (1 - f));\n const [r, g, b] = [[v, t, p], [q, v, p], [p, v, t], [p, q, v], [t, p, v], [v, p, q]][i % 6]!;\n return rgba(r! * 255, g! * 255, b! * 255, a);\n}\n\n/** Hue `h` moved up to `deg` degrees toward `target`, the short way round. */\nfunction drift(h: number, target: number, deg: number): number {\n let d = target - h;\n if (d > 180) d -= 360;\n if (d < -180) d += 360;\n return h + Math.sign(d) * Math.min(Math.abs(d), deg);\n}\n\nconst clamp01 = (x: number) => Math.max(0, Math.min(1, x));\nconst CACHE = new Map<string, Color>();\n\n/**\n * `c` shaded by `f` the way `shade` would (f < 1 darkens, f > 1 lifts toward white), with the hue moved the way\n * `material` moves it. `f === 1` returns `c` itself. A colour with too little saturation to have a hue (steel,\n * grey wool, white linen) takes the material's hue outright, faintly, so a grey coat still has a violet shadow.\n */\nexport function hueShade(c: Color, f: number, material: Material): Color {\n if (f === 1) return c;\n const key = `${c}:${f}:${material}`;\n let out = CACHE.get(key);\n if (out !== undefined) return out;\n const L = LIGHT[material];\n const plain = shade(c, f);\n const [h, s, v] = toHsv(plain);\n const a = plain >>> 24;\n // how grey the colour is: a grey has no hue of its own to move, so it is tinted with the target hue instead —\n // drifting a grey's accidental hue partway round the wheel is how steel turned green in its lights\n const grey = clamp01(1 - toHsv(c)[1] / 0.14);\n let coloured: Color;\n let tinted: Color;\n if (f < 1) {\n const k = (1 - f) / 0.5;\n coloured = fromHsv(drift(h, L.cool, L.coolDeg * k), clamp01(s + L.coolSat * k), v, a);\n tinted = fromHsv(L.cool, clamp01(s + L.coolSat * k * 1.2), v, a);\n } else {\n const k = Math.min(1.5, (f - 1) / 0.3);\n // lifting toward white bleaches; a warm light keeps a little of its colour back\n coloured = fromHsv(drift(h, L.warm, L.warmDeg * k), clamp01(s * 1.08), v, a);\n tinted = fromHsv(L.warm, clamp01(s + 0.03 * k), v, a);\n }\n out = grey > 0 ? mix(coloured, tinted, grey) : coloured;\n CACHE.set(key, out);\n return out;\n}\n\nconst RAMPS = new Map<string, Ramp>();\n\nexport function ramp(c: Color, material: Material): Ramp {\n const key = `${c}:${material}`;\n let r = RAMPS.get(key);\n if (!r) {\n const [deep, dark, mid, light, glint] = RAMP_FACTORS[material].map((f) => hueShade(c, f, material)) as [Color, Color, Color, Color, Color];\n r = { deep, dark, mid, base: c, light, glint };\n RAMPS.set(key, r);\n }\n return r;\n}\n\n/** Every tone of `c`'s ramp, for masking a material cue to that material. */\nexport function rampTones(c: Color, material: Material): Color[] {\n const r = ramp(c, material);\n return [r.deep, r.dark, r.mid, r.base, r.light, r.glint];\n}\n\nconst DEEP = new Map<Color, Color>();\n\n/**\n * The selective-outline tone of a fill: its own hue, cooled and pushed dark enough to hold an edge against grass\n * (value at most 0.3), so the outline on the lit side is the fill's own darkest shade instead of flat black.\n */\nexport function outlineOf(c: Color): Color {\n let d = DEEP.get(c);\n if (d === undefined) {\n const [h, s, v] = toHsv(hueShade(c, 0.42, 'shadow'));\n d = fromHsv(h, clamp01(s * 1.1 + 0.08), Math.min(v, 0.3), 255);\n DEEP.set(c, d);\n }\n return d;\n}\n","import { P } from './palette';\nimport { type Color, PixelGrid, rgba } from './pixel';\nimport { hueShade, outlineOf } from './ramp';\n\n/*\n * Pieces shared by every map prop painter (`props.ts`, `buildings.ts`, `streetProps.ts`). A prop is anchored at the\n * bottom-centre of its tile footprint: `anchorX/anchorY` are pixel coordinates inside its canvas.\n */\n\nexport interface PropArt {\n canvas: HTMLCanvasElement;\n anchorX: number;\n anchorY: number;\n}\n\nexport function art(g: PixelGrid, anchorX: number, anchorY: number): PropArt {\n return { canvas: g.toCanvas(), anchorX, anchorY };\n}\n\n/**\n * The selective outline a prop takes, lit from the upper left like the map: the same ring a plain outline lays, but\n * full dark only where the silhouette meets the ground (under it) and on its shadow side (the right); along the top\n * and the left it is the darkest tone of the fill it borders (`outlineOf`), so a lit edge reads as the thing's own\n * shade rather than a sticker's line. Translucent pixels (a cast\n * shadow on the ground) are not part of the silhouette.\n */\nexport function litOutline(g: PixelGrid, dark: Color = P.outline): void {\n const { w, h } = g;\n const on = new Uint8Array(w * h);\n for (let i = 0; i < w * h; i++) on[i] = g.data[i]! >>> 24 === 255 ? 1 : 0;\n const at = (x: number, y: number) => x >= 0 && y >= 0 && x < w && y < h && on[y * w + x] === 1;\n for (let y = 0; y < h; y++)\n for (let x = 0; x < w; x++) {\n if (on[y * w + x]) continue;\n const above = at(x, y - 1);\n const left = at(x - 1, y);\n const right = at(x + 1, y);\n const below = at(x, y + 1);\n if (!(above || left || right || below)) continue;\n g.px(x, y, above || left ? dark : outlineOf(g.get(right ? x + 1 : x, right ? y : y + 1)));\n }\n}\n\n/**\n * A soft shadow thrown down and to the right onto the ground, laid only on empty pixels (call it after `litOutline`,\n * or the outline would ring the shadow): a darker core and a fainter rim, the violet of the rocks' shadows.\n */\nexport function groundShadow(g: PixelGrid, cx: number, cy: number, rx: number, ry: number): void {\n for (let y = Math.floor(cy - ry); y <= Math.ceil(cy + ry); y++)\n for (let x = Math.floor(cx - rx); x <= Math.ceil(cx + rx); x++) {\n if (!g.inBounds(x, y) || g.alphaAt(x, y)) continue;\n const dx = (x + 0.5 - cx) / rx;\n const dy = (y + 0.5 - cy) / ry;\n const d = dx * dx + dy * dy;\n if (d <= 0.55) g.px(x, y, SHADOW_CORE);\n else if (d <= 1) g.px(x, y, SHADOW_RIM);\n }\n}\n\nconst SHADOW_CORE = rgba(26, 22, 44, 78);\nconst SHADOW_RIM = rgba(26, 22, 44, 40);\n/*\n * ── Ramp-shaded pieces ──\n * `shadeBox` shades with hue-shifted ramps (`townPalette.ts`) instead of `shade`; with `litOutline` above, a prop\n * painted with them looks like the rig's people standing next to it.\n */\n\n/**\n * Moves every opaque pixel of a box one step into shadow (or, with `f > 1`, into light) along its own hue: the eave's\n * shadow on a wall, the dark side of a chimney, a porch's shade. `mask` limits it to some pixels of the box.\n */\nexport function shadeBox(g: PixelGrid, x: number, y: number, w: number, h: number, f: number, mask?: (x: number, y: number) => boolean): void {\n for (let yy = y; yy < y + h; yy++)\n for (let xx = x; xx < x + w; xx++) {\n if (!g.inBounds(xx, yy)) continue;\n const c = g.get(xx, yy);\n if (!(c >>> 24) || (mask && !mask(xx, yy))) continue;\n g.px(xx, yy, hueShade(c, f, 'shadow'));\n }\n}\n","import { P } from './palette';\nimport type { PixelGrid } from './pixel';\nimport { outlineOf } from './ramp';\n\n/*\n * The selective outline (\"selout\") round an assembled body. It lands on exactly the pixels a plain outline would —\n * one ring outside the silhouette per grid pixel of `width` — so nothing about the silhouette changes, only the\n * colour of the ring: where the body turns away from the light (the back, facing left of a body facing right) and\n * where it stands on the ground (under the feet, under an arm) the ring stays full dark; on the lit side (the front\n * and the top of the head and shoulders) it takes the dark tone of the fill it borders (`outlineOf`). A hard black\n * line all round a 20x24 body is a sticker; a line that is the coat's own darkest shade on its lit side is a body.\n */\nexport function selectiveOutline(g: PixelGrid, width = 1): void {\n const { w, h, data } = g;\n const solid = new Uint8Array(data.length);\n let x0 = w, y0 = h, x1 = -1, y1 = -1;\n for (let y = 0; y < h; y++) {\n const row = y * w;\n for (let x = 0; x < w; x++)\n if (data[row + x]! >>> 24) {\n solid[row + x] = 1;\n if (x < x0) x0 = x;\n if (x > x1) x1 = x;\n if (y < y0) y0 = y;\n y1 = y;\n }\n }\n if (x1 < 0) return;\n let frontier: number[] = [];\n for (let y = Math.max(0, y0 - 1); y <= Math.min(h - 1, y1 + 1); y++)\n for (let x = Math.max(0, x0 - 1); x <= Math.min(w - 1, x1 + 1); x++) {\n const i = y * w + x;\n if (solid[i]) continue;\n const above = y > 0 && solid[i - w] === 1;\n const right = x + 1 < w && solid[i + 1] === 1;\n const left = x > 0 && solid[i - 1] === 1;\n const below = y + 1 < h && solid[i + w] === 1;\n if (!(above || right || left || below)) continue;\n // under the body or behind it: full dark; in front of it or over it: the fill's own darkest tone\n data[i] = above || right ? P.outline : outlineOf(data[left ? i - 1 : i + w]!);\n frontier.push(i);\n }\n for (const i of frontier) solid[i] = 1;\n // a thicker outline (tools that paint above 1x) grows each ring from the one before it, keeping its colour\n for (let step = 1; step < width && frontier.length; step++) {\n const next: number[] = [];\n for (const i of frontier) {\n const x = i % w;\n const y = (i / w) | 0;\n const c = data[i]!;\n const grow = (ok: boolean, k: number) => {\n if (!ok || solid[k]) return;\n solid[k] = 1;\n data[k] = c;\n next.push(k);\n };\n grow(x > 0, i - 1);\n grow(x + 1 < w, i + 1);\n grow(y > 0, i - w);\n grow(y + 1 < h, i + w);\n }\n frontier = next;\n }\n}\n","import type { Graphics } from '../core/Graphics';\nimport { PixelLayer } from './PixelLayer';\n\n/*\n * Colour ramps and ordered dithering for the pixel effects. A ramp turns one colour into five tones the way pixel\n * artists shade: shadows shift toward blue-violet and lose saturation, highlights shift toward yellow. The dither fade\n * drops pixels in a 4x4 Bayer order, so an effect thins out pixel by pixel instead of vanishing in one frame.\n */\n\nexport interface Ramp {\n /** Darkest: under-shade and outline pixels. */\n shade: number;\n deep: number;\n base: number;\n light: number;\n /** Near-white glint. */\n hi: number;\n}\n\nconst RAMPS = new Map<number, Ramp>();\n\nfunction toHsl(c: number): [number, number, number] {\n const r = ((c >> 16) & 255) / 255;\n const g = ((c >> 8) & 255) / 255;\n const b = (c & 255) / 255;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n if (max === min) return [0, 0, l];\n const d = max - min;\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n const h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;\n return [h / 6, s, l];\n}\n\nfunction fromHsl(h: number, s: number, l: number): number {\n const hue = (p: number, q: number, t: number) => {\n const u = (t + 1) % 1;\n if (u < 1 / 6) return p + (q - p) * 6 * u;\n if (u < 1 / 2) return q;\n if (u < 2 / 3) return p + (q - p) * (2 / 3 - u) * 6;\n return p;\n };\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n const ch = (t: number) => Math.round(Math.max(0, Math.min(1, s === 0 ? l : hue(p, q, t))) * 255);\n return (ch(h + 1 / 3) << 16) | (ch(h) << 8) | ch(h - 1 / 3);\n}\n\n/** Hue moved `amount` (turns) toward `target`, the short way round. */\nfunction drift(h: number, target: number, amount: number): number {\n let d = target - h;\n if (d > 0.5) d -= 1;\n if (d < -0.5) d += 1;\n return (h + Math.sign(d) * Math.min(Math.abs(d), amount) + 1) % 1;\n}\n\n/**\n * Ramps picked by hand for the colours the kits are built on — a kit module paints its crescents, rings and trails in\n * one material colour and lets the shapes shade themselves, so without these every shade of a kit was the formula's\n * . `ramp` of one of these colours returns its hand ramp; every other colour\n * gets `derivedRamp`. `base` is always the colour itself.\n */\nconst HAND_RAMPS = new Map<number, Omit<Ramp, 'base'>>([\n // arcane violet\n [0xc8a0ff, { hi: 0xfbf0ff, light: 0xe6cdfc, deep: 0x8456c8, shade: 0x3e2466 }],\n // straw and bone (the hunters' arrows)\n [0xe8d8a0, { hi: 0xfffbe8, light: 0xf6ecc4, deep: 0xb09a62, shade: 0x5a4a30 }],\n // dusk violet\n [0xb070ff, { hi: 0xf4e6ff, light: 0xd4b0ff, deep: 0x7040b8, shade: 0x301a5a }],\n // cold sky steel\n [0x9fe6ff, { hi: 0xf4fcff, light: 0xd0f4ff, deep: 0x5a9ac8, shade: 0x243e6a }],\n // bright steel\n [0xe0e0f0, { hi: 0xffffff, light: 0xf2f2fa, deep: 0x9a9cb6, shade: 0x4a4a64 }],\n // wind over grass\n [0xa8f0c0, { hi: 0xf0fff4, light: 0xd4fae0, deep: 0x5eb088, shade: 0x245a46 }],\n // holy gold\n [0xffd98a, { hi: 0xfffbe6, light: 0xffecb8, deep: 0xc8963e, shade: 0x6a4424 }],\n // judgement gold\n [0xffe08a, { hi: 0xfffbe2, light: 0xfff0bc, deep: 0xd0a044, shade: 0x704a22 }],\n // trap amber\n [0xffc040, { hi: 0xfff4d0, light: 0xffe090, deep: 0xc07a20, shade: 0x6a3a16 }],\n // hunter's gold\n [0xd0b070, { hi: 0xfff6dc, light: 0xecd6a0, deep: 0x8e7040, shade: 0x4a3a24 }],\n // war-cry amber\n [0xffb13b, { hi: 0xfff0cc, light: 0xffd488, deep: 0xc0701e, shade: 0x683414 }],\n // moonlit silver-blue\n [0xa0b0ff, { hi: 0xf2f4ff, light: 0xd0d8ff, deep: 0x5e6ac8, shade: 0x2a2e6a }],\n // blood\n [0xff4a3a, { hi: 0xffe0d4, light: 0xff9a86, deep: 0xa81e22, shade: 0x4e0c16 }],\n // pale violet steel\n [0xe0d0ff, { hi: 0xfbf6ff, light: 0xf0e8ff, deep: 0x9a86c8, shade: 0x4a3a6e }],\n]);\n\nconst HAND = new Map<number, Ramp>([...HAND_RAMPS].map(([c, r]) => [c, { ...r, base: c }]));\n\nexport function ramp(color: number): Ramp {\n return HAND.get(color) ?? derivedRamp(color);\n}\n\n/** The formula's five tones for any colour: shadows cool and desaturate, highlights warm. */\nexport function derivedRamp(color: number): Ramp {\n let r = RAMPS.get(color);\n if (r) return r;\n const [h, s, l] = toHsl(color);\n const cool = drift(h, 0.72, 0.06);\n const warm = drift(h, 0.14, 0.04);\n r = {\n shade: fromHsl(cool, Math.min(1, s * 0.85), Math.max(0.08, l * 0.38)),\n deep: fromHsl(drift(h, 0.72, 0.03), s, Math.max(0.14, l * 0.66)),\n base: color,\n light: fromHsl(warm, s * 0.9, Math.min(0.9, l + (1 - l) * 0.45)),\n hi: fromHsl(warm, s * 0.5, Math.min(0.97, l + (1 - l) * 0.8)),\n };\n RAMPS.set(color, r);\n return r;\n}\n\nconst GRADED = new Map<number, number>();\n\n/**\n * The colour a pixel is actually painted with: effects are authored in bright, saturated colours, and this pulls them\n * into the world's palette (muted earth, grass and wood) — saturation down by a quarter, near-whites toned down and\n * warmed, so an effect sits in the scene instead of glowing on top of it. Glints keep most of their lift.\n */\nexport function grade(color: number): number {\n let out = GRADED.get(color);\n if (out !== undefined) return out;\n const [h, s, l] = toHsl(color);\n const lift = l > 0.82 ? 0.82 + (l - 0.82) * 0.55 : l;\n out = fromHsl(l > 0.82 ? drift(h, 0.12, 0.05) : h, s * (l > 0.82 ? 0.55 : 0.74), lift * 0.97);\n GRADED.set(color, out);\n return out;\n}\n\n/*\n * Outline capture: while one is open, `dot` and `hline` record pixels instead of painting them, and `endOutline`\n * paints a dark 1px rim round the recorded silhouette before the pixels themselves — the same outline the character\n * and prop sprites carry, for effects that have a shape (a shield, a skull, a flask, a bolt).\n */\nlet capture: Map<number, number> | null = null;\nconst key = (x: number, y: number) => ((x + 32768) << 16) | ((y + 32768) & 0xffff);\n\nexport function capturing(): Map<number, number> | null {\n return capture;\n}\n\n/** The four sides a rim pixel may lie on, as dx, dy pairs. */\nconst RIM_STEPS = [1, 0, -1, 0, 0, 1, 0, -1];\n\nexport function beginOutline(): void {\n capture = new Map();\n}\n\nexport function endOutline(g: Graphics, outline: number): void {\n const pixels = capture;\n capture = null;\n if (!pixels) return;\n // each rim pixel once, however many silhouette pixels it touches\n const rim = new Set<number>();\n for (const k of pixels.keys()) {\n const x = (k >>> 16) - 32768;\n const y = (k & 0xffff) - 32768;\n for (let i = 0; i < 8; i += 2) {\n const n = key(x + RIM_STEPS[i]!, y + RIM_STEPS[i + 1]!);\n if (!pixels.has(n)) rim.add(n);\n }\n }\n const ink = grade(outline);\n fillRuns(g, new Map([...rim].map((k) => [k, ink])));\n fillRuns(g, pixels);\n}\n\n/**\n * Lays pixels (keyed by `key`, each with its colour already graded) row by row, one rect for every run of one colour:\n * the same pixels as one rect each, at a fraction of the rects (single-pixel rects ran to 5,000–9,000 a frame for one\n * big ring or smoke, enough to be felt as lag).\n */\nexport function fillRuns(g: Graphics, pixels: Map<number, number>): void {\n if (batchG !== null && g === batchG) {\n if (direct) for (const [k, c] of pixels) direct.stage((k >>> 16) - 32768, (k & 0xffff) - 32768, 1, c);\n else for (const [k, c] of pixels) batch!.set(k, c);\n return;\n }\n layRuns(g, pixels);\n}\n\n/*\n * A frame's batch (`beginBatch` / `endBatch`): while one is open every solid pixel `dot`, `hline` and `fillRuns` paint goes into it,\n * the last write of a pixel winning as it would on screen, and it is laid as runs when the frame is done — so an\n * effect that plots a pixel at a time costs a rect a run, not a rect a pixel. A translucent fill (smoke, a heat wash)\n * calls `flushBatch` first, so what was painted before it stays under it.\n *\n * On a `PixelLayer` the batch is the layer's own staging: each pixel goes\n * straight into its list in the order painted and `commit` lays them, the later winning — the same pixels the map,\n * its sort and its runs gave, without them. Any other Graphics keeps the map.\n */\nlet batch: Map<number, number> | null = null;\nlet direct: PixelLayer | null = null;\nlet batchG: Graphics | null = null;\n/** Batches opened under this one (a layer painted from inside another's paint), each laid and closed on its own. */\nconst outer: { batch: Map<number, number> | null; direct: PixelLayer | null; g: Graphics | null }[] = [];\n\nexport function beginBatch(g: Graphics): void {\n outer.push({ batch, direct, g: batchG });\n if (g instanceof PixelLayer) {\n batch = null;\n direct = g;\n } else {\n batch = new Map();\n direct = null;\n }\n batchG = g;\n}\n\nexport function endBatch(): void {\n flushBatch();\n const was = outer.pop();\n batch = was?.batch ?? null;\n direct = was?.direct ?? null;\n batchG = was?.g ?? null;\n}\n\n/**\n * Where a solid pixel painted on `g` goes while its batch is open: the layer's staging, the batch's map, or nowhere\n * (paint it now). `stagePixel` writes into whichever it is.\n */\nexport function batchFor(g: Graphics): Map<number, number> | PixelLayer | null {\n if (batchG === null || g !== batchG) return null;\n return direct ?? batch;\n}\n\n/** Writes a solid run of `w` pixels at (x, y) into what `batchFor` returned. */\nexport function stageRun(held: Map<number, number> | PixelLayer, x: number, y: number, w: number, color: number): void {\n if (held instanceof PixelLayer) {\n held.stage(x, y, w, color);\n return;\n }\n for (let i = 0; i < w; i++) held.set(key(x + i, y), color);\n}\n\n/** Lays what the batch holds now, so a translucent fill that follows lies over it. */\nexport function flushBatch(): void {\n if (direct) {\n direct.commit();\n return;\n }\n if (!batch || !batchG || batch.size === 0) return;\n const held = batch;\n batch = new Map();\n layRuns(batchG, held);\n}\n\nfunction layRuns(g: Graphics, pixels: Map<number, number>): void {\n if (g instanceof PixelLayer) {\n // the layer lays its own runs; nothing between here and its commit is drawn\n for (const [k, c] of pixels) g.stage((k >>> 16) - 32768, (k & 0xffff) - 32768, 1, c);\n g.commit();\n return;\n }\n const keys = [...pixels.keys()].sort((a, b) => (a & 0xffff) - (b & 0xffff) || (a >>> 16) - (b >>> 16));\n let runX = 0;\n let runY = 0;\n let runW = 0;\n let runC = -1;\n for (const k of keys) {\n const x = (k >>> 16) - 32768;\n const y = (k & 0xffff) - 32768;\n const c = pixels.get(k)!;\n if (runW > 0 && y === runY && x === runX + runW && c === runC) {\n runW++;\n continue;\n }\n if (runW > 0) g.fillStyle(runC, 1).fillRect(runX, runY, runW, 1);\n runX = x;\n runY = y;\n runW = 1;\n runC = c;\n }\n if (runW > 0) g.fillStyle(runC, 1).fillRect(runX, runY, runW, 1);\n}\n\n/** The key `capturing()` and `fillRuns` file a world pixel under. */\nexport function pixelKey(x: number, y: number): number {\n return key(x, y);\n}\n\nexport function record(x: number, y: number, color: number): void {\n capture?.set(key(x, y), color);\n}\n\nconst BAYER = [0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5];\n\n/** 1 draws every pixel, 0 none; set around each paint so every shape thins out together. */\nlet coverage = 1;\n\nexport function setCoverage(value: number): void {\n coverage = value;\n}\n\n/** The current dither fade (1 while nothing fades), for translucent fills that fade with their layer. */\nexport function currentCoverage(): number {\n return coverage;\n}\n\n/** Whether the world pixel at (x, y) is dropped by the current dither fade. */\nexport function dithered(x: number, y: number): boolean {\n if (coverage >= 1) return false;\n const cx = (Math.round(x) & 3) >>> 0;\n const cy = (Math.round(y) & 3) >>> 0;\n return BAYER[cy * 4 + cx]! / 16 >= coverage;\n}\n","import { batchFor, beginOutline, capturing, currentCoverage, dithered, endOutline, fillRuns, flushBatch, grade, pixelKey, ramp, record, stageRun } from './pixelTone';\nimport { PixelLayer } from './PixelLayer';\nimport type { Graphics } from '../core/Graphics';\n\n/*\n * Pixel painting shared by every kit's effects: every shape lands on the 1px world grid — the pixel size of the\n * character, prop and tile art, so an effect never looks chunkier than the body it sits on — and is redrawn at 12\n * frames per second. Every colour is pulled into the world's palette on the way out (`grade`). Shapes shade themselves from their colour's ramp (pixelTone.ts): rings are\n * brighter on the near side, thick arcs and discs carry a light edge and a deep underside, and strokes taper. Every\n * layer thins out with an ordered dither in its last frames instead of vanishing.\n */\n\nexport type Point = { x: number; y: number };\nexport const WHITE = 0xfff4d6;\nexport const snap = (n: number) => Math.round(n);\n\n/** A `size`-px square (1 by default: one art pixel) on the world grid, graded into the world palette. */\nexport function dot(g: Graphics, x: number, y: number, color: number, size = 1): void {\n const px = snap(x);\n const py = snap(y);\n if (dithered(px, py)) return;\n const c = grade(color);\n if (capturing()) {\n for (let dy = 0; dy < size; dy++) for (let dx = 0; dx < size; dx++) record(px + dx, py + dy, c);\n return;\n }\n const held = batchFor(g);\n if (held) {\n for (let dy = 0; dy < size; dy++) stageRun(held, px, py + dy, size, c);\n return;\n }\n g.fillStyle(c, 1).fillRect(px, py, size, size);\n}\n\n/**\n * Pixels a shape plots, the last plot of a pixel winning as it would on screen, laid when the shape is done as runs of\n * one tone (`fillRuns`) instead of a rect a pixel. A dither fade drops the same pixels `dot` would, and inside an\n * outline capture they are recorded like any `dot`.\n */\nclass Plot {\n private readonly at = new Map<number, number>();\n\n set(x: number, y: number, color: number): void {\n this.at.set(pixelKey(snap(x), snap(y)), color);\n }\n\n lay(g: Graphics): void {\n if (capturing()) {\n for (const [k, c] of this.at) dot(g, (k >>> 16) - 32768, (k & 0xffff) - 32768, c);\n return;\n }\n const held = batchFor(g);\n if (held instanceof PixelLayer) {\n // straight into the layer's staging: the keys are already one a pixel\n for (const [k, c] of this.at) {\n const x = (k >>> 16) - 32768;\n const y = (k & 0xffff) - 32768;\n if (!dithered(x, y)) held.stage(x, y, 1, grade(c));\n }\n return;\n }\n const graded = new Map<number, number>();\n for (const [k, c] of this.at) if (!dithered((k >>> 16) - 32768, (k & 0xffff) - 32768)) graded.set(k, grade(c));\n fillRuns(g, graded);\n }\n}\n\n/** A horizontal run of `w` px from (x, y), one pixel tall; drawn pixel by pixel while a dither fade or outline is on. */\nexport function hline(g: Graphics, x: number, y: number, w: number, color: number): void {\n const x0 = snap(x);\n const width = snap(w);\n if (width <= 0) return;\n if (!capturing() && !dithered(x0, y) && !dithered(x0 + 1, y) && !dithered(x0 + 2, y + 1) && !dithered(x0 + 3, y + 1)) {\n const held = batchFor(g);\n if (held) {\n stageRun(held, x0, snap(y), width, grade(color));\n return;\n }\n g.fillStyle(grade(color), 1).fillRect(x0, snap(y), width, 1);\n return;\n }\n for (let i = 0; i < width; i++) dot(g, x0 + i, y, color);\n}\n\n/** Paints `draw` with a dark 1px outline round everything it drew, like the outline on character and prop sprites. */\nexport function outlined(g: Graphics, outline: number, draw: () => void): void {\n beginOutline();\n try {\n draw();\n } finally {\n endOutline(g, outline);\n }\n}\n\n/**\n * A line `width` px thick built from 1px rows: the row on one side is lit, the far row deep, and a long stroke tapers\n * to the deep tone at both ends and catches a glint a third of the way along.\n */\nexport function stroke(g: Graphics, a: Point, b: Point, color: number, width = 2): void {\n const len = Math.hypot(b.x - a.x, b.y - a.y);\n const steps = Math.max(1, Math.ceil(len));\n const nx = len ? -(b.y - a.y) / len : 0;\n const ny = len ? (b.x - a.x) / len : 1;\n const r = ramp(color);\n const rows = Math.max(1, Math.round(width));\n for (let i = 0; i <= steps; i++) {\n const end = steps >= 10 && (i <= 1 || i >= steps - 1);\n const glint = steps >= 16 && Math.abs(i - Math.round(steps / 3)) <= 1;\n const x = a.x + ((b.x - a.x) * i) / steps;\n const y = a.y + ((b.y - a.y) * i) / steps;\n for (let k = 0; k < rows; k++) {\n const off = k - (rows - 1) / 2;\n const edge = rows >= 2 ? (k === 0 ? r.light : k === rows - 1 ? r.deep : color) : color;\n dot(g, x + nx * off, y + ny * off, end ? r.deep : glint && k === 0 ? r.hi : edge);\n }\n }\n}\n\n/** A broken ellipse of radius `r` in the ground's 2:1 perspective, lit on the near side, turning with `phase`. */\nexport function ring(g: Graphics, r: number, color: number, phase = 0, cy = 0): void {\n const tones = ramp(color);\n const n = Math.max(32, Math.ceil(r * 5));\n const plot = new Plot();\n for (let i = 0; i < n; i++) {\n const seg = ((((i * 64) / n + phase) % 16) + 16) % 16;\n if (seg < 3) continue;\n const a = (i * Math.PI * 2) / n;\n const near = Math.sin(a);\n // the near side of the ellipse is lit and a pixel thicker; the far side sinks into the deep tone\n const tone = seg < 4 ? tones.hi : near > 0.35 ? tones.light : near < -0.35 ? tones.deep : color;\n const x = Math.cos(a) * r;\n const y = cy + near * r * 0.5;\n plot.set(x, y, tone);\n if (near > 0.5) plot.set(x, y + 1, tones.deep);\n }\n plot.lay(g);\n}\n\n/** A faceted gem: light left face, base right face, deep lower tip and a glint on top once it is big enough. */\nexport function diamond(g: Graphics, x: number, y: number, r: number, color: number): void {\n const tones = ramp(color);\n for (let row = -r; row <= r; row++) {\n const width = Math.max(1, snap(r - Math.abs(row)));\n const left = snap(x - width / 2);\n if (row > r * 0.45) {\n hline(g, left, y + row, width, tones.deep);\n continue;\n }\n const half = Math.floor(width / 2);\n if (r < 3 || half < 1) hline(g, left, y + row, width, color);\n else {\n hline(g, left, y + row, half, tones.light);\n hline(g, left + half, y + row, width - half, color);\n }\n }\n if (r >= 5) dot(g, x - 1, y - r + 2, tones.hi);\n}\n\nexport function shards(g: Graphics, t: number, r: number, color: number, inward = false): void {\n for (let i = 0; i < 12; i++) {\n const a = i * Math.PI / 6 + (inward ? t * 1.8 : 0);\n const d = r * (inward ? 1 - t : t);\n dot(g, Math.cos(a) * d, -8 + Math.sin(a) * d * 0.6 - (inward ? 0 : Math.sin(t * Math.PI) * 8), i % 3 ? color : WHITE, i % 3 ? 1 : 2);\n }\n}\n\n/** A filled stepped disc of radius `r` (smoke, gas, puddles), in the ground's 2:1 perspective when `flat`. */\nexport function blob(g: Graphics, x: number, y: number, r: number, color: number, flat = false): void {\n const ry = Math.max(1, Math.round(flat ? r * 0.5 : r));\n const tones = ramp(color);\n for (let row = -ry; row <= ry; row++) {\n const half = snap(r * Math.sqrt(Math.max(0, 1 - (row / ry) ** 2)));\n if (half <= 0) continue;\n const down = (row + ry) / (2 * ry || 1);\n hline(g, x - half, y + row, half * 2, down > 0.7 && r >= 3 ? tones.deep : color);\n // a lit cap on the upper left\n if (r >= 3 && down < 0.35 && half >= 2) hline(g, x - half + 1, y + row, snap(half * 0.6), tones.light);\n }\n if (r >= 4) dot(g, x - r * 0.4, y - ry * 0.55, tones.hi);\n}\n\n/** A droplet thrown from (x, y) with velocity (vx, vy) px/s under gravity, `ms` after it left; null once it lands. */\nexport function drop(x: number, y: number, vx: number, vy: number, ms: number, ground = y + 8): Point | null {\n const t = ms / 1000;\n const py = y + vy * t + 260 * t * t;\n return py > ground && vy * t + 260 * t * t > 0 ? null : { x: x + vx * t, y: py };\n}\n\n/** A pixel X, `r` from its centre to a tip. */\nexport function xMark(g: Graphics, x: number, y: number, r: number, color: number): void {\n stroke(g, { x: x - r, y: y - r }, { x: x + r, y: y + r }, color);\n stroke(g, { x: x - r, y: y + r }, { x: x + r, y: y - r }, color);\n}\n\n/** A dash streak from `a` to `b`: a dark body with a bright core, eaten away from the start as `t` goes 0 to 1. */\nexport function dashStreak(g: Graphics, a: Point, b: Point, t: number, edge: number, core: number): void {\n const from = { x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t };\n stroke(g, from, b, edge, 4);\n stroke(g, from, b, core, 2);\n}\n\n/**\n * A puff of smoke or gas: a small stepped disc whose rim is dithered (every other pixel) so it reads soft, with a\n * lighter cap on its upper left. Solid discs the same size read as boulders or bushes.\n */\nexport function puffBlob(g: Graphics, x: number, y: number, r: number, body: number, light: number, frame = 0, opacity = 0.7): void {\n r = Math.round(r);\n if (r < 2) return;\n const tones = ramp(body);\n const ry = Math.max(2, Math.round(r * 0.85));\n // smoke is translucent: overlapping puffs thicken toward the middle of a cloud and the ground shows through its edge\n const alpha = opacity * currentCoverage();\n flushBatch();\n const x0 = snap(x);\n for (let row = -ry; row <= ry; row++) {\n const half = r * Math.sqrt(Math.max(0, 1 - (row / (ry + 0.5)) ** 2));\n // the same pixels as one rect each, laid as runs of one tone and alpha\n let runAt = 0;\n let runW = 0;\n let runTone = -1;\n let runAlpha = 0;\n const end = Math.ceil(half);\n for (let dx = -end; dx <= end; dx++) {\n let tone = -1;\n let a = 0;\n if (dx < end) {\n const edge = half - Math.abs(dx + 0.5);\n const noise = ((dx * 73856093) ^ (row * 19349663) ^ (frame * 83492791)) >>> 0;\n if (!(edge < 1 && noise % 2 === 0)) {\n const lit = row < -ry * 0.3 && dx < half * 0.2;\n tone = lit ? light : row > ry * 0.4 ? tones.deep : noise % 9 === 0 ? tones.light : body;\n a = edge < 1 ? alpha * 0.6 : alpha;\n }\n }\n if (tone === runTone && a === runAlpha && tone !== -1) {\n runW++;\n continue;\n }\n if (runTone !== -1) g.fillStyle(grade(runTone), runAlpha).fillRect(x0 + runAt, snap(y + row), runW, 1);\n runAt = dx;\n runW = 1;\n runTone = tone;\n runAlpha = a;\n }\n }\n}\n\n/** An arc of dots on an ellipse from angle `a0` to `a1` (flat: in the ground's 2:1 perspective), `thick` rows deep. */\nexport function arc(g: Graphics, x: number, y: number, r: number, a0: number, a1: number, color: number, flat = true, thick = 1): void {\n const steps = Math.max(2, Math.ceil(Math.abs(a1 - a0) * r));\n const tones = ramp(color);\n // `thick` counts the old 2px rows, so an arc keeps its weight; it is built from 1px rows\n thick *= 2;\n const plot = new Plot();\n for (let t = 0; t < thick; t++) {\n const rr = r - t;\n // a thick arc is lit on its outer edge and sinks to the deep tone inside; a thin one fades in from its tail\n const row = t === 0 ? tones.light : t === thick - 1 ? tones.deep : color;\n for (let i = 0; i <= steps; i++) {\n const a = a0 + ((a1 - a0) * i) / steps;\n const tone = i >= steps - 1 ? tones.hi : thick <= 2 && steps >= 12 && i < steps * 0.2 ? tones.deep : row;\n plot.set(x + Math.cos(a) * rr, y + Math.sin(a) * rr * (flat ? 0.5 : 1), tone);\n }\n }\n plot.lay(g);\n}\n\n/** Pale stepped dust puffs kicked up around (x, y) and settling over `t` 0..1. */\nexport function dust(g: Graphics, x: number, y: number, t: number, spread = 10, color = 0xc8b89a): void {\n for (let i = 0; i < 4; i++) {\n const a = i * 1.7 + 0.3;\n const size = Math.round(4 * (1 - t));\n if (size >= 1) blob(g, x + Math.cos(a) * spread * t, y - 2 + Math.sin(a) * spread * 0.4 * t - t * 4, size, i % 2 ? color : 0xe0d4bc);\n }\n}\n\n/** Pixel chunks flung out of (x, y) under gravity (rock, splinters): `ms` after the blow. */\nexport function debris(g: Graphics, x: number, y: number, count: number, speed: number, ms: number, colors: number[]): void {\n for (let i = 0; i < count; i++) {\n const a = (i / count) * Math.PI * 2 + 0.3;\n const v = speed * (0.6 + ((i * 7) % 5) * 0.1);\n const p = drop(x, y, Math.cos(a) * v, -70 - ((i * 17) % 40), ms, y + 6);\n if (!p) continue;\n const c = colors[i % colors.length]!;\n const py = p.y + (Math.sin(a) * v * 0.3 * ms) / 1000;\n if (i % 3) dot(g, p.x, py, c);\n else {\n // a chunk: body, deep underside and a glint\n dot(g, p.x, py, c, 2);\n dot(g, p.x, py + 2, ramp(c).deep, 2);\n dot(g, p.x, py, ramp(c).hi);\n }\n }\n}\n\n","import { addPixelLayer, type PixelLayer } from './PixelLayer';\nimport type { Stage } from '../core/Stage';\nimport { engineSettings } from '../settings';\nimport type { WorldObject } from '../core/types';\nimport { ramp } from './pixelTone';\nimport type { PackedPixels } from './spritePixels';\n\n/** What a dying body hands over: its feet in the world, how it was drawn, and the pixels of its last frame. */\nexport interface DeathPixels {\n x: number;\n y: number;\n /** World pixels per sprite pixel (the body's `scale`), negative when the body faced left. */\n scaleX: number;\n scaleY: number;\n pixels: PackedPixels;\n}\n\nconst FRAME_MS = 1000 / 12;\n/** Pixels in flight across every cloud at once: a crowd dying together shares this, it never adds to it. */\nconst BUDGET = 1400;\nconst PER_BODY = 150;\nconst PER_BIG = 420;\n/** Even a body dying into a full budget leaves a few of its pixels, or it would just blink out. */\nconst MIN_PER_BODY = 16;\n/** The same three under reduced effects or the battery saver. */\nconst THIN = { budget: 500, body: 60, big: 160 };\n\ninterface Cloud {\n g: PixelLayer;\n x: number;\n y: number;\n born: number;\n end: number;\n size: number;\n n: number;\n /** Per particle: start offset, release delay, lifetime, drift speed, wobble phase. */\n x0: Float32Array;\n y0: Float32Array;\n delay: Float32Array;\n life: Float32Array;\n vx: Float32Array;\n vy: Float32Array;\n phase: Float32Array;\n color: Uint32Array;\n frame: number;\n}\n\n/**\n * A dead body evaporating: it breaks into its own pixels, which let go top rows first, rise, scatter a little and\n * give out, while the body itself is hidden by the caller. Every particle is one whole world pixel in a colour read\n * off the body's last frame, painted at 12 fps like every other effect; it pales up its own ramp as it rises and\n * steps its alpha down instead of melting, so it stays pixel art the whole way. A cloud is one `PixelLayer` (a pooled\n * texture) rather than a Graphics of up to 1,400 rects.\n */\nexport class Evaporation {\n private readonly clouds: Cloud[] = [];\n private live = 0;\n\n constructor(\n private readonly scene: Stage,\n private readonly track: (object: WorldObject) => void,\n ) {}\n\n play(d: DeathPixels, big: boolean, now: number): void {\n const s = engineSettings.getState();\n const thin = s.reducedFx || s.batterySaver;\n const want = Math.min(d.pixels.length, big ? (thin ? THIN.big : PER_BIG) : thin ? THIN.body : PER_BODY);\n const n = Math.min(want, Math.max(MIN_PER_BODY, (thin ? THIN.budget : BUDGET) - this.live));\n if (n <= 0) return;\n const size = Math.max(1, Math.round(Math.abs(d.scaleY)));\n const g = addPixelLayer(this.scene);\n this.track(g);\n const c: Cloud = {\n g, x: Math.round(d.x), y: Math.round(d.y), born: now, end: now, size, n, frame: -1,\n x0: new Float32Array(n), y0: new Float32Array(n), delay: new Float32Array(n), life: new Float32Array(n),\n vx: new Float32Array(n), vy: new Float32Array(n), phase: new Float32Array(n), color: new Uint32Array(n),\n };\n let top = 0;\n let bottom = -Infinity;\n let halfW = 1;\n const px = d.pixels;\n for (let k = 0; k < px.length; k++) {\n top = Math.min(top, px.dy[k]!);\n bottom = Math.max(bottom, px.dy[k]!);\n halfW = Math.max(halfW, Math.abs(px.dx[k]! * d.scaleX));\n }\n const height = Math.max(1, bottom - top);\n const spread = big ? 520 : 260;\n const lifeMs = big ? 900 : 620;\n // a random subset when the body has more pixels than its share; every pixel otherwise\n const keep = n / px.length;\n let i = 0;\n for (let k = 0; k < px.length && i < n; k++) {\n if (keep < 1 && Math.random() > keep && px.length - k > n - i) continue;\n const pdy = px.dy[k]!;\n const x = px.dx[k]! * d.scaleX;\n const y = pdy * Math.abs(d.scaleY);\n const fromTop = (pdy - top) / height;\n c.x0[i] = x;\n c.y0[i] = y;\n // the top lets go first and the feet last, so the body dissolves upwards\n c.delay[i] = fromTop * spread * 0.6 + Math.random() * spread * 0.4;\n c.life[i] = lifeMs * (0.6 + Math.random() * 0.6);\n c.vx[i] = (x / halfW) * 5 + (Math.random() - 0.5) * 10;\n c.vy[i] = -(10 + Math.random() * 16) * (big ? 1.3 : 1);\n c.phase[i] = Math.random() * Math.PI * 2;\n c.color[i] = px.color[k]!;\n c.end = Math.max(c.end, now + c.delay[i]! + c.life[i]!);\n i++;\n }\n c.n = i;\n this.live += c.n;\n this.clouds.push(c);\n this.draw(c, now);\n }\n\n update(now: number): void {\n for (let k = this.clouds.length - 1; k >= 0; k--) {\n const c = this.clouds[k]!;\n if (!c.g.active || now >= c.end) {\n if (c.g.active) c.g.destroy();\n this.live -= c.n;\n this.clouds.splice(k, 1);\n continue;\n }\n this.draw(c, now);\n }\n }\n\n private draw(c: Cloud, now: number): void {\n const frame = Math.floor((now - c.born) / FRAME_MS);\n if (frame === c.frame) return;\n c.frame = frame;\n const ms = frame * FRAME_MS;\n const g = c.g;\n g.clear();\n g.setPosition(c.x, c.y).setDepth(c.y + 2);\n const s = c.size;\n for (let i = 0; i < c.n; i++) {\n const t = ms - c.delay[i]!;\n let x = c.x0[i]!;\n let y = c.y0[i]!;\n let color = c.color[i]!;\n let alpha = 1;\n if (t > 0) {\n const k = t / c.life[i]!;\n if (k >= 1) continue;\n const sec = t / 1000;\n // rises faster as it goes, and sways as it rises\n x += c.vx[i]! * sec + Math.sin(c.phase[i]! + sec * 9) * k * 1.5;\n y += c.vy[i]! * sec - 22 * sec * sec;\n const r = ramp(color);\n color = k < 0.3 ? color : k < 0.6 ? r.light : r.hi;\n alpha = k < 0.55 ? 1 : k < 0.8 ? 0.66 : 0.33;\n }\n g.rect(Math.round(x), Math.round(y), s, s, color, alpha);\n }\n g.present();\n }\n}\n","import type { Image } from '../core/Image';\n\n/** One opaque world pixel of a sprite frame: offset from the frame's feet (origin 0.5, 1) and its colour. */\nexport interface SpritePixel {\n dx: number;\n dy: number;\n color: number;\n}\n\n/**\n * A frame's opaque pixels packed in typed arrays (12 bytes a pixel instead of an object each). Iterating hands out one\n * reused `SpritePixel`, so read it in the loop and keep nothing of it; `at(i)` reads one into a given object.\n */\nexport class PackedPixels implements Iterable<SpritePixel> {\n constructor(\n readonly dx: Float32Array,\n readonly dy: Float32Array,\n readonly color: Uint32Array,\n readonly length: number,\n ) {}\n\n *[Symbol.iterator](): Iterator<SpritePixel> {\n const p: SpritePixel = { dx: 0, dy: 0, color: 0 };\n for (let i = 0; i < this.length; i++) {\n p.dx = this.dx[i]!;\n p.dy = this.dy[i]!;\n p.color = this.color[i]!;\n yield p;\n }\n }\n}\n\nconst EMPTY = new PackedPixels(new Float32Array(0), new Float32Array(0), new Uint32Array(0), 0);\n/** No pixels: what a body hands over when there is nothing of it worth lifting (a death with nothing to evaporate). */\nexport const NO_PIXELS = EMPTY;\n/**\n * The largest frame read, in image pixels: well over any sheet's (192x180 is about the largest). An image with no frame shows\n * its whole atlas page, and reading that — 4096x3520, 4.4 million pixels, ~110 MB a death — is what took mobile web views\n * down.\n */\nconst MAX_FRAME_AREA = 512 * 512;\n/** Frames kept, the least recently read going first once either bound is passed. */\nconst MAX_FRAMES = 256;\nconst MAX_PIXELS = 300_000;\nconst CACHE = new Map<string, PackedPixels>();\nlet cachedPixels = 0;\n\nfunction remember(key: string, packed: PackedPixels): void {\n CACHE.set(key, packed);\n cachedPixels += packed.length;\n while (CACHE.size > MAX_FRAMES || cachedPixels > MAX_PIXELS) {\n const oldest = CACHE.keys().next();\n if (oldest.done) break;\n cachedPixels -= CACHE.get(oldest.value)!.length;\n CACHE.delete(oldest.value);\n }\n}\n\n/**\n * The opaque pixels of an image's current frame, one per **world** pixel (`artScale` image pixels to one), as offsets\n * from the frame's feet in unscaled, unflipped world pixels. Read straight off the texture's canvas, so it is the\n * frame actually on screen. Atlas frames are shared by every body of one kind and cached (least recently read out\n * first); a texture repainted while in use (a rig body) is read fresh.\n */\nexport function spritePixels(img: Image, artScale: number, live: boolean): PackedPixels {\n const cacheKey = `${img.textureKey}|${img.frameName}|${artScale}`;\n if (!live) {\n const hit = CACHE.get(cacheKey);\n if (hit) {\n // most recently read goes to the back\n CACHE.delete(cacheKey);\n CACHE.set(cacheKey, hit);\n return hit;\n }\n }\n const tex = img.texture;\n const canvas = tex.source.resource as unknown;\n if (!(canvas instanceof HTMLCanvasElement)) return EMPTY;\n const f = tex.frame;\n const fw = Math.round(f.width);\n const fh = Math.round(f.height);\n if (fw <= 0 || fh <= 0 || fw * fh > MAX_FRAME_AREA) return EMPTY;\n let data: Uint8ClampedArray;\n try {\n data = canvas.getContext('2d')!.getImageData(Math.round(f.x), Math.round(f.y), fw, fh).data;\n } catch {\n return EMPTY;\n }\n const s = Math.max(1, Math.round(artScale));\n const ww = Math.floor(fw / s);\n const wh = Math.floor(fh / s);\n const half = Math.floor(s / 2);\n let n = 0;\n for (let wy = 0; wy < wh; wy++) for (let wx = 0; wx < ww; wx++) if (data[((wy * s + half) * fw + wx * s + half) * 4 + 3]! >= 128) n++;\n const dx = new Float32Array(n);\n const dy = new Float32Array(n);\n const color = new Uint32Array(n);\n let k = 0;\n for (let wy = 0; wy < wh; wy++) {\n for (let wx = 0; wx < ww; wx++) {\n const i = ((wy * s + half) * fw + wx * s + half) * 4;\n if (data[i + 3]! < 128) continue;\n dx[k] = wx - ww / 2;\n dy[k] = wy - wh;\n color[k] = (data[i]! << 16) | (data[i + 1]! << 8) | data[i + 2]!;\n k++;\n }\n }\n const out = new PackedPixels(dx, dy, color, n);\n if (!live) remember(cacheKey, out);\n return out;\n}\n","/*\n * Short-lived light: what a fight throws into the dark — a fireball or a bolt in flight, a blast,\n * a blow landing. The map's own darkness (`Darkness`: the underground, a cave, the outdoor night) cuts each\n * one out of its sheet like a lamp, so a spell lights the corridor it flies down. Looks only, client-only; one list\n * for the whole client, since only one map is ever drawn. `engineSettings.combatLights` turns them off, and so does\n * `engineSettings.batterySaver`: the list still keeps time, but nothing reads it, so the dark stays as the map's lamps leave it.\n */\n\nimport { engineSettings } from '../settings';\n\nexport interface TransientLight {\n x: number;\n y: number;\n /** Radius at its brightest, world px. */\n r: number;\n born: number;\n /** When it is gone; a carried light's is pushed to `CARRIED_MAX_MS` and brought in by its `end()`. */\n until: number;\n /** A light riding a moving thing reads its place every frame. */\n follow?: () => { x: number; y: number };\n /** A flash shrinks as it goes out; a carried light keeps its size. */\n fades: boolean;\n /** The colour it lays on what it lights: a fireball's orange, a spell's violet, a blade's white. */\n color: number;\n}\n\n/** A light nobody named a colour for: the pale gold of a spark. */\nconst SPARK = 0xfff0c8;\n\nconst LIGHTS: TransientLight[] = [];\n/** More than this at once adds nothing a player can see, and each is a sprite in the night's redraw. */\nconst MAX_LIGHTS = 48;\n\n/** A flash at (x, y) in `color`: `r` px at once, shrinking to nothing over `ms`. */\nexport function flashLight(x: number, y: number, r: number, ms: number, color = SPARK, now = performance.now()): void {\n if (LIGHTS.length >= MAX_LIGHTS) LIGHTS.shift();\n LIGHTS.push({ x, y, r, born: now, until: now + ms, fades: true, color });\n}\n\n/** The longest a carried light burns when nothing ends it: no shot flies, nor any spell is held, that long. */\nconst CARRIED_MAX_MS = 20_000;\n\n/** A light that rides `at` until `end()` is called (a shot in flight), and never past `CARRIED_MAX_MS`. */\nexport function carriedLight(at: () => { x: number; y: number }, r: number, color = SPARK, now = performance.now()): { end: () => void } {\n const p = at();\n const light: TransientLight = { x: p.x, y: p.y, r, born: now, until: now + CARRIED_MAX_MS, follow: at, fades: false, color };\n if (LIGHTS.length >= MAX_LIGHTS) LIGHTS.shift();\n LIGHTS.push(light);\n return { end: () => (light.until = 0) };\n}\n\nconst NONE: readonly TransientLight[] = [];\n\n/** The lights burning at `now`, each with its radius then; spent ones are dropped. None while combat lights are off. */\nexport function liveLights(now: number): readonly TransientLight[] {\n for (let i = LIGHTS.length - 1; i >= 0; i--) if (LIGHTS[i]!.until <= now) LIGHTS.splice(i, 1);\n const settings = engineSettings.getState();\n // the battery saver puts the transient lights out too: each one redraws the night\n if (settings.combatLights === false || settings.batterySaver) return NONE;\n for (const l of LIGHTS) {\n if (!l.follow) continue;\n // a light whose rider has gone is put out, never left to throw in every frame's night\n let p: { x: number; y: number };\n try {\n p = l.follow();\n } catch {\n l.until = 0;\n l.follow = undefined;\n continue;\n }\n l.x = p.x;\n l.y = p.y;\n }\n return LIGHTS;\n}\n\n/** The radius `l` burns at `now`: a flash eases out from its full size, a carried light holds it. */\nexport function lightRadius(l: TransientLight, now: number): number {\n if (!l.fades) return l.r;\n const t = Math.min(1, (now - l.born) / Math.max(1, l.until - l.born));\n return l.r * Math.sqrt(1 - t);\n}\n\n/** A new map: nothing of the last one's fight is left burning. */\nexport function clearLights(): void {\n LIGHTS.length = 0;\n}\n","import { Container, RenderTexture, Sprite, Texture } from 'pixi.js';\nimport { TILE_SIZE } from '../net/constants';\nimport type { Stage } from '../core/Stage';\nimport { lightRadius, liveLights } from './lights';\nimport { isTouchUi } from '../platform/touch';\n\n/**\n * The dark underground, and the lights that are cut out of it.\n *\n * The obvious way to do this — a black sheet with glowing blobs added on top — is what makes a dungeon look\n * like it is standing in fog: adding light to black gives grey, so the floor inside the \"light\" is a washed-out\n * haze rather than lit stone. What reads as light is the opposite operation. The sheet of night and the lamps\n * are drawn into a texture of their own, the lamps **erasing** the night rather than adding to it, and that\n * texture is laid over the world. Inside a lamp there is simply no night left, so the art underneath shows at\n * its own colour; outside one there is nothing but black. That is the whole trick.\n *\n * It lives in screen space because the hole has to stay under the torch as the camera moves, and a texture the\n * size of the window is far cheaper than one the size of the map.\n */\n/** How often a flicker alone redraws the sheet (≈15 a second): a torch's wobble does not need 60. */\nconst FLICKER_MS = 66;\n/** The least time between two redraws on a phone (≈30 a second, what the phones run at by default). */\nconst PHONE_MS = 33;\n/** World pixels of night drawn past each edge of the window: room for a shake and for a phone's held redraw. */\nconst MARGIN = 8;\n\n/*\n * Lit the way pixel art lights a room: the night is drawn one texel to one **world** pixel, lined up\n * with the camera so its texels sit exactly on the art's pixels, and every light's falloff is a few levels of alpha\n * blended by an ordered (Bayer 4×4) dither in those world pixels — far off a stipple, close a solid fill — instead of\n * a smooth gradient laid over pixel art (which read as fog) or hard rings (which read as a target). A torch's\n * flicker is its radius stepping a whole pixel, not a sprite scaled by fractions.\n */\n\n/** How a light falls off with `d`, a share of its radius: a bright core and a long thinning tail. */\nconst holeAt = (d: number): number => Math.min(1, Math.pow(Math.max(0, 1 - d * d), 1.5) * 1.15);\n/** The colour a light lays on what it lights: strongest at the heart, gone well before its edge. */\nconst washAt = (d: number): number => Math.pow(Math.max(0, 1 - d), 2);\n/** Alpha levels the dither blends between: the hole's and the colour's. */\nconst HOLE_LEVELS = 4;\nconst WASH_LEVELS = 3;\n/** How strongly a light colours what it lights, before the night's own depth weighs it. */\nconst WASH_ALPHA = 0.3;\n/** A light's height over its width: the ground is seen at a slant, so a pool of light is an ellipse. */\nconst SQUASH = 0.85;\n/** A plain light's colour (a lamp nobody named one for, the light a body carries): warm, as flame is. */\nexport const WARM_LIGHT = 0xffc27a;\n\nconst BAYER = [0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5].map((v) => (v + 0.5) / 16);\n\n/**\n * Radii are painted at every second pixel up to 24 and every eighth above, so a shrinking flash reuses a few textures\n * (each new one is a canvas and an upload; one per pixel made the first flashes hitch).\n */\nconst bucket = (r: number): number => (r <= 24 ? Math.max(2, Math.round(r / 2) * 2) : Math.round(r / 8) * 8);\n/** Every bucket a light can take, painted ahead one per task (`warm`), so no flash pays for its texture. */\nconst BUCKETS = [...new Set(Array.from({ length: 160 }, (_, r) => bucket(r + 1)))];\n/** How often transient lights alone redraw the sheet (≈30 a second): a flash fading needs no more. */\nconst FLASH_MS = 33;\n\nconst textures = new Map<string, Texture>();\n\nlet warming = false;\n\n/** Paints every falloff ahead, one a task, so the first flashes find theirs made. */\nfunction warm(): void {\n if (warming) return;\n warming = true;\n const todo = BUCKETS.flatMap((r) => [['hole', r], ['wash', r]] as const);\n const next = () => {\n const item = todo.shift();\n if (!item) return;\n falloff(item[0], item[1]);\n setTimeout(next, 0);\n };\n setTimeout(next, 0);\n}\n\n/** One falloff at radius `r` world px, one texel a world pixel, dithered in place. */\nfunction falloff(kind: 'hole' | 'wash', r: number): Texture {\n const key = `${kind}${r}`;\n const cached = textures.get(key);\n if (cached) return cached;\n const w = r * 2;\n const h = Math.max(2, Math.round(r * 2 * SQUASH));\n const levels = kind === 'hole' ? HOLE_LEVELS : WASH_LEVELS;\n const curve = kind === 'hole' ? holeAt : washAt;\n const canvas = document.createElement('canvas');\n canvas.width = w;\n canvas.height = h;\n // a browser out of canvas memory (iOS) gives no context: no light this time, and the next asks again\n const ctx = canvas.getContext('2d');\n if (!ctx) return Texture.EMPTY;\n const img = ctx.createImageData(w, h);\n for (let y = 0; y < h; y++)\n for (let x = 0; x < w; x++) {\n const d = Math.hypot((x + 0.5 - w / 2) / r, (y + 0.5 - h / 2) / (r * SQUASH));\n if (d >= 1) continue;\n const v = Math.min(levels, Math.floor(curve(d) * levels + BAYER[(y % 4) * 4 + (x % 4)]!)) / levels;\n const i = (y * w + x) * 4;\n img.data[i] = img.data[i + 1] = img.data[i + 2] = 255;\n img.data[i + 3] = Math.round(v * 255);\n }\n ctx.putImageData(img, 0, 0);\n const texture = Texture.from(canvas);\n texture.source.scaleMode = 'nearest';\n textures.set(key, texture);\n return texture;\n}\n\n/** A light's two marks on the night: the hole it erases, and the colour it lays over what shows through. */\ninterface LightSprites {\n hole: Sprite;\n wash: Sprite;\n}\n\nexport class Darkness {\n private readonly scratch = new Container();\n private readonly sheet: Sprite;\n /** Every hole is erased before any colour is laid, or a later hole would wipe an earlier light's colour away. */\n private readonly holes = new Container();\n private readonly washes = new Container();\n private readonly lamps: { sprites: LightSprites; x: number; y: number; r: number; flicker: number }[] = [];\n /** The transient lights (`lights.ts`), reused frame to frame. */\n private readonly flashes: LightSprites[] = [];\n private rt: RenderTexture;\n /**\n * On the screen layer, laid over the world with its exact transform by the camera (`Camera.follow`), shake included:\n * the night is drawn in world pixels round the unshaken camera and only this layer moves with a shake, so a shaking\n * screen does not redraw the night every frame.\n */\n private readonly layer = new Container();\n private readonly view: Sprite;\n /** The light the player carries: the only one that follows them, and the last one they lose. */\n private readonly carried: LightSprites;\n private readonly unsubscribeResize: () => void;\n /** Lamps that flicker: while one does (or the player carries a light) every frame differs. */\n private flickering = 0;\n /** Something other than the camera changed what the night looks like (a lamp added, dimmed, the window resized). */\n private dirty = true;\n /** What the last drawn frame was drawn from: the texture, the camera's texel and the shade. */\n private drawn = '';\n /** The carried light's place at the last redraw (it follows the body). */\n private carriedAt = '';\n /** When the sheet was last redrawn. */\n private drawnAt = -Infinity;\n /** The world pixel the night's top-left texel stands on. */\n private ox = 0;\n private oy = 0;\n /** The night texture's size in world pixels, and the zoom it was made for. */\n private rtKey = '';\n /** The lamps' colour turned down (`setLampsDimmed`). */\n private dimLamps = false;\n /** A phone redraws the night at most `PHONE_MS` apart, whatever moves (`isTouchUi`). */\n private readonly phone = isTouchUi();\n\n constructor(\n private readonly stage: Stage,\n private color: number,\n private alpha: number,\n ) {\n // a flat sheet of night over the whole window: one white pixel, tinted and stretched\n this.sheet = new Sprite({ texture: Texture.WHITE });\n this.scratch.addChild(this.sheet, this.holes, this.washes);\n this.carried = this.light(0xfff0dc);\n\n this.rt = RenderTexture.create({ width: 1, height: 1 });\n this.view = new Sprite({ texture: this.rt });\n this.layer.addChild(this.view);\n stage.screen.addChild(this.layer);\n stage.cameras.main.follow(this.layer);\n this.unsubscribeResize = stage.onResize(() => (this.dirty = true));\n warm();\n }\n\n /** A hole and its colour, added to the night's layers. */\n private light(color: number): LightSprites {\n const hole = new Sprite({ texture: falloff('hole', 8) });\n hole.blendMode = 'erase';\n this.holes.addChild(hole);\n const wash = new Sprite({ texture: falloff('wash', 8) });\n wash.tint = color;\n this.washes.addChild(wash);\n return { hole, wash };\n }\n\n /** A lamp fixed in the world: a torch on a wall, the seep in its chamber, a crystal in a seam, in its own colour. */\n addLamp(x: number, y: number, radius: number, flicker = 0, color = WARM_LIGHT): void {\n this.lamps.push({ sprites: this.light(color), x, y, r: radius, flicker });\n if (flicker) this.flickering++;\n this.dirty = true;\n }\n\n /**\n * Changes how dark and what colour the sheet is (the outdoor night, `NightShade`, deepens and lifts with the\n * world clock). A sheet with no alpha left is neither drawn nor redrawn, so a map at noon pays nothing for its night.\n */\n setShade(color: number, alpha: number): void {\n this.color = color;\n this.alpha = alpha;\n this.layer.visible = alpha > 0.004;\n }\n\n /**\n * Dimmed lamps lay only `LAMP_DIM` of their colour on the dark (a \"fewer ambient lights\" setting). The holes they\n * cut stay as wide, so a dark place is still seen by them.\n */\n setLampsDimmed(dim: boolean): void {\n if (dim === this.dimLamps) return;\n this.dimLamps = dim;\n this.dirty = true;\n }\n\n /**\n * The night's own texture, one texel a world pixel and `MARGIN` to spare on each side (a shake, or a camera that\n * moved while a phone waits for its next redraw, never shows its edge), remade when the window or the zoom changes:\n * at zoom 2 or 3 it is a quarter or a ninth of the screen's pixels. True when it was remade.\n */\n private fit(w: number, h: number, zoom: number): boolean {\n const tw = Math.ceil(w / zoom) + MARGIN * 2;\n const th = Math.ceil(h / zoom) + MARGIN * 2;\n const key = `${tw},${th},${zoom}`;\n if (key === this.rtKey) return false;\n this.rtKey = key;\n this.rt.destroy(true);\n this.rt = RenderTexture.create({ width: tw, height: th });\n this.rt.source.scaleMode = 'nearest';\n this.view.texture = this.rt;\n return true;\n }\n\n /** Redraws the night with this frame's holes in it, when anything in it changed. `px`/`py` is where the player stands. */\n update(now: number, px: number, py: number, carriedRadius: number): void {\n if (!this.layer.visible) return;\n const cam = this.stage.cameras.main;\n const zoom = cam.zoom || 1;\n const remade = this.fit(this.stage.width, this.stage.height, zoom);\n // the texel grid follows the camera (never its shake) in whole world pixels\n const ox = Math.floor(cam.scrollX) - MARGIN;\n const oy = Math.floor(cam.scrollY) - MARGIN;\n const key = `${ox},${oy},${this.rtKey},${this.color},${this.alpha}`;\n const lights = liveLights(now);\n const carriedAt = carriedRadius > 0 ? `${Math.round(px)},${Math.round(py)},${Math.round(carriedRadius)}` : '';\n // the light a body carries goes where it goes; a fight's flashes fade (`FLASH_MS`), torches wobble (`FLICKER_MS`)\n const since = now - this.drawnAt;\n const due =\n this.dirty ||\n key !== this.drawn ||\n carriedAt !== this.carriedAt ||\n (lights.length > 0 && since >= FLASH_MS) ||\n ((carriedRadius > 0 || this.flickering > 0) && since >= FLICKER_MS);\n if (!due) return;\n // a phone holds every redraw `PHONE_MS` apart (redrawing the night at 60 a second runs it hot); the night stays\n // pinned to the world meanwhile, and only a camera about to show the texture's edge cannot wait\n const edge = Math.abs(ox - this.ox) >= MARGIN - 1 || Math.abs(oy - this.oy) >= MARGIN - 1;\n if (this.phone && since < PHONE_MS && !remade && !edge) return;\n this.dirty = false;\n this.drawn = key;\n this.carriedAt = carriedAt;\n this.drawnAt = now;\n this.ox = ox;\n this.oy = oy;\n this.view.position.set(ox, oy);\n this.sheet.width = this.rt.width;\n this.sheet.height = this.rt.height;\n this.sheet.position.set(0, 0);\n this.sheet.tint = this.color;\n this.sheet.alpha = this.alpha;\n\n // the colour a light lays shows as much as the night is deep: a dungeon's lamps colour their stone fully, a dusk\n // street's only a little\n const wash = WASH_ALPHA * Math.min(1, this.alpha * 1.4);\n if (carriedRadius <= 0) this.hide(this.carried);\n else this.place(this.carried, px, py - 6, carriedRadius * (1 + Math.sin(now / 260) * 0.03 + Math.sin(now / 90) * 0.015), wash * 0.5);\n const lampWash = this.dimLamps ? wash * LAMP_DIM : wash;\n for (const l of this.lamps) {\n // torchlight is never still: each one wobbles on its own phase so a corridor of them does not pulse as one,\n // and its colour breathes with it\n const wobble = l.flicker ? 1 + Math.sin(now / 190 + l.flicker) * 0.05 + Math.sin(now / 71 + l.flicker) * 0.03 : 1;\n this.place(l.sprites, l.x, l.y, l.r * wobble, lampWash * (l.flicker ? 0.9 + (wobble - 1) * 2 : 1));\n }\n while (this.flashes.length < lights.length) this.flashes.push(this.light(WARM_LIGHT));\n for (let i = 0; i < this.flashes.length; i++) {\n const l = lights[i];\n const f = this.flashes[i]!;\n if (!l) {\n this.hide(f);\n continue;\n }\n f.wash.tint = l.color;\n // a flash colours what it lights more than a lamp does: it is the brightest thing in the room for its moment\n this.place(f, l.x, l.y, lightRadius(l, now), Math.min(0.6, wash * 1.6));\n }\n\n this.stage.app.renderer.render({ container: this.scratch, target: this.rt, clear: true });\n }\n\n private hide(l: LightSprites): void {\n l.hole.visible = false;\n l.wash.visible = false;\n }\n\n /** Lays light `l` at world (wx, wy), `r` px across its radius, in the night's world-pixel grid. */\n private place(l: LightSprites, wx: number, wy: number, r: number, wash: number): void {\n const R = bucket(r);\n const cx = Math.round(wx) - this.ox;\n const cy = Math.round(wy) - this.oy;\n // a light wholly off the texture cannot be seen, so it is not drawn\n if (r < 1 || cx < -R || cy < -R || cx > this.rt.width + R || cy > this.rt.height + R) {\n this.hide(l);\n return;\n }\n l.hole.texture = falloff('hole', R);\n l.wash.texture = falloff('wash', R);\n for (const sprite of [l.hole, l.wash]) {\n sprite.visible = true;\n sprite.position.set(cx - R, cy - Math.round(R * SQUASH));\n }\n l.wash.alpha = wash;\n l.wash.visible = wash > 0.01;\n }\n\n destroy(): void {\n this.unsubscribeResize();\n this.stage.cameras.main.unfollow(this.layer);\n this.layer.destroy({ children: true });\n this.rt.destroy(true);\n this.scratch.destroy({ children: true, context: true });\n }\n}\n\n/** What is left of a lamp's glow and colour while lamps are dimmed (`setLampsDimmed`). */\nexport const LAMP_DIM = 0.35;\n\n/** World units of light the player carries underground — about five tiles of certainty in any direction. */\nexport const CARRIED_LIGHT = TILE_SIZE * 5;\n"],"names":["patchPixi","MAX_SIDE","SIDES","POOL_PER_CLASS","POOL_MAX_BYTES","SHRINK_AFTER","POOL","pooledBytes","made","sideFor","n","s","classOf","w","h","takeSurface","capW","capH","list","best","k","l","area","hit","pixels","source","BufferImageSource","Texture","giveSurface","key","addPixelLayer","stage","PixelLayer","Graphics","Sprite","pooled","color","alpha","x","y","x0","y0","rw","rh","r","i","minX","minY","maxX","maxY","surface","words","cap","c","a","cr","cg","cb","word","row","p","end","keep","pr","pg","pb","pa","other","px","py","roomy","grow","next","CLEAR","rgba","g","b","R","G","B","hex","channels","shade","f","t","mix","c1","c2","withAlpha","toCss","hash2","seed","mulberry32","valueNoise","scale","fx","fy","tx","ty","sx","sy","d","PixelGrid","yy","xx","x1","y1","cx","cy","rx","ry","dx","dy","thickness","err","e2","points","xs","q","diagonal","width","solid","has","frontier","step","nx","ny","from","to","pred","src","flipX","dst","canvas","img","factor","ctx","bytes","PixelWindow","lx","ly","makeSheet","frames","maxWidth","first","cols","rows","sheet","upscale","P","MATERIALS","LIGHT","RAMP_FACTORS","toHsv","max","min","fromHsv","v","hh","drift","target","deg","clamp01","CACHE","hueShade","material","out","L","plain","grey","coloured","tinted","RAMPS","ramp","deep","dark","mid","light","glint","rampTones","DEEP","outlineOf","art","anchorX","anchorY","litOutline","on","at","above","left","right","below","groundShadow","SHADOW_CORE","SHADOW_RIM","shadeBox","mask","selectiveOutline","data","ok","toHsl","fromHsl","hue","u","ch","amount","HAND_RAMPS","HAND","derivedRamp","cool","warm","GRADED","grade","lift","capture","capturing","RIM_STEPS","beginOutline","endOutline","outline","rim","ink","fillRuns","batchG","direct","batch","layRuns","outer","beginBatch","endBatch","flushBatch","was","batchFor","stageRun","held","keys","runX","runY","runW","runC","pixelKey","record","BAYER","coverage","setCoverage","value","currentCoverage","dithered","WHITE","snap","dot","size","Plot","graded","hline","outlined","draw","stroke","len","steps","off","edge","ring","phase","tones","plot","seg","near","tone","diamond","half","shards","inward","blob","flat","down","drop","vx","vy","ms","ground","xMark","dashStreak","core","puffBlob","body","frame","opacity","runAt","runTone","runAlpha","noise","arc","a0","a1","thick","rr","dust","spread","debris","count","speed","colors","FRAME_MS","BUDGET","PER_BODY","PER_BIG","MIN_PER_BODY","THIN","Evaporation","scene","track","big","now","engineSettings","thin","want","top","bottom","halfW","height","lifeMs","pdy","fromTop","sec","PackedPixels","length","EMPTY","NO_PIXELS","MAX_FRAME_AREA","MAX_FRAMES","MAX_PIXELS","cachedPixels","remember","packed","oldest","spritePixels","artScale","live","cacheKey","tex","fw","fh","ww","wh","wy","wx","SPARK","LIGHTS","MAX_LIGHTS","flashLight","CARRIED_MAX_MS","carriedLight","NONE","liveLights","settings","lightRadius","clearLights","FLICKER_MS","PHONE_MS","MARGIN","holeAt","washAt","HOLE_LEVELS","WASH_LEVELS","WASH_ALPHA","SQUASH","WARM_LIGHT","bucket","BUCKETS","_","FLASH_MS","textures","warming","todo","item","falloff","kind","cached","levels","curve","texture","Darkness","RenderTexture","Container","isTouchUi","hole","wash","radius","flicker","dim","zoom","tw","th","carriedRadius","cam","remade","ox","oy","lights","carriedAt","since","lampWash","LAMP_DIM","wobble","sprite","CARRIED_LIGHT","TILE_SIZE"],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Frame animation of one sprite: which clip plays, which frame it is on. Pure state, advanced by time; a system copies
3
+ * `frame` onto the sprite (`animationSystem`).
4
+ *
5
+ * ```ts
6
+ * const clips = { idle: { frames: [0, 1], fps: 2 }, walk: { frames: [2, 3, 4, 5], fps: 10 }, die: { frames: [6, 7, 8], fps: 8, loop: false } };
7
+ * const a = new Animator(clips, 'idle');
8
+ * a.play('walk'); // switching to the clip already playing keeps its place
9
+ * a.update(dt); // seconds
10
+ * sprite.setFrame(a.frame);
11
+ * ```
12
+ */
13
+ export interface AnimationClip {
14
+ /** Frame names or indices of the sprite sheet, in order. */
15
+ frames: readonly (string | number)[];
16
+ /** Frames per second (default 10). Pixel art usually wants 8–12. */
17
+ fps?: number;
18
+ /** Start over at the end (default true); otherwise hold the last frame and report it finished. */
19
+ loop?: boolean;
20
+ /** Per-frame lengths in ms, overriding `fps` (a held key pose, a quick smear). */
21
+ durations?: readonly number[];
22
+ }
23
+ export type AnimationClips = Record<string, AnimationClip>;
24
+ export declare class Animator<Name extends string = string> {
25
+ private readonly clips;
26
+ private clip;
27
+ private index;
28
+ private elapsed;
29
+ private ended;
30
+ private name;
31
+ /** Called when a clip that does not loop reaches its last frame. */
32
+ onComplete: ((clip: Name) => void) | null;
33
+ /** Playback speed multiplier (1 normal, 0 paused). */
34
+ speed: number;
35
+ constructor(clips: Record<Name, AnimationClip>, initial: NoInfer<Name>);
36
+ /** The clip playing. */
37
+ get current(): Name;
38
+ /** The frame to show now. */
39
+ get frame(): string | number;
40
+ /** Which frame of the clip (0-based). */
41
+ get frameIndex(): number;
42
+ /** A non-looping clip has reached its last frame. */
43
+ get finished(): boolean;
44
+ /** Plays `name`. The clip already playing keeps its place unless `restart`. */
45
+ play(name: Name, restart?: boolean): this;
46
+ /** Advances by `dt` seconds; returns true when the frame changed. */
47
+ update(dt: number): boolean;
48
+ private lengthOf;
49
+ }
50
+ //# sourceMappingURL=Animator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Animator.d.ts","sourceRoot":"","sources":["../../../src/anim/Animator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IACrC,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kGAAkG;IAClG,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,kFAAkF;IAClF,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAE3D,qBAAa,QAAQ,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM;IAY9C,OAAO,CAAC,QAAQ,CAAC,KAAK;IAXxB,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,IAAI,CAAO;IACnB,oEAAoE;IACpE,UAAU,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IACjD,sDAAsD;IACtD,KAAK,SAAK;gBAGS,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,EACnD,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC;IASxB,wBAAwB;IACxB,IAAI,OAAO,IAAI,IAAI,CAElB;IAED,6BAA6B;IAC7B,IAAI,KAAK,IAAI,MAAM,GAAG,MAAM,CAE3B;IAED,yCAAyC;IACzC,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,qDAAqD;IACrD,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,+EAA+E;IAC/E,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,UAAQ,GAAG,IAAI;IAavC,qEAAqE;IACrE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAqB3B,OAAO,CAAC,QAAQ;CAIjB"}
@@ -0,0 +1,13 @@
1
+ import type { Image } from '../core/Image.js';
2
+ import { type ComponentType, type System } from '../ecs/World.js';
3
+ import type { Animator } from './Animator.js';
4
+ /** The engine's sprite component: the `Image` an entity is drawn as. */
5
+ export declare const SpriteComponent: ComponentType<Image>;
6
+ /** The engine's animation component: the `Animator` choosing the sprite's frame. */
7
+ export declare const AnimationComponent: ComponentType<Animator>;
8
+ /**
9
+ * Advances every `Animator` each frame and shows its frame on the entity's sprite (only when it changed, so an idle
10
+ * crowd costs no texture swaps).
11
+ */
12
+ export declare function animationSystem(name?: string): System;
13
+ //# sourceMappingURL=animationSystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animationSystem.d.ts","sourceRoot":"","sources":["../../../src/anim/animationSystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAA2B,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,wEAAwE;AACxE,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,KAAK,CAAoC,CAAC;AAEtF,oFAAoF;AACpF,eAAO,MAAM,kBAAkB,EAAE,aAAa,CAAC,QAAQ,CAA0C,CAAC;AAElG;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,SAAc,GAAG,MAAM,CAO1D"}
@@ -0,0 +1,85 @@
1
+ import { type TileMap, type Tileset } from '../tilemap/tiled.js';
2
+ /** Where loaded images go: the stage's `TextureRegistry` satisfies it. */
3
+ export interface TextureSink {
4
+ addCanvas(key: string, canvas: HTMLCanvasElement): unknown;
5
+ addSpriteSheet(key: string, canvas: HTMLCanvasElement, size: {
6
+ frameWidth: number;
7
+ frameHeight: number;
8
+ }): unknown;
9
+ }
10
+ export interface AssetLoaderOptions {
11
+ /** Prefix for relative URLs (default: none, so relative to the page). */
12
+ baseUrl?: string;
13
+ /** Requests running at once (default 6). */
14
+ concurrency?: number;
15
+ /** For tests and custom transports: defaults to the global `fetch`. */
16
+ fetch?: (url: string) => Promise<{
17
+ ok: boolean;
18
+ status: number;
19
+ blob(): Promise<Blob>;
20
+ json(): Promise<unknown>;
21
+ text(): Promise<string>;
22
+ }>;
23
+ /** Turns image bytes into a canvas; defaults to `createImageBitmap` drawn onto a new canvas. */
24
+ toCanvas?: (blob: Blob) => Promise<HTMLCanvasElement>;
25
+ }
26
+ export interface TilemapAssetOptions {
27
+ /** The texture key a tileset's image is loaded under (default: the tileset's name). */
28
+ textureKey?: (tileset: Tileset) => string;
29
+ }
30
+ export interface LoadProgress {
31
+ done: number;
32
+ total: number;
33
+ /** The asset that just finished. */
34
+ key: string;
35
+ }
36
+ /** `url` resolved against `base` the way a browser would (a bare file name sits beside its map). */
37
+ export declare function resolveUrl(url: string, base: string): string;
38
+ /**
39
+ * Loads a scene's assets before it starts: queue them, then `await load()`. Images become textures in the stage's
40
+ * registry (frames of a sprite sheet named 0, 1, 2…); JSON, text and Tiled maps are kept here by key. A failed asset
41
+ * fails the whole load with its URL in the message.
42
+ *
43
+ * ```ts
44
+ * override async onEnter() {
45
+ * const assets = new AssetLoader(this.engine.stage.textures);
46
+ * assets.spritesheet('hero', 'art/hero.png', { frameWidth: 20, frameHeight: 24 }).tilemap('level', 'maps/level.tmj');
47
+ * await assets.load(({ done, total }) => bar.set(done / total));
48
+ * const map = assets.map('level');
49
+ * }
50
+ * ```
51
+ */
52
+ export declare class AssetLoader {
53
+ private readonly textures;
54
+ private readonly options;
55
+ private readonly queue;
56
+ private readonly data;
57
+ private readonly maps;
58
+ private readonly fetcher;
59
+ private readonly toCanvas;
60
+ private total;
61
+ private done;
62
+ constructor(textures: TextureSink, options?: AssetLoaderOptions);
63
+ image(key: string, url: string): this;
64
+ /** An image cut into equal frames named 0, 1, 2…, left to right, then row by row. */
65
+ spritesheet(key: string, url: string, size: {
66
+ frameWidth: number;
67
+ frameHeight: number;
68
+ }): this;
69
+ json(key: string, url: string): this;
70
+ text(key: string, url: string): this;
71
+ /** A Tiled JSON map, then every tileset image it names (resolved beside the map file). */
72
+ tilemap(key: string, url: string, options?: TilemapAssetOptions): this;
73
+ /** Runs everything queued; `onProgress` after each asset. Safe to call again after queueing more. */
74
+ load(onProgress?: (p: LoadProgress) => void): Promise<void>;
75
+ /** A loaded JSON value. */
76
+ getJson<T = unknown>(key: string): T;
77
+ /** A loaded text file. */
78
+ getText(key: string): string;
79
+ /** A loaded Tiled map. */
80
+ map(key: string): TileMap;
81
+ private add;
82
+ private request;
83
+ private blob;
84
+ }
85
+ //# sourceMappingURL=AssetLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetLoader.d.ts","sourceRoot":"","sources":["../../../src/assets/AssetLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE1E,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAC3D,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;CACpH;AAED,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;QAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;KAAE,CAAC,CAAC;IAC5I,gGAAgG;IAChG,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,mBAAmB;IAClC,uFAAuF;IACvF,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC;CAC3C;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,GAAG,EAAE,MAAM,CAAC;CACb;AAID,oGAAoG;AACpG,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAU5D;AAcD;;;;;;;;;;;;;GAaG;AACH,qBAAa,WAAW;IAUpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAV1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA8B;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA8B;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;IACnE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6C;IACtE,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,IAAI,CAAK;gBAGE,QAAQ,EAAE,WAAW,EACrB,OAAO,GAAE,kBAAuB;IAMnD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAMrC,qFAAqF;IACrF,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAM9F,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAMpC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAMpC,0FAA0F;IAC1F,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,IAAI;IAS1E,qGAAqG;IAC/F,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAajE,2BAA2B;IAC3B,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC;IAKpC,0BAA0B;IAC1B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAI5B,0BAA0B;IAC1B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAMzB,OAAO,CAAC,GAAG;YAMG,OAAO;YAYP,IAAI;CAGnB"}