melonjs 20.6.0 → 20.8.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 (265) hide show
  1. package/README.md +6 -3
  2. package/build/application/defaultApplicationSettings.d.ts +5 -0
  3. package/build/application/defaultApplicationSettings.d.ts.map +1 -1
  4. package/build/application/header.d.ts.map +1 -1
  5. package/build/application/settings.d.ts +88 -0
  6. package/build/application/settings.d.ts.map +1 -1
  7. package/build/audio/backend/engine.d.ts +0 -1
  8. package/build/audio/backend/sound.d.ts +0 -1
  9. package/build/camera/camera2d.d.ts.map +1 -1
  10. package/build/camera/camera3d.d.ts +95 -8
  11. package/build/camera/camera3d.d.ts.map +1 -1
  12. package/build/geometries/box3d.d.ts +24 -6
  13. package/build/geometries/box3d.d.ts.map +1 -1
  14. package/build/geometries/ellipse.d.ts +14 -0
  15. package/build/geometries/ellipse.d.ts.map +1 -1
  16. package/build/geometries/polygon.d.ts +14 -0
  17. package/build/geometries/polygon.d.ts.map +1 -1
  18. package/build/geometries/sphere.d.ts +35 -6
  19. package/build/geometries/sphere.d.ts.map +1 -1
  20. package/build/index.d.ts +10 -3
  21. package/build/index.d.ts.map +1 -1
  22. package/build/index.js +23361 -20195
  23. package/build/index.js.map +4 -4
  24. package/build/input/pointerevent.d.ts +8 -0
  25. package/build/input/pointerevent.d.ts.map +1 -1
  26. package/build/lang/deprecated.d.ts.map +1 -1
  27. package/build/level/gltf/GLTFModel.d.ts +17 -31
  28. package/build/level/gltf/GLTFModel.d.ts.map +1 -1
  29. package/build/level/gltf/GLTFScene.d.ts +40 -1
  30. package/build/level/gltf/GLTFScene.d.ts.map +1 -1
  31. package/build/level/level.d.ts +36 -0
  32. package/build/level/level.d.ts.map +1 -1
  33. package/build/level/tiled/TMXLayer.d.ts +5 -2
  34. package/build/level/tiled/TMXLayer.d.ts.map +1 -1
  35. package/build/level/tiled/TMXObject.d.ts +0 -1
  36. package/build/level/tiled/TMXTile.d.ts +2 -1
  37. package/build/level/tiled/TMXTile.d.ts.map +1 -1
  38. package/build/level/tiled/TMXTileMap.d.ts +7 -4
  39. package/build/level/tiled/TMXTileMap.d.ts.map +1 -1
  40. package/build/level/tiled/TMXTileset.d.ts +1 -1
  41. package/build/level/tiled/TMXTileset.d.ts.map +1 -1
  42. package/build/level/tiled/TMXTilesetGroup.d.ts +5 -0
  43. package/build/level/tiled/TMXTilesetGroup.d.ts.map +1 -1
  44. package/build/level/tiled/factories/shape.d.ts +0 -1
  45. package/build/level/tiled/renderer/TMXHexagonalRenderer.d.ts +6 -5
  46. package/build/level/tiled/renderer/TMXHexagonalRenderer.d.ts.map +1 -1
  47. package/build/level/tiled/renderer/TMXIsometricRenderer.d.ts +5 -0
  48. package/build/level/tiled/renderer/TMXIsometricRenderer.d.ts.map +1 -1
  49. package/build/level/tiled/renderer/TMXObliqueRenderer.d.ts +8 -7
  50. package/build/level/tiled/renderer/TMXObliqueRenderer.d.ts.map +1 -1
  51. package/build/level/tiled/renderer/TMXOrthogonalRenderer.d.ts +5 -0
  52. package/build/level/tiled/renderer/TMXOrthogonalRenderer.d.ts.map +1 -1
  53. package/build/level/tiled/renderer/TMXRenderer.d.ts +19 -4
  54. package/build/level/tiled/renderer/TMXRenderer.d.ts.map +1 -1
  55. package/build/level/tiled/renderer/autodetect.d.ts +0 -4
  56. package/build/level/tiled/renderer/autodetect.d.ts.map +1 -1
  57. package/build/lighting/light2d.d.ts +68 -2
  58. package/build/lighting/light2d.d.ts.map +1 -1
  59. package/build/lighting/light3d.d.ts.map +1 -1
  60. package/build/loader/loader.d.ts +63 -0
  61. package/build/loader/loader.d.ts.map +1 -1
  62. package/build/loader/loadingscreen.d.ts +1 -2
  63. package/build/loader/loadingscreen.d.ts.map +1 -1
  64. package/build/loader/parsers/fontface.d.ts +2 -0
  65. package/build/loader/parsers/fontface.d.ts.map +1 -1
  66. package/build/loader/parsers/mtl.d.ts.map +1 -1
  67. package/build/loader/parsers/shader.d.ts +0 -2
  68. package/build/math/color.d.ts +27 -4
  69. package/build/math/color.d.ts.map +1 -1
  70. package/build/particles/emitter.d.ts.map +1 -1
  71. package/build/particles/particle.d.ts +22 -1
  72. package/build/particles/particle.d.ts.map +1 -1
  73. package/build/particles/settings.d.ts +69 -0
  74. package/build/particles/settings.d.ts.map +1 -1
  75. package/build/physics/adapter.d.ts +152 -3
  76. package/build/physics/adapter.d.ts.map +1 -1
  77. package/build/physics/builtin/body.d.ts +9 -18
  78. package/build/physics/builtin/body.d.ts.map +1 -1
  79. package/build/physics/builtin/builtin-adapter.d.ts.map +1 -1
  80. package/build/physics/builtin/detector.d.ts +0 -1
  81. package/build/physics/builtin/detector.d.ts.map +1 -1
  82. package/build/physics/builtin/sat.d.ts +0 -7
  83. package/build/physics/builtin/sat.d.ts.map +1 -1
  84. package/build/physics/builtin/sat3d.d.ts +46 -0
  85. package/build/physics/builtin/sat3d.d.ts.map +1 -1
  86. package/build/physics/physicseditor.d.ts +2 -0
  87. package/build/physics/physicseditor.d.ts.map +1 -0
  88. package/build/physics/response.d.ts +45 -62
  89. package/build/physics/response.d.ts.map +1 -1
  90. package/build/renderable/collectable.d.ts +6 -1
  91. package/build/renderable/collectable.d.ts.map +1 -1
  92. package/build/renderable/colorlayer.d.ts +4 -4
  93. package/build/renderable/colorlayer.d.ts.map +1 -1
  94. package/build/renderable/container.d.ts +23 -17
  95. package/build/renderable/container.d.ts.map +1 -1
  96. package/build/renderable/entity/entity.d.ts +14 -16
  97. package/build/renderable/entity/entity.d.ts.map +1 -1
  98. package/build/renderable/frameAnimation.d.ts +1 -1
  99. package/build/renderable/groundshadow.d.ts +1 -0
  100. package/build/renderable/groundshadow.d.ts.map +1 -1
  101. package/build/renderable/imagelayer.d.ts +12 -5
  102. package/build/renderable/imagelayer.d.ts.map +1 -1
  103. package/build/renderable/instanced_mesh.d.ts +2 -9
  104. package/build/renderable/instanced_mesh.d.ts.map +1 -1
  105. package/build/renderable/mesh.d.ts +306 -5
  106. package/build/renderable/mesh.d.ts.map +1 -1
  107. package/build/renderable/nineslicesprite.d.ts +3 -13
  108. package/build/renderable/nineslicesprite.d.ts.map +1 -1
  109. package/build/renderable/renderable.d.ts +129 -28
  110. package/build/renderable/renderable.d.ts.map +1 -1
  111. package/build/renderable/sprite.d.ts +77 -19
  112. package/build/renderable/sprite.d.ts.map +1 -1
  113. package/build/renderable/sprite3d.d.ts +27 -16
  114. package/build/renderable/sprite3d.d.ts.map +1 -1
  115. package/build/renderable/text/bitmaptext.d.ts +13 -3
  116. package/build/renderable/text/bitmaptext.d.ts.map +1 -1
  117. package/build/renderable/text/bitmaptextdata.d.ts +0 -4
  118. package/build/renderable/text/bitmaptextdata.d.ts.map +1 -1
  119. package/build/renderable/text/text.d.ts +5 -3
  120. package/build/renderable/text/text.d.ts.map +1 -1
  121. package/build/renderable/text/textmetrics.d.ts +2 -0
  122. package/build/renderable/text/textmetrics.d.ts.map +1 -1
  123. package/build/renderable/trail.d.ts +0 -1
  124. package/build/renderable/trail.d.ts.map +1 -1
  125. package/build/renderable/trigger.d.ts +39 -14
  126. package/build/renderable/trigger.d.ts.map +1 -1
  127. package/build/renderable/ui/progressbar.d.ts +194 -0
  128. package/build/renderable/ui/progressbar.d.ts.map +1 -0
  129. package/build/renderable/ui/uibaseelement.d.ts +48 -3
  130. package/build/renderable/ui/uibaseelement.d.ts.map +1 -1
  131. package/build/renderable/ui/uispriteelement.d.ts +19 -3
  132. package/build/renderable/ui/uispriteelement.d.ts.map +1 -1
  133. package/build/state/stage.d.ts +22 -0
  134. package/build/state/stage.d.ts.map +1 -1
  135. package/build/system/legacy_pool.d.ts +2 -2
  136. package/build/system/legacy_pool.d.ts.map +1 -1
  137. package/build/system/pool.d.ts +10 -0
  138. package/build/system/pool.d.ts.map +1 -1
  139. package/build/tweens/tween.d.ts +49 -2
  140. package/build/tweens/tween.d.ts.map +1 -1
  141. package/build/video/buffer/vertex.d.ts.map +1 -1
  142. package/build/video/canvas/canvas_renderer.d.ts +34 -23
  143. package/build/video/canvas/canvas_renderer.d.ts.map +1 -1
  144. package/build/video/effects/blendEffect.d.ts +0 -1
  145. package/build/video/effects/bloom.d.ts +72 -0
  146. package/build/video/effects/bloom.d.ts.map +1 -0
  147. package/build/video/effects/blur.d.ts +3 -2
  148. package/build/video/effects/blur.d.ts.map +1 -1
  149. package/build/video/effects/chromaticAberration.d.ts +3 -2
  150. package/build/video/effects/chromaticAberration.d.ts.map +1 -1
  151. package/build/video/effects/colorMatrix.d.ts +3 -2
  152. package/build/video/effects/colorMatrix.d.ts.map +1 -1
  153. package/build/video/effects/desaturate.d.ts +10 -2
  154. package/build/video/effects/desaturate.d.ts.map +1 -1
  155. package/build/video/effects/dissolve.d.ts +3 -2
  156. package/build/video/effects/dissolve.d.ts.map +1 -1
  157. package/build/video/effects/dropShadow.d.ts +3 -2
  158. package/build/video/effects/dropShadow.d.ts.map +1 -1
  159. package/build/video/effects/flash.d.ts +3 -2
  160. package/build/video/effects/flash.d.ts.map +1 -1
  161. package/build/video/effects/glow.d.ts +3 -2
  162. package/build/video/effects/glow.d.ts.map +1 -1
  163. package/build/video/effects/hologram.d.ts +3 -2
  164. package/build/video/effects/hologram.d.ts.map +1 -1
  165. package/build/video/effects/invert.d.ts +10 -2
  166. package/build/video/effects/invert.d.ts.map +1 -1
  167. package/build/video/effects/outline.d.ts +3 -2
  168. package/build/video/effects/outline.d.ts.map +1 -1
  169. package/build/video/effects/pixelate.d.ts +3 -2
  170. package/build/video/effects/pixelate.d.ts.map +1 -1
  171. package/build/video/effects/radialGradient.d.ts +8 -3
  172. package/build/video/effects/radialGradient.d.ts.map +1 -1
  173. package/build/video/effects/scanline.d.ts +3 -2
  174. package/build/video/effects/scanline.d.ts.map +1 -1
  175. package/build/video/effects/sepia.d.ts +10 -2
  176. package/build/video/effects/sepia.d.ts.map +1 -1
  177. package/build/video/effects/shadereffect.d.ts +10 -4
  178. package/build/video/effects/shadereffect.d.ts.map +1 -1
  179. package/build/video/effects/shine.d.ts +3 -2
  180. package/build/video/effects/shine.d.ts.map +1 -1
  181. package/build/video/effects/tintPulse.d.ts +3 -2
  182. package/build/video/effects/tintPulse.d.ts.map +1 -1
  183. package/build/video/effects/tonemap.d.ts +121 -0
  184. package/build/video/effects/tonemap.d.ts.map +1 -0
  185. package/build/video/effects/vignette.d.ts +3 -2
  186. package/build/video/effects/vignette.d.ts.map +1 -1
  187. package/build/video/effects/wave.d.ts +3 -2
  188. package/build/video/effects/wave.d.ts.map +1 -1
  189. package/build/video/gpu/meshmaterial.d.ts +2 -0
  190. package/build/video/gpu/meshmaterial.d.ts.map +1 -0
  191. package/build/video/gpu/vertexformat.d.ts +26 -0
  192. package/build/video/gpu/vertexformat.d.ts.map +1 -1
  193. package/build/video/gradient.d.ts +0 -1
  194. package/build/video/gradient.d.ts.map +1 -1
  195. package/build/video/renderer.d.ts +111 -7
  196. package/build/video/renderer.d.ts.map +1 -1
  197. package/build/video/renderstate.d.ts +2 -0
  198. package/build/video/renderstate.d.ts.map +1 -1
  199. package/build/video/rendertarget/canvasrendertarget.d.ts +3 -4
  200. package/build/video/rendertarget/canvasrendertarget.d.ts.map +1 -1
  201. package/build/video/rendertarget/render_target_pool.d.ts +0 -1
  202. package/build/video/rendertarget/webglrendertarget.d.ts +0 -1
  203. package/build/video/rendertarget/webglrendertarget.d.ts.map +1 -1
  204. package/build/video/rendertarget/webgpurendertarget.d.ts +18 -2
  205. package/build/video/rendertarget/webgpurendertarget.d.ts.map +1 -1
  206. package/build/video/texture/atlas.d.ts +1 -0
  207. package/build/video/texture/atlas.d.ts.map +1 -1
  208. package/build/video/texture/cache.d.ts +1 -3
  209. package/build/video/texture/frametexture.d.ts +0 -1
  210. package/build/video/texture/frametexture.d.ts.map +1 -1
  211. package/build/video/texture/noise_texture2d.d.ts +1 -0
  212. package/build/video/texture/noise_texture2d.d.ts.map +1 -1
  213. package/build/video/utils/autodetect.d.ts +0 -2
  214. package/build/video/webgl/batchers/batcher.d.ts +0 -9
  215. package/build/video/webgl/batchers/batcher.d.ts.map +1 -1
  216. package/build/video/webgl/batchers/lit_quad_batcher.d.ts +13 -1
  217. package/build/video/webgl/batchers/lit_quad_batcher.d.ts.map +1 -1
  218. package/build/video/webgl/batchers/material_batcher.d.ts +4 -2
  219. package/build/video/webgl/batchers/material_batcher.d.ts.map +1 -1
  220. package/build/video/webgl/batchers/mesh_batcher.d.ts +2 -3
  221. package/build/video/webgl/batchers/mesh_batcher.d.ts.map +1 -1
  222. package/build/video/webgl/batchers/quad_batcher.d.ts +4 -0
  223. package/build/video/webgl/batchers/quad_batcher.d.ts.map +1 -1
  224. package/build/video/webgl/buffer/index.d.ts +0 -1
  225. package/build/video/webgl/buffer/retained_geometry.d.ts +0 -1
  226. package/build/video/webgl/glshader.d.ts +5 -3
  227. package/build/video/webgl/glshader.d.ts.map +1 -1
  228. package/build/video/webgl/renderers/tmxlayer/orthogonal.d.ts +0 -4
  229. package/build/video/webgl/shaders/multitexture-lit.d.ts.map +1 -1
  230. package/build/video/webgl/texture/store.d.ts +0 -1
  231. package/build/video/webgl/webgl_renderer.d.ts +63 -24
  232. package/build/video/webgl/webgl_renderer.d.ts.map +1 -1
  233. package/build/video/webgpu/batchers/lit_quad_batcher.d.ts +17 -0
  234. package/build/video/webgpu/batchers/lit_quad_batcher.d.ts.map +1 -1
  235. package/build/video/webgpu/batchers/mesh_batcher.d.ts +0 -3
  236. package/build/video/webgpu/batchers/mesh_batcher.d.ts.map +1 -1
  237. package/build/video/webgpu/batchers/quad_batcher.d.ts +0 -2
  238. package/build/video/webgpu/batchers/quad_batcher.d.ts.map +1 -1
  239. package/build/video/webgpu/batchers/webgpu_batcher.d.ts +0 -2
  240. package/build/video/webgpu/batchers/webgpu_batcher.d.ts.map +1 -1
  241. package/build/video/webgpu/pipeline/cache.d.ts.map +1 -1
  242. package/build/video/webgpu/renderers/tmxlayer/orthogonal.d.ts +0 -2
  243. package/build/video/webgpu/texture/frametexture.d.ts +0 -2
  244. package/build/video/webgpu/texture/frametexture.d.ts.map +1 -1
  245. package/build/video/webgpu/texture/store.d.ts +0 -1
  246. package/build/video/webgpu/texture/store.d.ts.map +1 -1
  247. package/build/video/webgpu/webgpu_renderer.d.ts +8 -75
  248. package/build/video/webgpu/webgpu_renderer.d.ts.map +1 -1
  249. package/package.json +1 -1
  250. package/skills/melonjs-3d/SKILL.md +293 -19
  251. package/skills/melonjs-3d-assets/SKILL.md +123 -13
  252. package/skills/melonjs-camera-and-drawing/SKILL.md +57 -1
  253. package/skills/melonjs-effects-and-shaders/SKILL.md +341 -29
  254. package/skills/melonjs-input/SKILL.md +48 -4
  255. package/skills/melonjs-lighting/SKILL.md +45 -1
  256. package/skills/melonjs-loading-assets/SKILL.md +1 -1
  257. package/skills/melonjs-particles-and-trails/SKILL.md +106 -4
  258. package/skills/melonjs-performance/SKILL.md +79 -2
  259. package/skills/melonjs-physics/SKILL.md +420 -29
  260. package/skills/melonjs-renderables/SKILL.md +15 -1
  261. package/skills/melonjs-scenes-and-state/SKILL.md +121 -1
  262. package/skills/melonjs-tilemaps/SKILL.md +9 -0
  263. package/skills/melonjs-ui-and-text/SKILL.md +165 -4
  264. package/build/level/gltf/srgb.d.ts +0 -20
  265. package/build/level/gltf/srgb.d.ts.map +0 -1
