littlejsengine 1.17.11 → 1.17.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.
Files changed (48) hide show
  1. package/AI.md +162 -0
  2. package/README.md +50 -63
  3. package/dist/littlejs.d.ts +150 -68
  4. package/dist/littlejs.esm.js +323 -105
  5. package/dist/littlejs.esm.min.js +1 -1
  6. package/dist/littlejs.js +320 -104
  7. package/dist/littlejs.min.js +1 -1
  8. package/dist/littlejs.release.js +318 -101
  9. package/examples/electron/{build.js → build.mjs} +26 -23
  10. package/examples/electron/game.js +5 -50
  11. package/examples/electron/index.html +2 -2
  12. package/examples/index.html +1 -0
  13. package/examples/module/{build.js → build.mjs} +22 -19
  14. package/examples/shorts/base.html +1 -1
  15. package/examples/shorts/hillGlideGame.js +1 -1
  16. package/examples/shorts/nineSlice.js +3 -3
  17. package/examples/shorts/shapes.js +1 -1
  18. package/examples/shorts/uiSystem.js +17 -16
  19. package/examples/starter/build.bat +1 -1
  20. package/examples/starter/{build.js → build.mjs} +25 -22
  21. package/examples/starter/index.html +2 -2
  22. package/examples/typescript/build.mjs +60 -0
  23. package/examples/typescript/game.js +2 -2
  24. package/examples/typescript/tsconfig.json +11 -2
  25. package/package.json +2 -2
  26. package/plugins/pluginExport.js +1 -0
  27. package/plugins/uiSystem.js +143 -20
  28. package/reference.md +0 -1
  29. package/src/engine.js +16 -14
  30. package/src/engineAudio.js +9 -6
  31. package/src/{engineBuild.js → engineBuild.mjs} +95 -78
  32. package/src/engineDebug.js +8 -5
  33. package/src/engineDraw.js +16 -14
  34. package/src/engineExport.js +2 -1
  35. package/src/engineInput.js +29 -8
  36. package/src/engineMath.js +46 -14
  37. package/src/engineMedals.js +6 -3
  38. package/src/engineObject.js +14 -3
  39. package/src/engineParticles.js +8 -3
  40. package/src/engineRelease.js +6 -2
  41. package/src/engineTileLayer.js +8 -4
  42. package/src/engineUtilities.js +6 -2
  43. package/src/engineWebGL.js +11 -8
  44. package/src/jsconfig.json +2 -1
  45. package/examples/electron/build.bat +0 -7
  46. package/examples/module/build.bat +0 -7
  47. package/examples/typescript/build.bat +0 -5
  48. package/examples/typescript/build.js +0 -31
@@ -3,6 +3,15 @@
3
3
  "allowJs": true,
4
4
  "module": "es2020",
5
5
  "target": "es2020",
6
- "outDir": "build"
7
- }
6
+ "outDir": "build",
7
+ "moduleResolution": "bundler",
8
+ "skipLibCheck": true
9
+ },
10
+ "include": [
11
+ "*.ts"
12
+ ],
13
+ "exclude": [
14
+ "node_modules",
15
+ "build"
16
+ ]
8
17
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "littlejsengine",
3
- "version": "1.17.11",
3
+ "version": "1.17.15",
4
4
  "description": "LittleJS - Tiny and Fast HTML5 Game Engine",
5
5
  "main": "dist/littlejs.esm.js",
6
6
  "types": "dist/littlejs.d.ts",
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "homepage": "https://github.com/KilledByAPixel/LittleJS",
32
32
  "scripts": {
33
- "build": "node src/engineBuild.js"
33
+ "build": "node src/engineBuild.mjs"
34
34
  },
