melonjs 20.3.0 → 20.5.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.
- package/README.md +19 -19
- package/build/application/application.d.ts +0 -17
- package/build/application/application.d.ts.map +1 -1
- package/build/application/settings.d.ts +3 -0
- package/build/application/settings.d.ts.map +1 -1
- package/build/audio/audio.d.ts.map +1 -1
- package/build/audio/backend/engine.d.ts +0 -19
- package/build/audio/backend/engine.d.ts.map +1 -1
- package/build/audio/backend/sound.d.ts +1 -51
- package/build/audio/backend/sound.d.ts.map +1 -1
- package/build/audio/backend/spatial.d.ts.map +1 -1
- package/build/audio/backend/types.d.ts +11 -1
- package/build/audio/backend/types.d.ts.map +1 -1
- package/build/audio/backend/voice.d.ts +0 -25
- package/build/audio/backend/voice.d.ts.map +1 -1
- package/build/audio/playback.d.ts.map +1 -1
- package/build/audio/procedural.d.ts +7 -2
- package/build/audio/procedural.d.ts.map +1 -1
- package/build/audio/state.d.ts +6 -79
- package/build/audio/state.d.ts.map +1 -1
- package/build/audio/types.d.ts +22 -0
- package/build/audio/types.d.ts.map +1 -1
- package/build/camera/camera2d.d.ts +28 -68
- package/build/camera/camera2d.d.ts.map +1 -1
- package/build/camera/camera3d.d.ts +110 -82
- package/build/camera/camera3d.d.ts.map +1 -1
- package/build/camera/effects/fade_effect.d.ts +0 -5
- package/build/camera/effects/fade_effect.d.ts.map +1 -1
- package/build/camera/effects/mask_effect.d.ts +0 -5
- package/build/camera/effects/mask_effect.d.ts.map +1 -1
- package/build/camera/fog.d.ts +118 -0
- package/build/camera/fog.d.ts.map +1 -0
- package/build/geometries/box3d.d.ts +0 -28
- package/build/geometries/box3d.d.ts.map +1 -1
- package/build/geometries/ellipse.d.ts +0 -20
- package/build/geometries/ellipse.d.ts.map +1 -1
- package/build/geometries/observablePoint.d.ts +0 -3
- package/build/geometries/observablePoint.d.ts.map +1 -1
- package/build/geometries/path2d.d.ts +0 -19
- package/build/geometries/path2d.d.ts.map +1 -1
- package/build/geometries/polygon.d.ts +7 -13
- package/build/geometries/polygon.d.ts.map +1 -1
- package/build/geometries/roundrect.d.ts +0 -18
- package/build/geometries/roundrect.d.ts.map +1 -1
- package/build/geometries/sphere.d.ts +0 -9
- package/build/geometries/sphere.d.ts.map +1 -1
- package/build/geometries/toarccanvas.d.ts.map +1 -1
- package/build/index.d.ts +5 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3697 -563
- package/build/index.js.map +4 -4
- package/build/input/gamepad.d.ts.map +1 -1
- package/build/input/pointer.d.ts +0 -4
- package/build/input/pointer.d.ts.map +1 -1
- package/build/input/pointerevent.d.ts +0 -6
- package/build/input/pointerevent.d.ts.map +1 -1
- package/build/lang/deprecated.d.ts.map +1 -1
- package/build/level/gltf/GLTFModel.d.ts +44 -82
- package/build/level/gltf/GLTFModel.d.ts.map +1 -1
- package/build/level/gltf/GLTFScene.d.ts +1 -44
- package/build/level/gltf/GLTFScene.d.ts.map +1 -1
- package/build/level/gltf/gltf_sampler.d.ts +1 -48
- package/build/level/gltf/gltf_sampler.d.ts.map +1 -1
- package/build/level/level.d.ts +195 -113
- package/build/level/level.d.ts.map +1 -1
- package/build/level/tiled/TMXGroup.d.ts +1 -65
- package/build/level/tiled/TMXGroup.d.ts.map +1 -1
- package/build/level/tiled/TMXLayer.d.ts +0 -44
- package/build/level/tiled/TMXLayer.d.ts.map +1 -1
- package/build/level/tiled/TMXObject.d.ts +1 -136
- package/build/level/tiled/TMXObject.d.ts.map +1 -1
- package/build/level/tiled/TMXObjectFactory.d.ts +1 -40
- package/build/level/tiled/TMXObjectFactory.d.ts.map +1 -1
- package/build/level/tiled/TMXTile.d.ts +1 -30
- package/build/level/tiled/TMXTile.d.ts.map +1 -1
- package/build/level/tiled/TMXTileMap.d.ts +0 -10
- package/build/level/tiled/TMXTileMap.d.ts.map +1 -1
- package/build/level/tiled/TMXTileset.d.ts +0 -113
- package/build/level/tiled/TMXTileset.d.ts.map +1 -1
- package/build/level/tiled/TMXTilesetGroup.d.ts +0 -1
- package/build/level/tiled/TMXTilesetGroup.d.ts.map +1 -1
- package/build/level/tiled/TMXUtils.d.ts +1 -43
- package/build/level/tiled/TMXUtils.d.ts.map +1 -1
- package/build/level/tiled/factories/shape.d.ts +1 -7
- package/build/level/tiled/factories/shape.d.ts.map +1 -1
- package/build/level/tiled/factories/text.d.ts +1 -7
- package/build/level/tiled/factories/text.d.ts.map +1 -1
- package/build/level/tiled/factories/tile.d.ts +1 -7
- package/build/level/tiled/factories/tile.d.ts.map +1 -1
- package/build/level/tiled/renderer/TMXHexagonalRenderer.d.ts +0 -60
- package/build/level/tiled/renderer/TMXHexagonalRenderer.d.ts.map +1 -1
- package/build/level/tiled/renderer/TMXIsometricRenderer.d.ts +0 -42
- package/build/level/tiled/renderer/TMXIsometricRenderer.d.ts.map +1 -1
- package/build/level/tiled/renderer/TMXObliqueRenderer.d.ts +0 -5
- package/build/level/tiled/renderer/TMXObliqueRenderer.d.ts.map +1 -1
- package/build/level/tiled/renderer/TMXOrthogonalRenderer.d.ts +0 -31
- package/build/level/tiled/renderer/TMXOrthogonalRenderer.d.ts.map +1 -1
- package/build/level/tiled/renderer/TMXRenderer.d.ts +2 -2
- package/build/level/tiled/renderer/TMXRenderer.d.ts.map +1 -1
- package/build/level/tiled/renderer/TMXStaggeredRenderer.d.ts.map +1 -1
- package/build/level/tiled/renderer/autodetect.d.ts +1 -6
- package/build/level/tiled/renderer/autodetect.d.ts.map +1 -1
- package/build/lighting/light2d.d.ts +0 -25
- package/build/lighting/light2d.d.ts.map +1 -1
- package/build/lighting/light3d.d.ts +20 -63
- package/build/lighting/light3d.d.ts.map +1 -1
- package/build/loader/loader.d.ts +146 -37
- package/build/loader/loader.d.ts.map +1 -1
- package/build/loader/loadingscreen.d.ts +0 -33
- package/build/loader/loadingscreen.d.ts.map +1 -1
- package/build/loader/parsers/aseprite.d.ts +0 -13
- package/build/loader/parsers/aseprite.d.ts.map +1 -1
- package/build/loader/parsers/audio.d.ts +1 -30
- package/build/loader/parsers/audio.d.ts.map +1 -1
- package/build/loader/parsers/binary.d.ts +1 -10
- package/build/loader/parsers/binary.d.ts.map +1 -1
- package/build/loader/parsers/compressed_textures/compressed_image.d.ts.map +1 -1
- package/build/loader/parsers/compressed_textures/parseDDS.d.ts +1 -7
- package/build/loader/parsers/compressed_textures/parseDDS.d.ts.map +1 -1
- package/build/loader/parsers/compressed_textures/parseKTX.d.ts +1 -7
- package/build/loader/parsers/compressed_textures/parseKTX.d.ts.map +1 -1
- package/build/loader/parsers/compressed_textures/parseKTX2.d.ts +1 -7
- package/build/loader/parsers/compressed_textures/parseKTX2.d.ts.map +1 -1
- package/build/loader/parsers/compressed_textures/parsePKM.d.ts +1 -7
- package/build/loader/parsers/compressed_textures/parsePKM.d.ts.map +1 -1
- package/build/loader/parsers/compressed_textures/parsePVR.d.ts +1 -7
- package/build/loader/parsers/compressed_textures/parsePVR.d.ts.map +1 -1
- package/build/loader/parsers/fontface.d.ts +1 -13
- package/build/loader/parsers/fontface.d.ts.map +1 -1
- package/build/loader/parsers/gltf.d.ts +1 -70
- package/build/loader/parsers/gltf.d.ts.map +1 -1
- package/build/loader/parsers/image.d.ts +1 -22
- package/build/loader/parsers/image.d.ts.map +1 -1
- package/build/loader/parsers/json.d.ts +1 -10
- package/build/loader/parsers/json.d.ts.map +1 -1
- package/build/loader/parsers/mtl.d.ts +1 -28
- package/build/loader/parsers/mtl.d.ts.map +1 -1
- package/build/loader/parsers/obj.d.ts +1 -59
- package/build/loader/parsers/obj.d.ts.map +1 -1
- package/build/loader/parsers/pbr.d.ts +1 -62
- package/build/loader/parsers/pbr.d.ts.map +1 -1
- package/build/loader/parsers/script.d.ts +1 -10
- package/build/loader/parsers/script.d.ts.map +1 -1
- package/build/loader/parsers/shader.d.ts +1 -52
- package/build/loader/parsers/shader.d.ts.map +1 -1
- package/build/loader/parsers/tmx.d.ts +1 -10
- package/build/loader/parsers/tmx.d.ts.map +1 -1
- package/build/loader/parsers/video.d.ts +1 -10
- package/build/loader/parsers/video.d.ts.map +1 -1
- package/build/math/color.d.ts.map +1 -1
- package/build/math/noise.d.ts +0 -40
- package/build/math/noise.d.ts.map +1 -1
- package/build/math/observableVector2d.d.ts +0 -3
- package/build/math/observableVector2d.d.ts.map +1 -1
- package/build/math/observableVector3d.d.ts +0 -3
- package/build/math/observableVector3d.d.ts.map +1 -1
- package/build/math/vector2d.d.ts +0 -6
- package/build/math/vector2d.d.ts.map +1 -1
- package/build/math/vertex.d.ts +25 -0
- package/build/math/vertex.d.ts.map +1 -1
- package/build/particles/emitter.d.ts +0 -65
- package/build/particles/emitter.d.ts.map +1 -1
- package/build/particles/particle.d.ts +0 -81
- package/build/particles/particle.d.ts.map +1 -1
- package/build/physics/bounds.d.ts +0 -1
- package/build/physics/bounds.d.ts.map +1 -1
- package/build/physics/broadphase/broadphase.d.ts +0 -7
- package/build/physics/broadphase/broadphase.d.ts.map +1 -1
- package/build/physics/broadphase/octree.d.ts +0 -91
- package/build/physics/broadphase/octree.d.ts.map +1 -1
- package/build/physics/broadphase/quadtree.d.ts +0 -47
- package/build/physics/broadphase/quadtree.d.ts.map +1 -1
- package/build/physics/builtin/body.d.ts +2 -65
- package/build/physics/builtin/body.d.ts.map +1 -1
- package/build/physics/builtin/detector.d.ts +0 -312
- package/build/physics/builtin/detector.d.ts.map +1 -1
- package/build/physics/builtin/sat.d.ts +1 -48
- package/build/physics/builtin/sat.d.ts.map +1 -1
- package/build/physics/builtin/sat3d.d.ts +1 -56
- package/build/physics/builtin/sat3d.d.ts.map +1 -1
- package/build/physics/collision.d.ts +0 -2
- package/build/physics/collision.d.ts.map +1 -1
- package/build/physics/response.d.ts +0 -1
- package/build/physics/response.d.ts.map +1 -1
- package/build/physics/world.d.ts.map +1 -1
- package/build/renderable/anchorPoint.d.ts +1 -73
- package/build/renderable/anchorPoint.d.ts.map +1 -1
- package/build/renderable/animation.d.ts +21 -13
- package/build/renderable/animation.d.ts.map +1 -1
- package/build/renderable/colorlayer.d.ts +0 -5
- package/build/renderable/colorlayer.d.ts.map +1 -1
- package/build/renderable/container.d.ts +27 -60
- package/build/renderable/container.d.ts.map +1 -1
- package/build/renderable/draggable.d.ts +0 -5
- package/build/renderable/draggable.d.ts.map +1 -1
- package/build/renderable/dragndrop.d.ts +1 -12
- package/build/renderable/dragndrop.d.ts.map +1 -1
- package/build/renderable/entity/entity.d.ts +0 -8
- package/build/renderable/entity/entity.d.ts.map +1 -1
- package/build/renderable/frameAnimation.d.ts +0 -41
- package/build/renderable/frameAnimation.d.ts.map +1 -1
- package/build/renderable/groundshadow.d.ts +1 -91
- package/build/renderable/groundshadow.d.ts.map +1 -1
- package/build/renderable/imagelayer.d.ts +0 -29
- package/build/renderable/imagelayer.d.ts.map +1 -1
- package/build/renderable/instanced_mesh.d.ts +55 -108
- package/build/renderable/instanced_mesh.d.ts.map +1 -1
- package/build/renderable/mesh.d.ts +257 -231
- package/build/renderable/mesh.d.ts.map +1 -1
- package/build/renderable/nineslicesprite.d.ts +0 -4
- package/build/renderable/nineslicesprite.d.ts.map +1 -1
- package/build/renderable/renderable.d.ts +18 -44
- package/build/renderable/renderable.d.ts.map +1 -1
- package/build/renderable/sprite.d.ts +0 -45
- package/build/renderable/sprite.d.ts.map +1 -1
- package/build/renderable/sprite3d.d.ts +12 -97
- package/build/renderable/sprite3d.d.ts.map +1 -1
- package/build/renderable/text/bitmaptext.d.ts +32 -21
- package/build/renderable/text/bitmaptext.d.ts.map +1 -1
- package/build/renderable/text/bitmaptextdata.d.ts +0 -22
- package/build/renderable/text/bitmaptextdata.d.ts.map +1 -1
- package/build/renderable/text/glyph.d.ts +1 -39
- package/build/renderable/text/glyph.d.ts.map +1 -1
- package/build/renderable/text/text.d.ts +75 -20
- package/build/renderable/text/text.d.ts.map +1 -1
- package/build/renderable/text/textmetrics.d.ts +2 -0
- package/build/renderable/text/textmetrics.d.ts.map +1 -1
- package/build/renderable/text/textstyle.d.ts +1 -5
- package/build/renderable/text/textstyle.d.ts.map +1 -1
- package/build/renderable/trail.d.ts +0 -29
- package/build/renderable/trail.d.ts.map +1 -1
- package/build/renderable/trigger.d.ts +0 -6
- package/build/renderable/trigger.d.ts.map +1 -1
- package/build/renderable/ui/uibaseelement.d.ts +0 -40
- package/build/renderable/ui/uibaseelement.d.ts.map +1 -1
- package/build/renderable/ui/uispriteelement.d.ts +0 -35
- package/build/renderable/ui/uispriteelement.d.ts.map +1 -1
- package/build/state/stage.d.ts +5 -50
- package/build/state/stage.d.ts.map +1 -1
- package/build/state/state.d.ts.map +1 -1
- package/build/system/device.d.ts +1 -13
- package/build/system/device.d.ts.map +1 -1
- package/build/system/dom.d.ts +1 -8
- package/build/system/dom.d.ts.map +1 -1
- package/build/system/legacy_pool.d.ts +1 -6
- package/build/system/legacy_pool.d.ts.map +1 -1
- package/build/system/platform.d.ts +0 -1
- package/build/system/platform.d.ts.map +1 -1
- package/build/system/pool.d.ts +0 -9
- package/build/system/pool.d.ts.map +1 -1
- package/build/system/save.d.ts +44 -1
- package/build/system/save.d.ts.map +1 -1
- package/build/system/timer.d.ts +0 -20
- package/build/system/timer.d.ts.map +1 -1
- package/build/tweens/tween.d.ts +0 -62
- package/build/tweens/tween.d.ts.map +1 -1
- package/build/utils/array-multimap.d.ts +1 -13
- package/build/utils/array-multimap.d.ts.map +1 -1
- package/build/utils/decode.d.ts.map +1 -1
- package/build/utils/fetchdata.d.ts +1 -31
- package/build/utils/fetchdata.d.ts.map +1 -1
- package/build/utils/utils.d.ts +0 -13
- package/build/utils/utils.d.ts.map +1 -1
- package/build/video/blendmodes.d.ts +1 -106
- package/build/video/blendmodes.d.ts.map +1 -1
- package/build/video/buffer/index.d.ts +1 -39
- package/build/video/buffer/index.d.ts.map +1 -1
- package/build/video/buffer/vertex.d.ts +1 -82
- package/build/video/buffer/vertex.d.ts.map +1 -1
- package/build/video/canvas/canvas_renderer.d.ts +2 -23
- package/build/video/canvas/canvas_renderer.d.ts.map +1 -1
- package/build/video/canvas_factory.d.ts +1 -24
- package/build/video/canvas_factory.d.ts.map +1 -1
- package/build/video/effects/blendEffect.d.ts +0 -54
- package/build/video/effects/blendEffect.d.ts.map +1 -1
- package/build/video/effects/colorMatrix.d.ts +0 -10
- package/build/video/effects/colorMatrix.d.ts.map +1 -1
- package/build/video/effects/glsl_realization.d.ts +1 -17
- package/build/video/effects/glsl_realization.d.ts.map +1 -1
- package/build/video/effects/mesh_splice.d.ts +2 -0
- package/build/video/effects/mesh_splice.d.ts.map +1 -0
- package/build/video/effects/radialGradient.d.ts +0 -1
- package/build/video/effects/radialGradient.d.ts.map +1 -1
- package/build/video/effects/shadereffect.d.ts +12 -241
- package/build/video/effects/shadereffect.d.ts.map +1 -1
- package/build/video/effects/wgsl/layout.d.ts +1 -27
- package/build/video/effects/wgsl/layout.d.ts.map +1 -1
- package/build/video/effects/wgsl/parse.d.ts +1 -8
- package/build/video/effects/wgsl/parse.d.ts.map +1 -1
- package/build/video/effects/wgsl/scaffold.d.ts +1 -42
- package/build/video/effects/wgsl/scaffold.d.ts.map +1 -1
- package/build/video/effects/wgsl_realization.d.ts +1 -82
- package/build/video/effects/wgsl_realization.d.ts.map +1 -1
- package/build/video/gpu/batcher.d.ts +1 -13
- package/build/video/gpu/batcher.d.ts.map +1 -1
- package/build/video/gpu/instancerecord.d.ts +1 -163
- package/build/video/gpu/instancerecord.d.ts.map +1 -1
- package/build/video/gpu/meshchunk.d.ts +1 -48
- package/build/video/gpu/meshchunk.d.ts.map +1 -1
- package/build/video/gpu/meshvertex.d.ts +1 -53
- package/build/video/gpu/meshvertex.d.ts.map +1 -1
- package/build/video/gpu/primitives.d.ts +1 -59
- package/build/video/gpu/primitives.d.ts.map +1 -1
- package/build/video/gpu/quadcorners.d.ts +1 -10
- package/build/video/gpu/quadcorners.d.ts.map +1 -1
- package/build/video/gpu/textureslots.d.ts +1 -121
- package/build/video/gpu/textureslots.d.ts.map +1 -1
- package/build/video/gpu/texturestore.d.ts +1 -138
- package/build/video/gpu/texturestore.d.ts.map +1 -1
- package/build/video/gpu/topology.d.ts.map +1 -1
- package/build/video/gpu/vertexformat.d.ts +0 -28
- package/build/video/gpu/vertexformat.d.ts.map +1 -1
- package/build/video/gradient.d.ts +15 -77
- package/build/video/gradient.d.ts.map +1 -1
- package/build/video/renderer.d.ts +21 -102
- package/build/video/renderer.d.ts.map +1 -1
- package/build/video/renderstate.d.ts +0 -51
- package/build/video/renderstate.d.ts.map +1 -1
- package/build/video/rendertarget/canvasrendertarget.d.ts +0 -10
- package/build/video/rendertarget/canvasrendertarget.d.ts.map +1 -1
- package/build/video/rendertarget/render_target_pool.d.ts +1 -82
- package/build/video/rendertarget/render_target_pool.d.ts.map +1 -1
- package/build/video/rendertarget/webglrendertarget.d.ts +1 -64
- package/build/video/rendertarget/webglrendertarget.d.ts.map +1 -1
- package/build/video/rendertarget/webgpurendertarget.d.ts +0 -8
- package/build/video/rendertarget/webgpurendertarget.d.ts.map +1 -1
- package/build/video/texture/atlas.d.ts +1 -75
- package/build/video/texture/atlas.d.ts.map +1 -1
- package/build/video/texture/cache.d.ts +0 -136
- package/build/video/texture/cache.d.ts.map +1 -1
- package/build/video/texture/frametexture.d.ts +1 -71
- package/build/video/texture/frametexture.d.ts.map +1 -1
- package/build/video/texture/noise_texture2d.d.ts +101 -77
- package/build/video/texture/noise_texture2d.d.ts.map +1 -1
- package/build/video/texture/parser/aseprite.d.ts +1 -8
- package/build/video/texture/parser/aseprite.d.ts.map +1 -1
- package/build/video/texture/parser/spritesheet.d.ts +1 -8
- package/build/video/texture/parser/spritesheet.d.ts.map +1 -1
- package/build/video/texture/parser/texturepacker.d.ts +1 -8
- package/build/video/texture/parser/texturepacker.d.ts.map +1 -1
- package/build/video/texture/resource.d.ts +0 -9
- package/build/video/texture/resource.d.ts.map +1 -1
- package/build/video/texture/texture2d.d.ts +0 -11
- package/build/video/texture/texture2d.d.ts.map +1 -1
- package/build/video/utils/autodetect.d.ts +1 -5
- package/build/video/utils/autodetect.d.ts.map +1 -1
- package/build/video/webgl/batchers/batcher.d.ts +0 -55
- package/build/video/webgl/batchers/batcher.d.ts.map +1 -1
- package/build/video/webgl/batchers/lit_mesh_batcher.d.ts +0 -14
- package/build/video/webgl/batchers/lit_mesh_batcher.d.ts.map +1 -1
- package/build/video/webgl/batchers/lit_quad_batcher.d.ts +0 -72
- package/build/video/webgl/batchers/lit_quad_batcher.d.ts.map +1 -1
- package/build/video/webgl/batchers/material_batcher.d.ts +0 -89
- package/build/video/webgl/batchers/material_batcher.d.ts.map +1 -1
- package/build/video/webgl/batchers/mesh_batcher.d.ts +14 -343
- package/build/video/webgl/batchers/mesh_batcher.d.ts.map +1 -1
- package/build/video/webgl/batchers/primitive_batcher.d.ts +0 -10
- package/build/video/webgl/batchers/primitive_batcher.d.ts.map +1 -1
- package/build/video/webgl/batchers/quad_batcher.d.ts +0 -30
- package/build/video/webgl/batchers/quad_batcher.d.ts.map +1 -1
- package/build/video/webgl/buffer/index.d.ts +1 -36
- package/build/video/webgl/buffer/index.d.ts.map +1 -1
- package/build/video/webgl/buffer/instance_buffer.d.ts +1 -53
- package/build/video/webgl/buffer/instance_buffer.d.ts.map +1 -1
- package/build/video/webgl/buffer/retained_geometry.d.ts +1 -81
- package/build/video/webgl/buffer/retained_geometry.d.ts.map +1 -1
- package/build/video/webgl/buffer/uniformblock.d.ts +1 -80
- package/build/video/webgl/buffer/uniformblock.d.ts.map +1 -1
- package/build/video/webgl/buffer/vertexstate.d.ts +1 -100
- package/build/video/webgl/buffer/vertexstate.d.ts.map +1 -1
- package/build/video/webgl/glshader.d.ts +7 -51
- package/build/video/webgl/glshader.d.ts.map +1 -1
- package/build/video/webgl/lighting/pack3d.d.ts +1 -47
- package/build/video/webgl/lighting/pack3d.d.ts.map +1 -1
- package/build/video/webgl/lighting/std140.d.ts +1 -109
- package/build/video/webgl/lighting/std140.d.ts.map +1 -1
- package/build/video/webgl/renderers/tmxlayer/orthogonal.d.ts +1 -103
- package/build/video/webgl/renderers/tmxlayer/orthogonal.d.ts.map +1 -1
- package/build/video/webgl/shaders/multitexture-lit.d.ts +1 -26
- package/build/video/webgl/shaders/multitexture-lit.d.ts.map +1 -1
- package/build/video/webgl/shaders/multitexture.d.ts +1 -9
- package/build/video/webgl/shaders/multitexture.d.ts.map +1 -1
- package/build/video/webgl/texture/store.d.ts +1 -50
- package/build/video/webgl/texture/store.d.ts.map +1 -1
- package/build/video/webgl/utils/attributes.d.ts +1 -11
- package/build/video/webgl/utils/attributes.d.ts.map +1 -1
- package/build/video/webgl/utils/maxtextures.d.ts +1 -36
- package/build/video/webgl/utils/maxtextures.d.ts.map +1 -1
- package/build/video/webgl/utils/precision.d.ts +1 -14
- package/build/video/webgl/utils/precision.d.ts.map +1 -1
- package/build/video/webgl/utils/program.d.ts +1 -5
- package/build/video/webgl/utils/program.d.ts.map +1 -1
- package/build/video/webgl/utils/samplercache.d.ts +1 -68
- package/build/video/webgl/utils/samplercache.d.ts.map +1 -1
- package/build/video/webgl/utils/string.d.ts +1 -21
- package/build/video/webgl/utils/string.d.ts.map +1 -1
- package/build/video/webgl/utils/topology.d.ts +1 -23
- package/build/video/webgl/utils/topology.d.ts.map +1 -1
- package/build/video/webgl/utils/uniforms.d.ts +1 -25
- package/build/video/webgl/utils/uniforms.d.ts.map +1 -1
- package/build/video/webgl/utils/vertexformat.d.ts +1 -26
- package/build/video/webgl/utils/vertexformat.d.ts.map +1 -1
- package/build/video/webgl/webgl_renderer.d.ts +22 -285
- package/build/video/webgl/webgl_renderer.d.ts.map +1 -1
- package/build/video/webgpu/batchers/lit_mesh_batcher.d.ts +0 -6
- package/build/video/webgpu/batchers/lit_mesh_batcher.d.ts.map +1 -1
- package/build/video/webgpu/batchers/lit_quad_batcher.d.ts +0 -8
- package/build/video/webgpu/batchers/lit_quad_batcher.d.ts.map +1 -1
- package/build/video/webgpu/batchers/mesh_batcher.d.ts +7 -231
- package/build/video/webgpu/batchers/mesh_batcher.d.ts.map +1 -1
- package/build/video/webgpu/batchers/primitive_batcher.d.ts.map +1 -1
- package/build/video/webgpu/batchers/quad_batcher.d.ts +0 -82
- package/build/video/webgpu/batchers/quad_batcher.d.ts.map +1 -1
- package/build/video/webgpu/buffer/arena.d.ts +1 -63
- package/build/video/webgpu/buffer/arena.d.ts.map +1 -1
- package/build/video/webgpu/buffer/instance_buffer.d.ts +1 -64
- package/build/video/webgpu/buffer/instance_buffer.d.ts.map +1 -1
- package/build/video/webgpu/buffer/retained_geometry.d.ts +1 -54
- package/build/video/webgpu/buffer/retained_geometry.d.ts.map +1 -1
- package/build/video/webgpu/buffer/uniformring.d.ts +1 -67
- package/build/video/webgpu/buffer/uniformring.d.ts.map +1 -1
- package/build/video/webgpu/effect_binding.d.ts +1 -16
- package/build/video/webgpu/effect_binding.d.ts.map +1 -1
- package/build/video/webgpu/pipeline/bindgroups.d.ts +1 -32
- package/build/video/webgpu/pipeline/bindgroups.d.ts.map +1 -1
- package/build/video/webgpu/pipeline/cache.d.ts +1 -163
- package/build/video/webgpu/pipeline/cache.d.ts.map +1 -1
- package/build/video/webgpu/renderers/tmxlayer/orthogonal.d.ts +1 -87
- package/build/video/webgpu/renderers/tmxlayer/orthogonal.d.ts.map +1 -1
- package/build/video/webgpu/shaders/mesh-instanced.d.ts +1 -43
- package/build/video/webgpu/shaders/mesh-instanced.d.ts.map +1 -1
- package/build/video/webgpu/texture/compressed.d.ts +1 -32
- package/build/video/webgpu/texture/compressed.d.ts.map +1 -1
- package/build/video/webgpu/texture/frametexture.d.ts +1 -62
- package/build/video/webgpu/texture/frametexture.d.ts.map +1 -1
- package/build/video/webgpu/texture/store.d.ts +1 -147
- package/build/video/webgpu/texture/store.d.ts.map +1 -1
- package/build/video/webgpu/webgpu_renderer.d.ts +1 -88
- package/build/video/webgpu/webgpu_renderer.d.ts.map +1 -1
- package/package.json +5 -4
- package/skills/melonjs/SKILL.md +1 -1
- package/skills/melonjs-3d/SKILL.md +453 -5
- package/skills/melonjs-3d-assets/SKILL.md +164 -6
- package/skills/melonjs-audio/SKILL.md +38 -0
- package/skills/melonjs-camera-and-drawing/SKILL.md +49 -0
- package/skills/melonjs-effects-and-shaders/SKILL.md +95 -2
- package/skills/melonjs-loading-assets/SKILL.md +127 -2
- package/skills/melonjs-performance/SKILL.md +60 -1
- package/skills/melonjs-physics/SKILL.md +78 -0
- package/skills/melonjs-renderables/SKILL.md +63 -1
- package/skills/melonjs-renderer-backends/SKILL.md +19 -0
- package/skills/melonjs-scenes-and-state/SKILL.md +56 -0
- package/skills/melonjs-tilemaps/SKILL.md +31 -11
- package/skills/melonjs-ui-and-text/SKILL.md +131 -117
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: melonjs-3d-assets
|
|
3
|
-
description: "Use this skill when loading 3D models into melonJS — glTF and GLB scenes, OBJ/MTL models, materials, imported lights, node animation, ground shadows and GPU instancing. Covers level.load options, the rightHanded conversion, and exactly what the loader does and does not support. Triggers on: glTF, gltf, glb, OBJ, MTL, 3D model, getGLTF, getOBJ, getMTL, GLTFModel, GLTFScene, level.load glb, rightHanded, lightIntensityScale, castGroundShadow, shadowGroundY, EXT_mesh_gpu_instancing, KHR_lights_punctual, skinning, Blender export, 3D asset."
|
|
3
|
+
description: "Use this skill when loading 3D models into melonJS — glTF and GLB scenes, OBJ/MTL models, materials, imported lights, node animation, ground shadows and GPU instancing. Covers level.load options including the async flag, the rightHanded conversion, and exactly what the loader does and does not support. Triggers on: glTF, gltf, glb, OBJ, MTL, 3D model, getGLTF, getOBJ, getMTL, GLTFModel, GLTFScene, level.load glb, rightHanded, lightIntensityScale, castGroundShadow, shadowGroundY, EXT_mesh_gpu_instancing, KHR_lights_punctual, skinning, Blender export, 3D asset."
|
|
4
4
|
license: MIT
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -34,6 +34,7 @@ or it renders flat. See `melonjs-3d` for the camera.
|
|
|
34
34
|
| `scale` | `1` | pixels per glTF unit, applied to the whole scene. Blender's metre-scale export usually needs 20–100. |
|
|
35
35
|
| `container` | `game.world` | where the nodes are added |
|
|
36
36
|
| `onLoaded` | `app.onLevelLoaded` | called with the **level id**, not the scene |
|
|
37
|
+
| `async` | `false` | return a promise that settles once the scene is in the world, instead of a boolean |
|
|
37
38
|
| `rightHanded` | `true` | see below |
|
|
38
39
|
| `lights` | `true` | instantiate authored `KHR_lights_punctual` lights as `Light3d` world children |
|
|
39
40
|
| `lightIntensityScale` | — | keep authored intensity ratios instead of normalising every light to 1 |
|
|
@@ -41,10 +42,19 @@ or it renders flat. See `melonjs-3d` for the camera.
|
|
|
41
42
|
| `shadowGroundY` | each object's own base | world Y of the floor the blobs land on |
|
|
42
43
|
|
|
43
44
|
`onLoaded` receives the level id — it is a "done" signal, not a handle on the
|
|
44
|
-
scene. You need it
|
|
45
|
-
defers the actual load to
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
scene. You need it, or `async`: with the game loop running, `level.load` stops
|
|
46
|
+
the loop and defers the actual load to a timer, so by default it returns
|
|
47
|
+
*before* anything is in the world.
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
await level.load("diorama", { scale: 50, async: true });
|
|
51
|
+
// the scene is in the world here
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Note `await level.load("diorama")` without the flag does not await the load — the
|
|
55
|
+
call returns a boolean, and `await true` resolves immediately. To get at what was
|
|
56
|
+
loaded, load into a container you own, or look the nodes up by their authored
|
|
57
|
+
names:
|
|
48
58
|
|
|
49
59
|
```js
|
|
50
60
|
level.load("diorama", { scale: 50, onLoaded: () => {
|
|
@@ -134,6 +144,27 @@ model.pause();
|
|
|
134
144
|
an explicit `loop: false` stops looping. `setCurrentAnimation` **throws** on a
|
|
135
145
|
clip name the asset does not define — check `getAnimationNames()` first.
|
|
136
146
|
|
|
147
|
+
### Placing and moving a model
|
|
148
|
+
|
|
149
|
+
A `GLTFModel` is placed like any other renderable — `pos`, `depth`, `rotate`
|
|
150
|
+
and `scale` move the **whole rig**, and compose with whatever the active clip
|
|
151
|
+
is doing, so a walk cycle plays wherever the character stands:
|
|
152
|
+
|
|
153
|
+
```js
|
|
154
|
+
const boat = new me.GLTFModel(me.loader.getGLTF("boat"), { scale: 40, lit: false });
|
|
155
|
+
boat.setCurrentAnimation("paddle", { loop: true });
|
|
156
|
+
app.world.addChild(boat);
|
|
157
|
+
|
|
158
|
+
boat.pos.set(steerX, waterLevel);
|
|
159
|
+
boat.depth = travelled;
|
|
160
|
+
boat.rotate(lean - lastLean, AXIS_Z); // `rotate` is RELATIVE — feed it the delta
|
|
161
|
+
boat.animationspeed = 0.85 + 0.9 * pace; // one authored tempo, many run speeds
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Constructing one directly from `loader.getGLTF(name)` is fine and is the way to
|
|
165
|
+
go when the model is a game object rather than a scene — `level.load` is for
|
|
166
|
+
loading a whole scene into the world.
|
|
167
|
+
|
|
137
168
|
**Vertex skinning is out of scope** — `JOINTS_0` / `WEIGHTS_0` are not read, and
|
|
138
169
|
neither are morph targets. A smoothly-deforming character will not deform. The
|
|
139
170
|
options are: rig it hierarchically instead (separate meshes parented into a
|
|
@@ -166,6 +197,12 @@ Omit `shadowGroundY` and each blob sits at its own object's base at full
|
|
|
166
197
|
strength, which is right for props already resting on the ground. Set it when
|
|
167
198
|
things jump or fly, so the shadow stays on the floor and shrinks with height.
|
|
168
199
|
|
|
200
|
+
A blob is centred on its caster's x/z and is never offset by light direction, so
|
|
201
|
+
a wide flat-bottomed prop hides its own shadow under itself. Raising
|
|
202
|
+
`shadowGroundY` to force one into view floats the blob up over the object as a
|
|
203
|
+
dark ring rather than sliding it clear — the setting is for things that leave
|
|
204
|
+
the ground, not a visibility knob.
|
|
205
|
+
|
|
169
206
|
## OBJ/MTL
|
|
170
207
|
|
|
171
208
|
A different shape entirely: OBJ produces raw geometry you hand to a `Mesh`,
|
|
@@ -203,6 +240,117 @@ MTL contributes `Kd` (diffuse tint), `d` / `Tr` (opacity), `Ke` (emissive),
|
|
|
203
240
|
want it directly. OBJ has no scene graph, no lights, no animation — use glTF for
|
|
204
241
|
anything beyond a single static model.
|
|
205
242
|
|
|
243
|
+
## Authoring assets for the engine
|
|
244
|
+
|
|
245
|
+
Notes from modelling props and a rigged character against this loader. They are
|
|
246
|
+
Blender-specific in the API details, general in the traps.
|
|
247
|
+
|
|
248
|
+
### One clip means one action
|
|
249
|
+
|
|
250
|
+
glTF names an animation after the **action** it came from, so three objects
|
|
251
|
+
each carrying their own action export as three separate clips — and a game can
|
|
252
|
+
only play one clip at a time, so the other two never move. Put every animated
|
|
253
|
+
object in **one action**, using slots (Blender 4.4+):
|
|
254
|
+
|
|
255
|
+
```python
|
|
256
|
+
shared = bpy.data.actions.new("paddle")
|
|
257
|
+
for ob in (pivot, shoulder_l, shoulder_r, body):
|
|
258
|
+
ad = ob.animation_data_create()
|
|
259
|
+
ad.action = shared
|
|
260
|
+
ad.action_slot = shared.slots.new('OBJECT', ob.name)
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Exporting with the scene/whole-timeline mode does **not** merge per-object
|
|
264
|
+
actions into one clip — it still emits one per action. Slots are the fix.
|
|
265
|
+
|
|
266
|
+
In Blender 5.x, `action.fcurves` no longer exists; curves live under
|
|
267
|
+
`action.layers[].strips[].channelbags[].fcurves`, and a channelbag identifies
|
|
268
|
+
its slot as `cb.slot.identifier` (there is no `slot_identifier`).
|
|
269
|
+
|
|
270
|
+
### Never re-parent or join a rig that is mid-pose
|
|
271
|
+
|
|
272
|
+
Both parenting and joining bake the objects' **current world transforms**.
|
|
273
|
+
Parenting a child while the parent sits in an animated pose writes the inverse
|
|
274
|
+
of that pose into `matrix_parent_inverse`, which silently cancels the animation
|
|
275
|
+
— the part renders rigid while the curves still exist. Detach the action, zero
|
|
276
|
+
the rig, do the surgery, then reattach:
|
|
277
|
+
|
|
278
|
+
```python
|
|
279
|
+
saved = [(o, o.animation_data.action_slot) for o in animated]
|
|
280
|
+
for ob, _ in saved:
|
|
281
|
+
ob.animation_data.action = None
|
|
282
|
+
ob.rotation_euler = (0, 0, 0)
|
|
283
|
+
# ...re-parent / join here...
|
|
284
|
+
for ob, slot in saved:
|
|
285
|
+
ob.animation_data.action = act
|
|
286
|
+
ob.animation_data.action_slot = slot
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
A joined mesh also inherits the **active** object's scale, so joining into a
|
|
290
|
+
box that was scaled to `(0.8, 2.0, 0.1)` leaves a node with that non-uniform
|
|
291
|
+
scale and geometry divided back through it. It renders in the right place but
|
|
292
|
+
skews flat-shaded normals — apply transforms (`rotation=True, scale=True`)
|
|
293
|
+
after joining. Watch for a related trap: setting `ob.scale.x` on a mesh whose
|
|
294
|
+
size was already applied *multiplies* rather than replaces it.
|
|
295
|
+
|
|
296
|
+
### A model only needs to stay split where something animates it
|
|
297
|
+
|
|
298
|
+
Every glTF primitive is a draw call. Merge everything static into one mesh and
|
|
299
|
+
keep separate nodes only for the parts a clip actually drives — a boat with a
|
|
300
|
+
rabbit and a paddle went from 28 primitives to 5 that way, with no visible
|
|
301
|
+
change.
|
|
302
|
+
|
|
303
|
+
### One palette strip beats one material per colour
|
|
304
|
+
|
|
305
|
+
An `InstancedMesh` is **one geometry and one material**, so a prop that wants
|
|
306
|
+
five colours cannot use five materials. Give the whole model a single material
|
|
307
|
+
whose image is an *N*×1 strip, one pixel per shade, and point each face's UVs
|
|
308
|
+
at a cell centre (`u = (cell + 0.5) / N`, `v = 0.5`) with the sampler set to
|
|
309
|
+
nearest. A whole scene's palette then costs one tiny texture, a merged mesh can
|
|
310
|
+
be twenty colours, and there is nothing to bleed between cells.
|
|
311
|
+
|
|
312
|
+
Colour-space trap when generating that strip programmatically: Blender's
|
|
313
|
+
`image.pixels` are scene-linear floats, but this export path writes them out
|
|
314
|
+
**verbatim**, so pre-converting sRGB→linear darkens every colour. White is the
|
|
315
|
+
tell — it is the one value identical in both spaces, so if white survives and
|
|
316
|
+
everything else came out dark, that is the bug. Verify by decoding the PNG back
|
|
317
|
+
out of the GLB and comparing bytes to the source palette.
|
|
318
|
+
|
|
319
|
+
### Feeding an authored mesh into an `InstancedMesh`
|
|
320
|
+
|
|
321
|
+
`EXT_mesh_gpu_instancing` covers instances authored *in the file*. When the
|
|
322
|
+
game places them itself, take the geometry off the parsed descriptor instead:
|
|
323
|
+
|
|
324
|
+
```js
|
|
325
|
+
const node = me.loader.getGLTF("palm").nodes[0];
|
|
326
|
+
const trees = new me.InstancedMesh(0, groundY, {
|
|
327
|
+
vertices: node.vertices, uvs: node.uvs,
|
|
328
|
+
normals: node.normals, indices: node.indices,
|
|
329
|
+
texture: palette, textureFilter: "nearest", scale: 40,
|
|
330
|
+
instanceCount: count,
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
`nodes` is one entry **per primitive**, each in its own local space with a
|
|
335
|
+
separate `world` matrix — so this only works cleanly when the asset is a single
|
|
336
|
+
merged primitive exported with an identity node transform. Model it at the
|
|
337
|
+
origin, base on the floor, and apply transforms before exporting.
|
|
338
|
+
|
|
339
|
+
One geometry stamped out hundreds of times reads as one object *copied*
|
|
340
|
+
hundreds of times, so vary each instance in its transform. Rotate **after**
|
|
341
|
+
translating, or the instance swings around the group origin instead of turning
|
|
342
|
+
where it stands:
|
|
343
|
+
|
|
344
|
+
```js
|
|
345
|
+
placement.identity().translate(x / s, -y / s, z / s)
|
|
346
|
+
.rotate(math.randomFloat(0, Math.PI * 2), AXIS_Y);
|
|
347
|
+
const j = math.randomFloat(0.82, 1.18);
|
|
348
|
+
placement.scale(j, j, j);
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
Sizing every prop against **one** scale constant, rather than giving each its
|
|
352
|
+
own, keeps "this looks wrong" a modelling question instead of a scaling one.
|
|
353
|
+
|
|
206
354
|
## Packaging
|
|
207
355
|
|
|
208
356
|
A self-contained GLB is one file with nothing to resolve — the safest thing to
|
|
@@ -227,13 +375,23 @@ need a prefix.
|
|
|
227
375
|
| a character does not deform | vertex skinning is out of scope; rig hierarchically or billboard |
|
|
228
376
|
| animation names come back empty | the asset has no node-TRS channels (skin-only rig) |
|
|
229
377
|
| a hundred copies tank the frame rate | exported without `EXT_mesh_gpu_instancing` |
|
|
378
|
+
| a whole scatter looks like one object repeated | every instance shares the group transform — vary yaw/scale per instance, rotating *after* the translate |
|
|
379
|
+
| three clips where you authored one | one action per object; use a single action with a slot each |
|
|
380
|
+
| one part of a rig renders rigid while its curves exist | it was re-parented mid-pose, baking the inverse into `matrix_parent_inverse` |
|
|
381
|
+
| a merged mesh lights wrong along one axis | it inherited the active object's non-uniform scale on join — apply transforms |
|
|
382
|
+
| an authored palette comes out uniformly dark, but white is correct | linear values written to a strip that is saved verbatim |
|
|
383
|
+
| `getGLTF(name).nodes[0]` geometry lands in the wrong place | `nodes` is per primitive, each with its own `world`; merge to one primitive and export at the origin |
|
|
384
|
+
| a prop casts no visible shadow | wide and flat-bottomed — the blob is under it; `shadowGroundY` haloes it rather than revealing it |
|
|
385
|
+
| shadows only show on casters near the camera | `shadowGroundY` is on the wrong side — Y-down means the floor is a **greater** y, so a `pos.y - lift` puts the blob inside the caster and the depth test leaves only a hairline ring |
|
|
230
386
|
| a shadow smeared across the whole floor | a ground plane cast its own blob — use the scene-wide opt-in |
|
|
231
387
|
| `onLoaded` gets a string, not the scene | it is called with the level id; load into your own container instead |
|
|
232
388
|
| scene renders flat and unlit | no `Camera3d` — the 2D-camera path is CPU-projected and unlit (with a `Camera3d` on Canvas you get a black canvas instead) |
|
|
233
389
|
|
|
234
390
|
## Related skills
|
|
235
391
|
|
|
236
|
-
- `melonjs-3d` — conventions, `Camera3d`, meshes, `Light3d`, instancing
|
|
392
|
+
- `melonjs-3d` — conventions, `Camera3d`, meshes, `Light3d`, instancing, and
|
|
393
|
+
`camera.setFog` (an outdoor scene almost always wants it; it is set on the
|
|
394
|
+
camera, so a loaded scene needs no per-node work)
|
|
237
395
|
- `melonjs-lighting` — how `Light3d` behaves once imported
|
|
238
396
|
- `melonjs-loading-assets` — the loader, asset types and base URLs
|
|
239
397
|
- `melonjs-plugins` — the Spine plugin, for skeletal characters
|
|
@@ -141,6 +141,23 @@ audio.noise({ duration: 0.5, filter: { type: "lowpass", frequency: 800 } });
|
|
|
141
141
|
`"white"`), `attack`, `pan`, `filter` and `filterSweep`. `gain` defaults to `0.1`
|
|
142
142
|
on both.
|
|
143
143
|
|
|
144
|
+
### Sequencing: `delay`, not `setTimeout`
|
|
145
|
+
|
|
146
|
+
Both take `delay` — seconds before the sound starts, scheduled on the **audio
|
|
147
|
+
clock**. That is what builds a multi-part sound: a stinger's second note, an
|
|
148
|
+
explosion's double-tap.
|
|
149
|
+
|
|
150
|
+
```js
|
|
151
|
+
audio.tone({ freq: 392, duration: 0.12 });
|
|
152
|
+
audio.tone({ freq: 587, duration: 0.18, delay: 0.11 });
|
|
153
|
+
audio.tone({ freq: [784, 1176], duration: 0.75, delay: 0.23 });
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Do not reach for `setTimeout` here. A timer fires on the main thread, so a busy
|
|
157
|
+
frame slips the note late and the sequence audibly loses time — the fault is
|
|
158
|
+
easy to blame on the sound design rather than the scheduling. `delay` is
|
|
159
|
+
sample-accurate because the whole envelope is scheduled up front.
|
|
160
|
+
|
|
144
161
|
Both are **silent no-ops** when there is no WebAudio context — they bail on
|
|
145
162
|
`getAudioContext() === null` rather than throwing. Neither needs the clip to be
|
|
146
163
|
loaded; neither goes through the file-playback path at all.
|
|
@@ -195,6 +212,25 @@ same switch under its backend name.) `on` accepts the full lifecycle set:
|
|
|
195
212
|
Re-preloading a manifest that already contains a loaded clip is a no-op —
|
|
196
213
|
`audio.unload(name)` first if you genuinely want to reload it.
|
|
197
214
|
|
|
215
|
+
**Credentials use the same global switch as every other asset type** —
|
|
216
|
+
`loader.setOptions({ withCredentials: true })`, not an audio-specific option.
|
|
217
|
+
Buffered audio fetches through the shared loader path, so it honours it exactly
|
|
218
|
+
as an image or a JSON file does. A `stream: true` clip does not: it plays
|
|
219
|
+
through an `<audio>` element, which needs a `crossorigin` attribute rather than
|
|
220
|
+
fetch credentials. Preload a clip buffered if it sits behind a login.
|
|
221
|
+
|
|
222
|
+
**Failing clips and `setStopOnAudioError(false)`.** The default is to fail the
|
|
223
|
+
preload when a clip cannot be loaded after its retries: the error reaches the
|
|
224
|
+
loader, so `await loader.preload(...)` rejects and your `catch` runs, and the
|
|
225
|
+
reason is logged. Turn the flag off and the engine mutes audio, warns
|
|
226
|
+
(`failed loading <name>, disabling audio`) and lets the load *continue* — the
|
|
227
|
+
preload finishes and the game reaches the next scene without sound.
|
|
228
|
+
|
|
229
|
+
Before 20.4 both halves were broken: with the flag off it disabled audio and
|
|
230
|
+
failed the preload anyway, and a clip whose bytes arrived but would not decode
|
|
231
|
+
(a missing file served as HTML by an SPA rewrite, say) reported nothing at all
|
|
232
|
+
either way — blank screen, empty console.
|
|
233
|
+
|
|
198
234
|
## Symptom → cause
|
|
199
235
|
|
|
200
236
|
| symptom | cause |
|
|
@@ -207,6 +243,8 @@ Re-preloading a manifest that already contains a loaded clip is a no-op —
|
|
|
207
243
|
| music keeps playing after leaving a scene | used `play` instead of `playTrack`, or no `stopTrack` in teardown |
|
|
208
244
|
| `stereo` / `position` do nothing | the clip was loaded with `stream: true` — spatial is WebAudio-only |
|
|
209
245
|
| one format works, another does not | that codec is not in the `audio.init()` list |
|
|
246
|
+
| audio behind a login fails, or the preload hangs | `loader.setOptions({ withCredentials: true })` — the same switch every asset type uses |
|
|
247
|
+
| a streamed clip ignores `withCredentials` | `stream: true` plays through an `<audio>` element; preload it buffered instead |
|
|
210
248
|
| `audio.tone(440, {...})` does nothing / errors | `tone` takes a single options object with a required `duration` |
|
|
211
249
|
| `tone` / `noise` are silent with no error | no WebAudio context — `getAudioContext()` returned `null` |
|
|
212
250
|
|
|
@@ -78,6 +78,30 @@ whichever of world/screen matches the region — screen for a `floating` region,
|
|
|
78
78
|
world otherwise. Use the screen pair for anything that *moves* the camera, or
|
|
79
79
|
the drag feeds back on itself.
|
|
80
80
|
|
|
81
|
+
### In 3D: `Camera3d#worldToScreen`
|
|
82
|
+
|
|
83
|
+
`worldToLocal` is a 2D camera's offset subtraction — it knows nothing about a
|
|
84
|
+
perspective projection. To pin a label, damage number or marker to a point in a
|
|
85
|
+
3D scene, project it:
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
const p = camera.worldToScreen(x, y, z); // view + projection, divide included
|
|
89
|
+
if (p !== null) { // null = at or BEHIND the camera
|
|
90
|
+
label.pos.set(p.x, p.y);
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
It returns canvas pixels with the origin top-left and **y down**, which is the
|
|
95
|
+
engine's own 2D draw space — so the result feeds a `floating` renderable or the
|
|
96
|
+
immediate-mode API directly, with no flip.
|
|
97
|
+
|
|
98
|
+
**Always check for `null`.** A point at or behind the camera (clip `w <= 0`)
|
|
99
|
+
has no honest screen position, and projecting it anyway yields a mirrored
|
|
100
|
+
coordinate that puts your label on the wrong side of the screen. Skip it.
|
|
101
|
+
|
|
102
|
+
Do not hand-roll this with `Matrix3d` — the perspective divide and the behind-
|
|
103
|
+
camera case are exactly what gets it wrong.
|
|
104
|
+
|
|
81
105
|
## Secondary cameras
|
|
82
106
|
|
|
83
107
|
Cameras are first-class — a minimap is a second camera with `autoResize = false`
|
|
@@ -87,6 +111,10 @@ and an overridden `postDraw`:
|
|
|
87
111
|
this.cameras.set("minimap", new MinimapCamera());
|
|
88
112
|
```
|
|
89
113
|
|
|
114
|
+
View state is per camera, not per scene: a `Camera3d` carries its own distance
|
|
115
|
+
fog (`setFog`), so a minimap or split-screen view fogs independently of the main
|
|
116
|
+
one — and a `Camera2d` never fogs. See `melonjs-3d`.
|
|
117
|
+
|
|
90
118
|
## Immediate-mode drawing
|
|
91
119
|
|
|
92
120
|
Inside a custom `draw(renderer)` you can draw shapes directly. Remember the two
|
|
@@ -114,6 +142,27 @@ of them and throw `Invalid geometry for fill/stroke` for anything else.
|
|
|
114
142
|
noise — including seamless tiling and `asNormalMap` — so you rarely need to ship
|
|
115
143
|
noise PNGs.
|
|
116
144
|
|
|
145
|
+
Two things to get right when one is animated:
|
|
146
|
+
|
|
147
|
+
- **Drive it yourself.** `update(dt)` advances the time axis and re-bakes; the
|
|
148
|
+
engine never calls it. An `animated: true` texture nobody updates is a still
|
|
149
|
+
image, with no error to say so.
|
|
150
|
+
- **Hand consumers the texture, not its canvas.** Re-baking bumps the
|
|
151
|
+
`Texture2d`'s `version`, and that bump is what tells the renderer to
|
|
152
|
+
re-upload. `getTexture()` returns the baked canvas, which carries no version
|
|
153
|
+
— so a mesh given the canvas shows frame one forever.
|
|
154
|
+
|
|
155
|
+
Set `seamless: true` for anything tiled by UVs past 1, or every repeat carries a
|
|
156
|
+
visible seam.
|
|
157
|
+
|
|
158
|
+
**And it still will not animate on a `Mesh`.** Driving `update(dt)` genuinely
|
|
159
|
+
re-bakes the field — the pixels change, the version increments — but the mesh
|
|
160
|
+
path does not pick the new copy up, so a 3D surface textured with an animated
|
|
161
|
+
noise renders frozen while every counter reports success. Verify with a
|
|
162
|
+
checksum of `getTexture()` before concluding the animation is broken; it is the
|
|
163
|
+
upload that is missing, not the bake. For a moving 3D surface, scroll the UVs
|
|
164
|
+
or move the geometry instead.
|
|
165
|
+
|
|
117
166
|
## Clipping and masking
|
|
118
167
|
|
|
119
168
|
```js
|
|
@@ -25,6 +25,34 @@ app.viewport.addPostEffect(new VignetteEffect(app.renderer));
|
|
|
25
25
|
`renderable.shader = …` is **deprecated since 19.2.0**, and its setter destroys
|
|
26
26
|
whatever it replaces. Use `addPostEffect` / `getPostEffect` / `removePostEffect`.
|
|
27
27
|
|
|
28
|
+
### A camera effect covers the HUD too
|
|
29
|
+
|
|
30
|
+
A camera's post-effect brackets the **entire** world draw — floating children
|
|
31
|
+
included. So the obvious way to write a full-screen pass also washes over every
|
|
32
|
+
HUD label in that world, which is rarely what you want.
|
|
33
|
+
|
|
34
|
+
To land a pass *after* the world but *before* the HUD, host the effect on a
|
|
35
|
+
screen-filling floating renderable ordered below the HUD's z instead:
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
const quad = new Sprite(0, 0, { image: anyImage });
|
|
39
|
+
quad.anchorPoint.set(0, 0);
|
|
40
|
+
quad.scale(viewW / anyImage.width, viewH / anyImage.height);
|
|
41
|
+
quad.floating = true; // its own uv is now screen space
|
|
42
|
+
quad.blendMode = "additive";
|
|
43
|
+
quad.addPostEffect(myEffect);
|
|
44
|
+
world.addChild(quad, HUD_Z - 10); // BELOW the labels, not above
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Two things follow from the quad filling the frame: its own `uv` is screen space
|
|
48
|
+
(so a pass like this needs none of the `screen_uv` / `screen_texture` builtins),
|
|
49
|
+
and the incoming `color` is the quad's own texture, which a body that paints
|
|
50
|
+
from scratch can ignore entirely.
|
|
51
|
+
|
|
52
|
+
Depth here is easy to get backwards — a higher z draws **later**, i.e. on top.
|
|
53
|
+
Verify it by returning a flat colour from the body for one frame: whatever it
|
|
54
|
+
tints is what the pass covers.
|
|
55
|
+
|
|
28
56
|
## Toggle with `enabled`, do not remove
|
|
29
57
|
|
|
30
58
|
**`removePostEffect()` destroys the effect** — it calls `effect.destroy()` and
|
|
@@ -80,7 +108,34 @@ one `@group(3) @binding(0) var<uniform>` struct — so a single `setUniform` cal
|
|
|
80
108
|
feeds whichever backend is live. `setTime` is a convenience for a `uTime`
|
|
81
109
|
uniform and silently does nothing if the shader does not declare one.
|
|
82
110
|
|
|
83
|
-
|
|
111
|
+
### One effect is one program — prefer preloading, and share
|
|
112
|
+
|
|
113
|
+
A `ShaderEffect` compiles and links in its **constructor**, and the link is
|
|
114
|
+
checked with `getProgramParameter(LINK_STATUS)` straight after `linkProgram` —
|
|
115
|
+
a blocking call. So the cost is paid on whatever frame the effect is
|
|
116
|
+
constructed, and *n* identical effects cost it *n* times. `clone()` does not
|
|
117
|
+
avoid it: it constructs a new effect and links a new program.
|
|
118
|
+
|
|
119
|
+
Preload it instead. Loader type `"shader"` takes a `src` **or inline source via
|
|
120
|
+
`data`**, compiles at load time (inside the loading screen), and hands back a
|
|
121
|
+
**shared** instance:
|
|
122
|
+
|
|
123
|
+
```js
|
|
124
|
+
loader.preload([{ name: "ramp", type: "shader", data: myFragmentBody }]);
|
|
125
|
+
// …then, for every label that wants it:
|
|
126
|
+
label.addPostEffect(loader.getShader("ramp"));
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Sharing one instance across renderables is safe *because* the loader sets
|
|
130
|
+
`effect.shared`. Without that flag a renderable's teardown destroys its post
|
|
131
|
+
effects, which would free the program out from under everything else still
|
|
132
|
+
using it. Uniforms live on the effect, so a shared instance means one set of
|
|
133
|
+
uniform values — fine when the look is uniform, and the reason to clone (and
|
|
134
|
+
pay a link) when it is not.
|
|
135
|
+
|
|
136
|
+
Note this covers **your** effects only. The engine's own mesh/quad shader
|
|
137
|
+
variants are compiled lazily per feature combination on first draw and cannot be
|
|
138
|
+
preloaded — see `melonjs-loading-assets` for the warm-up that covers those.
|
|
84
139
|
|
|
85
140
|
### Screen-reading builtins
|
|
86
141
|
|
|
@@ -109,6 +164,43 @@ Two places where a straight port really does differ:
|
|
|
109
164
|
uniform (initialise it to `1.0`) and multiply vertical offsets by it; the
|
|
110
165
|
renderer feeds `-1` on that path and `+1` everywhere else.
|
|
111
166
|
|
|
167
|
+
## A ShaderEffect cannot shade a mesh on WebGPU
|
|
168
|
+
|
|
169
|
+
The single-effect fast path swaps the renderable's program outright instead of
|
|
170
|
+
rendering through an offscreen target. On WebGL that works for a `Mesh` too, so
|
|
171
|
+
a custom mesh shader is a `ShaderEffect` away. **On WebGPU it does not** — the
|
|
172
|
+
renderer says so in its own source, warns once, and then keeps the built-in
|
|
173
|
+
mesh shading.
|
|
174
|
+
|
|
175
|
+
Nothing throws. The mesh simply draws with its plain texture, which looks like
|
|
176
|
+
a broken shader, a bad binding, or a texture that failed to load — and since
|
|
177
|
+
`video.AUTO` prefers WebGPU where it is available, this is the default outcome
|
|
178
|
+
on most desktops. It cost several hours here: the symptom was a water surface
|
|
179
|
+
rendering flat white, and alpha, bindings, transparency and lighting were all
|
|
180
|
+
eliminated before the backend was.
|
|
181
|
+
|
|
182
|
+
2D renderables are unaffected: `Sprite`, `Text` and the rest go through the
|
|
183
|
+
quad path, which hosts effects on both backends. So a gradient fill for text,
|
|
184
|
+
or a refraction over a sprite, is fine — it is specifically the mesh path.
|
|
185
|
+
|
|
186
|
+
If you need a genuinely custom mesh shader that runs everywhere, supply a full
|
|
187
|
+
dual-language `GLShader` rather than a fragment body, and declare the fog
|
|
188
|
+
uniforms yourself (see `melonjs-3d`).
|
|
189
|
+
|
|
190
|
+
## Extra textures bind in setTexture order
|
|
191
|
+
|
|
192
|
+
`setTexture("uFoo", …)` assigns bindings **1 and 2** to the first extra
|
|
193
|
+
texture, **3 and 4** to the second, and so on. The WGSL must match:
|
|
194
|
+
|
|
195
|
+
```wgsl
|
|
196
|
+
@group(3) @binding(1) var uFoo : texture_2d<f32>;
|
|
197
|
+
@group(3) @binding(2) var uFooSampler : sampler;
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Copying a two-texture effect and deleting one leaves the survivor declared at
|
|
201
|
+
3/4 while it is bound at 1/2 — the program fails to build and the effect is
|
|
202
|
+
silently dropped.
|
|
203
|
+
|
|
112
204
|
## Blend modes
|
|
113
205
|
|
|
114
206
|
Fourteen modes; thirteen of them are honoured by all three renderers:
|
|
@@ -174,4 +266,5 @@ same question after construction.
|
|
|
174
266
|
## Related skills
|
|
175
267
|
|
|
176
268
|
- `melonjs-renderables` — where post effects attach, and the destroy trap
|
|
177
|
-
- `melonjs-3d` —
|
|
269
|
+
- `melonjs-3d` — the GPU-backend requirement, and why a custom mesh shader is
|
|
270
|
+
not affected by the camera's distance fog
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: melonjs-loading-assets
|
|
3
|
-
description: "Use this skill for loading and managing game assets in melonJS — the resource descriptor format, the full asset type list, preload versus load, retrieving loaded assets, base URLs and cross-origin settings, and the loading screen. Triggers on: loader, loader.preload, loader.load, resources, getImage, getJSON, getTMX, getGLTF, getVideo, getFont, setBaseURL, setOptions, crossOrigin, asset, preload, LOADER_COMPLETE, loading screen, unload."
|
|
3
|
+
description: "Use this skill for loading and managing game assets in melonJS — the resource descriptor format, the full asset type list, preload versus load, retrieving loaded assets, base URLs and cross-origin settings, and the loading screen. Triggers on: loader, loader.preload, loader.load, resources, getImage, getJSON, getTMX, getGLTF, getVideo, getFont, setBaseURL, setOptions, crossOrigin, withCredentials, credentials, cookies, authenticated assets, CORS, asset, preload, LOADER_COMPLETE, loading screen, unload."
|
|
4
4
|
license: MIT
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -46,11 +46,107 @@ The type strings are melonJS-specific — this is not a generic loader:
|
|
|
46
46
|
| `"binary"` | raw data, bitmap font `.fnt` descriptors |
|
|
47
47
|
| `"fontface"` | web fonts (`.ttf`, `.woff`) |
|
|
48
48
|
| `"aseprite"` | Aseprite JSON + image |
|
|
49
|
-
| `"shader"` | GLSL/WGSL shader sources |
|
|
49
|
+
| `"shader"` | GLSL/WGSL shader sources — `src` **or** inline via `data` |
|
|
50
50
|
| `"obj"` / `"mtl"` | Wavefront models and materials |
|
|
51
51
|
| `"gltf"` / `"glb"` | glTF scenes |
|
|
52
52
|
| `"js"` | scripts |
|
|
53
53
|
|
|
54
|
+
## What belongs in the manifest — and what cannot
|
|
55
|
+
|
|
56
|
+
Preloading is not only for things with a URL. Three tiers, and the middle one
|
|
57
|
+
is the one people miss.
|
|
58
|
+
|
|
59
|
+
**1. Assets with a source.** Everything in the type table above. Note `"shader"`
|
|
60
|
+
takes **inline source** as well as a `src`, via the `data` field:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
import { myRamp } from "./myRamp"; // a GLSL fragment body, in your own module
|
|
64
|
+
|
|
65
|
+
loader.preload([
|
|
66
|
+
{ name: "ramp", type: "shader", data: myRamp },
|
|
67
|
+
]);
|
|
68
|
+
const fx = loader.getShader("ramp"); // shared, already compiled
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
This matters more than it looks. A `ShaderEffect` compiles its program in its
|
|
72
|
+
**constructor**, and `compileProgram` calls `getProgramParameter(LINK_STATUS)`
|
|
73
|
+
immediately after `linkProgram` — a blocking call that forces the driver to
|
|
74
|
+
finish. So building one during a scene costs that link on the frame it appears,
|
|
75
|
+
and building three identical ones costs it three times. Preloaded as an asset it
|
|
76
|
+
is compiled at load time, behind the loading screen, and the loader hands out a
|
|
77
|
+
**shared** instance (`effect.shared === true`), which is what stops one
|
|
78
|
+
renderable's teardown freeing it out from under the others. `clone()` does NOT
|
|
79
|
+
help here — it constructs a new effect, and therefore links a new program.
|
|
80
|
+
|
|
81
|
+
**2. Derived assets — build once, after the preload.** Canvases you bake,
|
|
82
|
+
`NoiseTexture2d`, `TextureAtlas`: the loader cannot carry these, but they must
|
|
83
|
+
not be rebuilt per scene either. The renderer's texture cache is keyed by the
|
|
84
|
+
**image object**, so a freshly baked canvas is a brand new GPU texture with a
|
|
85
|
+
new mip chain — rebuild one per stage and a title → play → game-over cycle
|
|
86
|
+
uploads four copies of the same pixels. Build them once after `preload`
|
|
87
|
+
resolves and share them, the way the platformer example builds its
|
|
88
|
+
`TextureAtlas` into a module the scenes read from.
|
|
89
|
+
|
|
90
|
+
**3. The engine's own shader variants — not preloadable at all.** The mesh
|
|
91
|
+
batcher compiles a program per *feature combination* (lit, instanced, instance
|
|
92
|
+
colours, instance data, fog — fog joins the key), lazily, on the first draw that
|
|
93
|
+
needs it. There is no loader type for these and no API to warm the cache: the
|
|
94
|
+
only lever is to **draw** that combination once while the loading screen is
|
|
95
|
+
still up, then throw the scene away — the compiled programs stay in the
|
|
96
|
+
renderer. Worth doing for a heavy 3D scene, where first-draw linking is easily a
|
|
97
|
+
few hundred ms and lands as a freeze on the first frame of the first level.
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
await loader.preload(resources);
|
|
101
|
+
buildScene(app); // same geometry the level uses
|
|
102
|
+
await twoFrames(); // event.GAME_AFTER_DRAW
|
|
103
|
+
removeOnlyWhatYouAdded(app); // keep the programs, drop the scene
|
|
104
|
+
state.change(state.PLAY);
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**It borrows the LOADING stage's world, and that has three teeth**, all learned
|
|
108
|
+
the hard way:
|
|
109
|
+
|
|
110
|
+
- **Never tear down with `app.world.reset()`.** It clears *every* child of that
|
|
111
|
+
world, the loading screen's own included, and the screen goes blank for the
|
|
112
|
+
rest of the load. Snapshot `app.world.children` first and remove only what
|
|
113
|
+
you added.
|
|
114
|
+
- **Restore anything the warm-up changes that the loading screen shows** — the
|
|
115
|
+
renderer's `backgroundColor` above all, or the warm-up flashes its own empty
|
|
116
|
+
first frame.
|
|
117
|
+
- **Under a `Camera3d` it will hide the built-in loading screen, and there is no
|
|
118
|
+
clean way around it** — see below.
|
|
119
|
+
|
|
120
|
+
### `DefaultLoadingScreen` lives in the WORLD, not on the screen
|
|
121
|
+
|
|
122
|
+
The built-in loading screen is written for a `Camera2d`. Its progress bar and
|
|
123
|
+
logo are added with `app.world.addChild(bar, 1)` / `addChild(logo, 2)` and are
|
|
124
|
+
**`floating === false`** — ordinary world-space renderables. They read as an
|
|
125
|
+
overlay only because that stage's world is otherwise empty.
|
|
126
|
+
|
|
127
|
+
So with `cameraClass: Camera3d`, anything you add to that world is in the scene
|
|
128
|
+
*with* them, and a 3D scene simply swallows them: the depth buffer puts terrain
|
|
129
|
+
in front of a bar sitting at z = 1. What does NOT rescue it, all tried:
|
|
130
|
+
|
|
131
|
+
- **Raising their `z`** — for a mesh on the `Camera3d` path `pos.z` IS world
|
|
132
|
+
depth, so the scene's own z values are geometry, not layering, and the bar
|
|
133
|
+
still loses to the depth test.
|
|
134
|
+
- **`moveToTop()`** — it early-returns for a child already at index 0, which the
|
|
135
|
+
loading screen's children always are, having been added before anything else.
|
|
136
|
+
It silently does nothing.
|
|
137
|
+
- **Flipping them to `floating = true`** for the duration — the scene still
|
|
138
|
+
covers them.
|
|
139
|
+
|
|
140
|
+
If you want a warm-up (or any 3D behind a loading screen), write your own
|
|
141
|
+
loading stage and draw its progress UI as **floating** renderables over the
|
|
142
|
+
scene. That is also the nicer result: the player watches the level assemble
|
|
143
|
+
instead of a logo. Budget it as real work, not a one-liner — and weigh it
|
|
144
|
+
against what the warm-up actually saves.
|
|
145
|
+
|
|
146
|
+
One more limit: a warm-up only covers the combinations it actually draws.
|
|
147
|
+
Renderables the real level has and the warm-up does not will still link on
|
|
148
|
+
entry.
|
|
149
|
+
|
|
54
150
|
## Two conventions that produce 404s
|
|
55
151
|
|
|
56
152
|
**Audio `src` is a directory.** The loader appends the asset name plus each
|
|
@@ -138,6 +234,32 @@ If you preload without a loading stage and then change state immediately, pass
|
|
|
138
234
|
state.change(state.PLAY, true);
|
|
139
235
|
```
|
|
140
236
|
|
|
237
|
+
## Cross-origin and authenticated assets
|
|
238
|
+
|
|
239
|
+
Two settings, both global and both applying to **every** asset type — there is
|
|
240
|
+
no per-asset or per-type spelling to remember:
|
|
241
|
+
|
|
242
|
+
```js
|
|
243
|
+
loader.setOptions({
|
|
244
|
+
crossOrigin: "anonymous", // CORS mode for remote assets
|
|
245
|
+
withCredentials: true, // send cookies / auth with the request
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
`withCredentials` is what an asset behind a session cookie or an
|
|
250
|
+
`Authorization`-style login needs. Every fetched asset — image, json, binary,
|
|
251
|
+
tmx, tsx, shader, gltf/glb, obj, mtl, aseprite, video — carries it, and so does
|
|
252
|
+
buffered audio.
|
|
253
|
+
|
|
254
|
+
**Set them through `setOptions`.** `loader.crossOrigin` and
|
|
255
|
+
`loader.withCredentials` are read-only module bindings; assigning to them
|
|
256
|
+
throws, the same trap as the removed `loader.onload` / `onProgress`.
|
|
257
|
+
|
|
258
|
+
| | |
|
|
259
|
+
| --- | --- |
|
|
260
|
+
| one streamed clip (`stream: true` / `html5: true`) ignores `withCredentials` | it plays through an `<audio>` element, which needs a `crossorigin` attribute rather than fetch credentials. Preload it buffered if it is behind auth |
|
|
261
|
+
| credentials silently dropped for audio before 20.4 | the loader forwarded them under a pre-20.3 name the backend never read — a hung preload rather than an error |
|
|
262
|
+
|
|
141
263
|
## Symptom → cause
|
|
142
264
|
|
|
143
265
|
| symptom | cause |
|
|
@@ -146,6 +268,9 @@ state.change(state.PLAY, true);
|
|
|
146
268
|
| audio fails, `preload()` rejects with "Failed loading resource" | `audio.init()` not called before preloading — the real message is replaced by the loader's |
|
|
147
269
|
| blank level, missing tiles | `.tsx` or tileset image not listed in the resources |
|
|
148
270
|
| cross-origin textures fail | missing `loader.setOptions({ crossOrigin: "anonymous" })` |
|
|
271
|
+
| assets behind a login 401 / audio preload hangs | missing `loader.setOptions({ withCredentials: true })` — one switch, all asset types |
|
|
272
|
+
| `TypeError` assigning `loader.withCredentials` / `crossOrigin` | read-only module bindings; use `loader.setOptions({ … })` |
|
|
273
|
+
| preload never finishes, blank screen, no error | a failing sound with `audio.setStopOnAudioError(false)` before 20.4 — it disabled audio *and* failed the preload |
|
|
149
274
|
| text renders in a fallback font | web font not preloaded as `"fontface"` |
|
|
150
275
|
| `BitmapText` renders nothing | the `.fnt` (as `"binary"`) or its image is missing |
|
|
151
276
|
| `TypeError` assigning `loader.onProgress` / `onload` | removed in 20.3; they were never writable — use the `LOADER_*` events |
|