@@ -39,7 +39,7 @@ The type strings are melonJS-specific — this is not a generic loader:
39
39
  | type | for |
40
40
  |---|---|
41
41
  | `"image"` | textures, sprite sheets, normal maps |
42
- | `"json"` | data, texture-atlas descriptors |
42
+ | `"json"` | data, texture-atlas descriptors, collision shapes from a shape editor |
43
43
  | `"tmx"` / `"tsx"` | Tiled maps and external tilesets |
44
44
  | `"audio"` | sound — **`src` is a directory**, see below |
45
45
  | `"video"` | video textures |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: melonjs-particles-and-trails
3
- description: "Use this skill for particle effects and motion trails in melonJS — ParticleEmitter configuration, burst versus stream emission, the referenceSpace frame of reference introduced in 20.2, and the Trail renderable. Covers the emitter that silently does nothing until you call an emit method. Triggers on: ParticleEmitter, particles, burstParticles, streamParticles, referenceSpace, ParticleEmitterSettings, Trail, explosion, smoke, sparks, exhaust, emitter."
3
+ description: "Use this skill for particle effects and motion trails in melonJS — ParticleEmitter configuration, burst versus stream emission, the referenceSpace frame of reference introduced in 20.2, 3D particle motion through elevation and minSpread/maxSpread in 20.8, and the Trail renderable. Covers the emitter that silently does nothing until you call an emit method. Triggers on: ParticleEmitter, particles, burstParticles, streamParticles, referenceSpace, ParticleEmitterSettings, elevation, minSpread, maxSpread, spawn area, Trail, explosion, smoke, sparks, debris, ring, exhaust, emitter."
4
4
  license: MIT