35
35
  "devDependencies": {
36
36
  "bestzip": "^2.2.1",
@@ -23,6 +23,7 @@ export
23
23
  UISystemPlugin,
24
24
  UIObject,
25
25
  UIText,
26
+ UITextInput,
26
27
  UITile,
27
28
  UIButton,
28
29
  UICheckbox,
@@ -118,9 +118,16 @@ class UISystemPlugin
118
118
  this.lastHoverObject = undefined;
119
119
  /** @property {UIObject} - Current confirm menu being shown */
120
120
  this.confirmDialog = undefined;
121
+ /** @property {UIObject} - Object to send keyboard input to */
122
+ this.keyInputObject = undefined;
121
123
 
122
124
  engineAddPlugin(uiUpdate, uiRender);
123
125
 
126
+ // key down handler
127
+ function onKeyDown(e)
128
+ { uiSystem.keyInputObject?.onKeyDown(e); }
129
+ document.addEventListener('keydown', onKeyDown);
130
+
124
131
  // set object position in parent space
125
132
  function updateTransforms(o)
126
133
  {
@@ -139,9 +146,18 @@ class UISystemPlugin
139
146
  // reset hover object at start of update
140
147
  uiSystem.lastHoverObject = uiSystem.hoverObject;
141
148
  uiSystem.hoverObject = undefined;
142
-
149
+
143
150
  if (mouseWasPressed(0))
144
151
  {
152
+ // exit navigation mode on mouse press
153
+ uiSystem.navigationMode = false;
154
+ uiSystem.navigationObject = undefined;
155
+ }
156
+ if (uiSystem.keyInputObject)
157
+ {
158
+ // handle text input
159
+ uiSystem.activeObject = uiSystem.keyInputObject;
160
+ uiSystem.hoverObject = uiSystem.keyInputObject;
145
161
  uiSystem.navigationMode = false;
146
162
  uiSystem.navigationObject = undefined;
147
163
  }
@@ -150,7 +166,7 @@ class UISystemPlugin
150
166
  const navigableObjects = uiSystem.getNavigableObjects();
151
167
  if (!navigableObjects.length)
152
168
  uiSystem.navigationObject = undefined;
153
- else
169
+ else if (!uiSystem.keyInputObject)
154
170
  {
155
171
  // unselect object if it is no longer navigable
156
172
  if (!navigableObjects.includes(uiSystem.navigationObject))
@@ -463,6 +479,7 @@ class UISystemPlugin
463
479
  this.activeObject = undefined;
464
480
  this.hoverObject = undefined;
465
481
  this.lastHoverObject = undefined;
482
+ this.keyInputObject = undefined;
466
483
  }
467
484
 
468
485
  /** Get all navigable UI objects sorted by navigationIndex
@@ -743,7 +760,7 @@ class UIObject
743
760
  }
744
761
  }
745
762
 
746
- /** Check if the mouse is overlapping a box in screen space
763
+ /** Check if the mouse is overlapping this ui object
747
764
  * @return {boolean} - True if overlapping */
748
765
  isMouseOverlapping()
749
766
  {
@@ -762,8 +779,16 @@ class UIObject
762
779
  this.onUpdate();
763
780
 
764
781
  // unset active if disabled
765
- if (this.disabled && this === uiSystem.activeObject)
766
- uiSystem.activeObject = undefined;
782
+ if (this.disabled)
783
+ {
784
+ if (this === uiSystem.activeObject)
785
+ uiSystem.activeObject = undefined;
786
+ if (this === uiSystem.keyInputObject)
787
+ uiSystem.keyInputObject = undefined;
788
+ }
789
+
790
+ if (uiSystem.keyInputObject)
791
+ return;
767
792
 
768
793
  const wasHover = uiSystem.lastHoverObject === this;
769
794
  const isActive = this.isActiveObject();
@@ -790,19 +815,12 @@ class UIObject
790
815
  uiSystem.activeObject = this;
791
816
 
792
817
  if (uiSystem.activateOnPress)
793
- {
794
- this.onClick();
795
- if (!this.soundPress && this.soundClick)
796
- this.soundClick.play();
797
- }
818
+ this.click(!this.soundPress);
798
819
  }
799
820
  }
800
821
  if (!uiSystem.activateOnPress)
801
822
  if (!mouseDown && this.isActiveObject() && this.interactive)
802
- {
803
- this.onClick();
804
- this.soundClick && this.soundClick.play();
805
- }
823
+ this.click();
806
824
  }
807
825
 
808
826
  // clear mouse was pressed state even when disabled
@@ -854,11 +872,7 @@ class UIObject
854
872
  }
855
873
 
856
874
  /** Called when the navigation button is pressed on this object */
