KAPLAY v4000 Alpha 22
lajbel, 10/9/2025, from sponges factory
Hey! lajbel here to introduce you the 4000.0.0-alpha.22 and this new blog format, where we gonna talk about the specific releases in the KAPLAY repository.
To install it, you can use:
npm install kaplay@4000.0.0-alpha.22There’s a new super cool thing called Advanced TypeScript features, a new API that will let you use TypeScript in a more powerful way, getting autocomplete in places where before it has been impossible, until now:

In the other side, we got constraints, a way to restrict the movement of game objects.

A lot of more was added, like improvements in Animation API, new AI methods and new ways to transform objects (with skew). Thanks to all contributors helping with KAPLAY. I’ll leave you with the full changelog.
[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: 
- 
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
 
  
   
  
 