littlejsengine 1.23.1 → 1.24.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/CHANGELOG.md +234 -0
- package/COPYRIGHT.txt +0 -27
- package/FAQ.md +4 -9
- package/README.md +3 -2
- package/REFERENCE.md +30 -17
- package/dist/littlejs.d.ts +141 -97
- package/dist/littlejs.esm.js +407 -258
- package/dist/littlejs.esm.min.js +3 -3
- package/dist/littlejs.js +406 -254
- package/dist/littlejs.min.js +2 -2
- package/dist/littlejs.release.js +401 -253
- package/package.json +2 -1
- package/plugins/pluginExport.js +0 -4
- package/plugins/render3d.js +92 -17
- package/plugins/render3dEditor.js +5 -1
- package/plugins/render3dExtras.js +166 -70
- package/plugins/render3dLevel.js +24 -4
- package/src/engine.js +1 -1
- package/src/engineAudio.js +2 -2
- package/src/engineBuild.mjs +0 -1
- package/src/engineExport.js +1 -0
- package/src/engineTileLayer.js +117 -0
- package/plugins/zzfxm.js +0 -162
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# LittleJS Changelog
|
|
2
|
+
|
|
3
|
+
What changed in each release, newest first. Releases before 1.20.0 are on the
|
|
4
|
+
[GitHub releases page](https://github.com/KilledByAPixel/LittleJS/releases).
|
|
5
|
+
|
|
6
|
+
## Unreleased
|
|
7
|
+
|
|
8
|
+
Nothing yet.
|
|
9
|
+
|
|
10
|
+
## 1.24.0 - 2026-10-02
|
|
11
|
+
|
|
12
|
+
### New Demos
|
|
13
|
+
|
|
14
|
+
- [3D Lens Flare](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20Lens%20Flare) - Now with hexagons, and flares on lamps as well as the sun
|
|
15
|
+
- [Text](https://killedbyapixel.github.io/LittleJS/examples/?example=Text) - What drawText can do: sizes, outlines, alignment, fonts, rows and text placed in pixels
|
|
16
|
+
- [Physics](https://killedbyapixel.github.io/LittleJS/examples/?example=Physics) - The engine's own objects falling, bouncing, sliding and floating, and a sensor
|
|
17
|
+
- [Random](https://killedbyapixel.github.io/LittleJS/examples/?example=Random) - Random numbers, and a seeded generator that gives the same result every time
|
|
18
|
+
|
|
19
|
+
### New Changes
|
|
20
|
+
|
|
21
|
+
- Every short example has a write-up in the example browser: what it shows, how its code works, things to try in the editor and where to look next, with links to the docs and to other examples
|
|
22
|
+
- Lens flares on lights: `light.addFlare()` gives a `Light3D` a lens flare of its own and returns it, `light.flare` is the flare, and it goes with the light; a `DirectionalLight3D` can have one too, far away like the sun's
|
|
23
|
+
- 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
|
+
- 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
|
+
- 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
|
|
27
|
+
- A Tiled tileset with a margin or a spacing, a sheet with gaps between its tiles, is read where its tiles are
|
|
28
|
+
- The 3D Example has lens flares, on the sun and on each orb
|
|
29
|
+
- CHANGELOG.md lists what changed in each release, and the site's root goes to the example browser
|
|
30
|
+
|
|
31
|
+
### Breaking Changes
|
|
32
|
+
|
|
33
|
+
- ZzFXM, the tracker music plugin, is removed: it was made for the js13k size limit. A game with a song in that format includes ZzFXM itself and hands its samples to a `Sound`
|
|
34
|
+
- 3D picking hits only the faces that are drawn: a mesh seen from inside is no longer hit unless it is `doubleSided`
|
|
35
|
+
- `LensFlare3D`: `getSunScreenPos` is now `getScreenPos` and `isSunHidden` is now `isHidden`, since a flare may be a light's; `visible` is 0 while the sun is off the screen; a flare pointed at a light is destroyed with it
|
|
36
|
+
- The repository's `dist/` is now the last release, not the latest source: it is committed only for a release, and the site is built from the source
|
|
37
|
+
|
|
38
|
+
### Fixes
|
|
39
|
+
|
|
40
|
+
- A lens flare that is off the screen, or of a light that is off, no longer looks for what hides it every frame
|
|
41
|
+
- 3D level editor: an edit of a level's scene, or its undo, no longer takes away a sun lens flare that an earlier level's scene gave the game
|
|
42
|
+
- Shorts: the lander lands upright after a full turn, the maze reaches its top row and works at even sizes, a pocketed cue ball comes back, the 3D Voxels player floats in water, and more that writing them up turned up
|
|
43
|
+
|
|
44
|
+
## 1.23.1 - 2026-10-02
|
|
45
|
+
|
|
46
|
+
### New Changes
|
|
47
|
+
|
|
48
|
+
- 3D sprites are batched: an object with a tile and no mesh, or a `drawBillboard`, that is not transparent is drawn as one instanced batch with the other sprites of its sheet, its clear pixels cut out, so many sprites cost little; transparent and additive sprites still draw sorted, one by one
|
|
49
|
+
- A level's block map works in a game with no images: it shows plain colored blocks, where it used to fail
|
|
50
|
+
- glTF: emission stronger than 1 from Blender is read (`KHR_materials_emissive_strength`), a texture is smooth or pixelated as its sampler says whatever the game's tiles are, and a model with basis textures says they are not read
|
|
51
|
+
- The 2D level editor keeps the last 100 undo steps, as the 3D one does
|
|
52
|
+
- The npm package and the release zip include REFERENCE.md and EDITOR.md
|
|
53
|
+
- EDITOR.md says how to keep a level as a script for a game opened from disk, and what changing the editors' own tools takes
|
|
54
|
+
- The deprecated names from 1.20 are kept until 1.25 at least
|
|
55
|
+
|
|
56
|
+
### Fixes
|
|
57
|
+
|
|
58
|
+
- A UI button pressed and released inside one frame was clicked twice
|
|
59
|
+
- `drawRegularPoly`, and circles with `setGLCircleSides`, hung on a side count that was not a whole number
|
|
60
|
+
- 2D level editor: a click on an object no longer rewrites its position with rounding noise and adds an undo step; applying saved edits to a file that gained an object layer leaves that layer alone; a level whose url has a `%20` in it matches its file again
|
|
61
|
+
- 3D level editor: saves of a prefab are written in the order they were asked for when `onSave` is async, a prefab edit that was undone no longer comes back after a reload, and objects a game's tool adds without ids get ids
|
|
62
|
+
- An attached prefab inside another prefab is placed where it belongs, and its collision box follows parts that are turned
|
|
63
|
+
- `levelEditor.onSave` may be an async function in TypeScript too
|
|
64
|
+
- A `Sound` made while sound is off counts as loaded, so a loading screen that waits for sounds finishes
|
|
65
|
+
- A tween callback that throws no longer leaves the tween system allocating on every update
|
|
66
|
+
- The build and the docs build leave `dist/` and `docs/` untouched when a step fails
|
|
67
|
+
|
|
68
|
+
## 1.23.0 - 2026-10-01
|
|
69
|
+
|
|
70
|
+
### New Demos
|
|
71
|
+
|
|
72
|
+
- [3D Prefab Maker](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20Prefab%20Maker) - Build a prefab in the level editor and save it for a game to place
|
|
73
|
+
- [3D Level Editor](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20Level%20Editor) - Now makes prefabs, flattens and paints terrain, and fills boxes of blocks
|
|
74
|
+
- [Parallax](https://killedbyapixel.github.io/LittleJS/examples/?example=Parallax) - Rebuilt on the new parallax plugin, with ranges of mountains that repeat as the camera goes by
|
|
75
|
+
|
|
76
|
+
### New Changes
|
|
77
|
+
|
|
78
|
+
- 3D prefabs: a prefab is a small level placed many times. `level3DAddPrefab('House', data)` makes it a type, a level places it like a Box, and `level3DSpawn` places one from code; each part is a solid object of its own, or with `attached` the parts move with the instance as one body, for a vehicle or a creature
|
|
79
|
+
- The 3D level editor is the prefab editor too: Ctrl+G makes the selection a prefab, Enter opens one to edit it alone and every instance follows, Ctrl+Shift+G unpacks one, and the panel exports a prefab to a file and loads one from a file; prefabs can hold prefabs, and are saved in the level
|
|
80
|
+
- Make the level editors your own: `levelEditor.addKey`, `addButton` and `addTool` add a key, a panel button and a mouse tool of your game's own, `onOpen`, `onUpdate`, `onDraw`, `onPanel` and `onSave` are called by the editors, and `levelEditor.edit2D` and `edit3D` are the edit functions, each change an undo step. The same calls work in the 2D and the 3D editor
|
|
81
|
+
- Or extend it: `class MyEditor extends LevelEditor` with the hooks as methods, then `setLevelEditor(new MyEditor)`. Release builds take all of it and call none of it, so a game needs no guards
|
|
82
|
+
- New guide, [EDITOR.md](https://github.com/KilledByAPixel/LittleJS/blob/main/EDITOR.md): how to turn the built-in editors into an editor for your own game, written for people and AI assistants, with every example tested
|
|
83
|
+
- Added the Parallax plugin: a `ParallaxLayer` follows the camera by a part of its movement and repeats across the view, so a level of any width has a background; it draws mountains by default, or anything you draw into it
|
|
84
|
+
- Touch has a mouse wheel: a pinch of two fingers turns `mouseWheel`, so what zooms with the wheel zooms with a pinch, and `touchPinch` reads it by itself
|
|
85
|
+
- 3D level editor: the Terrain tool has a flatten brush and a paint brush that colors the ground, the Blocks tool fills a box with a drag and resizes its map, and the Move handles can follow an object's own axes (L)
|
|
86
|
+
- A `LensFlare3D` can be a light's flare: set `flare.light` and it sits at the lamp, in its color, hidden by what is in front of it
|
|
87
|
+
- The example browser has Prev and Next buttons, to go through the examples on a phone
|
|
88
|
+
- `Sound.range` can be set after a sound is made, and 3D sounds use it
|
|
89
|
+
- Size: the full build is about 122 KB gzipped, up from 119 KB; a bundler like Vite leaves out the plugins you don't use
|
|
90
|
+
- Fixes: a `SpriteAnimator` clip that ends and switches clips reads the new clip, glass and water blocks no longer hide the sun's lens flare, 3D particles appear at once like 2D ones, a spotlight that casts shadows lights no wider than its shadow map, the 3D editor's Scene box no longer undoes a field edited just before, and the example browser always shows the example picked last; the test suite grew from 1724 to 1848 tests
|
|
91
|
+
|
|
92
|
+
### Upgrade Notes
|
|
93
|
+
|
|
94
|
+
- With two fingers down the touch screen pinches: the second finger lets go of the button the first one pressed. A game that uses two fingers its own way calls `setTouchPinchWheel(false)` to get the old behavior back
|
|
95
|
+
- A `ParticleEmitter3D` makes its first particle at once, where it used to wait one emit interval
|
|
96
|
+
- A spotlight set as `render3D.shadowLight` has its cone capped at 1.35 radians, what its shadow map covers
|
|
97
|
+
- `levelEditor.onRestart`, `onPlayFrom` and `onTile` are set the same way as before, but they are now empty methods when a game has not set them, so `if (levelEditor.onRestart)` is always true; nothing in a game needs to read them
|
|
98
|
+
- The Parallax short moved to the plugins section, and the platformer example uses the plugin for its mountains
|
|
99
|
+
- These names changed in 1.20 and the old ones still work for now: `collideTiles` is now `collideLevel`, and `Box2dWeldJoint.setSpringDampingRatio` is now `setDampingRatio`
|
|
100
|
+
|
|
101
|
+
## 1.22.0 - 2026-10-01
|
|
102
|
+
|
|
103
|
+
### New Demos
|
|
104
|
+
|
|
105
|
+
- [Particle Effects](https://killedbyapixel.github.io/LittleJS/examples/?example=Particle%20Effects) - Every built-in particle effect, one line each
|
|
106
|
+
- [Particle Options](https://killedbyapixel.github.io/LittleJS/examples/?example=Particle%20Options) - One effect, and what each option does to it
|
|
107
|
+
- [3D Lens Flare](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20Lens%20Flare) - The sun flares across the screen and hides behind pillars
|
|
108
|
+
- [3D First Person](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20First%20Person) - Now with a night, and a flashlight that casts the shadows
|
|
109
|
+
- [3D Level Editor](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20Level%20Editor) - Now paints blocks, sculpts terrain and sets the sky, sun and fog
|
|
110
|
+
- [Tween Advanced](https://killedbyapixel.github.io/LittleJS/examples/?example=Tween%20Advanced) - Every tween feature in labeled rows
|
|
111
|
+
- [Particle Designer](https://killedbyapixel.github.io/LittleJS/examples/particles/) - Rebuilt on the effects library, with a 3D preview
|
|
112
|
+
|
|
113
|
+
### New Changes
|
|
114
|
+
|
|
115
|
+
- Added the Particle Effects plugin: `particleEffect('fire', pos)` plays one of 24 built-in effects in one line, and `particleEffect3D` plays the same effect in 3D; the options scale it, turn its hue, change its saturation, swap in your own tile, or replace any setting, like `{emitTime: .5}` for a burst
|
|
116
|
+
- The built-in effects are fire, torch, smoke, steam, explosion, sparks, hit, dust, debris, sparkle, magic, heal, poison, portal, rain, snow, leaves, bubbles, fireflies, trail, muzzle, blood, confetti and splash, each sized to fit a one unit object and drawn with shapes the plugin makes itself, so they need no image
|
|
117
|
+
- The Particle Designer is rebuilt on the plugin: the built-in effects are its presets, Save Library writes the file `particleEffectsLoad` reads so a game plays your effects by name, and it previews an effect in 2D or 3D with the same options a game passes
|
|
118
|
+
- `ParticleEmitter` has `scale`, which grows a whole effect, and `gravity`, its own fall; `ParticleEmitter3D` has `gravityScale` and `emitFlat`, which makes its spawn area a disc or a flat sheet
|
|
119
|
+
- 3D level editor: the Blocks tool (B) paints a level's block map, the Terrain tool (T) sculpts its terrain with a brush, and the Scene box sets its sky, sun, fog and shadows; all three are saved in the level's JSON, undo and autosave with the rest, and `level3DLoad` makes them with no game code
|
|
120
|
+
- Spotlights: a `Light3D` with a `coneAngle` shines along its own forward, with `coneSoftness` for where the fade starts, and `render3D.shadowLight` makes one spotlight cast the shadows in place of the sun, for a flashlight in the dark
|
|
121
|
+
- Added `LensFlare3D`, the sun's lens flare: a glow at the sun and a row of discs and rings across the screen, with its size, count, brightness and colors to set, fading out when something hides the sun
|
|
122
|
+
- 2D lights glow like the 3D ones: `light.glow` and `glowFalloff` on a `Light` of the light system
|
|
123
|
+
- Built-in post processing effects: `postProcessEffects` joins scanlines, noise, vignette, curve, chromatic, glow and a 3D outline into one shader, with your own GLSL as a piece too
|
|
124
|
+
- A texture can be smooth or pixelated on its own: `TextureInfo` takes `pixelated`, and `setPixelated` changes it
|
|
125
|
+
- Textures the engine sizes itself, like the shadow maps, fall back to the largest size a device supports; `glClampTextureSize` does the same for your own
|
|
126
|
+
- Faster: particles draw about 30% faster, `InstancedMesh3D` moves many instances with `setTransforms` and uploads less, the 3D draw state is checked with one number per draw, and ZzFX 1.4.0 generates sounds faster
|
|
127
|
+
- `render3D.playSound` hears a sound with no range of its own out to `render3D.soundDefaultRange`, 100 units
|
|
128
|
+
- Added a browser smoke suite, `npm run test:browser`: real WebGL in headless Chrome checks 2D draws, shaders, the 3D pass, spotlights, the lens flare, a lost and restored context, and that every short runs
|
|
129
|
+
- Size: the full build is about 119 KB gzipped, up from 108 KB; a bundler like Vite leaves out the plugins you don't use
|
|
130
|
+
- Fixes: post process feedback keeps the previous frame again, `loadGLTF` follows redirects and takes blob and data urls, overlapping Saves in the level editors write in order, and a scene `leave` that throws no longer blocks later switches; the test suite grew from 1562 to 1724 tests
|
|
131
|
+
|
|
132
|
+
### Upgrade Notes
|
|
133
|
+
|
|
134
|
+
- A sound with no range of its own is now heard to 100 units when played with `render3D.playSound`, where it was 40; pass a range to `new Sound`, or set `render3D.soundDefaultRange`, to change it. 2D sounds are unchanged
|
|
135
|
+
- `particleEffect3D` and the particle designer's files use the plugin's effect format; an effect saved by the older designer still loads and keeps its tile
|
|
136
|
+
- The light system writes the sizes it could make back to `shadowMapSize`, `shadowTextureSize` and `textureSize` when a device can not make the size asked for
|
|
137
|
+
- The engine's own soft textures, the light glow and the particle shapes, are smooth even when `tilesPixelated` is on
|
|
138
|
+
- The Tween System and Stress Test full examples are gone, the Tween Advanced short covers tweens
|
|
139
|
+
- These names changed in 1.20 and the old ones still work for now: `collideTiles` is now `collideLevel`, and `Box2dWeldJoint.setSpringDampingRatio` is now `setDampingRatio`
|
|
140
|
+
|
|
141
|
+
## 1.21.0 - 2026-09-29
|
|
142
|
+
|
|
143
|
+
### New Demos
|
|
144
|
+
|
|
145
|
+
- [3D Level Editor](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20Level%20Editor) - Place boxes, lights and coins, then walk around
|
|
146
|
+
- [3D Materials](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20Materials) - Bricks from a normal map made in code, a polished ball reflecting the sky, and glowing windows
|
|
147
|
+
- [3D Ambient Occlusion](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20Ambient%20Occlusion) - Creases and corners darkened from the new depth texture, side by side with plain
|
|
148
|
+
- [3D Water](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20Water) - Rain on a pool, its waves a cellular automaton, reflecting the sky
|
|
149
|
+
- [Scenes](https://killedbyapixel.github.io/LittleJS/examples/?example=Scenes) - A title, a game with a pause overlay and game over, switched with `setScene`
|
|
150
|
+
- [Animation](https://killedbyapixel.github.io/LittleJS/examples/?example=Animation) - Sprite animation, with clips switched by name
|
|
151
|
+
- [3D Lights](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20Lights) - The lamps now glow
|
|
152
|
+
|
|
153
|
+
### New Changes
|
|
154
|
+
|
|
155
|
+
- Added the 3D Level Editor, in debug builds only: press 0 on the debug overlay in a game that loaded a 3D level to pause it and place, move, rotate and scale its objects with handles, grid and ground snapping, undo, autosave, Save back to the level's JSON file and Reset to file
|
|
156
|
+
- 3D levels: `level3DAddType`, `level3DAddMesh` and `level3DLoad` make a level's objects from plain JSON, with Box, Sphere, Cylinder and Light built in
|
|
157
|
+
- Added a free camera, in debug builds only: press C on the debug overlay to fly around the running game while it reads no keyboard or mouse (`inputCapture`)
|
|
158
|
+
- 3D materials: `normalMap` and `normalScale` bend the surface with no tangents needed, `normalMapFromHeight` makes a normal map in code, `shininess` sets the highlight's size, `reflectivity` reflects the sky with a Fresnel edge, and `emissiveMap` with `emissiveMapColor` makes parts of a surface glow; glTF models bring their normal and emissive textures
|
|
159
|
+
- Turned boxes collide as turned: a box with a `rotation3D` collides as the box you see, so ramps, tilted platforms and turned walls just work, and the 3D box helpers take an optional rotation
|
|
160
|
+
- Standing in 3D: resting on another object sets `groundObject`, and `groundAngle` (45 degrees by default) is the steepest slope an object stands on without sliding
|
|
161
|
+
- The 2D physics settings work in 3D: `damping`, `angleDamping`, `friction` on the ground (a moving platform carries what rides it) and `clampSpeed`
|
|
162
|
+
- Added `render3D.depthTexture`: the post process shader gets the 3D depth as `iChannel2` and reads it with `sceneDepth(uv)`, for ambient occlusion, fog and outlines
|
|
163
|
+
- `Light3D` has a soft hazy `glow`, with `glowFalloff` for how fast it fades
|
|
164
|
+
- 3D particles have the 2D emitter's callbacks, `particleCreateCallback`, `particleUpdateCallback`, `particleCollideCallback` and `particleDestroyCallback`, and `collideLevel` to bounce off height maps and voxel maps
|
|
165
|
+
- Added a loading screen: after the splash, startup waits for the images, `gameInit` and everything loaded while it runs, and shows a loading bar if that takes more than half a second; `setLoadingScreen` draws your own, and `engineAddLoad` adds anything else you load
|
|
166
|
+
- Added the Scene plugin: `setScene` and `getScene` switch between scenes with enter, leave, update and render hooks, clearing all but persistent objects
|
|
167
|
+
- Added `setEngineVariableStep`: one update per display frame with `timeDelta` the frame's time, and frame times are smoothed to whole display frames in both modes
|
|
168
|
+
- `SpriteAnimation.play(onEnd)` calls back when a play ends, and `SpriteAnimator` switches a character's clips by name
|
|
169
|
+
- A mesh with `dynamicDraw` uploads faster, and `levelEditor.paletteTiles` picks the tiles the 2D level editor's palette shows
|
|
170
|
+
- Size: the full build is about 107 KB gzipped, up from 100 KB; a bundler like Vite leaves out the plugins you don't use
|
|
171
|
+
- Fixes: three external review passes and their fixes, and the test suite grew from 1313 to 1562 tests
|
|
172
|
+
|
|
173
|
+
### Upgrade Notes
|
|
174
|
+
|
|
175
|
+
- `clampSpeed` now only holds an object to `objectMaxSpeed` (1 unit a frame per axis) while it collides, with solids, or with tiles or the level while it has a mass, in 2D and 3D; something that does not collide, like a bullet you move yourself, now moves at its full speed instead of being slowed
|
|
176
|
+
- In 3D, colliding objects are now held to `objectMaxSpeed`; set `clampSpeed = false` on fast colliding things, as in 2D
|
|
177
|
+
- In 3D, an object standing on something now slows by `friction`, 0.8 by default; set `friction = 1` for none
|
|
178
|
+
- In 3D, `damping` now slows objects with no mass too, and `angleDamping` slows `angleVelocity3D`; both are 1 by default, so nothing changes unless you set them
|
|
179
|
+
- A turned 3D solid now collides as turned, so a spinning solid sweeps what it touches; sprites still collide upright
|
|
180
|
+
- `engineObjectsCollect3D` finds a turned object by its turned box
|
|
181
|
+
- The game loop now starts once `gameInit` and everything loaded while it ran are done, sounds from files included; call `setLoadingScreen()` to turn the loading screen off
|
|
182
|
+
- These names changed in 1.20 and the old ones still work until 1.22: `collideTiles` is now `collideLevel`, and `Box2dWeldJoint.setSpringDampingRatio` is now `setDampingRatio`
|
|
183
|
+
|
|
184
|
+
## 1.20.0 - 2026-09-28
|
|
185
|
+
|
|
186
|
+
### New Demos
|
|
187
|
+
|
|
188
|
+
- [3D Voxels](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20Voxels) - Walk, jump, dig and build in a little Minecraft style world
|
|
189
|
+
- [3D Mesh Operations](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20Mesh%20Operations) - Bevels, CSG cuts, mirror and spin
|
|
190
|
+
- [3D Sync 2D](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20Sync%202D) - A 2D platformer with 2D physics and tile collision, drawn in 3D
|
|
191
|
+
- [3D Mesh](https://killedbyapixel.github.io/LittleJS/examples/?example=3D%20Mesh) - Load an OBJ or glTF model, or drop one in
|
|
192
|
+
- [Level Editor](https://killedbyapixel.github.io/LittleJS/examples/?example=Level%20Editor) - Paint a level and place objects, then play it
|
|
193
|
+
- [Platformer](https://killedbyapixel.github.io/LittleJS/examples/platformer/) - Press Esc then 0 to open the level editor on a real game
|
|
194
|
+
- [Light Shadows](https://killedbyapixel.github.io/LittleJS/examples/?example=Light%20Shadows) - Lights blocked by walls and tinted by glass
|
|
195
|
+
- [Particle Designer](https://killedbyapixel.github.io/LittleJS/examples/particles/) - Reworked, with an effect library, presets and code export
|
|
196
|
+
- [Tweakables](https://killedbyapixel.github.io/LittleJS/examples/?example=Tweakables) - Change values live from a debug panel
|
|
197
|
+
- [UI Tile Slice](https://killedbyapixel.github.io/LittleJS/examples/?example=UI%20Tile%20Slice) - UI styled with nine-slice and tile art
|
|
198
|
+
|
|
199
|
+
### New Changes
|
|
200
|
+
|
|
201
|
+
- Added the Level Editor, in debug builds only: press 0 on the debug overlay to pause the game and paint its Tiled tile layers, with stamps, fill, selections, undo and redo, then Escape to play and edit again
|
|
202
|
+
- The level editor places objects too: `objectLayersAddType` names your object classes, `objectLayersLoad` makes them from a Tiled object layer, and their properties are edited in the panel
|
|
203
|
+
- It saves straight back to the level's Tiled JSON file where the browser allows it (Chrome and Edge), autosaves every change, and has `levelEditor` hooks for restart, play from the mouse, resizing and your own tile rules
|
|
204
|
+
- Added the Tweakables plugin: `tweak()` puts any value on a debug panel (press 9) with sliders, checkboxes, colors and buttons
|
|
205
|
+
- Added `VoxelMap`, a grid of blocks drawn in chunks with hidden faces left out, per face tiles, see-through and blending blocks, corner shading, collision and a grid raycast for digging and building
|
|
206
|
+
- Level collision in 3D: objects with `collideLevel` land on and are stopped by height maps and voxel maps, `groundObject` says what they stand on, and `FirstPersonCamera3D` can jump (`jumpSpeed`) and set its `eyeHeight`
|
|
207
|
+
- `HeightMap` is now an object that draws itself, with world space lookups wherever it is placed
|
|
208
|
+
- Mesh operations: bevels and chamfers on the box, cylinder and cone builders, `mirror` and `spin`, and CSG `union`, `subtract` and `intersect`
|
|
209
|
+
- Added the glTF plugin: `loadGLTF` and `parseGLTF` load .gltf and .glb models with textures, node animations, WebP images and glass
|
|
210
|
+
- `InstancedMesh3D` keeps a set of instances on the GPU and draws them as one call, meshes upload as indexed triangle lists, and particles and objects allocate nothing per frame
|
|
211
|
+
- 3D lighting: the sky lights the scene from above and below, and `Light3D` point lights make specular highlights
|
|
212
|
+
- `sync2D` 3D objects start at their 3D position, so a 2D game with 3D looks just works
|
|
213
|
+
- Light System: lights are blocked by shadow casters, colored glass tints what passes through, and `emissive` objects glow in the dark
|
|
214
|
+
- Added `drawScreenSpace`, a setting that makes the draw functions default to screen space, for HUDs or a 3D game's 2D overlay
|
|
215
|
+
- `TileSlice` draws a tile as a nine-slice, three-slice or plain box, and the UI system can style its widgets with tile art
|
|
216
|
+
- Tiled maps keep their flipped and turned tiles, and the debug overlay's new Debug Tiles view (key 8) shows each tile layer's bounds and collision
|
|
217
|
+
- The particle designer was rebuilt with an effect library, presets, grouped settings and code export, and `particleUpdateCallback` runs for each particle
|
|
218
|
+
- The Newgrounds plugin was rewritten: medals unlock on the server, leaderboards work for guests too, and it uses the browser's WebCrypto with no dependencies
|
|
219
|
+
- The example tile sheets now have a 1 pixel border around each tile, with `setTileDefaultPadding(1)`, and the starter builds its level from a string you can edit
|
|
220
|
+
- Release builds no longer evaluate assert arguments, and `RandomGenerator` gives unrelated values for nearby seeds
|
|
221
|
+
- Size: the core engine is about 36 KB gzipped and every build includes the plugins; a bundler like Vite leaves out the ones you don't use, so a small 2D game is about 26 KB and a lit 3D scene about 47 KB
|
|
222
|
+
- Fixes: fifteen review passes fixed hundreds of bugs across the engine and plugins, the engine and plugins type check clean, and the test suite grew from 570 to 1313 tests
|
|
223
|
+
|
|
224
|
+
### Upgrade Notes
|
|
225
|
+
|
|
226
|
+
- These names changed in 1.20 and the old ones still work until 1.22:
|
|
227
|
+
- `collideTiles` is now `collideLevel`
|
|
228
|
+
- `Box2dWeldJoint.setSpringDampingRatio` and `getSpringDampingRatio` are now `setDampingRatio` and `getDampingRatio`
|
|
229
|
+
- `NewgroundsPlugin.logView()` does nothing, since the view is logged on start
|
|
230
|
+
- `drawNineSliceScreen` and `drawThreeSliceScreen` take a color after the start tile, before the border size; a number there still reads the old order
|
|
231
|
+
- `setCollision()` now turns on level collision for 3D objects
|
|
232
|
+
- A `HeightMap` draws itself, so remove any separate object you made to draw its mesh, and `terrain.size` is now `terrain.mapSize`
|
|
233
|
+
- A flat `buildGrid` is flat shaded unless you pass `smooth`
|
|
234
|
+
- The example tile sheets changed layout; if you copied `tiles.png` from an example, use it with `setTileDefaultPadding(1)`
|
package/COPYRIGHT.txt
CHANGED
|
@@ -36,30 +36,3 @@ appreciated but is not required.
|
|
|
36
36
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
37
37
|
misrepresented as being the original software.
|
|
38
38
|
3. This notice may not be removed or altered from any source distribution.
|
|
39
|
-
|
|
40
|
-
-------------------------------------------------------------------------------
|
|
41
|
-
|
|
42
|
-
ZzFXM License
|
|
43
|
-
|
|
44
|
-
The ZzFXM plugin (plugins/zzfxm.js) is a port of ZzFXM, the Zuper Zmall Zound Zynth music player.
|
|
45
|
-
https://github.com/keithclark/ZzFXM
|
|
46
|
-
|
|
47
|
-
Copyright (c) 2020 Keith Clark, Frank Force
|
|
48
|
-
|
|
49
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
50
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
51
|
-
in the Software without restriction, including without limitation the rights
|
|
52
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
53
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
54
|
-
furnished to do so, subject to the following conditions:
|
|
55
|
-
|
|
56
|
-
The above copyright notice and this permission notice shall be included in all
|
|
57
|
-
copies or substantial portions of the Software.
|
|
58
|
-
|
|
59
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
60
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
61
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
62
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
63
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
64
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
65
|
-
SOFTWARE.
|
package/FAQ.md
CHANGED
|
@@ -261,7 +261,6 @@ Plugins are self-contained features that live alongside the engine but aren't pa
|
|
|
261
261
|
| `tweakables.js` | A debug panel to change values live while the game runs, press 9 with the debug overlay open |
|
|
262
262
|
| `medalSystem.js` | Achievement / medal tracking with popup notifications |
|
|
263
263
|
| `newgrounds.js` | Newgrounds.io integration (medals held on the server, scoreboards) |
|
|
264
|
-
| `zzfxm.js` | Procedural chiptune music via the `ZzFXMusic` class |
|
|
265
264
|
| `audioEffects.js` | Web Audio effects like filter, reverb, delay, distortion and compressor, for a group of sounds or everything |
|
|
266
265
|
| `drawUtilities.js` | Higher-level drawing helpers like nine-slice and three-slice |
|
|
267
266
|
|
|
@@ -365,7 +364,7 @@ LittleJS has a dedicated [js13k branch](https://github.com/KilledByAPixel/Little
|
|
|
365
364
|
|
|
366
365
|
- **Use Canvas2D instead of WebGL**: call `setGLEnable(false)` before `engineInit`. Stripping the WebGL renderer saves a significant chunk of bytes, and for most pixel-art and low-sprite-count games the visual difference is imperceptible. A nice side effect: once the jam is over, you can flip WebGL back on with a single setting change for a big performance boost when publishing the game elsewhere.
|
|
367
366
|
- **Drop unused plugins**: every plugin is self-contained, so only include what you actually use. Skip `uiSystem.js`, `box2d.js`, `pathFinder.js`, etc. unless you need them.
|
|
368
|
-
- **Lean on built-ins to avoid asset files**: `Sound` with ZzFX parameters generates sound effects from a tiny array,
|
|
367
|
+
- **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.
|
|
369
368
|
- **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.
|
|
370
369
|
|
|
371
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.
|
|
@@ -538,19 +537,15 @@ sound_click.play(pos, volume, pitch); // play a sound
|
|
|
538
537
|
|
|
539
538
|
### How do I play music?
|
|
540
539
|
|
|
541
|
-
|
|
540
|
+
Load an mp3 or ogg file with the regular `Sound` class and play it with `playMusic`, which loops by default.
|
|
542
541
|
|
|
543
542
|
```javascript
|
|
544
|
-
//
|
|
545
|
-
const song = new ZzFXMusic(zzfxmSongData);
|
|
546
|
-
const songInstance = song.playMusic();
|
|
547
|
-
|
|
548
|
-
// or load an mp3/ogg and loop it
|
|
543
|
+
// load an mp3/ogg and loop it
|
|
549
544
|
const track = new Sound('music.mp3');
|
|
550
545
|
const trackInstance = track.playMusic(1, true); // volume, loop
|
|
551
546
|
```
|
|
552
547
|
|
|
553
|
-
|
|
548
|
+
Music pauses automatically when the tab loses focus (audio context suspends) and resumes when it comes back. `playMusic` returns a `SoundInstance`; keep it and call `trackInstance.stop()` to halt playback.
|
|
554
549
|
|
|
555
550
|
### Why doesn't my audio play until the user clicks something?
|
|
556
551
|
|
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ The code is very clean and well documented with many examples to get you started
|
|
|
25
25
|
|
|
26
26
|
<div align='center' markdown='1'>
|
|
27
27
|
|
|
28
|
-
## [Demos](https://killedbyapixel.github.io/LittleJS/examples) | [Arcade](https://killedbyapixel.github.io/LittleJSArcade) | [Docs](https://killedbyapixel.github.io/LittleJS/docs) | [FAQ](https://github.com/KilledByAPixel/LittleJS/blob/main/FAQ.md) | [Trailer](https://youtu.be/chuBzGjv7Ms) | [Discord](https://discord.gg/zb7hcGkyZe) | [AI](https://github.com/KilledByAPixel/LittleJS-AI)
|
|
28
|
+
## [Demos](https://killedbyapixel.github.io/LittleJS/examples) | [Arcade](https://killedbyapixel.github.io/LittleJSArcade) | [Docs](https://killedbyapixel.github.io/LittleJS/docs) | [Reference](https://github.com/KilledByAPixel/LittleJS/blob/main/REFERENCE.md) | [FAQ](https://github.com/KilledByAPixel/LittleJS/blob/main/FAQ.md) | [Trailer](https://youtu.be/chuBzGjv7Ms) | [Discord](https://discord.gg/zb7hcGkyZe) | [AI](https://github.com/KilledByAPixel/LittleJS-AI)
|
|
29
29
|
|
|
30
30
|
</div>
|
|
31
31
|
|
|
@@ -140,9 +140,10 @@ engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost);
|
|
|
140
140
|
- [Making Awesome Games With LittleJS](https://youtu.be/_dXKU0WgAj8) - A short talk about LittleJS with some tips on how to use it
|
|
141
141
|
- [Tutorial: Breakout](https://github.com/KilledByAPixel/LittleJS/tree/main/examples/breakoutTutorial) - Learn how to make a simple game from scratch
|
|
142
142
|
- [Tutorial: Make a ski game](https://eoinmcgrath.com/little-ski/tutorial.html) - A tutorial by eoinmcg that shows how to make a pixel art style game
|
|
143
|
-
- [LittleJS Quick Reference Sheet](https://github.com/KilledByAPixel/LittleJS/blob/main/REFERENCE.md) -
|
|
143
|
+
- [LittleJS Quick Reference Sheet](https://github.com/KilledByAPixel/LittleJS/blob/main/REFERENCE.md) - The whole API in one file, made to be read by people and by AI coding tools
|
|
144
144
|
- [Making Your Own Level Editor](https://github.com/KilledByAPixel/LittleJS/blob/main/EDITOR.md) - How to turn the built in 2D and 3D level editors into an editor for your own game
|
|
145
145
|
- [LittleJS FAQ](https://github.com/KilledByAPixel/LittleJS/blob/main/FAQ.md) - Answers to common questions about LittleJS
|
|
146
|
+
- [Changelog](https://github.com/KilledByAPixel/LittleJS/blob/main/CHANGELOG.md) - What changed in each release
|
|
146
147
|
- [JS13k Branch](https://github.com/KilledByAPixel/LittleJS/tree/js13k) - A special branch for size coding events that builds to a 7KB zip
|
|
147
148
|
|
|
148
149
|
## Examples
|
package/REFERENCE.md
CHANGED
|
@@ -403,7 +403,6 @@ glDraw(x, y, sizeX, sizeY, angle=0, uv0X, uv0Y, uv1X, uv1Y, rgba=-1, rgbaAdditiv
|
|
|
403
403
|
- Ability to play mp3, ogg, and wave files
|
|
404
404
|
- Route sounds or everything through effects with the audio effects plugin
|
|
405
405
|
- [ZzFX Sound Effect Generator](https://killedbyapixel.github.io/ZzFX)
|
|
406
|
-
- [ZzFXM Music System](https://keithclark.github.io/ZzFXM)
|
|
407
406
|
|
|
408
407
|
```javascript
|
|
409
408
|
// Sound Object
|
|
@@ -435,10 +434,6 @@ SoundInstance.getDuration() // Length of the sound, the same at any rate;
|
|
|
435
434
|
SoundInstance.getSource() // Get AudioBufferSourceNode
|
|
436
435
|
SoundInstance.onendedCallback // Called when it plays to its end, not on stop or pause; set it any time
|
|
437
436
|
|
|
438
|
-
// ZzFXM - Tiny music playing system
|
|
439
|
-
ZzFXMusic(zzfxMusic) // Create a zzfx music object
|
|
440
|
-
ZzFXMusic.playMusic(volume=1, loop=true, paused=false) // Play the music, it is a Sound so play and playLoop work too
|
|
441
|
-
|
|
442
437
|
// Audio functions
|
|
443
438
|
speak(text, volume=1, rate=1, pitch=1, language='') // Speak text line
|
|
444
439
|
speakStop() // Stop all queued speech
|
|
@@ -725,7 +720,14 @@ tileLayersLoad(tileMapData, tileInfo=tile(), renderOrder=0, collisionLayer, draw
|
|
|
725
720
|
// of the layer that gets collision, no tile when no image is loaded
|
|
726
721
|
// Load tile layers from exported data, Tiled flips and turns included;
|
|
727
722
|
// groups are flattened and layer indices count that flat list,
|
|
728
|
-
// hidden layers load with collision but are not drawn
|
|
723
|
+
// hidden layers load with collision but are not drawn; a
|
|
724
|
+
// tileset in the map with a margin or spacing is read where
|
|
725
|
+
// its tiles are
|
|
726
|
+
tileLayersFromLDtk(ldtk, level=0) // A Tiled map of an LDtk level, by index or identifier, to give
|
|
727
|
+
// 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
|
|
730
|
+
// objects with their fields as properties
|
|
729
731
|
objectLayersAddType(name, make, defaults={}, tileInfo) // Name a type of object in a Tiled map: a class made
|
|
730
732
|
// with new make(pos), or an arrow function called make(pos),
|
|
731
733
|
// defaults set on what it made; tileInfo is an editor icon
|
|
@@ -1263,8 +1265,9 @@ render3D.screenToRay(screenPos, canvasSize) // Ray3D under a screen point, alwa
|
|
|
1263
1265
|
// date for it, so worldToScreen keeps agreeing with them
|
|
1264
1266
|
render3D.screenToGround(screenPos, groundHeight=0, canvasSize) // where that ray meets a flat ground plane, or
|
|
1265
1267
|
// undefined; terrain has HeightMap.raycast
|
|
1266
|
-
render3D.pick(screenPos or ray, objects) // {object, distance} of the nearest object hit,
|
|
1267
|
-
//
|
|
1268
|
+
render3D.pick(screenPos or ray, objects) // {object, distance} of the nearest object hit, on its mesh's
|
|
1269
|
+
// triangles, the faces that show, both sides when doubleSided,
|
|
1270
|
+
// or a sprite's quad; a screen position goes through screenToRay
|
|
1268
1271
|
render3D.soundDefaultRange = 100 // how far a sound with no range of its own is heard in 3D, the 2D
|
|
1269
1272
|
// soundDefaultRange is 40; a Sound made with a range keeps it
|
|
1270
1273
|
render3D.playSound(sound, pos3D, volume, pitch, randomnessScale, loop, paused) // like sound.play(pos): quieter with
|
|
@@ -1744,14 +1747,22 @@ new LensFlare3D(size=1, count=7, intensity=1, saturation=1, color) // the sun's
|
|
|
1744
1747
|
// screen; it fades as the sun leaves the screen or goes behind something
|
|
1745
1748
|
flare.flareSize = 1.5 // scales every part; count is how many ghosts, intensity how bright, saturation
|
|
1746
1749
|
// how colorful, 0 all its own color; seed picks another arrangement
|
|
1747
|
-
flare.
|
|
1748
|
-
//
|
|
1749
|
-
|
|
1750
|
+
flare.shapes = ['hex', 'streak'] // what the ghosts are picked from: glow, disc, ring, hex, streak or star; glowSize
|
|
1751
|
+
// scales the glow at the sun, 0 for none, and ghostSize the ghosts
|
|
1752
|
+
flare.elements = [{at: .5, size: .1, color: hsl(.6,1,.6,.3), shape: 'disc'}] // or parts of your own, each a
|
|
1753
|
+
// LensFlareElement: at 0 the sun, 1 the middle, 2 as far past it; size a part of
|
|
1754
|
+
// the screen's height, or a vec2 for a wide one; shape one of the six, or
|
|
1755
|
+
// tileInfo for a tile of your own; angle turns it
|
|
1750
1756
|
flare.visible // how much of the sun shows, 0 to 1, eased over fadeTime, to read; what is not
|
|
1751
1757
|
// see through hides it, flare.occlusion = false turns that off
|
|
1752
|
-
|
|
1753
|
-
// smaller from farther than its radius, hidden by what is
|
|
1754
|
-
// spotlight's
|
|
1758
|
+
light.addFlare(size, count, intensity, saturation) // gives a Light3D a flare of its own and returns it: at the
|
|
1759
|
+
// light, in its color, smaller from farther than its radius, hidden by what is
|
|
1760
|
+
// in front of it, a spotlight's only from inside its beam
|
|
1761
|
+
light.flare // the light's LensFlare3D, its child, or undefined; set one of your own, and
|
|
1762
|
+
// destroy it to take it away; it goes with the light; a level's Light has a
|
|
1763
|
+
// lensFlare property
|
|
1764
|
+
flare.light = lamp // the same by hand, a flare made on its own and pointed at a light; it goes when
|
|
1765
|
+
// the light does; a DirectionalLight3D's flare is far away, where it shines from
|
|
1755
1766
|
// Trails - a ribbon through where the object has been, parent it to something that moves
|
|
1756
1767
|
new Trail3D(pos3D, lifeTime, width, tileInfo, color, colorEnd, additive) // thins and fades from head to tail over
|
|
1757
1768
|
// lifeTime seconds; Infinity keeps every
|
|
@@ -1856,7 +1867,8 @@ level3DVoxelSetup(tileInfo, (map)=> {}) // The sheet a level's block m
|
|
|
1856
1867
|
"sunDirection": [0.5, 1, 0.3], "sunColor": "#ffffff",
|
|
1857
1868
|
"fog": [25, 70], "fogColor": "#d6ecff", // start and end, an end of 0 for none; the horizon color
|
|
1858
1869
|
// when the level has a sky and no fogColor
|
|
1859
|
-
"shadows": true
|
|
1870
|
+
"shadows": true,
|
|
1871
|
+
"lensFlare": true}, // the sun's lens flare, a LensFlare3D made for it
|
|
1860
1872
|
"objects": []}
|
|
1861
1873
|
|
|
1862
1874
|
// A level can hold a map of blocks, made a VoxelMap when it loads: its corner, its size in cells, and its blocks
|
|
@@ -1893,14 +1905,15 @@ prefab.originOffset // from the prefab's origin to
|
|
|
1893
1905
|
// Built-in types and their properties
|
|
1894
1906
|
Box, Sphere, Cylinder // color, tile (-1 for none), solid (true); 1 unit across, the scale is the size
|
|
1895
1907
|
Light // color, radius (5), intensity (1); cone (0), degrees from its forward to the edge of
|
|
1896
|
-
// its beam, makes it a spotlight aimed by its rotation, softness (.2), shadows (false)
|
|
1908
|
+
// its beam, makes it a spotlight aimed by its rotation, softness (.2), shadows (false);
|
|
1909
|
+
// lensFlare (false) gives it a lens flare
|
|
1897
1910
|
```
|
|
1898
1911
|
|
|
1899
1912
|
### 3D level editor
|
|
1900
1913
|
Debug builds only. `0` on the debug overlay opens it for a level loaded with `level3DLoad`, the game pauses under it.
|
|
1901
1914
|
To make it your own game's editor, with your own types, keys and panel buttons, see [EDITOR.md](EDITOR.md).
|
|
1902
1915
|
The panel's Scene box edits the level's scene block: "Level sets the scene" starts one from what is on screen, and
|
|
1903
|
-
off leaves the sky, sun, fog and
|
|
1916
|
+
off leaves the sky, sun, fog, shadows and lens flare to the game.
|
|
1904
1917
|
|
|
1905
1918
|
```javascript
|
|
1906
1919
|
// Tools, the keys Unity, Unreal and Godot use
|