## KilledByAPixel/LittleJS — v1.24.2…v1.25.0

_24 commits._

### Features
- **Review 2026-10-03 pass 8: a failed image gives tiles of no size; sound, sprite and atlas load failures warn in release; Box2dObject keeps its pos; drawRectGradient size default; the release loop logs each new error and keeps its tick rate past one (tick time spent in finally); clicks under pointer lock; a stickless gamepad keeps its d-pad stick; a zzfx Sound with no AudioContext; WebGL creators typed undefined** (e2b4cbe)

### Backend
- **DeepScan: the weld joint import the removed alias test used** (d08cccf)
- **1.25.0: glTF skinned animation with cross-fades and joint matrices, tilt shift and depth of field post effects with postProcess.values and the 3D Focus Blur example, the names deprecated in 1.20 removed, and the review passes' fixes; dist and docs built for the release** (98aa477)
- **Pass 9 cleanups: literal JSDoc bracket defaults stripped and sampleRate's names audioDefaultSampleRate; dead code (ASSERT_VECTOR2_NORMAL, matrix4Identity, the release debugClearCount, two unused locals); release debug flags false; gray, center, canceled, @return; descriptions for the UIObject getters and the glTF and path finder constructors; one mirror wording; REFERENCE on where the draw orders differ and what functions give back, the FAQ on global names; coverage tests for tile collision walls, ledges and ceilings, polygon ear clipping, zzfx shapes and repeatTime, a raycast over two layers, the release loop, the gamepad axis filter and a GLB image by bufferView** (39fac37)
- **Review 2026-10-04 pass 10: shaders that fail to build in release say why, the engine's own falling back to Canvas2D and a game's Shader or post process drawing without it; the post process depth sampler highp, the outline and depth of field guarded where there is no depth and at an infinite far plane, one name check for values and settings with GLSL words; the 3D normal matrix, Fresnel, fog and shininess guards; lineTest from a whole start heading down, a particle's down by its gravityScale, readSaveData objects only; scaling: path smoothing by corners, tween removal without a search, CSG leaves polygons beyond the cutter, a 2D editor paint stroke draws its cells; Box2D adds may return undefined, REFERENCE fades; example fixes across the tutorial, platformer, Box2D, starters and shorts** (d84d16e)
- **Review 2026-10-04 findings 5 and 6: a child whose update throws leaves the engine's child list as it was (try/finally in updateChildObjects); the built in effects name their own locals with an underscore, so a postProcess value named glow, d or r is not hidden by one, and a value may not start with an underscore or be c, uv, p, sceneDepth, mainImage or main; focusBlur checks a value named glow** (f3b01a5)
- **Review 2026-10-04 pass 9, docs: REFERENCE units and directions, copy wording for vector and color methods, parameter names as the code has them; @return on the Box2D shape methods, vector helpers, engineInit and others; types on fields that reached the d.ts as any; DragAndDropCallback above its class; the particle example's labels; redundant @function tags** (8872e9b)
- **Review 2026-10-04 pass 9, code: glTF reads a second set of four joints and keeps each vertex's strongest four; depth of field blurs nothing without depth (iDepthRange 0 then); postProcess value names may start with i; a value changing its length makes the shader again; tiny and non-finite settings; blur at most 32; GLTFObject.destroy frees its skinned meshes; a blended play of the animation playing goes on; no AudioContext in zzfx and the visibility handler; editor tool types generic with a Vector2 default; TiledMap version a string or number, tileLayersLoad's map optional; DeepScan unused imports** (6f6b184)
- **Review 2026-10-04: the post process shader is made at the first render, so values set after the plugin is made are declared, as REFERENCE has it; stop during a cross-fade holds the mix, and a later blended play fades from it; glow's threshold and strength take value names, a number's shader as before; every setting that takes a name typed number|string** (886ff4c)
- **tag** (035345a)
- **AGENTS.md: the focusBlur smoke page** (f4fa411)
- **Tilt shift and depth of field post effects, postProcess.values for live settings (any effect setting may name one), the 3D Focus Blur example focusing with the mouse, tilt shift in Post Effects, and a focusBlur browser smoke page** (cabe2a5)
- **3D Mesh short: buttons and the arrow keys step through a model's animations, cross-faded, with the name shown; the write-up says how** (2ccd1e9)
- **glTF skinning review fixes: a fade started during another fades from the mix (the old state was cleared before it was read); every node's parent comes from the children lists, so joints outside the scene's nodes keep theirs** (17190a0)
- **glTF skinned animation: skins read (four joints a vertex, weights summed to one, flat-normal splits mapped back), bent on the CPU each frame into a dynamicDraw mesh per object from the shared node pose; play takes a blend time to cross-fade from the pose it is in, the animation left going on; getJointMatrix finds a node's world matrix; checked on RiggedSimple, CesiumMan and Fox** (0b3c8ea)
- **Small leftovers: audio resumes through audioResume, a refusal caught; release debug flags are false; Box2dPinJoint's default point documented on the class** (10d5359)
- **TypeScript: TiledMap and Level3D types for the level loaders, records for type defaults and properties, typed tool pos and ray, onPlayFrom, open and close, a zzfx array for Sound, and fetchJSON giving any** (92412a1)
- **Load errors name the file: fetchJSON and loadGLTF say which file failed to read and when it is a web page (a dev server's answer to a mistyped path); loadOBJ warns of a file with no faces** (042e828)
- **Release builds: levelEditor.edit2D is an object that changes nothing, where it was undefined; EDITOR.md says so** (7d66a97)
- **Level editor: a turned or mirrored stamp turns or mirrors its objects: rotation, a box's corner, polygon points, a tile object's flip** (08ac34d)
- **1.24.3: the 2026-10-03 pass 7 and 8 fixes (failed images, load failures warned and retried, Box2dObject pos, release loop input and rate, pointer lock clicks, glTF files in subfolders), a d.ts that keeps undefined; dist built for it** (604750c)
- **d.ts built with strictNullChecks, so undefined stays in accessor and object types, with the redundant | undefined of optional parameters and fields taken off so the rest reads as before; boxCast and boxCastAll documented as bounding box tests** (7f2c146)
- **Review 2026-10-03 pass 7 (series 2): a release build going on past an error clears the frame's input, so a key press whose action threw is not pressed again; a load whose file failed is forgotten, so loading it again tries again** (84f21d8)
- **glTF files in subfolders found from a drop of what is in the model's folder: the longest key the path ends with, a folder deep; a name found alone compared in lower case, where capitals never matched since c51a6089; the 3D Mesh short keeps a dropped folder's name when other files come with it** (f7dad2f)

_Recap by [Repo Wrapped](https://repowrapped.com/gh/KilledByAPixel/LittleJS?utm_source=github-action)._