857
- navigatePressed()
858
- {
859
- this.onClick();
860
- this.soundClick && this.soundClick.play();
861
- }
875
+ navigatePressed() { this.click(); }
862
876
 
863
877
  /** @return {boolean} - Is the mouse hovering over this element */
864
878
  isHoverObject() { return uiSystem.hoverObject === this; }
@@ -869,6 +883,9 @@ class UIObject
869
883
  /** @return {boolean} - Is the gamepad or keyboard navigation object */
870
884
  isNavigationObject() { return uiSystem.navigationObject === this; }
871
885
 
886
+ /** @return {boolean} - Is this object in keyboard input mode */
887
+ isKeyInputObject() { return uiSystem.keyInputObject === this; }
888
+
872
889
  /** @return {boolean} - Can it be interacted with */
873
890
  isInteractive() { return this.interactive && this.visible && !this.disabled;}
874
891
 
@@ -905,6 +922,15 @@ class UIObject
905
922
  uiSystem.drawRect(this.pos, this.size, CLEAR_BLACK, 4, color);
906
923
  }
907
924
 
925
+ /** Internal function called when object is clicked
926
+ * @param {boolean} [playSound] */
927
+ click(playSound)
928
+ {
929
+ this.onClick();
930
+ if (playSound && this.soundClick)
931
+ this.soundClick.play();
932
+ }
933
+
908
934
  /** Called each frame before object updates */
909
935
  onUpdate() {}
910
936
 
@@ -980,6 +1006,102 @@ class UIText extends UIObject
980
1006
  }
981
1007
  }
982
1008
 
1009
+ ///////////////////////////////////////////////////////////////////////////////
1010
+ /**
1011
+ * UITextInput - An editable text input field
1012
+ * - A simple text entry field that supports basic editing
1013
+ * - Suitable for short text input like names or numbers
1014
+ * @extends UIObject
1015
+ * @memberof UISystem
1016
+ */
1017
+ class UITextInput extends UIObject
1018
+ {
1019
+ /** Create a UITextInput object
1020
+ * @param {Vector2} [pos]
1021
+ * @param {Vector2} [size]
1022
+ * @param {string} [text]
1023
+ */
1024
+ constructor(pos, size, text='')
1025
+ {
1026
+ super(pos, size);
1027
+
1028
+ ASSERT(isString(text), 'ui text must be a string');
1029
+
1030
+ /** @property {number} - Max length of input (0 = no limit) */
1031
+ this.maxLength = 0;
1032
+
1033
+ // set properties
1034
+ this.text = text;
1035
+ this.interactive = true;
1036
+ this.canBeHover = true;
1037
+ }
1038
+
1039
+ click()
1040
+ {
1041
+ // start editing the text
1042
+ uiSystem.keyInputObject = this;
1043
+ this.onClick();
1044
+ }
1045
+
1046
+ /** Stop editing the text edited */
1047
+ stopEditing()
1048
+ {
1049
+ if (!this.isKeyInputObject())
1050
+ return;
1051
+
1052
+ if (this.soundRelease)
1053
+ this.soundRelease.play();
1054
+ uiSystem.activeObject = undefined;
1055
+ uiSystem.keyInputObject = undefined;
1056
+ this.onChange();
1057
+ }
1058
+
1059
+ /** Key down event handler if this object is being edited
1060
+ * @param {KeyboardEvent} [e] */
1061
+ onKeyDown(e)
1062
+ {
1063
+ const code = e.code, key = e.key
1064
+ if (code === 'Backspace')
1065
+ this.text = this.text.slice(0, -1);
1066
+ else if (code === 'Enter' || code === 'Escape')
1067
+ this.stopEditing();
1068
+ else if (key.length === 1) // printable characters
1069
+ {
1070
+ if (!this.maxLength || this.text.length < this.maxLength)
1071
+ this.text += key;
1072
+ }
1073
+ }
1074
+
1075
+ update()
1076
+ {
1077
+ super.update();
1078
+
1079
+ if (!this.isKeyInputObject())
1080
+ return;
1081
+
1082
+ // click off object to stop editing
1083
+ if (mouseWasPressed(0) && !this.isMouseOverlapping() ||
1084
+ gamepadWasPressed(0, gamepadPrimary))
1085
+ {
1086
+ this.stopEditing();
1087
+ inputClearKey(0,0);
1088
+ }
1089
+ }
1090
+
1091
+ render()
1092
+ {
1093
+ super.render();
1094
+
1095
+ // draw the text scaled to fit
1096
+ const textSize = this.getTextSize();
1097
+ let text = this.text;
1098
+ if (this.isKeyInputObject()) // add a cursor to end of text
1099
+ text += timeReal%1 < .5 ? '█' : '░';
1100
+ uiSystem.drawText(text, this.pos, textSize,
1101
+ this.textColor, this.textLineWidth, this.textLineColor, this.align, this.font, this.fontStyle, true, this.textShadow);
1102
+ }
1103
+ }
1104
+
983
1105
  ///////////////////////////////////////////////////////////////////////////////
