littlejsengine 1.18.12 → 1.18.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/FAQ.md CHANGED
@@ -4,7 +4,7 @@ Welcome to the LittleJS FAQ!
4
4
  This document addresses common questions and issues to help developers get started and troubleshoot their projects.
5
5
  If you don't find an answer here, feel free to ask the community or check the documentation.
6
6
 
7
- Getting Started
7
+ **Getting Started**
8
8
  - [What is LittleJS, and how is it different from other JavaScript game engines?](#what-is-littlejs-and-how-is-it-different-from-other-javascript-game-engines)
9
9
  - [How do I set up a basic LittleJS project?](#how-do-i-set-up-a-basic-littlejs-project)
10
10
  - [How do I use LittleJS as an ES module?](#how-do-i-use-littlejs-as-an-es-module)
@@ -12,11 +12,14 @@ Getting Started
12
12
  - [Why do I see a blank screen when I run my game?](#why-do-i-see-a-blank-screen-when-i-run-my-game)
13
13
  - [Do I need a local server to run LittleJS games, and how do I set one up?](#do-i-need-a-local-server-to-run-littlejs-games-and-how-do-i-set-one-up)
14
14
  - [How does the camera and world coordinate systems work?](#how-does-the-camera-and-world-coordinate-systems-work)
15
+ - [How do I configure engine settings?](#how-do-i-configure-engine-settings)
16
+ - [What plugins ship with LittleJS?](#what-plugins-ship-with-littlejs)
15
17
  - [How do I use Vite with LittleJS?](#how-do-i-use-vite-with-littlejs)
16
18
  - [How do I use Box2D with Vite?](#how-do-i-use-box2d-with-vite)
17
19
  - [How do I build and publish my game?](#how-do-i-build-and-publish-my-game)
20
+ - [How do I shrink my game for js13kGames?](#how-do-i-shrink-my-game-for-js13kgames)
18
21
 
19
- Graphics and Sound
22
+ **Graphics and Sound**
20
23
  - [How do I load and add images to my game?](#how-do-i-load-and-add-images-to-my-game)
21
24
  - [What is the tile function and how do tile indexes work?](#what-is-the-tile-function-and-how-do-tile-indexes-work)
22
25
  - [Can I add and switch between multiple sprites for a game object?](#can-i-add-and-switch-between-multiple-sprites-for-a-game-object)
@@ -25,20 +28,25 @@ Graphics and Sound
25
28
  - [How do I control the camera in LittleJS?](#how-do-i-control-the-camera-in-littlejs)
26
29
  - [How do I use post-processing shaders?](#how-do-i-use-post-processing-shaders)
27
30
  - [How do I play sounds in LittleJS?](#how-do-i-play-sounds-in-littlejs)
31
+ - [How do I play music?](#how-do-i-play-music)
32
+ - [Why doesn't my audio play until the user clicks something?](#why-doesnt-my-audio-play-until-the-user-clicks-something)
28
33
  - [If I load several images, how do I control which is used?](#if-i-load-several-images-how-do-i-control-which-is-used)
29
34
  - [How can I check if an object is on screen?](#how-can-i-check-if-an-object-is-on-screen)
30
35
 
31
- Gameplay and Programming
36
+ **Gameplay and Programming**
32
37
  - [How do I add keyboard or mouse input to my game?](#how-do-i-add-keyboard-or-mouse-input-to-my-game)
33
38
  - [How does touch input work on mobile?](#how-does-touch-input-work-on-mobile)
34
39
  - [How do I create and update game objects?](#how-do-i-create-and-update-game-objects)
40
+ - [How do I use parent/child objects?](#how-do-i-use-parentchild-objects)
41
+ - [How do collisions work?](#how-do-collisions-work)
35
42
  - [How can I load a 2D level map?](#how-can-i-load-a-2d-level-map)
36
43
  - [Can I use physics with LittleJS?](#can-i-use-physics-with-littlejs)
37
44
  - [How do I add particle effects to my game?](#how-do-i-add-particle-effects-to-my-game)
45
+ - [How do I use timers?](#how-do-i-use-timers)
38
46
  - [How do I save and load game state?](#how-do-i-save-and-load-game-state)
39
47
  - [How do I use the medals (achievements) system?](#how-do-i-use-the-medals-achievements-system)
40
48
 
41
- Debugging and Development
49
+ **Debugging and Development**
42
50
  - [How do I debug my game in LittleJS?](#how-do-i-debug-my-game-in-littlejs)
43
51
 
44
52
  ---
@@ -47,9 +55,9 @@ Debugging and Development
47
55
  ### What is LittleJS, and how is it different from other JavaScript game engines?
48
56
 
49
57
  LittleJS is a lightweight, high-performance JavaScript game engine designed for simplicity and speed.
50
- It offers a hybrid rendering system that combines the advantages of WebGL and 2D Canvas.
51
- Unlike larger, feature-heavy engines, LittleJS focuses on 2D games and providing a comprehensive set of simple, easy to use features.
52
- LittleJS is perfect for developers who want a minimal yet powerful engine to bring their 2D game ideas to life without the complexity of larger frameworks.
58
+ It offers a hybrid rendering system that combines the advantages of WebGL and 2D Canvas, and in our sprite-rendering benchmarks it outperforms larger engines like Phaser, Pixi, and Kaboom.
59
+ Unlike those feature-heavy engines, LittleJS focuses on 2D games and providing a comprehensive set of simple, easy to use features.
60
+ LittleJS is perfect for developers who want a minimal yet powerful engine to bring their 2D game ideas to life without the complexity of larger frameworks, and it's especially well suited for size-constrained competitions like js13kGames.
53
61
 
54
62
  ### How do I set up a basic LittleJS project?
55
63
 
@@ -67,6 +75,7 @@ The most basic example is just an empty project.
67
75
 
68
76
  <script src=../../dist/littlejs.js></script>
69
77
  <script src=game.js></script>
78
+ </body></html>
70
79
  ```
71
80
 
72
81
  [Empty Example JavaScript file:](https://github.com/KilledByAPixel/LittleJS/blob/main/examples/empty/game.js)
@@ -198,9 +207,54 @@ Another option is to setup a simple local web server like [http-server](https://
198
207
 
199
208
  LittleJS drawing functions are all handled in world coordinates by default.
200
209
  The conversion from world to screen is determined by the camera position and scale as well as the canvas size in pixels.
201
- Camera scale determines how many screen pixels equals 1 world unit while the cameraPosition is the offset in world units.
210
+ Camera scale determines how many screen pixels equals 1 world unit while the cameraPos is the offset in world units.
202
211
  There is also a function you can use called getCameraSize() to get the viewable camera window in world coordinates.
203
212
 
213
+ One thing to keep in mind: in **world space**, Y increases *upward* and tile coordinates use a bottom-left origin. This often surprises developers coming from Canvas2D or other 2D libraries. **Screen space** (used when you pass `screenSpace=true` to a draw function, or when reading `mousePosScreen`) follows the Canvas2D convention instead — Y increases *downward* with a top-left origin. Pick the right one for what you're doing: world space for gameplay, screen space for HUDs and UI overlays.
214
+
215
+ ### How do I configure engine settings?
216
+
217
+ LittleJS exposes settings through `setX()` functions for every tunable value. Most settings need to be applied **before** `engineInit()` because they affect canvas creation, WebGL setup, or input registration:
218
+
219
+ ```javascript
220
+ setCanvasFixedSize(vec2(640, 480)); // lock canvas to a fixed resolution
221
+ setCanvasPixelated(true); // crisp pixel-art scaling
222
+ setGLEnable(false); // Canvas2D only (no WebGL)
223
+ setShowSplashScreen(false); // skip the LittleJS splash
224
+ setGravity(vec2(0, -.02)); // global gravity for physics
225
+ setTileDefaultSize(vec2(8)); // default tile size for tile()
226
+
227
+ engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);
228
+ ```
229
+
230
+ A few common categories of settings:
231
+
232
+ - **Canvas** — `setCanvasFixedSize`, `setCanvasMaxSize`, `setCanvasMinAspect`, `setCanvasPixelated`, `setCanvasPixelRatio`
233
+ - **Rendering** — `setGLEnable`, `setTilesPixelated`, `setCanvasClearColor`
234
+ - **Physics** — `setGravity`, `setObjectDefaultDamping`, `setObjectDefaultRestitution`, `setEnablePhysicsSolver`
235
+ - **Audio** — `setSoundEnable`, `setSoundVolume`, `setSoundDefaultRange`
236
+ - **Input** — `setTouchInputEnable`, `setTouchGamepadEnable`, `setInputWASDEmulateDirection`
237
+
238
+ Camera settings (`setCameraPos`, `setCameraScale`, `setCameraAngle`) are safe to call at runtime — typically from `gameInit` or `gameUpdate`. See [src/engineSettings.js](src/engineSettings.js) for the full list with defaults.
239
+
240
+ ### What plugins ship with LittleJS?
241
+
242
+ Plugins are self-contained features that live alongside the engine but aren't part of it — nothing in the core engine source references them, and they only depend on the public engine API. Drop in only what you need:
243
+
244
+ | Plugin | Purpose |
245
+ |--------|---------|
246
+ | `box2d.js` | Full Box2D physics via WebAssembly (more realistic than the built-in arcade physics) |
247
+ | `postProcess.js` | Shadertoy-style fragment shaders for screen-wide effects |
248
+ | `uiSystem.js` | Lightweight in-engine UI widgets (buttons, text, tabs) |
249
+ | `tweenSystem.js` | Tween any property over time with easing curves |
250
+ | `pathFinder.js` | Grid-based A* pathfinding with optional path smoothing |
251
+ | `medalSystem.js` | Achievement / medal tracking with toast notifications |
252
+ | `newgrounds.js` | Newgrounds.io integration (scoreboards, cloud saves) |
253
+ | `zzfxm.js` | Procedural chiptune music via the `ZzFXMusic` class |
254
+ | `drawUtilities.js` | Higher-level drawing helpers like nine-slice and three-slice |
255
+
256
+ This self-contained design means the community can also ship plugins independently of the main repo — you can write your own plugin as just a JavaScript file that uses the engine's public API.
257
+
204
258
  ### How do I use Vite with LittleJS?
205
259
 
206
260
  There is an official [Vite](https://vite.dev) starter template in `examples/vite-starter`. The fastest way to start a new project from it is with [degit](https://github.com/Rich-Harris/degit):
@@ -293,6 +347,17 @@ Then zip up your game folder for itch.io or push to GitHub Pages.
293
347
 
294
348
  **For size coding competitions** like js13kGames, see the [js13k branch](https://github.com/KilledByAPixel/LittleJS/tree/js13k) which provides a build that fits in 7KB zipped.
295
349
 
350
+ ### How do I shrink my game for js13kGames?
351
+
352
+ LittleJS has a dedicated [js13k branch](https://github.com/KilledByAPixel/LittleJS/tree/js13k) that builds to about 7KB zipped, leaving most of the 13KB budget for your game. A few practical tips for hitting tiny sizes:
353
+
354
+ - **Use Canvas2D instead of WebGL**: call `setGLEnable(false)` before `engineInit`. Stripping the WebGL renderer saves a significant chunk of bytes, and for most pixel-art and low-sprite-count games the visual difference is imperceptible. A nice side effect: once the jam is over, you can flip WebGL back on with a single setting change for a big performance boost when publishing the game elsewhere.
355
+ - **Drop unused plugins**: every plugin is self-contained, so only include what you actually use. Skip `uiSystem.js`, `box2d.js`, `pathFinder.js`, etc. unless you need them.
356
+ - **Lean on built-ins to avoid asset files**: `Sound` with ZzFX parameters generates sound effects from a tiny array, `ZzFXMusic` makes procedural chiptunes, and built-in shape drawing avoids shipping image assets.
357
+ - **Use a packer**: the js13k branch is set up to compress the final bundle with Roadroller or a similar packer. Check the branch's build script for the current toolchain.
358
+
359
+ For normal production (non-13KB) builds, the engine ships `dist/littlejs.release.js` (asserts stripped) and `dist/littlejs.min.js` (minified) — both well under 100KB.
360
+
296
361
  ---
297
362
 
298
363
  ## Graphics and Sound
@@ -390,8 +455,8 @@ this.tileInfo = playerSprite.frame(animationFrame);
390
455
  ### How do I control the camera in LittleJS?
391
456
 
392
457
  LittleJS uses a world space rendering system, so objects can move independently of the camera.
393
- The camera is easy to control using cameraPosition and cameraScale, which indicate the world space position and how many pixels is equivalent to one world unit.
394
- The default cameraScale is 32 while the default cameraPosition is just the origin.
458
+ The camera is easy to control using cameraPos and cameraScale, which indicate the world space position and how many pixels is equivalent to one world unit.
459
+ The default cameraScale is 32 while the default cameraPos is just the origin.
395
460
  It is also possible to draw using screen space pixel coordinates by passing in true as the screenSpace parameter to most drawing functions.
396
461
 
397
462
  ```javascript
@@ -427,8 +492,8 @@ The constructor has two optional positional arguments after the shader source:
427
492
  new PostProcessPlugin(shader, includeMainCanvas, feedbackTexture);
428
493
  ```
429
494
 
430
- - `includeMainCanvas=true` composites the Canvas2D layer (where some debug and text rendering goes) onto the WebGL canvas before the shader runs. Pass `true` if your post-process effect should apply to *everything* on screen, not just the WebGL-rendered objects.
431
- - `feedbackTexture=true` makes the previous frame available as `iChannel0` for effects like motion trails or feedback loops. Mutually exclusive with `includeMainCanvas`.
495
+ - `includeMainCanvas` (default `false`) composites the Canvas2D layer (where some debug and text rendering goes) onto the WebGL canvas before the shader runs. Pass `true` if your post-process effect should apply to *everything* on screen, not just the WebGL-rendered objects.
496
+ - `feedbackTexture` (default `false`) makes the previous frame available as `iChannel0` for effects like motion trails or feedback loops. Mutually exclusive with `includeMainCanvas`.
432
497
 
433
498
  See [plugins/postProcess.js](plugins/postProcess.js) and the [Breakout example](https://killedbyapixel.github.io/LittleJS/examples/breakout/) for working post-process effects.
434
499
 
@@ -444,6 +509,28 @@ const sound_jump = new Sound('jump.mp3'); // load an mp3 sound
444
509
  sound_click.play(pos, volume, pitch); // play a sound
445
510
  ```
446
511
 
512
+ ### How do I play music?
513
+
514
+ For procedural chiptune music, use the `ZzFXMusic` class from the [ZzFXM plugin](plugins/zzfxm.js). It extends `Sound` and accepts a ZzFXM-format song array — the music is generated on the fly so it adds essentially no bytes to your build. For longer scored music, load an mp3 or ogg file with the regular `Sound` class and pass `true` as the loop parameter.
515
+
516
+ ```javascript
517
+ // procedural ZzFXM music (tiny, generated at runtime)
518
+ const music = new ZzFXMusic(zzfxmSongData);
519
+ music.play();
520
+
521
+ // or load an mp3/ogg and loop it
522
+ const music = new Sound('music.mp3');
523
+ music.play(undefined, 1, 1, 0, true); // pos, volume, rate, pan, loop
524
+ ```
525
+
526
+ Both pause automatically when the tab loses focus (audio context suspends) and resume when it comes back. Use `music.stop()` to halt playback.
527
+
528
+ ### Why doesn't my audio play until the user clicks something?
529
+
530
+ Browsers require a user interaction (click, key press, touch) before audio is allowed to play — this is a hard rule from the browser's autoplay policy, not something the engine can bypass. LittleJS handles the actual resume for you: the audio context starts in a suspended state and is automatically resumed on the first input event. You don't need to call `audioContext.resume()` yourself.
531
+
532
+ The practical implication is that sounds you try to play during `gameInit()` or on the very first frame won't be audible. Design opening audio (title-screen music, intro sounds) so it kicks in after the first input — a common pattern is a "Press any key to start" screen that begins playing music the moment the player presses something.
533
+
447
534
  ### If I load several images, how do I control which is used?
448
535
 
449
536
  Pass multiple image paths to `engineInit` and select between them with the third argument to `tile()` (the `texture` index):
@@ -543,6 +630,55 @@ Common things you'll do on an `EngineObject`:
543
630
  - `this.gravityScale = 0` — disable gravity for this object (e.g. UI or floating objects)
544
631
  - `this.destroy()` — remove from the world (calls cleanup on children too)
545
632
 
633
+ ### How do I use parent/child objects?
634
+
635
+ `EngineObject` supports a parent/child hierarchy with local transforms. Attached children automatically follow their parent's position, angle, and mirror state each frame:
636
+
637
+ ```javascript
638
+ const ship = new EngineObject(vec2(10, 5), vec2(2));
639
+ const turret = new EngineObject(vec2(), vec2(.5));
640
+ ship.addChild(turret, vec2(0, .5)); // turret sits .5 units above the ship in local space
641
+ ```
642
+
643
+ `addChild(child, localPos, localAngle)` attaches the child with a local offset; the child's world-space `pos` and `angle` are recomputed each frame from the parent's transform. To detach, call `parent.removeChild(child)` — or just `child.destroy()`, which also detaches it (and destroying a parent destroys all its children).
644
+
645
+ A few things to know:
646
+ - **Mirroring a parent flips children** — a mirrored ship has its turret on the correct side automatically (`localPos.x` and `localAngle` are inverted).
647
+ - **Velocity is not inherited** — physics runs on the world transform after parenting, so a child doesn't automatically pick up the parent's velocity. If you need that, set the child's velocity manually before attaching.
648
+ - **For decorative attachments** that shouldn't be affected by physics, set `gravityScale = 0` and skip `setCollision()` on the child.
649
+
650
+ ### How do collisions work?
651
+
652
+ Opt in to collision on an `EngineObject` by calling `setCollision()` — by default it's off so most objects don't pay the collision cost.
653
+
654
+ ```javascript
655
+ class Player extends EngineObject {
656
+ constructor(pos) {
657
+ super(pos, vec2(1), tile(0, 16));
658
+ this.setCollision(); // collide with solid objects and tile map
659
+ }
660
+ }
661
+ ```
662
+
663
+ `setCollision(collideSolidObjects, isSolid, collideTiles, collideRaycast)` — all default to `true`. Pass `false` to opt out of any of them (e.g. a ghost that passes through walls: `setCollision(false, false, false)`).
664
+
665
+ For custom collision logic, override `collideWithObject(other)` and `collideWithTile(tileData, pos)` on your subclass. Return `true` to actually block the collision, `false` to pass through. Both fire during the physics step:
666
+
667
+ ```javascript
668
+ class Bullet extends EngineObject {
669
+ collideWithObject(other) {
670
+ if (other instanceof Enemy) {
671
+ other.damage(1);
672
+ this.destroy();
673
+ return false; // don't physically bounce off the enemy
674
+ }
675
+ return true; // solid collision with everything else
676
+ }
677
+ }
678
+ ```
679
+
680
+ For raycasting against the tile collision map (line-of-sight checks, hitscan weapons, etc.), use `tileCollisionRaycast(start, end)` which returns the hit position or `undefined`.
681
+
546
682
  ### How can I load a 2D level map?
547
683
 
548
684
  There are two parts that work together to make 2D level maps in LittleJS.
@@ -578,6 +714,36 @@ new ParticleEmitter(
578
714
  );
579
715
  ```
580
716
 
717
+ ### How do I use timers?
718
+
719
+ The `Timer` class is a small but very useful utility for anything that needs to happen *after some time has passed* — cooldowns, animation timing, delayed spawns, fades, etc. It tracks elapsed time automatically, so you don't have to add `timeDelta` to a variable every frame.
720
+
721
+ ```javascript
722
+ const cooldown = new Timer(2); // 2-second timer, starts immediately
723
+
724
+ function gameUpdate() {
725
+ if (cooldown.elapsed()) {
726
+ fireWeapon();
727
+ cooldown.set(2); // restart it
728
+ }
729
+ }
730
+ ```
731
+
732
+ Useful methods:
733
+ - `set(seconds)` — start or restart the timer
734
+ - `unset()` — disable it (`isSet()` becomes false)
735
+ - `active()` / `elapsed()` — boolean checks
736
+ - `get()` — seconds elapsed (negative while still counting down)
737
+ - `getPercent()` — 0 → 1 progress, handy for easing animations
738
+
739
+ By default, a timer ticks on **game time** — it pauses when the game is paused and slows down or speeds up with `setTimeScale`. For UI animations, on-screen notifications, or anything that should keep running regardless of game state, use a real-time timer:
740
+
741
+ ```javascript
742
+ const uiFade = new Timer(.5, true); // useRealTime = true
743
+ ```
744
+
745
+ Real-time timers track `timeReal` instead of `time` — unaffected by pause or time scale. You can also flip an existing timer between modes with `timer.setUseRealTime(true)` while it's unset.
746
+
581
747
  ### How do I save and load game state?
582
748
 
583
749
  LittleJS has built-in helpers for localStorage-backed save data — no need to roll your own JSON serialization:
@@ -618,10 +784,26 @@ The plugin also supports [Newgrounds](https://www.newgrounds.com) integration vi
618
784
 
619
785
  ### How do I debug my game in LittleJS?
620
786
 
621
- In addition to your browser's built in developer mode, LittleJS has its own debug view.
622
- Press the Esc key to show the debug menu. From here there are several options that can be accessed via the number keys.
787
+ In addition to your browser's built-in developer tools, LittleJS has its own debug overlay. Press `Esc` to show it — the overlay lists the available toggles and their number-key bindings, so you don't have to memorize them. `+` and `-` adjust the time scale, which is great for slowing tricky moments down or speeding past a slow section.
788
+
789
+ **Debug draw functions** let you visualize state directly in the world without committing to permanent UI. They're drawn for one frame and only render in debug builds:
790
+
791
+ ```javascript
792
+ debugRect(pos, size, color); // outline a rectangle
793
+ debugCircle(pos, radius, color); // outline a circle
794
+ debugLine(posA, posB, color); // a line between two points
795
+ debugText(string, pos, size, color); // text at a world position
796
+ debugPoint(pos, color); // small marker
797
+ ```
623
798
 
624
- You can also press + or - to adjust game speed to help with debugging, or just for fun!
799
+ These are perfect for "where exactly is this AI heading?" or "is this hitbox where I think it is?" investigations — drop a call into your update or render code, see the answer, then delete it.
800
+
801
+ **`ASSERT` and `LOG`** are similar to `console.assert` / `console.log`, but they're *stripped from release builds* (`littlejs.release.js`, `littlejs.min.js`). That means you can leave them in your code with no cost to shipped users. Don't rely on side effects inside the arguments — they won't run in release.
802
+
803
+ ```javascript
804
+ ASSERT(player.health > 0, 'player damaged below zero', player);
805
+ LOG('spawned enemy at', pos);
806
+ ```
625
807
 
626
808
  ---
627
809
 
package/README.md CHANGED
@@ -8,6 +8,7 @@
8
8
  [![Build Size][build-size]][build-size-url]
9
9
  [![NPM Downloads][npm-downloads]][npmtrends-url]
10
10
  [![DeepScan][deepscan]][deepscan-url]
11
+ [![MIT License][license]][license-url]
11
12
  [![Discord][discord]][discord-url]
12
13
 
13
14
  </div>
@@ -24,7 +25,7 @@ The code is very clean and well documented with many examples to get you started
24
25
 
25
26
  <div align='center' markdown='1'>
26
27
 
27
- ## [Demos](https://killedbyapixel.github.io/LittleJS/examples) | [Docs](https://killedbyapixel.github.io/LittleJS/docs) | [Trailer](https://youtu.be/chuBzGjv7Ms) | [Discord](https://discord.gg/zb7hcGkyZe) | [FAQ](https://github.com/KilledByAPixel/LittleJS/blob/main/FAQ.md)
28
+ ## [Demos](https://killedbyapixel.github.io/LittleJS/examples) | [Docs](https://killedbyapixel.github.io/LittleJS/docs) | [Reference](https://github.com/KilledByAPixel/LittleJS/blob/main/REFERENCE.md) | [FAQ](https://github.com/KilledByAPixel/LittleJS/blob/main/FAQ.md) | [Trailer](https://youtu.be/chuBzGjv7Ms) | [Discord](https://discord.gg/zb7hcGkyZe)
28
29
 
29
30
  </div>
30
31
 
@@ -89,21 +90,37 @@ npm install
89
90
  npm run dev
90
91
  ```
91
92
 
93
+ Here is a minimal Hello World example game.
94
+
95
+ ```html
96
+ <!DOCTYPE html>
97
+ <script src="../dist/littlejs.js"></script>
98
+ <script>
99
+ function gameInit() {}
100
+ function gameUpdate() {}
101
+ function gameUpdatePost() {}
102
+ function gameRender() {}
103
+ function gameRenderPost() { drawTextScreen('Hello World!', mainCanvasSize.scale(.5), 80); }
104
+ engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost);
105
+ </script>
106
+ ```
107
+
92
108
  ## Tutorials
93
109
 
94
110
  - [Making Awesome Games With LittleJS](https://youtu.be/_dXKU0WgAj8?si=ZDXLYAFDWp54hrGT) - A short talk about LittleJS with some tips on how to use it.
95
111
  - [Tutorial: Breakout](https://github.com/KilledByAPixel/LittleJS/tree/main/examples/breakoutTutorial) - Learn how to make a simple game from scratch
96
112
  - [Tutorial: Make a ski game](https://eoinmcgrath.com/little-ski/tutorial.html) - This tutorial by eoinmcg that shows how to make a pixel art style game.
97
- - [LittleJS Quick Reference Sheet](https://github.com/KilledByAPixel/LittleJS/blob/main/reference.md) - A reference sheet to help you get started.
113
+ - [LittleJS Quick Reference Sheet](https://github.com/KilledByAPixel/LittleJS/blob/main/REFERENCE.md) - A reference sheet to help you get started.
98
114
  - [Little JS FAQ](https://github.com/KilledByAPixel/LittleJS/blob/main/FAQ.md) - Answers to common questions about LittleJS.
99
115
  - [JS13k Branch](https://github.com/KilledByAPixel/LittleJS/tree/js13k) - For size coding events like JS13k there is a special branch that builds to a 7KB zip.
100
116
  - [LittleJS AI Tools](https://github.com/KilledByAPixel/LittleJS-AI) - Experiments, games, and templates to improve LittleJS + AI workflows.
101
117
 
102
118
  ## Examples
103
119
 
104
- LittleJS comes with a several demos both for learning and using as starter projects to create new games.
120
+ LittleJS comes with several demos both for learning and using as starter projects to create new games.
105
121
 
106
- - [Example Browser](https://killedbyapixel.github.io/LittleJS/examples/) - Live example browser with all examples
122
+ - [Example Browser](https://killedbyapixel.github.io/LittleJS/examples/) - Live example browser with all examples and editable source
123
+ - [Short Examples](https://github.com/KilledByAPixel/LittleJS/tree/main/examples/shorts) - 60+ single-file demos showing off individual engine features
107
124
  - [Breakout](https://killedbyapixel.github.io/LittleJS/examples/breakout/) - Block breaking game with post-processing effects
108
125
  - [Puzzle Game](https://killedbyapixel.github.io/LittleJS/examples/puzzle/) - Match 3 puzzle game with HD rendering and high score tracking
109
126
  - [Platformer](https://killedbyapixel.github.io/LittleJS/examples/platformer/) - Platformer/shooter demo that loads level data
@@ -141,13 +158,15 @@ Here are a few of the many amazing games created with LittleJS...
141
158
  - [Bug&Bee](https://itch.io/jam/littlejs-game-jam-2025/results) - Low fi shoot em up with co-op gameplay. LittleJS Jam 1st place! by [eoinmcg](https://eoinmcg.itch.io/)
142
159
  - [Little Platformer](https://psemo.itch.io/little-platformer) - Platformer with many mechanics. LittleJS Jam 2st place! by [PSEMO](https://psemo.itch.io/), [Solita666](https://itch.io/profile/solita666), [GabrielRG](https://gabrielrg.itch.io/), [Nate](https://natesassoon.itch.io/)
143
160
  - [Rogue Pong](https://itch.io/jam/littlejs-game-jam-2025/rate/4004165) - Roguelike crossed with classic pong gameplay. LittleJS Jam 3rd place! by [webdevbrian](https://webdevbrian.itch.io/)
144
- - [Orbitswarm](https://focaccai.itch.io/orbitswarm) - Fast paced space strategy game. by [Focaccai](https://www.focaccai.com/)
161
+ - [Alien Escape Pinball](https://focaccai.itch.io/alien-pinball) - Pinball game with physics and aliens. by [Focaccai](https://www.focaccai.com/)
145
162
  - [LittleJS Jam 2024 Results](https://itch.io/jam/littlejs-jam-2024/results) - All the games from the first LittleJS Game Jam.
146
163
  - [LittleJS Jam 2025 Results](https://itch.io/jam/littlejs-game-jam-2025/results) - All the games from the second LittleJS Game Jam.
147
164
 
148
- ![LittleJS Screenshot](examples/games.jpg)
165
+ ![A collage of screenshots from games made with LittleJS](examples/games.jpg)
166
+
167
+ *A sample of games built with LittleJS.*
149
168
 
150
- ![LittleJS Logo](examples/favicon.png)
169
+ ![LittleJS pixel-art favicon](examples/favicon.png)
151
170
 
152
171
  [npm]: https://img.shields.io/npm/v/littlejsengine
153
172
  [npm-url]: https://www.npmjs.com/package/littlejsengine
@@ -159,3 +178,5 @@ Here are a few of the many amazing games created with LittleJS...
159
178
  [deepscan-url]: https://deepscan.io/dashboard#view=project&tid=22950&pid=26229&bid=831487
160
179
  [discord]: https://img.shields.io/discord/939926111469568050
161
180
  [discord-url]: https://discord.gg/zb7hcGkyZe
181
+ [license]: https://img.shields.io/github/license/KilledByAPixel/LittleJS
182
+ [license-url]: https://github.com/KilledByAPixel/LittleJS/blob/main/LICENSE