5
5
  ---
6
6
 
@@ -28,6 +28,101 @@ emitter.burstParticles(); // one shot
28
28
  `duration` setting, which defaults to `Infinity` — a stream runs until
29
29
  `stopStream()`. `burstParticles(n)` launches `n`, or `totalParticles`.
30
30
 
31
+ ## Where particles are born
32
+
33
+ `width` and `height` are the spawn AREA, and both default to `1` — so by
34
+ default every particle launches from the same pixel. That is fine for a
35
+ fountain and wrong for an explosion: additive sprites piled on one point clip
36
+ all three channels there however well they are tinted, so a burst reads as one
37
+ bright flash rather than as debris.
38
+
39
+ Give it the size of whatever broke. The area is measured from the emitter's own
40
+ position, NOT centred on it, so offset by half or the whole burst sits down and
41
+ to the right of its source:
42
+
43
+ ```js
44
+ const area = radius * 2;
45
+ const emitter = new ParticleEmitter(x - area / 2, y - area / 2, {
46
+ width: area, height: area,
47
+ });
48
+ ```
49
+
50
+ ## Particles in 3D
51
+
52
+ By default a particle keeps the depth it was born at for its whole life: it
53
+ moves across the emitter's plane and never toward or away from the camera.
54
+ Under a `Camera3d` that reads as a flat sticker anywhere but dead ahead.
55
+
56
+ `elevation` lifts the launch out of that plane and `elevationVariation` spreads
57
+ it. `angle` is the azimuth within the plane, as it always was:
58
+
59
+ ```js
60
+ const emitter = new ParticleEmitter(x, y, {
61
+ angle: 0, angleVariation: Math.PI * 2,
62
+ elevation: 0, elevationVariation: Math.PI / 2, // a sphere of debris
63
+ speed: 9,
64
+ });
65
+ world.addChild(emitter, z); // the depth slice the burst belongs to
66
+ emitter.burstParticles();
67
+ ```
68
+
69
+ `speed` is the length of the whole 3D vector, so an "all directions" burst
70
+ covers the sphere evenly instead of bunching toward the poles.
71
+
72
+ Both default to `0`, and that is a gate rather than the 3D path with zeros in
73
+ it: an emitter that asks for no elevation runs the same two trig calls it
74
+ always did, writes no depth and starts no sort.
75
+
76
+ **The launch is in WORLD axes.** `vel.x` and `vel.y` add to the particle's
77
+ `pos.x`/`pos.y` and `velZ` adds to its depth, so `angle` and `elevation`
78
+ describe a direction in the world, not on the screen. Building them from a
79
+ camera basis works only while the camera's axes ARE the world axes, which stops
80
+ being true the moment you pose a `Camera3d`. For a direction `d` already in
81
+ world terms the pair is `angle: Math.atan2(-d.y, d.x)`,
82
+ `elevation: Math.asin(d.z)`.
83
+
84
+ ### Cones, rings and spheres: aiming around an axis
85
+
86
+ `angleVariation` and `elevationVariation` are sampled INDEPENDENTLY, spreading
87
+ particles over a rectangle of azimuth by elevation. That cannot describe a
88
+ shape defined against a direction. A ring of debris leaving a point on a sphere
89
+ is the set of directions at ninety degrees to that point's normal, and on a
90
+ rectangle the elevation that satisfies it is a function of the azimuth, so no
91
+ pair of variations gets there.
92
+
93
+ Set `maxSpread` and `angle`/`elevation` become an AXIS instead. Each particle
94
+ leaves at a polar angle between `minSpread` and `maxSpread` off that axis,
95
+ around a uniformly random azimuth:
96
+
97
+ | `minSpread` … `maxSpread` | shape |
98
+ |---|---|
99
+ | `0` … `0.5` | a tight cone along the axis |
100
+ | `0` … `Math.PI` | the whole sphere |
101
+ | either value at `Math.PI / 2` | a flat disc perpendicular to the axis |
102
+
103
+ An explosion on a planet's surface is a ring tangent to it: set the axis to the
104
+ surface normal and use `minSpread: Math.PI / 2 - 0.3, maxSpread: Math.PI / 2`.
105
+ Keeping the band at or inside ninety degrees is what stops debris tilting back
106
+ into the body it came off. `angleVariation` and `elevationVariation` are unused
107
+ while `maxSpread` is set.
108
+
109
+ ### Sorting, and why it is keyed off the blend mode
110
+
111
+ A 3D burst only needs depth sorting when its blend is order dependent, and the
112
+ emitter decides that for you. Additive blending is commutative, so an additive
113
+ burst looks the same however it is ordered and pays nothing; `"normal"` is not,
114
+ so a 3D burst drawn with it is sorted back to front.
115
+
116
+ The two differ in more than cost. Additive sprites overlapping near the centre
117
+ of a burst sum to white however they are tinted, so debris that has to keep its
118
+ colour wants `textureAdditive: false` and accepts the sort. A common shape is
119
+ two emitters: a solid, sorted body of debris with a sparser additive spray of
120
+ sparks over it.
121
+
122
+ The default particle sprite is a filled SQUARE, which additive blending hides
123
+ and normal blending does not. Pass your own soft `image` for non-additive
124
+ debris.
125
+
31
126
  For one-shot effects, `autoDestroyOnComplete: true` removes the emitter once its