984
1106
  /**
985
1107
  * UITile - A UI object that displays a tile image
@@ -1091,9 +1213,10 @@ class UICheckbox extends UIObject
1091
1213
  this.color = color.copy();
1092
1214
  this.interactive = true;
1093
1215
  }
1094
- onClick()
1216
+ click()
1095
1217
  {
1096
1218
  this.checked = !this.checked;
1219
+ this.onClick();
1097
1220
  this.onChange();
1098
1221
  }
1099
1222
  render()
package/reference.md CHANGED
@@ -49,7 +49,6 @@ smoothStep(percent) // Applies smoothstep function
49
49
  nearestPowerOfTwo(value) // Returns the nearest power of two
50
50
  isOverlapping(pointA, sizeA, pointB, sizeB) // Checks if bounding boxes overlap
51
51
  isIntersecting(start, end, pos, size) // Checks if ray intersects box
52
- wave(frequency=1, amplitude=1, t=time) // Returns oscillating wave
53
52
  formatTime(t) // Formats seconds for display
54
53
 
55
54
  // Random functions
package/src/engine.js CHANGED
@@ -3,18 +3,20 @@
3
3
  * MIT License - Copyright 2021 Frank Force
4
4
  *
5
5
  * Engine Features
6
- * - Object oriented system with base class engine object
7
- * - Base class object handles update, physics, collision, rendering, etc
8
- * - Engine helper classes and functions like Vector2, Color, and Timer
9
- * - Super fast rendering system for tile sheets
10
- * - Sound effects audio with zzfx and music with zzfxm
11
- * - Input processing system with gamepad and touchscreen support
12
- * - Tile layer rendering and collision system
13
- * - Particle effect system
14
- * - Medal system tracks and displays achievements
15
- * - Debug tools and debug rendering system
16
- * - Post processing effects
17
- * - Call engineInit() to start it up!
6
+ * - Object oriented system with EngineObject base class
7
+ * - Automatic object lifecycle (update, physics, collision, rendering)
8
+ * - Engine helper classes: Vector2, Color, Timer, RandomGenerator
9
+ * - Hybrid rendering with WebGL batching and Canvas2D fallback
10
+ * - Audio system with wave, mp3, or ZzFX sound effects
11
+ * - Input system with keyboard, mouse, gamepad, and touch support
12
+ * - Tile layer rendering and collision detection
13
+ * - Particle effect system with emitters
14
+ * - Medal/achievement system with local storage
15
+ * - Comprehensive debug tools and visualizations
16
+ * - Fixed 60 FPS timestep with configurable time scale
17
+ * - Raycast and spatial query utilities
18
+ * - Plugin system for extending engine functionality
19
+ * - Start with engineInit() and provide your game callbacks
18
20
  * @namespace Engine
19
21
  */
20
22
 
@@ -30,7 +32,7 @@ const engineName = 'LittleJS';
30
32
  * @type {string}
31
33
  * @default
32
34
  * @memberof Engine */
33
- const engineVersion = '1.17.11';
35
+ const engineVersion = '1.17.15';
34
36
 
