The theme of this release is developer experience and performance. We've removed a lot of paper cuts in the api with quick and easy ways to do what you want.
- Actors can now have a default graphic and/or material set in their constructor!
- Debug Draw has had a huge improvement, both in performance, and visual fidelity through the browser extension!
- Offscreen, Tilemaps, Realistic Collisions, and more all got big performance increases
- Realistic Physics Bodies now sleep consistently giving a huge perf boost to physics games
- Easing functions are now the good ol' 0 -> 1 style you see all over the internet, BYOF easily!
Did you know we have a playground now?
recording_20251223_091245.mp4
https://excaliburjs.com/playground
Breaking Changes
- Behavior change: Realistic physics bodies can now sleep by default
canSleepByDefault - Behavior change: The
sleepBiasdefault is lowered to 0.5 from .9 - Behavior change: Bodies do not sleep until all bodies in an Island are low motion for at least
sleepTimeThreshold, default 1000ms - Debug: Improve body related information output in the debug draw
recording_20251222_211543.mp4
Deprecated
- Legacy
EasingFunctions.*are deprecated in favor of the simpler forms - Legacy
ex.BoundingBox.draw(..)is deprecated, useex.BoundBox.debug(...)
Added
-
Added new contact
ex.Islandphysics optimization, excalibur physics bodies will now wake or sleep the entire connected graph of bodies,
this only works in the Realistic solver, but it's a huge perf win. -
Added new
ex.angleDifference(angle1, angle2)for calculating differences between angles in [0, 2Pi) -
Added new debug stats to the frame to measure ECS system durations in milliseconds
const stats: Record<string, number> = engine.stats.currFrame.systemDuration; // "update:CollisionSystem.update" -> .50
-
Added new parameter to
ex.Soundsto schedule start time, this allows you to synchronize playback of multiple audio tracksconst start500MsFromNow = AudioContextFactory.currentTime() + 500; Resources.MusicSurface.play({ volume: .5, scheduledStartTime: start500MsFromNow }); // Start layered tracks at 0 volume so they are synchronized Resources.MusicIndDrums.play({ volume: 0, scheduledStartTime: start500MsFromNow }); Resources.MusicIndTopper.play({ volume: 0, scheduledStartTime: start500MsFromNow }); Resources.MusicGroovyDrums.play({ volume: 0, scheduledStartTime: start500MsFromNow }); Resources.MusicGroovyTopper.play({ volume: 0, scheduledStartTime: start500MsFromNow });
-
Added new Timer events!
const timer = new ex.Timer({...}); timer.events.on('complete', () => {...}); // after the last repeat timer.events.on('action', () => {...}); // every fire of the timer timer.events.on('start', () => {...}); // after the timer is started timer.events.on('stop', () => {...}); // after the timer is stopped timer.events.on('pause', () => {...}); // after every pause timer.events.on('resume', () => {...}); // after every resume timer.events.on('cancel', () => {...}); // after cancel // or specify the onComplete in the constructor const timer2 = new ex.Timer({ onComplete: () => {...}, ... });
-
Added a way to configure general debug settings on text
class DebugConfig { ... public settings = { text: { foreground: Color.Black, background: Color.Transparent, border: Color.Transparent }, z: { text: Number.POSITIVE_INFINITY, point: Number.MAX_SAFE_INTEGER - 1, ray: Number.MAX_SAFE_INTEGER - 1, dashed:Number.MAX_SAFE_INTEGER - 2, solid: Number.MAX_SAFE_INTEGER - 3 } } ... }
-
Added foreground and background color to
ex.DebugText -
Added a convenience parameter to set the initial graphics or material in an Actor
const cloudSprite = cloud.toSprite(); const swirlMaterial = game.graphicsContext.createMaterial({ name: 'swirl', fragmentSource }); const actor = new ex.Actor({ graphic: cloudSprite, material: swirlMaterial });
-
Simpler easing functions of the form
(currentTime: number) => numberinstead of the 4 parameter legacy ones -
Support for disabling integration for all offscreen entities, or on a per entity basis
// for all entities const game = new ex.Engine({ physics: { integration: { // defaults to false onScreenOnly: true }, }); // per entity (only if engine is off) const actor = new ex.Actor(...); actor.get(MotionComponent).integration.onScreenOnly = true;
-
DX: Support for Visual Studio Code Dev Containers for an out-of-the-box contribution dev environment
-
DX: Support for Vitest UI for browser testing
-
[feat] Adding hasChild() to Entity's by @jyoung4242 in #3550
-
[feat] Color.Lerp by @jyoung4242 in #3534
Fixed
- perf: Fix pointer perf on tilemaps by @eonarheim in #3539
- Fixed possible perf issue in
canonicalizeAngleif a large angle was provided it could take a long time - Fixed issue where physics bodies did not sleep under certain situations, especially when gravity was high.
- Fixed issue where Animation fromSpriteSheet was ignoring repeated sprite sheet indices
- Fixed issue where setting the width/height of a ScreenElement was incorrectly scaled when supplied with a scale in the ctor
- Fixed issue where onRemove would sometimes not be called
- Fixed issue where pointer containment WAS NOT being uses on collision shape geometry, only their bounds
- Fixed issue where overriding built in uniforms and graphics no longer worked as v0.30.x
- Fixed issue where clearSchedule during a scheduled callback could cause a cb to be skipped
- Fixed issue where specifying custom events was difficult in TypeScript switched from
export type ...Events {toexport interface ...Events {which allows declaration merging by user game code to specify custom events - Fixed issue where the Loader could run twice even if already loaded when included in the scene loader.
- Fixed issue where pixel ratio was accidentally doubled during load if the loader was included in the scene loader.
- Fixed issue where Slide trasition did not work properly when DisplayMode was FitScreenAndFill
- Fixed issue where not(tags) and not(component) queries weren't updating in the querymanager
- Fixed Tilemap/Isometric map pointer performance on moderate to large maps, we changed the strategy to only consider tiles under the pointer instead of try to do sorted dispatch on NxM tiles.
- Fixed issue that caused coroutines to not automatically discover the engine scheduler when inside an async lifecycle sometimes. This is because of the stack replacement issue of async/await the context reverts too soon.
- Fixed issue actor kill event was triggered twice
Updates
- Perf improvement in debug draw mode
- When overriding a built-in uniform/graphic there is now a warning in dev excalibur builds
- Camera zoom and move now support new easing functions form
- MoveTo/MoveBy actions now support new easing function form
- Transitions now support new easing functions form
- Deps: Upgraded to Playwright 1.55.1
- Tests: Split test suite into
unitandvisualtests
Changed
- Debug Text Font is switched to the more legible monogram
What's Changed
Details
- feat: Add Dev Container support by @kamranayub in #3507
- chore: Update babel monorepo by @renovate[bot] in #3526
- chore: Update dependency @types/react to v18.3.25 by @renovate[bot] in #3529
- chore: Update dependency @mdx-js/react to v3.1.1 by @renovate[bot] in #3527
- chore: Update dependency concurrently to v9.2.1 by @renovate[bot] in #3530
- Site particle docs by @chrisk-7777 in #3531
- [DOCS] Adding Tint docs by @jyoung4242 in #3535
- [feat] Color.Lerp by @jyoung4242 in #3534
- Update 04.7-tint.mdx by @jyoung4242 in #3537
- perf: Fix pointer perf on tilemaps by @eonarheim in #3539
- chore: Update dependency vite to v6.4.1 [SECURITY] by @renovate[bot] in #3542
- fix: ECS Queries incorrect when using not conditions by @eonarheim in #3540
- fix: Slide transition on FitScreenAndFill by @eonarheim in #3544
- feat: Simpler easing function by @eonarheim in #3532
- [feat] Adding hasChild() to Entity's by @jyoung4242 in #3550
- chore(deps): bump ws in /site by @dependabot[bot] in #3543
- chore(deps-dev): bump tar-fs from 3.1.0 to 3.1.1 by @dependabot[bot] in #3521
- fix: [#3524] Loader runs twice if included in scene and default by @eonarheim in #3551
- feat: added Color.random() by @jyoung4242 in #3552
- chore: Update babel monorepo to v7.28.5 by @renovate[bot] in #3553
- chore: Update dependency @types/react to v18.3.26 by @renovate[bot] in #3554
- chore: Update dependency patch-package to v8.0.1 by @renovate[bot] in #3555
- chore: Update dependency remark-emoji to v5.0.2 by @renovate[bot] in #3556
- chore: Update dependency ts-loader to v9.5.4 by @renovate[bot] in #3557
- chore: Update dependency vite-plugin-static-copy to v3.1.4 by @renovate[bot] in #3558
- chore: Update actions/github-script action to v7.1.0 by @renovate[bot] in #3559
- chore: Update dependency excalibur-jasmine to v0.4.1 by @renovate[bot] in #3560
- chore: Update dependency globals to v16.5.0 by @renovate[bot] in #3561
- chore: Update dependency jasmine to v5.12.0 by @renovate[bot] in #3562
- chore: Update dependency jasmine-core to v5.12.1 by @renovate[bot] in #3563
- chore: Update dependency mermaid to v11.12.1 by @renovate[bot] in #3564
- chore: Update dependency playwright to v1.56.1 by @renovate[bot] in #3565
- chore: Update dependency puppeteer to v24.27.0 by @renovate[bot] in #3566
- chore(deps): update to node 24 lts by @kamranayub in #3567
- docs: update playground links to use embed variant by @chrisk-7777 in #3572
- fix: [#3578] clearSchedule during a scheduled callback would skip the next cb by @eonarheim in #3579
- fix: Allow materials to override u_graphic by @eonarheim in #3580
- feat: Add convenience
graphicandmaterialto Actor ctor by @eonarheim in #3581 - fix: Switch to
interfaces instead oftypes for Events by @eonarheim in #3582 - docs: adds type checking to all samples by @chrisk-7777 in #3568
- docs: Sprite fusion update by @jyoung4242 in #3587
- blog: New blog article on using SF tile attributes by @jyoung4242 in #3588
- feat!: debug draw improvements by @eonarheim in #3585
- fix: [#3592] Check pointer containment on colliders by @eonarheim in #3594
- Fixed Actor kill event was triggered twice by @Jerry457 in #3593
- Fix spelling of 'Fusion' in blog attributes by @jyoung4242 in #3595
- fix: [#3570] onRemove sometimes not called by @eonarheim in #3597
- feat: Mobile play button by @eonarheim in #3591
- chore(deps): bump node-forge from 1.3.1 to 1.3.2 in /site by @dependabot[bot] in #3590
- chore(deps): bump js-yaml in /site by @dependabot[bot] in #3583
- chore: Update dependency @eslint/eslintrc to v3.3.3 by @renovate[bot] in #3600
- chore: Update dependency @types/jasmine to v5.1.13 by @renovate[bot] in #3601
- chore: Update dependency @types/react to v18.3.27 by @renovate[bot] in #3602
- chore: Update dependency @types/node to v22.19.1 by @renovate[bot] in #3603
- chore: Update dependency playwright to v1.57.0 by @renovate[bot] in #3604
- chore: Update dependency prettier to v3.7.3 by @renovate[bot] in #3605
- chore: Update dependency puppeteer to v24.31.0 by @renovate[bot] in #3606
- chore: Update dependency webpack to v5.103.0 by @renovate[bot] in #3609
- fix(tests): compatibility with VS Code Vitest extension by @kamranayub in #3612
- fix: [#3599] ScreenElement scale by @eonarheim in #3615
- [feat] Add methods to retrieve parsed sprite and image by @jyoung4242 in #3614
- feat: [#3596] Add Timer events support by @eonarheim in #3616
- Docs migrate playground by @chrisk-7777 in #3598
- docs: add deferred mount to playground embed by @chrisk-7777 in #3618
- docs: Add text quality information by @eonarheim in #3620
- fix: flip lookup in fromSpriteSheet to resolve repeated sprite sheet indices being ignored by @chrisk-7777 in #3625
- docs: add share tooltip indicator for visual feedback by @chrisk-7777 in #3624
- feat: Add better debug settings by @eonarheim in #3622
- chore: Update dependency storybook to v9.1.17 [SECURITY] by @renovate[bot] in #3626
- docs: updated code examples for flappy bird tutorial by @scottwestover in #3628
- feat: new release script by @eonarheim in #3629
- feat: Sound scheduled start by @eonarheim in #3545
- chore(deps): bump express from 4.21.2 to 4.22.1 in /site by @dependabot[bot] in #3610
- chore(deps): bump mdast-util-to-hast from 13.0.2 to 13.2.1 in /site by @dependabot[bot] in #3611
- fix: Realistic body sleeping by @eonarheim in #3589
Special Thanks
- @mattjennings & @kamranayub for Vite + Dev Container Support!
- @jyoung4242 For adding a ton of new documentation for Colors!
- @jyoung4242 Fixing Erik's many spelling errors
- @jyoung4242 Building out our new SpriteFusion capability!
- @chrisk-7777 Running with the new Excalibur Playground and making it AWESOME, it is now embedded in our documentation!
- @chrisk-7777 Better Particle documentation! Huge!
- @scottwestover For finding a sharp edge in the flappy bird tutorial and fixing it
New Contributors
- @Jerry457 made their first contribution in #3593
- @scottwestover made their first contribution in #3628
Full Changelog: v0.31.0...v0.32.0