32
127
  particles have finished. The `onComplete` callback fires at that same moment
33
128
  either way.
@@ -95,9 +190,10 @@ draws a flat ribbon that does not recede with perspective — so it is the wrong
95
190
  tool for a trail behind an object moving *into* the scene. For that:
96
191
 
97
192
  - **`ParticleEmitter` with `referenceSpace: "world"`** — particles stay where
98
- they were dropped while the emitter moves on, and the emitter propagates its
99
- depth to each particle so `Camera3d` projects them correctly. This is the
100
- built-in answer for exhaust, ski tracks and speed trails in 3D.
193
+ they were dropped while the emitter moves on, and each one sits at the
194
+ emitter's depth slice so `Camera3d` projects it correctly. Add an `elevation`
195
+ and they recede as well. This is the built-in answer for exhaust, ski tracks
196
+ and speed trails in 3D.
101
197
  - **A procedural `Mesh`** built from the object's recent path, with
102
198
  `mesh.vertexColors` for a per-vertex gradient — more work, but a continuous
103
199
  ribbon rather than discrete puffs.
@@ -129,6 +225,12 @@ tool for a trail behind an object moving *into* the scene. For that:
129
225
  | particles do not travel far enough | settings tuned pre-20.2, when drawn travel was doubled |
130
226
  | one-shot emitters accumulate | missing `autoDestroyOnComplete: true` |