35
37
  /** Frames per second to update
36
38
  * @type {number}
@@ -604,7 +606,7 @@ function drawEngineLogo(t)
604
606
  const color = (c,l)=> l?`hsl(${[.95,.56,.13][c%3]*360} 99%${[0,50,75][l]}%`:'#000';
605
607
 
606
608
  // center and fit tos screen
607
- const alpha = wave(1,1,t);
609
+ const alpha = oscillate(1,1,t);
608
610
  const p = percent(alpha, .1, .5);
609
611
  const size = min(6, min(w,h)/99);
610
612
  x.translate(w/2,h/2);
@@ -1,11 +1,14 @@
1
1
  /**
2
2
  * LittleJS Audio System
3
- * - <a href=https://killedbyapixel.github.io/ZzFX/>ZzFX Sound Effects</a> - ZzFX Sound Effect Generator
4
- * - <a href=https://keithclark.github.io/ZzFXM/>ZzFXM Music</a> - ZzFXM Music System
5
- * - Caches sounds and music for fast playback
6
- * - Can attenuate and apply stereo panning to sounds
7
- * - Ability to play mp3, ogg, and wave files
8
- * - Speech synthesis functions
3
+ * - Play audio files (mp3, ogg, wave) and generate sounds with ZzFX
4
+ * - ZzFX sound generator integration: <a href=https://killedbyapixel.github.io/ZzFX/>ZzFX</a>
5
+ * - Sound caching for fast playback and memory efficiency
6
+ * - Volume control with attenuation and stereo panning
7
+ * - 2D spatial audio based on camera position with distance-based falloff
8
+ * - Sound instance management (pause, resume, stop)
9
+ * - Speech synthesis for text-to-speech
10
+ * - Music playback with ZzFXM support
11
+ * - Web Audio API integration with master gain control
9
12
  * @namespace Audio
10
13
  */
11
14
 
@@ -1,19 +1,27 @@
1
- #!/usr/bin/env node
2
-
3
1
  /**
4
2
  * LittleJS Build System
5
- * - Combine input files
6
- * - Run custom build steps
7
- * - Check for errors
8
- * - Output to build folder
3
+ * - Concatenates engine source files into distributable bundles
4
+ * - Generates multiple output formats (standard, ES6 module, minified)
5
+ * - Creates debug and release builds (with/without debug code)
6
+ * - Produces TypeScript definition file (.d.ts)
7
+ * - Includes plugin files in builds
8
+ * - Validates code and checks for errors
9
+ * - Outputs to dist/ folder
9
10
  */
10
11
 
11
- 'use strict';
12
+ import fs from 'node:fs';
13
+ import { execSync } from 'node:child_process';
14
+ import { fileURLToPath } from 'node:url';
15
+ import { dirname, join } from 'node:path';
16
+
17
+ const __filename = fileURLToPath(import.meta.url);
18
+ const __dirname = dirname(__filename);
19
+ const ROOT_DIR = join(__dirname, '..');
12
20
 
13
21
  const ENGINE_NAME = 'littlejs';
14
- const BUILD_FOLDER = 'dist';
15
- const SOURCE_FOLDER = 'src';
16
- const PLUGIN_FOLDER = 'plugins';
22
+ const BUILD_FOLDER = join(ROOT_DIR, 'dist');
23
+ const SOURCE_FOLDER = join(ROOT_DIR, 'src');
24
+ const PLUGIN_FOLDER = join(ROOT_DIR, 'plugins');
17
25
  const engineSourceFiles =
