littlejsengine 1.24.0 → 1.24.2

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 (43) hide show
  1. package/CHANGELOG.md +86 -1
  2. package/EDITOR.md +2 -0
  3. package/FAQ.md +13 -2
  4. package/README.md +2 -2
  5. package/REFERENCE.md +27 -10
  6. package/dist/littlejs.d.ts +104 -29
  7. package/dist/littlejs.esm.js +2499 -1979
  8. package/dist/littlejs.esm.min.js +3 -3
  9. package/dist/littlejs.js +2496 -1979
  10. package/dist/littlejs.min.js +2 -2
  11. package/dist/littlejs.release.js +2438 -1983
  12. package/package.json +1 -1
  13. package/plugins/box2d.js +1 -1
  14. package/plugins/gltf.js +62 -9
  15. package/plugins/lightSystem.js +1 -1
  16. package/plugins/math3d.js +1014 -1013
  17. package/plugins/medalSystem.js +7 -11
  18. package/plugins/particleEffects.js +2 -2
  19. package/plugins/pathFinder.js +2 -2
  20. package/plugins/pluginExport.js +1 -0
  21. package/plugins/render3d.js +134 -57
  22. package/plugins/render3dEditor.js +28 -12
  23. package/plugins/render3dExtras.js +32 -17
  24. package/plugins/render3dLevel.js +21 -12
  25. package/plugins/render3dVoxels.js +15 -8
  26. package/plugins/textureSheet.js +97 -3
  27. package/plugins/tweakables.js +1 -1
  28. package/plugins/tweenSystem.js +2 -2
  29. package/plugins/uiSystem.js +6 -2
  30. package/src/engine.js +34 -11
  31. package/src/engineAudio.js +13 -3
  32. package/src/engineDebug.js +4 -1
  33. package/src/engineDraw.js +29 -16
  34. package/src/engineEditor.js +99 -56
  35. package/src/engineExport.js +2 -0
  36. package/src/engineInput.js +17 -3
  37. package/src/engineMath.js +6 -2
  38. package/src/engineObject.js +675 -675
  39. package/src/engineParticles.js +1 -1
  40. package/src/engineSettings.js +21 -1
  41. package/src/engineTileLayer.js +142 -43
  42. package/src/engineUtilities.js +20 -8
  43. package/src/engineWebGL.js +12 -8
package/CHANGELOG.md CHANGED
@@ -7,6 +7,86 @@ What changed in each release, newest first. Releases before 1.20.0 are on the
7
7
 
8
8
  Nothing yet.
9
9
 