131
227
  | frame rate drops with many effects | an emitter per event instead of one re-aimed emitter |
228
+ | a 3D burst is invisible under a `Camera3d` | before 20.8 a particle was culled at twice its depth; update |
229
+ | the whole burst launches from one pixel | `width`/`height` are the spawn area and default to `1` |
230
+ | the burst sits down-right of its source | the spawn area starts at the emitter's position; offset by half |
231
+ | the middle of a burst goes white | additive sprites overlapping — `textureAdditive: false`, or spread them |
232
+ | debris chunks look like squares | the default sprite is a filled square; pass your own `image` |
233
+ | a ring tilts with the camera instead of staying on a surface | the launch axis is in WORLD axes, not the camera basis |
132
234
 
133
235
  ## Related skills
134
236
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: melonjs-performance
3
- description: "Use this skill when a melonJS game drops frames, allocates heavily, or needs to scale to many objects. Covers object pooling, draw-call batching, atlases, baking with CanvasRenderTarget, instancing, culling and alwaysUpdate, the debug plugin, and where the real costs are. Triggers on: performance, slow, frame rate, fps, lag, pool, pool.register, pool.pull, batching, draw calls, InstancedMesh, culling, alwaysUpdate, inViewport, CanvasRenderTarget, optimise, profiling, debug plugin, memory."
3
+ description: "Use this skill when a melonJS game drops frames, allocates heavily, or needs to scale to many objects. Covers object pooling, draw-call batching, atlases, baking with CanvasRenderTarget, instancing, culling and alwaysUpdate, the debug plugin, and where the real costs are. Triggers on: performance, slow, frame rate, fps, lag, pool, pool.register, pool.pull, batching, draw calls, InstancedMesh, culling, alwaysUpdate, inViewport, CanvasRenderTarget, optimise, profiling, debug plugin, memory, render targets, hdr."
4
4
  license: MIT