18
26
  [
19
27
  `${SOURCE_FOLDER}/engineMath.js`,
@@ -53,10 +61,8 @@ const license = '// LittleJS Engine - MIT License - Copyright 2021 Frank Force\n
53
61
  '// https://github.com/KilledByAPixel/LittleJS\n\n';
54
62
 
55
63
  console.log(asciiArt);
56
- console.log('Choo Choo... Building LittleJS Engine!\n');
64
+ console.log('🚂 Choo Choo... Building LittleJS Engine!');
57
65
  const startTime = Date.now();
58
- const fs = require('node:fs');
59
- const child_process = require('node:child_process');
60
66
 
61
67
  try
62
68
  {
@@ -71,71 +77,82 @@ try
71
77
  }
72
78
  catch (e) { handleError(e, 'Failed to create build folder!'); }
73
79
 
74
- Build
75
- (
76
- 'Build Engine -- all',
77
- `${BUILD_FOLDER}/${ENGINE_NAME}.js`,
78
- [
79
- `${SOURCE_FOLDER}/engine.js`,
80
- `${SOURCE_FOLDER}/engineDebug.js`,
81
- ...engineSourceFiles,
82
- ...enginePluginFiles
83
- ],
84
- [], true
85
- );
86
-
87
- Build
88
- (
89
- 'Build Engine -- release',
90
- `${BUILD_FOLDER}/${ENGINE_NAME}.release.js`,
91
- [
92
- `${SOURCE_FOLDER}/engine.js`,
93
- `${SOURCE_FOLDER}/engineRelease.js`,
94
- ...engineSourceFiles,
95
- ...enginePluginFiles
96
- ],
97
- [], true
98
- );
99
-
100
- Build
101
- (
102
- 'Build Engine -- minified',
103
- `${BUILD_FOLDER}/${ENGINE_NAME}.min.js`,
104
- [`${BUILD_FOLDER}/${ENGINE_NAME}.release.js`],
105
- [closureCompilerStep, uglifyBuildStep, addLicenseStep]
106
- );
107
-
108
- Build
109
- (
110
- 'Build Engine -- ESM',
111
- `${BUILD_FOLDER}/${ENGINE_NAME}.esm.js`,
112
- [
113
- `${BUILD_FOLDER}/${ENGINE_NAME}.js`,
114
- `${SOURCE_FOLDER}/engineExport.js`,
115
- `${PLUGIN_FOLDER}/pluginExport.js`
116
- ],
117
- [typeScriptBuildStep]
118
- );
119
-
120
- Build
121
- (
122
- 'Build Engine -- ESM minified release',
123
- `${BUILD_FOLDER}/${ENGINE_NAME}.esm.min.js`,
124
- [
125
- `${BUILD_FOLDER}/${ENGINE_NAME}.release.js`,
126
- `${SOURCE_FOLDER}/engineExport.js`,
127
- `${PLUGIN_FOLDER}/pluginExport.js`
128
- ],
129
- [uglifyBuildStep, addLicenseStep]
130
- );
131
-
132
- console.log(`Engine built in ${((Date.now() - startTime)/1e3).toFixed(2)} seconds!`);
80
+ // Build all versions
81
+ await buildAll();
82
+
83
+ console.log(`Engine built in ${((Date.now() - startTime)/1e3).toFixed(2)} seconds! ✨`);
84
+
85
+ ///////////////////////////////////////////////////////////////////////////////
86
+
87
+ async function buildAll()
88
+ {
89
+ // Build independent base versions in parallel
90
+ await Promise.all([
91
+ Build
92
+ (
93
+ 'Build Engine -- all',
94
+ `${BUILD_FOLDER}/${ENGINE_NAME}.js`,
95
+ [
96
+ `${SOURCE_FOLDER}/engine.js`,
97
+ `${SOURCE_FOLDER}/engineDebug.js`,
98
+ ...engineSourceFiles,
99
+ ...enginePluginFiles
100
+ ],
101
+ [], true
102
+ ),
103
+ Build
104
+ (
105
+ 'Build Engine -- release',
106
+ `${BUILD_FOLDER}/${ENGINE_NAME}.release.js`,
107
+ [
108
+ `${SOURCE_FOLDER}/engine.js`,
109
+ `${SOURCE_FOLDER}/engineRelease.js`,
110
+ ...engineSourceFiles,
111
+ ...enginePluginFiles
112
+ ],
113
+ [], true
114
+ )
115
+ ]);
116
+
117
+ // Build dependent versions in parallel
118
+ await Promise.all([
119
+ Build
120
+ (
121
+ 'Build Engine -- minified',
122
+ `${BUILD_FOLDER}/${ENGINE_NAME}.min.js`,
123
+ [`${BUILD_FOLDER}/${ENGINE_NAME}.release.js`],
124
+ [closureCompilerStep, uglifyBuildStep, addLicenseStep]
125
+ ),
126
+ Build
127
+ (
128
+ 'Build Engine -- ESM',
129
+ `${BUILD_FOLDER}/${ENGINE_NAME}.esm.js`,
130
+ [
131
+ `${BUILD_FOLDER}/${ENGINE_NAME}.js`,
132
+ `${SOURCE_FOLDER}/engineExport.js`,
133
+ `${PLUGIN_FOLDER}/pluginExport.js`
134
+ ],
135
+ [typeScriptBuildStep]
136
+ ),
137
+ Build
138
+ (
139
+ 'Build Engine -- ESM minified release',
140
+ `${BUILD_FOLDER}/${ENGINE_NAME}.esm.min.js`,
141
+ [
142
+ `${BUILD_FOLDER}/${ENGINE_NAME}.release.js`,
143
+ `${SOURCE_FOLDER}/engineExport.js`,
144
+ `${PLUGIN_FOLDER}/pluginExport.js`
145
+ ],
146
+ [uglifyBuildStep, addLicenseStep]
147
+ )
148
+ ]);
149
+ }
133
150
 
134
151
  ///////////////////////////////////////////////////////////////////////////////
135
152
 
136
153
  // A single build with its own source files, build steps, and output file
137
154
  // - each build step is a callback that accepts a single filename
138
- function Build(message, outputFile, files=[], buildSteps=[], isPrimaryBuild)
155
+ async function Build(message, outputFile, files=[], buildSteps=[], isPrimaryBuild)
139
156
  {
140
157
  console.log(message);
141
158
 
@@ -176,18 +193,18 @@ function closureCompilerStep(filename)
176
193
  fs.copyFileSync(filename, filenameTemp);
177
194
  try
178
195
  {
179
- child_process.execSync(`npx google-closure-compiler --js=${filenameTemp} --js_output_file=${filename} --warning_level=VERBOSE --jscomp_off=*`);
196
+ execSync(`npx google-closure-compiler --js=${filenameTemp} --js_output_file=${filename} --warning_level=VERBOSE --jscomp_off=*`);
180
197
  fs.rmSync(filenameTemp);
181
198
  }
182
199
  catch (e) { handleError(e, 'Failed to run Closure Compiler step!'); }
183
- };
200
+ }
184
201
 