10
+ ## 1.24.2 - 2026-10-03
11
+
12
+ ### New Changes
13
+
14
+ - Tile sets from separate images: `loadTiles(['grass.png', 'brick.png', 'props.png'], 16)` packs tile images, or several tile sheets, into the texture sheets as one tile set, numbered in the order given, for `tileLayersLoad`, tile layers and the level editor's palette; an image that is not whole tiles gives the whole tiles in it, and a map's tileset margin or spacing does not replace the set
15
+ - Spotlight gels: `light.gel` is a picture the shadow casting spotlight shines through, cast along its beam in its colors, like a slide or stained glass; with none a scene draws exactly as before. The 3D First Person flashlight has one on G
16
+ - Less garbage each frame: objects are sorted only when one is out of render order and the destroyed taken out only when there are some, an object with mass that collides with nothing copies no position, and outlines and regular polygons are made into kept vectors, about 98 fewer for each outlined circle; a 3D pick makes no vectors for an object it misses
17
+ - `Mesh.computeNormals(true)` is 5 to 7 times faster, the same normals to the last bit: a 960 point flag in 0.24 ms where it took 1.8, so a mesh can be bent every frame
18
+ - `loadSprite`, `loadTiles` and `loadAtlas` give back what the first load did when the same image is loaded again with the same settings, packed once
19
+ - A release build goes on past an error in a frame, logging the first, where one error froze the game for good; a debug build stops and shows it as before
20
+
21
+ ### Fixes
22
+
23
+ - A Tiled property named as a method of the object it is for, like `update`, is left out, where it replaced the method; a debug build says so
24
+ - `noise2D` stays noise however far out y is, where past about 24 million every row was one value; it gives the same values as before everywhere else
25
+ - Medals: the save keeps the unlock of a medal the game has not made this time, and a medal made after `medalsInit` reads its unlock, so a medal made late or behind a flag is never lost; `medalsReset` locks those too
26
+ - Older browsers: the engine starts with no `OffscreenCanvas` (Safari before 16.4), drawing into a canvas element in its place, and so do the textures it makes itself (normal maps from heights, particle shapes, light glows, lens flares, glTF's white texture), and uses neither `Array.prototype.at` nor `Object.hasOwn` (Safari before 15.4); the example browser's markdown has no lookbehind, which Safari before 16.4 could not read
27
+ - On an iPhone the silent switch mutes the game, as it does a ringtone, and the player's music plays on beside it; `setSoundIgnoreSilentSwitch(true)` has the game play through the switch as media does (Safari 16.4 and up)
28
+ - Level editor: the brush, its ghost and the palette read a tile past the end of a sheet as nothing, as the layer draws it, where a collision value picked up with the right button asserted every frame; the palette of a tile set filled in after it was first shown shows its tiles
29
+ - A light's flare looks past four lamps around it to what is behind them, where the fourth counted as hidden
30
+ - A click or tap in the bars around a letterboxed canvas presses nothing, where it pressed whatever was at the canvas edge
31
+ - `showConfirmDialog` while one is open gives the one open, where a second broke UI navigation in release builds
32
+ - The level editor's cut, copy and stamps keep an object's name, size, turn and visibility, where a paste made a bare point; objects moved with a selection or stamped land on their place to the digit, not a hair off
33
+ - The 3D editor's terrain paint rounds no heights, and a sculpt stroke rounds only those it changed
34
+ - A `UISlider` let go in the frame it moves takes that last place
35
+ - A gamepad of fewer buttons put in the slot of another holds none of the other's buttons; a gamepad axis that reads NaN is centered, where it failed an assert in debug builds
36
+ - `UITextInput` takes a keydown with no key, as autofill sends, where it threw
37
+ - `parseOBJ` reads a comment after a face, carriage return line ends and a line carried on with a backslash, and a release build leaves out a face of a vertex the file does not have
38
+ - `tileLayersFromLDtk` keeps a tile layer with no tiles as an empty layer, so a level of one loads and the editor can paint it
39
+ - Level editor: a property set in the box keeps its place and a `file` or `object` property its type; a save leaves out the object layer made for a first object that was undone; a new object layer's id is past every layer's
40
+ - 3D editor: taking a prefab out of the level takes its instances out of the game; a level's parts are saved in one order, so a level reloaded from its autosave saves the same
41
+ - `writeSaveData` asserts its data is an object, which `readSaveData` reads back, and returns whether it was written, false when storage is full or unavailable
42
+ - `parseAtlas` warns of two sprites with one name; `nearestPowerOfTwo` is never less than its value and is 1 for a value of 1 or less; a particle effect's name cut to 60 characters ends with no space
43
+ - A tile layer's raycast toward a point far beyond the layer walks only across the layer, where a ray to a far constant took seconds
44
+ - `debugShowErrors` shows a message as text, so a file name with markup in it can not add elements to the page
45
+ - Canvas2D tints clamp the color to 0 to 1, as WebGL does
46
+ - glTF: the keys of the files given may start with ./ or / or use backslashes, a uri above them is refused, and an accessor that reaches past its buffer is refused before its floats are made
47
+ - A level whose prefab holds itself, several times over, loads at once with that prefab left out where it holds itself, in place of making thousands of objects
48
+ - Small malformed files no longer make a loader run on: an Aseprite tag past its frames keeps to them, a glTF node reached twice and an accessor of millions with no buffer are refused, an LDtk level of millions of cells is refused and a tile or entity with no place is passed by
49
+ - LDtk: an IntGrid layer whose rule tiles are on another tileset keeps its values for collision, its tiles left out with a warning
50
+ - A collision layer named that no layer has says so in release builds too
51
+ - A light's lens flare: its lamp is a mesh around the light that the ray meets near the light and that is thin, so a globe or a lamp post is its own fixture, while a room or a level mesh hides the light, even one close behind its wall
52
+ - VoxelMap: the inside of a doubleSided face is split along the same diagonal as its outside, so it shows no seam
53
+ - glTF: `parseGLTF(data, baseUrl, files)` finds the `.bin` and image files a `.gltf` names among files given, like a drop's, from the model's own folder, or by the file name alone when only one file has it; a file it can not find is named in the error, and an image that can not be read in a warning; the 3D Mesh example takes a `.gltf` dropped with its files or in its folder, and frees the model it replaces
54
+ - Example browser: after the arrow keys move through the list, Enter keeps the example they went to, and Escape in the search clears it without also closing the list
55
+ - 3D levels: a color that is not a string, and a number that is NaN or Infinity (1e999 in JSON), are read as the default, in place of an assert or a NaN
56
+ - `tileLayersLoad` says so when a map is not a whole number of cells across and down, has no layers, or a layer's tiles do not fill it, in release builds too, in place of running on; every layer is checked before any is made. A game that relied on a release build loading such a map anyway now gets the error
57
+ - A tile past the end of a sheet read by its columns draws nothing, as an LDtk IntGrid layer's values past the art did in the level editor, which asserted
58
+ - A tween that loops or ping pongs with a duration of 0 or less, possible in release builds, ends its loops
59
+
60
+ ### New Demos
61
+
62
+ - [Custom Editor](https://killedbyapixel.github.io/LittleJS/examples/?example=Custom%20Editor) - A level editor made for one game: a class of its own with a tool that lays out rooms by a drag, a button, a key and an overlay
63
+
64
+ ## 1.24.1 - 2026-10-02
65
+
66
+ ### New Changes
67
+
68
+ - A VoxelMap block type can be `doubleSided`, its faces shown from inside the block too, so the surface of water shows from under it
69
+ - 3D Voxels: the player goes under water and walks on the bottom, in place of floating at the surface
70
+ - `tileLayersLoad`'s `collisionLayer` may be a layer's name
71
+ - `light.addFlare` takes the flare's color too
72
+ - LDtk: an IntGrid layer is always a hidden layer of its values under its own name, its rule tiles in layers over it named with tiles, so `tileLayersLoad(map, tileInfo, 0, 'Collisions')` is solid where the values say, whatever the tiles stack or fade; a project of several worlds loads; a project with no tileset entry keeps its tiles
73
+ - The example browser has a new look, in the dark colors of the docs site: a slim top bar in place of the title, the demo at 16:9, and the example list as rows under their headings. A handle between the code and its write-up drags to give one the other's space, by touch and the arrow keys too, and is remembered; a double click puts the quarter back. On a phone the example's name, between Prev and Next, opens a full screen picker with the search. The Screenshot button is gone. A button in the top bar switches between dark and light, the choice shared with the docs site
74
+
75
+ ### Breaking Changes
76
+
77
+ - LDtk: an IntGrid layer with tiles is now a hidden layer of its values under its own name, its tiles in layers named with tiles over it, so the layer indices and names of such a level move; name the collision layer, `tileLayersLoad(map, tileInfo, 0, 'Collisions')`, in place of an index
78
+
79
+ ### Fixes
80
+
81
+ - Box2D: `addRegularPoly` with a side count that is not a whole number no longer hangs, as the engine's own polygons do not since 1.23.1
82
+ - The level editor's tile palette no longer asserts on a Tiled tileset with a margin or a spacing
83
+ - LDtk: a see-through tile keeps its opacity, in a layer of its own; a layer whose tileset is another size is left out with a warning, in place of being read as stacks; a missing level says so in release builds too
84
+ - A Tiled tileset's margin and spacing count from where the game's sheet starts, so a sheet inside an atlas keeps its place
85
+ - 2D level editor: applying an autosave of another size leaves an object layer it does not know about as the file has it, and an autosave whose tiles do not fit its size no longer resizes the map
86
+ - A light's lens flare is hidden by a room or a level mesh around it, seen from outside: only a lamp, a mesh around the light no wider than half its radius, is passed by
87
+ - Example browser: Enter on a focused example selects it, a heading named in a write-up is no longer a link that does nothing, blocked or broken saved preferences no longer stop the page, and the handle drags with the main button only
88
+ - 3D level editor: a broken autosave no longer blocks every edit until Drop, and one older than the last edits, which storage had no room for, says so as the 2D editor does
89
+
10
90
  ## 1.24.0 - 2026-10-02
11
91
 
12
92
  ### New Demos
@@ -23,7 +103,7 @@ Nothing yet.
23
103
  - Lens flares in the 3D level editor: a level's Light has a `lensFlare` property, and the Scene box has a Lens flare checkbox for the sun's, saved in the level's scene block
24
104
  - Lens flares have three more shapes, `hex`, `streak` and `star`; `flare.shapes` says what the ghosts are picked from, `glowSize` and `ghostSize` scale its parts, and an element may be a tile of the game's own (`tileInfo`), turned (`angle`) and wider than tall
25
105
  - 3D picking is triangle accurate: `render3D.pick`, `engineObjectsRaycast3D` and clicks in the 3D level editor hit a mesh on its triangles, not the box around it
26
- - LDtk levels load: `tileLayersFromLDtk(ldtk, level)` makes a level of an LDtk project a Tiled map for `tileLayersLoad` and `objectLayersLoad`, with its tile, auto and IntGrid layers, its entities as objects and their fields as properties
106
+ - LDtk levels load: `tileLayersFromLDtk(ldtk, level)` makes a level of an LDtk project a Tiled map for `tileLayersLoad` and `objectLayersLoad`, with its tile, auto and IntGrid layers, tiles stacked in a cell and see-through tiles, its entities as objects and their fields as properties
27
107
  - A Tiled tileset with a margin or a spacing, a sheet with gaps between its tiles, is read where its tiles are
28
108
  - The 3D Example has lens flares, on the sun and on each orb
29
109
  - CHANGELOG.md lists what changed in each release, and the site's root goes to the example browser
@@ -64,6 +144,11 @@ Nothing yet.
64
144
  - A `Sound` made while sound is off counts as loaded, so a loading screen that waits for sounds finishes
65
145
  - A tween callback that throws no longer leaves the tween system allocating on every update
66
146
  - The build and the docs build leave `dist/` and `docs/` untouched when a step fails
147
+ - A `Timer` set to a time below zero reads as done
148
+ - `UIVideo` lets go of its video when it is destroyed
149
+ - A texture atlas tag with no frames no longer drops the groups after it
150
+ - `setAdditiveBlendMode` works in headless mode
151
+ - The release build's `levelEditor` has `keys`, `buttons` and `tools`, as the debug one does
67
152
 
68
153
  ## 1.23.0 - 2026-10-01
69
154
 
package/EDITOR.md CHANGED
@@ -341,6 +341,8 @@ after a reload.
341
341
 
342
342
  ## Where the working examples are
343
343
 
344
+ - `examples/shorts/customEditor.js`: a 2D editor class of a game's own, with a tool that lays out rooms by a
345
+ drag, a button, a key and an overlay drawn in `onDraw`.
344
346
  - `examples/shorts/render3dLevelEditor.js`: a 3D level with its own Coin and PlayerStart types and both hooks.
345
347
  - `examples/shorts/render3dPrefab.js`: the 3D editor used as a prefab maker.
346
348
  - `examples/shorts/levelEditor.js` and `examples/platformer/`: the 2D editor with a game's own types, palette
package/FAQ.md CHANGED
@@ -206,6 +206,10 @@ If you are using [Visual Studio Code](https://code.visualstudio.com/) there is a
206
206
 
207
207
  Another option is to setup a simple local web server like [http-server](https://www.npmjs.com/package/http-server) via npm.
208
208
 
209
+ ### Which browsers does LittleJS run in?
210
+
211
+ Current Chrome, Edge, Firefox and Safari, on desktop and on phones. The oldest it aims to support is Safari 15 (iOS 15) and the other browsers from 2021 on. Where WebGL2 is missing, 2D games fall back to Canvas2D rendering on their own; the 3D plugin needs WebGL2.
212
+
209
213
  ### How does the camera and world coordinate systems work?
210
214
 
211
215
  LittleJS drawing functions are all handled in world coordinates by default.
@@ -263,6 +267,13 @@ Plugins are self-contained features that live alongside the engine but aren't pa
263
267
  | `newgrounds.js` | Newgrounds.io integration (medals held on the server, scoreboards) |
264
268
  | `audioEffects.js` | Web Audio effects like filter, reverb, delay, distortion and compressor, for a group of sounds or everything |
265
269
  | `drawUtilities.js` | Higher-level drawing helpers like nine-slice and three-slice |
270
+ | `render3dVoxels.js` | `VoxelMap`, a 3D grid of blocks that draws itself and that objects collide with |
271
+ | `render3dLevel.js` | 3D levels as JSON: object types, prefabs, a scene block, block maps and terrain, loaded with `level3DLoad` |
272
+ | `render3dDebug.js` | 3D debug draws (`debugBox3D`, `debugSphere3D`, `debugLine3D`), in debug builds only |
273
+ | `render3dEditor.js` | The free camera and the 3D level editor, in debug builds only |
274
+ | `sceneSystem.js` | Scenes as plain objects, switched with `setScene` |
275
+ | `parallax.js` | `ParallaxLayer`, a background that follows the camera at its own depth and repeats |
276
+ | `particleEffects.js` | A library of ready made particle effects, and their designer's file format |
266
277
 
267
278
  This self-contained design means the community can also ship plugins independently of the main repo — you can write your own plugin as just a JavaScript file that uses the engine's public API.
268
279
 
@@ -367,7 +378,7 @@ LittleJS has a dedicated [js13k branch](https://github.com/KilledByAPixel/Little
367
378
  - **Lean on built-ins to avoid asset files**: `Sound` with ZzFX parameters generates sound effects from a tiny array, and built-in shape drawing avoids shipping image assets.
368
379
  - **Use a packer**: the js13k branch is set up to compress the final bundle with Roadroller or a similar packer. Check the branch's build script for the current toolchain.
369
380
 
370
- For normal production (non-13KB) builds, the engine ships `dist/littlejs.release.js` (asserts stripped) and `dist/littlejs.min.js` (minified) — both well under 100KB.
381
+ For normal production (non-13KB) builds, the engine ships `dist/littlejs.release.js` (asserts stripped, about 1.5 MB with every plugin and its comments) and `dist/littlejs.min.js` (minified, about 420 KB, about 125 KB gzipped). A bundler like Vite leaves out the plugins a game does not use, which makes a small game far smaller.
371
382
 
372
383
  ---
373
384
 
@@ -387,7 +398,7 @@ LittleJS works best when your tile sheet is broken up into grids of tiles becaus
387
398
  drawTile(vec2(21,5), vec2(4.5), tile(3,128));
388
399
  ```
389
400
 
390
- Once loaded, the underlying images are available via `textureInfos[0].image`, `textureInfos[1].image`, etc. This is useful for tasks like reading pixel data to generate a level — see [examples/module/game.js](examples/module/game.js) for an example that reads tile data directly from an image.
401
+ Once loaded, the underlying images are available via `textureInfos[0].image`, `textureInfos[1].image`, etc. This is useful for tasks like reading pixel data to generate a level — the [Level Editor short](https://killedbyapixel.github.io/LittleJS/examples/?example=Level%20Editor) loads a level from data instead, and [examples/module/game.js](examples/module/game.js) builds one from a string.
391
402
 
392
403
  ### What is the tile function and how do tile indexes work?
393
404
 
package/README.md CHANGED
@@ -105,7 +105,7 @@ The code is very clean and well documented with many examples to get you started
105
105
 
106
106
  ## How To Use LittleJS
107
107
 
108
- To get started download the latest LittleJS package from GitHub or install via npm:
108
+ To get started download the latest release from GitHub, the engine's builds and source as npm has them (the examples are in the repository), or install via npm:
109
109
 
110
110
  ```
111
111
  npm install littlejsengine
@@ -172,7 +172,7 @@ LittleJS comes with several demos both for learning and using as starter project
172
172
  | [littlejs.esm.js](https://github.com/KilledByAPixel/LittleJS/blob/main/dist/littlejs.esm.js) | Debug | ESM | Debug mode with asserts |
173
173
  | [littlejs.esm.min.js](https://github.com/KilledByAPixel/LittleJS/blob/main/dist/littlejs.esm.min.js) | Release | ESM | Optimized for release and minified |
174
174
 
175
- Every build includes the plugins. littlejs.min.js is about 100 KB gzipped: the core engine is about 36 KB of that and the 3D plugins about 40 KB. A bundler like Vite leaves out the plugins a game does not use, so a small 2D game comes to about 26 KB gzipped, and a lit 3D scene to about 47 KB.
175
+ Every build includes the plugins. littlejs.min.js is about 125 KB gzipped, and the 3D plugins are a large part of that. A bundler like Vite leaves out the plugins a game does not use, so a small 2D game comes to about 26 KB gzipped, and a lit 3D scene to about 47 KB.
176
176
 
177
177
  ## Games Made With LittleJS
178
178
 
package/REFERENCE.md CHANGED
@@ -144,7 +144,7 @@ fetchJSON(url) // Fetch and parse a JSON file (async)
144
144
  shareURL(title, url, callback) // Share a URL via the navigator share API
145
145
  readSaveData(saveName, defaultSaveData) // Read game save data from localStorage, default must be an object
146
146
  // the result has the default's type in TypeScript
147
- writeSaveData(saveName, saveData) // Write game save data to localStorage; give medalsInit a different name
147
+ writeSaveData(saveName, saveData) // Write a save data object to localStorage, false if it could not; give medalsInit a different name
148
148
 
149
149
  // Random functions
150
150
  rand(valueA=1, valueB=0) // Random float between values
@@ -441,6 +441,8 @@ getNoteFrequency(semitoneOffset, rootFrequency=220) // Get frequency for musica
441
441
 
442
442
  // Audio settings
443
443
  soundEnable = true // Should sound be enabled?
444
+ soundIgnoreSilentSwitch = false // play with an iPhone's silent switch on, as media, pausing the player's music;
445
+ // off, the switch mutes the game; setSoundIgnoreSilentSwitch(true)
444
446
  soundVolume = .3 // Volume scale to apply to all sound
445
447
  soundDefaultRange = 40 // Default range where sound no longer plays
446
448
  soundDefaultTaper = .7 // Default range percent to taper off sound (0-1)
@@ -717,7 +719,8 @@ tileCollisionRaycast(posStart, posEnd, object, normal, solidOnly=true) // Where
717
719
  // or undefined; a normal vec2 passed in is set to the surface's
718
720
  tileCollisionLayers // List of all tile collision layers
719
721
  tileLayersLoad(tileMapData, tileInfo=tile(), renderOrder=0, collisionLayer, draw=true) // collisionLayer is the index
720
- // of the layer that gets collision, no tile when no image is loaded
722
+ // or the name of the layer that gets collision, no tile when no
723
+ // image is loaded
721
724
  // Load tile layers from exported data, Tiled flips and turns included;
722
725
  // groups are flattened and layer indices count that flat list,
723
726
  // hidden layers load with collision but are not drawn; a
@@ -725,8 +728,10 @@ tileLayersLoad(tileMapData, tileInfo=tile(), renderOrder=0, collisionLayer, draw
725
728
  // its tiles are
726
729
  tileLayersFromLDtk(ldtk, level=0) // A Tiled map of an LDtk level, by index or identifier, to give
727
730
  // tileLayersLoad and objectLayersLoad: its layers bottom first, an
728
- // IntGrid layer with no tiles a hidden layer for collision, tiles
729
- // stacked in a cell in layers above, named (2), (3); its entities
731
+ // IntGrid layer a hidden layer of its values under its name, for
732
+ // collisionLayer, its rule tiles over it as name tiles, tiles
733
+ // stacked in a cell in layers above, named (2), (3), and a
734
+ // see-through tile in a layer of its opacity; its entities
730
735
  // objects with their fields as properties
731
736
  objectLayersAddType(name, make, defaults={}, tileInfo) // Name a type of object in a Tiled map: a class made
732
737
  // with new make(pos), or an arrow function called make(pos),
@@ -1298,6 +1303,9 @@ light.coneAngle = .5 // a spotlight: the angle in radians from its
1298
1303
  // cone, 0 by default for a light that shines every way; it shines along its
1299
1304
  // own forward, so rotation3D or what it is attached to aims it
1300
1305
  light.coneSoftness = .2 // how much of the cone is its fading edge: 0 a hard edge, 1 fading from the middle
1306
+ light.gel = textureInfo // or a TileInfo's whole texture: a picture the light shines through, cast along its cone in its colors, upright
1307
+ // as the light looks out, like a slide or stained glass; only the spotlight that
1308
+ // casts the shadows has one, render3D.shadows on and it as render3D.shadowLight
1301
1309
  light.glow = 1 // a soft hazy glow over the light this big, like a lamp at night; 0 by default,
1302
1310
  // added onto what is behind it, hidden by what is in front
1303
1311
  light.glowFalloff = 1 // how fast the glow fades from its middle, .5 a wide haze, 2 a tight bright core
@@ -1664,8 +1672,9 @@ const map = new VoxelMap(pos3D=vec3(), mapSize=vec3(16), tileInfo=tile()) // a g
1664
1672
  // that objects with collideLevel collide with; pos3D is its corner and a cell is 1 unit, it stays upright
1665
1673
  map.setVoxel(cell, type) / map.getVoxel(cell) // type 1-255 shows that tile on every face, 0 is empty, a cell outside
1666
1674
  // the map is ignored and reads 0
1667
- map.setBlockType(type, faces, {seeThrough, transparent}) // faces: a tile, six (+x, -x, +y, -y, +z, -z), or
1668
- // {top, side, bottom}; seeThrough for holes like leaves, transparent to blend like water, drawn after the rest
1675
+ map.setBlockType(type, faces, {seeThrough, transparent, doubleSided}) // faces: a tile, six (+x, -x, +y, -y, +z,
1676
+ // -z), or {top, side, bottom}; seeThrough for holes like leaves, transparent to blend like water, drawn after
1677
+ // the rest; doubleSided for faces seen from inside too, so the surface of water shows from under it
1669
1678
  map.raycast(ray, maxDistance, test) // {distance, cell, normal, type} of the first block a ray hits, or
1670
1679
  // undefined; test(type, cell) says which blocks count
1671
1680
  map.data / map.rebuild() // the Uint8Array of types, x + mapSize.x*(y + mapSize.y*z); rebuild
@@ -1680,8 +1689,10 @@ await loadOBJ(url, smooth) // fetch then parse, in an async gameInit; chain .cen
1680
1689
  // glTF models - the glTF plugin, .gltf with its files beside it or .glb in one file; meshes with their node placement,
1681
1690
  // vertex colors, material colors and base color textures, and node animations; no skins or morph targets, and no
1682
1691
  // Draco or meshopt compressed geometry, which throws saying so
1683
- const model = await loadGLTF(url) // a GLTFModel, in an async gameInit; or await parseGLTF(data, baseUrl) on bytes or
1684
- // JSON you already have
1692
+ const model = await loadGLTF(url) // a GLTFModel, in an async gameInit; or await parseGLTF(data, baseUrl, files) on
1693
+ // bytes or JSON you already have; files, a Map of the .bin and image files a
1694
+ // .gltf names by their paths, like the files of a drop, in place of fetching,
1695
+ // baseUrl then the .gltf's folder among them
1685
1696
  model.parts // one GLTFPart per primitive of every node: name, mesh in model space, color,
1686
1697
  // textureInfo when the material has one and WebGL is on, transparent for a
1687
1698
  // blending material or glass (KHR_materials_transmission), which comes in
@@ -1755,7 +1766,7 @@ flare.elements = [{at: .5, size: .1, color: hsl(.6,1,.6,.3), shape: 'disc'}] //
1755
1766
  // tileInfo for a tile of your own; angle turns it
1756
1767
  flare.visible // how much of the sun shows, 0 to 1, eased over fadeTime, to read; what is not
1757
1768
  // see through hides it, flare.occlusion = false turns that off
1758
- light.addFlare(size, count, intensity, saturation) // gives a Light3D a flare of its own and returns it: at the
1769
+ light.addFlare(size, count, intensity, saturation, color) // gives a Light3D a flare of its own and returns it: at the
1759
1770
  // light, in its color, smaller from farther than its radius, hidden by what is
1760
1771
  // in front of it, a spotlight's only from inside its beam
1761
1772
  light.flare // the light's LensFlare3D, its child, or undefined; set one of your own, and
@@ -2169,6 +2180,11 @@ getCrescentPoints(pos, size=1, percent=0, angle=0, invert=false, sides=glCircleS
2169
2180
  - See `examples/shorts/textureSheet.js`
2170
2181
 
2171
2182
  ```javascript
2183
+ loadTiles(sources, tileSize, padding=1) // Pack tile images, or several tile sheets, into one tile set: each image cut
2184
+ // into tiles, numbered from 0 in the order given; give the TileInfo it
2185
+ // returns to tileLayersLoad or a TileLayer, and await spritesReady first
2186
+ tileInfo.tiles // a tile set's tiles, each where it was packed: a tile layer draws tile n
2187
+ // from tiles[n], and the level editor's palette offers each
2172
2188
  loadSprite(src, frameSize, padding=1, sourcePadding=0) // Load an image and pack it, returns a TileInfo
2173
2189
  loadAtlas(imageSrc, jsonSrc, padding=1) // Load a TexturePacker or Aseprite atlas, returns name->TileInfo object
2174
2190
  parseAtlas(data) // Parse atlas json into named frame groups, used by loadAtlas
@@ -2285,7 +2301,8 @@ debugLine(posA, posB, color, width=.1, time) // Draw debug line
2285
2301
  debugPoly(pos, points, color=WHITE, time=0, angle=0, fill) // Draw debug polygon
2286
2302
  debugText(text, pos, size=1, color=WHITE, time=0, angle=0) // Draw debug text
2287
2303
  debugOverlap(pA, sA, pB, sB, color) // Draw a debug overlap between two boxes
2288
- // each debug draw also takes screenSpace after the params above, defaulting to drawScreenSpace
2304
+ // each debug draw also takes screenSpace as its last parameter, defaulting to drawScreenSpace; debugText takes a
2305
+ // font before it
2289
2306
  debugClear() // Clear all debug primitives
2290
2307
  debugScreenshot() // Save a screenshot at the end of this frame
2291
2308
  debugShowErrors() // Show full page error message when an error occurs