Releases: kaplayjs/kaplay
4000.0.0-alpha.25
[4000.0.0-alpha.25] - 2025-12-23
Added
- Added the
fakeMouseMoveevent inFakeMouseComp, it will triggers when you move the object - @lajbel - Global
retrieve()method to get the objects with area within a certain rectangle - @mflerackers
Changed
- Transforms are now only recalculated when needed. Thus static objects no longer increase computation in the transform phase - @mflerackers
- Areas are now only recalculated when the area settings or (optional) renderArea has changed - @mflerackers
- World (transformed) areas are now only recalculated when the area or transform has changed - @mflerackers
- World bounding boxes are now only recalculated when the world area has changed - @mflerackers
- Broad stage collision detection spatial structures are now only updated when an object's world bounding box has changed - @mflerackers
- You can no longer change the position of an object by doing obj.pos.x += 1. You need to assign a new Vec2 or use moveBy instead - @mflerackers
- The grid broadphase has been rewritten for performance - @mflerackers
Full Changelog: 4000.0.0-alpha.24...4000.0.0-alpha.25
4000.0.0-alpha.24
[4000.0.0-alpha.24] - 2025-12-12
Added
- Added the
maxTimeStepandfixedUpdateModeoptions, as well as
setFixedSpeed()for more granular control over fixed update and timing -
@dragoncoder047 - Added parameterized formatting tags like
"[color=red]Red text![/color]"in
CharTransformFuncfor more powerful text formatting options -
@dragoncoder047 - Added
createRegularPolygon()andcreateStarPolygon()to create 2D regular
polytopes - @mflerackers - Added
createCogPolygon()to create 2D regular cogs - @mflerackers - Added
getSpriteOutline()that takes a sprite asset and returns a polygon
showing the outline - @milosilo-dev - Added Quadtree for collision detection (only for fixed size screen for now,
needs expansion) - @mflerackers - Added vertical sweep and prune - @mflerackers
- Added configuration to choose broad phase algorithm - @mflerackers
Fixed
- Fixed the
fakeMouse()component not giving the right position when the
camera transform was not the identity matrix - @dragoncoder047 - Fixed tall fonts being cropped - @anthonygood
- Fixed the sprite animation
onEnd()callback being called before the
animation actually stopped, so if the onEnd callback started a new animation,
the new animation was instantly stopped - @dragoncoder047 - Now
playMusic()actually uses the requested volume and playback rate given
in the options - @dragoncoder047
4000.0.0-alpha.23
[4000.0.0-alpha.23] - 2025-11-05
Added
-
Added
getGamepadAnalogButton()to read the analog value of buttons like the
triggers - @dragoncoder047isGamepadButtonDown("rtrigger"); // -> true/false, 0/1 getGamepadAnalogButton("rtrigger"); // -> analog value between 0 (not pressed) and 1 (fully pressed)
-
Added chorded button bindings using the Buttons API, so you can bind different
actions totabandshift+tab, and handle them like normal. Also works with
gamepads and mouse! - @dragoncoder047kaplay({ buttons: { forward: { keyboard: "tab", gamepad: "south", }, backward: { keyboard: "shift+tab", gamepad: "rshoulder+south", }, }, });
-
Added
skewto text formatting, so now italics is possible - @dragoncoder047 -
Added lifetime scopes, a way to define the lifetime of an event handler
using a specific scope,scene,appor a game object - @lajbel,
@dragoncoder047app.onUpdate(() => { // runs until it is cancelled }); scene("game", () => { const obj = add([]); obj.onUpdate(() => { // runs until obj is destroyed }); scene.onUpdate(() => { // or just onUpdate(() => { // runs until scene is changed }); });
All the available handlers in the scopes are
GameEventHandlersones:onKeyDown()onKeyPress()onKeyPressRepeat()onKeyRelease()onCharInput()onMouseDown()onMousePress()onMouseRelease()onMouseMove()onScroll()onTouchStart()onTouchMove()onTouchEnd()onGamepadConnect()onGamepadDisconnect()onGamepadButtonDown()onGamepadButtonPress()onGamepadButtonRelease()onGamepadStick()onButtonDown()onButtonPress()onButtonRelease()onTabHide()onTabShow()
And this game object handlers may differ when using it with
objand
scene/app:onFixedUpdate()onUpdate()onDraw()
-
Added
appscope for app event handlers - @lajbelapp.onUpdate(() => { // runs until it is cancelled });
-
Added
KAPLAYOpt.defaultLifetimeScopefor setting the default lifetime scope
used for event handlers - @lajbelkaplay({ defaultLifetimeScope: "app", // default is "scene" }); onKeyPress("space", () => { // runs until is cancelled });
-
Added
skewto text formatting, so now italics is possible - @dragoncoder047
Changed
-
(!) Renamed
onShow()toonTabShow()andonHide()toonTabHide()-
@lajbel -
In addition to being the
scene()function, nowsceneis also a scope for
scene event handlers - @lajbelscene("game", () => { scene.onUpdate(() => { // or just onUpdate(() => { // runs until scene is changed }); });
Fixed
- Now
pushScene()andpopScene()give the arguments to the scene in the same
way thatgo()does rather than passing them all to the first argument as an
array - @dragoncoder047 - Fixed a flicker due to the fadeIn not setting opacity until the next frame -
@mflerackers - Fixed FPS cap not working correctly - @mflerackers, @dragoncoder047
Full Changelog: 4000.0.0-alpha.22...4000.0.0-alpha.23
4000.0.0-alpha.22
[4000.0.0-alpha.22] - 2025-10-9
Added
-
Added
KAPLAYOpt.types,kaplayTypes()andOptto config specific
TypeScript Advanced Features (TAF) - @lajbelkaplay({ types: kaplayTypes< // Opt<> is optional but recommended to get autocomplete Opt<{ scenes: {}; // define scenes and arguments strictScenes: true; // you can only use defined scenes }> >(), });
-
Added
TypesOpt.scenesto type scenes and parameters - @lajbelconst k = kaplay({ types: kaplayTypes< Opt<{ scenes: { game: [gamemode: "normal" | "hard"]; gameOver: [score: number, highScore: number]; }; }> >(), }); // If you trigger autocomplete it shows "game" or "gameOver" k.scene("game", (gamemode) => { // gamemode is now type "normal" | "hard" // @ts-expect-error Argument of type 'string' is not assignable // to parameter of type 'number'. k.go("gameOver", "10", 10); // });
The methods that support this are:
scenegoonSceneLeavegetSceneName
-
Added
TypesOpt.strictScenesto make usable scenes just the ones defined -
@lajbelconst k = kaplay({ types: kaplayTypes< Opt<{ scenes: { game: [gamemode: "normal" | "hard"]; gameOver: [score: number, highScore: number]; }; strictScenes: true; }> >(), }); // @ts-expect-error Argument of type '"hi"' is not assignable to // parameter of type '"game" | "gameOver"'. k.scene("hi", () => {});
-
Added named animations - @mflerackers
By giving a name to an animation, you can define more than one animation
const anim = obj.animation.get("idle"); anim.animate("pos", [0, 5, 0], { relative: true });
-
Added
screenshotToBlob()to get a screenshot as aBlob- @dragoncoder047 -
Added
getButtons()to get the input binding buttons definition - @lajbel -
Added
RuleSystem,DecisionTreeandStateMachinefor enemy AI -
@mflerackers -
Added constraint components for distance, translation, rotation, scale and
transform constraints - @mflerackers -
Added inverse kinematics constraint components using FABRIK and CCD, the
latter one can use bone constraints to constrain the angle - @mflerackers -
Added skew to Mat23, transformation stack, RenderProps, GameObjRaw as well as
a component - @mflerackers -
Added texture uniforms, in order to access more than one texture at a time in
shaders - @mflerackers
Fixed
- Now error screen should be instantly shown - @lajbel
Changed
- Now, you can use
color(c)with a hexadecimal literal number (ex: 0x00ff00) -
@lajbel// blue frog add([ sprite("bean"), color(0x0000ff), ]);
- (!)
KAPLAYCtxdoesn't use generics anymore. Now,KAPLAYCtxTuses
them - @lajbel - Now,
kaplaywill returnKAPLAYCtxorKAPLAYCtxTdepending if it's using
Advanced TypeScript Features or not - @lajbel loadShader()now also checks for link errors as well as compile errors and
reports them rather than just silently trying to use a borked shader -
@dragoncoder047- The debug
record()function now records with sound enabled like it should -
@dragoncoder047 - Now
KAPLAYOpt.spriteAtlasPaddingis set to2by default - @lajbel - Transformation and drawing is split now, so the transform can be modified
before drawing - @mflerackers
Full Changelog: 4000.0.0-alpha.21...4000.0.0-alpha.22
4000.0.0-alpha.21
[4000.0.0-alpha.21] - 2025-08-07
Added
- Added Prefabs - @mflerackers, @lajbel, @amyspark-ng and other contributors.
- Added new scene methods
pushScene()andpopScene(), for stack behaviour in
scenes - @itzKiwiSky - Added
throwError()for throwing custom errors to the blue screen, even
errors KAPLAY can't handle. - @lajbel - Added
insertionSort()- @dragoncoder047 - Added a mapping for PS5 (DualSense) gamepads, so now you can bind actions to
the touchpad press (only works in Chrome for some reason) - @dragoncoder047
Changed
- Renamed
KAPLAYOpt.tagsAsComponentstoKAPLAYOpt.tagComponentIds- @lajbel - Now moving mouse changes the value of
getLastInputDevice()- @amyspark-ng - Now
GameObjRaw.exists()work for nested objects
Fixed
- Fixed shader error messages - @dragoncoder047
New Contributors
- @FowluhhDev made their first contribution in #839
- @itzKiwiSky made their first contribution in #842
- @bobrosoft made their first contribution in #862
Full Changelog: 4000.0.0-alpha.20...4000.0.0-alpha.21
4000.0.0-alpha.20
[4000.0.0-alpha.20] - 2025-06-15
Added
- Now you can use the frames of a sprite in an atlas also as a font -
@dragoncoder047 - Improved various doc entries. - All Contributors.
Fixed
- Fixed
AreaComp#onClick()attaching events to app, instead of object, so
event wasn't being paused withobj.paused- @lajbel - Fixed all touch events having a bad transform - @lajbel
- Fixed sprite scaling not working properly when letterbox - @mflerackers
- Fixed "add" event running twice in
addLevel()tiles - @lajbel - Fixed blend component having a wrong ID - @lajbel
Removed
loadPeditwas removed - @lajbel
Full Changelog: 4000.0.0-alpha.19...4000.0.0-alpha.20
3001.0.19
4000.0.0-alpha.19
What's Changed
- fix: blocks and binarydata by @lajbel in #732
- fix: PatrolComp is not going to last waypoint by @nojaf in #735
- Layers, transform update, stack functions, arc points, step and smoothstep by @mflerackers in #736
- fix: transformation order by @mflerackers in #741
- fix: Fixes fixed by @mflerackers in #745
- chore: add category in examples by @lajbel in #746
- doc: Basic examples by @lajbel in #749
- Caches local area instead of creating a new one each frame by @mflerackers in #754
- feat:
Vec2.setby @lajbel in #751 - test: Adds small hover playtest by @amyspark-ng in #737
- feat:
GameObjRawas a prototype, and others by @lajbel in #743 - Fixes some performance issues with area and shape by @mflerackers in #756
- docs: Mention relativity with parent for pos component. by @nojaf in #755
- feat: lerp example by @amyspark-ng in #757
- examples: fixed some grammar on lerp.js by @amyspark-ng in #758
- Added line bias by @mflerackers in #760
- feat: allow do kaplay(), quit(), and kaplay() again (REFACTOR PART 3) by @lajbel in #762
- feat: add
timeLeftproperty to wait, loop and tween by @amyspark-ng in #705 - Add SAT as option by @mflerackers in #766
- Resurrected Minkowski box collision by @mflerackers in #767
- refactor: separate context creation in core/context PART 4 by @lajbel in #768
- examples: fix misuse of dino sprites as tga and dungeon-dino by @imaginarny in #769
- examples: add kaplay logo animation example by @imaginarny in #770
- Feat: HealthComp changes by @amyspark-ng in #765
- chore: Help Menu by @niceEli in #771
- fix: hp vs. hp() after #765 by @dragoncoder047 in #772
- feat: Typed StateComp by @amyspark-ng in #740
- refactor: REFACTOR PART 5 by @lajbel in #774
- fix: TexPacker.add wasn't returning in add_single, add_single -> addSingle by @lajbel in #777
- fix: update wasn't making effect at all and pause events even if created after .paused = true by @lajbel in #776
New Contributors
Full Changelog: 4000.0.0-alpha.18...4000.0.0-alpha.19
3001.0.18
[3001.0.18] - 2025-05-16
Fixed
- Removed beant - @lajbel
- Fixed TexPacker loading big images - @lajbel, @mflerackers
- Various fixes and improvements - All Contributors
Full Changelog: 3001.0.17...3001.0.18