5
5
  ---
6
6
 
@@ -81,6 +81,23 @@ Two rules that cause subtle bugs when missed:
81
81
  successfully recycled object never sees it. Pair event subscriptions with
82
82
  `onActivateEvent` / `onDeactivateEvent` instead, or you leak handlers.
83
83
 
84
+ - **`removeChild` is DEFERRED, which breaks a pool you re-lend in the same
85
+ frame.** The removal is queued and runs after the update and draw stack has
86
+ unwound, so an object you remove and immediately hand out again is torn out
87
+ from under its new owner when the queue drains: it vanishes, and the frame
88
+ after that the removal throws `Child is not mine.` Take it out immediately
89
+ instead, keeping the instance alive for reuse:
90
+
91
+ ```js
92
+ world.removeChildNow(bullet, true); // keepalive: do NOT destroy it
93
+ this.freeList.push(bullet);
94
+ ```
95
+
96
+ `removeChildNow(child, keepalive)` with `keepalive` true skips the destroy,
97
+ which is what you want for anything you own the lifetime of. This is the
98
+ usual cause of a pooled effect that flickers out one frame after it is
99
+ recycled.
100
+
84
101
  Engine classes are poolable too: `pool.pull("Tween", target)`. The canonical
85
102
  names are unprefixed — `Entity`, `Collectable`, `Trigger`, `Light2d`,