185
202
  // Process with Uglify to minify
186
203
  function uglifyBuildStep(filename)
187
204
  {
188
205
  try
189
206
  {
190
- child_process.execSync(`npx uglifyjs ${filename} -o ${filename}`);
207
+ execSync(`npx uglifyjs ${filename} -o ${filename}`);
191
208
  }
192
209
  catch (e) { handleError(e,'Failed to run Uglify minification step!'); }
193
210
  };
@@ -210,8 +227,8 @@ function typeScriptBuildStep(filename)
210
227
  {
211
228
  try
212
229
  {
213
- const tsFilename = `${BUILD_FOLDER}/${ENGINE_NAME}.d.ts`
214
- child_process.execSync(`npx tsc ${filename} --declaration --allowJs --emitDeclarationOnly --outFile ${tsFilename}`);
230
+ const tsFilename = join(BUILD_FOLDER, `${ENGINE_NAME}.d.ts`);
231
+ execSync(`npx -p typescript tsc ${filename} --declaration --allowJs --emitDeclarationOnly --outFile ${tsFilename}`);
215
232
 
216
233
  // Make declare module part use the package name littlejsengine
217
234
  let fileContent = fs.readFileSync(tsFilename, 'utf8');
@@ -1,10 +1,13 @@
1
1
  /**
2
2
  * LittleJS Debug System
3
- * - Press Esc to show debug overlay with mouse pick
4
- * - Number keys toggle debug functions
5
- * - +/- apply time scale
6
- * - Debug primitive rendering
7
- * - Save a 2d canvas as a png image
3
+ * - Press Esc to toggle debug overlay with object picking
4
+ * - Number keys toggle debug visualizations (physics, particles, etc.)
5
+ * - +/- keys control time scale for slow motion/fast forward
6
+ * - ASSERT and LOG macros for development (removed in release builds)
7
+ * - Debug primitive rendering (rectangles, circles, lines, points, text)
8
+ * - Screenshot and video capture support
9
+ * - FPS counter and performance watermark
10
+ * - Debug overlay shows mouse position and picked objects
8
11
  * @namespace Debug
9
12
  */
10
13