You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
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
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
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
loadSprite, loadTiles and loadAtlas give back what the first load did when the same image is loaded again with the same settings, packed once
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
Fixes
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
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
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
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
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)
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
A light's flare looks past four lamps around it to what is behind them, where the fourth counted as hidden
A click or tap in the bars around a letterboxed canvas presses nothing, where it pressed whatever was at the canvas edge
showConfirmDialog while one is open gives the one open, where a second broke UI navigation in release builds
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
The 3D editor's terrain paint rounds no heights, and a sculpt stroke rounds only those it changed
A UISlider let go in the frame it moves takes that last place
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
UITextInput takes a keydown with no key, as autofill sends, where it threw
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
tileLayersFromLDtk keeps a tile layer with no tiles as an empty layer, so a level of one loads and the editor can paint it
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
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
writeSaveData asserts its data is an object, which readSaveData reads back, and returns whether it was written, false when storage is full or unavailable
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
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
debugShowErrors shows a message as text, so a file name with markup in it can not add elements to the page
Canvas2D tints clamp the color to 0 to 1, as WebGL does
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
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
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
LDtk: an IntGrid layer whose rule tiles are on another tileset keeps its values for collision, its tiles left out with a warning
A collision layer named that no layer has says so in release builds too
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
VoxelMap: the inside of a doubleSided face is split along the same diagonal as its outside, so it shows no seam
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
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
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
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
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
A tween that loops or ping pongs with a duration of 0 or less, possible in release builds, ends its loops
New Demos
Custom Editor - 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