86
103
  `Particle`, `Sprite`, `NineSliceSprite`, `Renderable`, `Text`, `BitmapText`,
@@ -95,13 +112,34 @@ name in new code; do not "correct" an `me.`-prefixed one, it is not broken.
95
112
  ## `scale()` is multiplicative
96
113
 
97
114
  A pooled sprite arrives carrying its previous life's transform, and calling
98
- `scale()` each frame compounds. For absolute scaling:
115
+ `scale()` each frame compounds. `rotate()` is the same. For absolute values,
116
+ reset first:
99
117
 
100
118
  ```js
101
119
  sprite.currentTransform.identity();
102
120
  sprite.currentTransform.scale(s, s, 1);
103
121
  ```
104
122
 
123
+ **Order matters, and it is the opposite of what reads naturally.**
124
+ `Matrix2d.scale` multiplies the matrix ROWS, so it applies AFTER whatever the
125
+ matrix already holds. Scale first and then rotate; rotate first and the scale
126
+ lands in the rotated frame and SHEARS anything non-uniform:
127
+
128
+ ```js
129
+ // correct: a long thin quad, rotated
130
+ t.identity();
131
+ t.scale(length / texW, width / texH);
132
+ t.rotate(angle);
133
+
134
+ // wrong: the same quad arrives as a parallelogram
135
+ t.identity();
136
+ t.rotate(angle);
137
+ t.scale(length / texW, width / texH);
138
+ ```
139
+
140
+ The symptom is a sprite that looks right at 0 and 90 degrees and skews in
141
+ between, which reads as a bad texture rather than as a transform bug.
142
+
105
143
  ## Culling and update cost
106
144
 
107
145
  - `Container` recomputes `inViewport` for every child each frame against every
@@ -231,6 +269,45 @@ SwiftShader, where the absolute numbers are wildly pessimistic and the JS
231
269
  profile shows the time as `(program)`, outside JS entirely. Ratios transfer;
232
270
  milliseconds do not.
233
271
 
272
+ ## Render targets, and what `hdr` costs
273
+
274
+ A render target is a canvas-sized GPU surface. The engine allocates them
275
+ lazily and only where a multi-pass chain actually needs one, which is worth
276
+ knowing before assuming an effect is expensive:
277
+
278
+ - a renderable with **no** post effects: none
279
+ - a renderable with **exactly one** post effect: still none. It takes the
280
+ `customShader` fast path and draws straight into whatever target is already
281
+ bound
282
+ - a **camera** with effects: a pair (one capture, one ping-pong intermediate)
283
+ - a sprite with **two or more** effects: its own pair
284
+
285
+ So the first lever is the count, not the cost of any one effect: going from
286
+ one effect to two on a sprite is what allocates, not going from a cheap shader
287
+ to an expensive one.
288
+
289
+ `hdr: true` changes the format of that camera pair from 8 bits per channel to
290
+ half-float, which is **8 bytes per pixel instead of 4**. At 1920×1080 that is
291
+ about 8 MB per target instead of 4 MB, so roughly +8 MB for the pair. With
292
+ `antiAlias` on, the capture half is also multisampled and its multisampled
293
+ surface takes the same format, so that part doubles too.
294
+
295
+ Nothing else moves. Sprite chains and the advanced-blend target stay 8-bit
296
+ whatever `hdr` says, for a correctness reason rather than a thrifty one: their
297
+ final blit composites with `ONE_MINUS_SRC_ALPHA`, and additive blending
298
+ accumulates alpha past 1 in a float target, which would turn that factor
299
+ negative and subtract the backdrop.
300
+
301
+ **With `hdr` off, nothing changes at all** — every target keeps the 8-bit
302
+ attachment it has always had, and a game that never adds a camera post-effect
303
+ allocates no render targets in the first place. The setting costs nothing
304
+ until something is actually using it.
305
+
306
+ ```js
307
+ // what you actually got, which is not always what you asked for
308
+ if (app.renderer.supportsHDR === false) { /* grade for a chain that clamps */ }
309
+ ```
310
+
234
311
  ## Where the costs actually are
235
312
 
236
313
  In rough order for a typical 2D game: