littlejsengine 1.25.0 → 1.26.0

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 (51) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/FAQ.md +49 -11
  3. package/README.md +6 -2
  4. package/REFERENCE.md +120 -18
  5. package/dist/littlejs.d.ts +464 -99
  6. package/dist/littlejs.esm.js +2853 -704
  7. package/dist/littlejs.esm.min.js +3 -3
  8. package/dist/littlejs.js +2844 -701
  9. package/dist/littlejs.min.js +2 -2
  10. package/dist/littlejs.release.js +2658 -512
  11. package/package.json +4 -4
  12. package/plugins/box2d.js +110 -34
  13. package/plugins/gltf.js +74 -22
  14. package/plugins/lightSystem.js +410 -28
  15. package/plugins/math3d.js +4 -2
  16. package/plugins/medalSystem.js +19 -7
  17. package/plugins/newgrounds.js +4 -2
  18. package/plugins/parallax.js +1 -0
  19. package/plugins/particleEffects.js +44 -10
  20. package/plugins/pathFinder.js +9 -11
  21. package/plugins/pluginExport.js +9 -0
  22. package/plugins/postProcess.js +4 -2
  23. package/plugins/render3d.js +485 -2385
  24. package/plugins/render3dDebug.js +5 -8
  25. package/plugins/render3dEditor.js +81 -6
  26. package/plugins/render3dExtras.js +103 -31
  27. package/plugins/render3dLevel.js +53 -5
  28. package/plugins/render3dMesh.js +1158 -0
  29. package/plugins/render3dObject.js +1451 -0
  30. package/plugins/render3dVoxels.js +15 -3
  31. package/plugins/textureSheet.js +9 -8
  32. package/plugins/threejs.js +1 -1
  33. package/plugins/tweenSystem.js +76 -51
  34. package/plugins/uiSystem.js +37 -8
  35. package/plugins/wavedash.js +229 -0
  36. package/src/engine.js +184 -36
  37. package/src/engineAudio.js +37 -21
  38. package/src/engineBuild.mjs +6 -1
  39. package/src/engineDebug.js +22 -162
  40. package/src/engineDraw.js +139 -34
  41. package/src/engineEditor.js +79 -18
  42. package/src/engineExport.js +0 -3
  43. package/src/engineInput.js +27 -18
  44. package/src/engineMath.js +35 -14
  45. package/src/engineObject.js +60 -41
  46. package/src/engineParticles.js +58 -11
  47. package/src/engineRelease.js +1 -5
  48. package/src/engineSettings.js +48 -9
  49. package/src/engineTileLayer.js +11 -4
  50. package/src/engineUtilities.js +41 -9
  51. package/src/engineWebGL.js +37 -13
@@ -85,7 +85,7 @@ declare module "littlejsengine" {
85
85
  */
86
86
  export type SpriteAnimationEndCallback = () => void;
87
87
  /**
88
- * - Function called when sound is loaded
88
+ * - Function called once a sound has loaded, or failed to, which sound.isLoaded() tells
89
89
  */
90
90
  export type SoundLoadCallback = (sound: Sound) => any;
91
91
  /**
@@ -191,6 +191,7 @@ declare module "littlejsengine" {
191
191
  reflectivity: number;
192
192
  emissiveMap: TextureInfo | undefined;
193
193
  emissiveMapColor: Color;
194
+ environmentMap: CubeMap | undefined;
194
195
  emissiveR: number;
195
196
  emissiveG: number;
196
197
  emissiveB: number;
@@ -295,7 +296,8 @@ declare module "littlejsengine" {
295
296
  */
296
297
  objects: Array<any>;
297
298
  /**
298
- * - The scene block: sky, ambient, sunDirection, sunColor, fog, fogColor, shadows, lensFlare
299
+ * - The scene block: sky, ambient, sunDirection, sunColor, fog, fogColor, shadows, lensFlare,
300
+ * skyBox, environment
299
301
  */
300
302
  scene?: any;
301
303
  /**
@@ -644,7 +646,7 @@ declare module "littlejsengine" {
644
646
  * @param {GameCallback} [gameUpdatePost] - Called after physics and objects are updated, even when paused, use for UI updates
645
647
  * @param {GameCallback} [gameRender] - Called before objects are rendered, use for drawing backgrounds/world elements
646
648
  * @param {GameCallback} [gameRenderPost] - Called after objects are rendered, use for drawing UI/overlays
647
- * @param {Array<string>} [imageSources=[]] - List of image file paths to preload (e.g., ['player.png', 'tiles.png'])
649
+ * @param {Array<string>|string} [imageSources=[]] - List of image file paths to preload (e.g., ['player.png', 'tiles.png']), or one path
648
650
  * @param {HTMLElement} [rootElement] - Root DOM element to attach canvas to, defaults to document.body
649
651
  * It keeps its own inline styles and the canvas centers inside it, but the canvas is still sized from the window,
650
652
  * so set canvasFixedSize or canvasMaxSize to fit a smaller element
@@ -660,7 +662,7 @@ declare module "littlejsengine" {
660
662
  * );
661
663
  * @memberof Engine
662
664
  * @return {Promise<void>} - Done when the images have loaded and gameInit has run */
663
- export function engineInit(gameInit?: GameInitCallback, gameUpdate?: GameCallback, gameUpdatePost?: GameCallback, gameRender?: GameCallback, gameRenderPost?: GameCallback, imageSources?: string[], rootElement?: HTMLElement): Promise<void>;
665
+ export function engineInit(gameInit?: GameInitCallback, gameUpdate?: GameCallback, gameUpdatePost?: GameCallback, gameRender?: GameCallback, gameRenderPost?: GameCallback, imageSources?: string | string[], rootElement?: HTMLElement): Promise<void>;
664
666
  /** Advance the engine by a number of frames
665
667
  * Requires setEngineManualStep(true), before engineInit or while running; it stops early if an update turns it off
666
668
  * Respects paused exactly as the normal update loop does
@@ -670,7 +672,7 @@ declare module "littlejsengine" {
670
672
  * setHeadlessMode(true);
671
673
  * setEngineManualStep(true);
672
674
  * await engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost);
673
- * engineStep(600); // advance 10 seconds of game time
675
+ * engineStep(600); // 600 updates of 1/60 second; the first is at time 0, so time is then 599/60
674
676
  * @memberof Engine */
675
677
  export function engineStep(frames?: number): void;
676
678
  /** Update each engine object and remove destroyed objects; time and frame are advanced by the engine loop, not here
@@ -747,7 +749,7 @@ declare module "littlejsengine" {
747
749
  * - setDebugKeysAlways lets those keys work with the overlay closed too
748
750
  * - ASSERT and LOG macros for development (removed in release builds)
749
751
  * - Debug primitive rendering (rectangles, circles, lines, points, text)
750
- * - Screenshot and video capture support
752
+ * - Screenshot support
751
753
  * - FPS counter and performance watermark
752
754
  * - Debug overlay shows mouse position and picked objects
753
755
  * @namespace Debug
@@ -1113,16 +1115,6 @@ declare module "littlejsengine" {
1113
1115
  * In release builds this function has no effect
1114
1116
  * @memberof Debug */
1115
1117
  export function debugShowErrors(): void;
1116
- /** Start capturing video
1117
- * @memberof Debug */
1118
- export function debugVideoCaptureStart(): void;
1119
- /** Stop capturing video and save to disk
1120
- * @memberof Debug */
1121
- export function debugVideoCaptureStop(): void;
1122
- /** Check if video capture is active
1123
- * @memberof Debug
1124
- * @return {boolean} */
1125
- export function debugVideoCaptureIsActive(): boolean;
1126
1118
  /**
1127
1119
  * LittleJS Engine Settings
1128
1120
  * - All settings for the engine are here
@@ -1504,6 +1496,7 @@ declare module "littlejsengine" {
1504
1496
  export function setCameraScale(scale: number): void;
1505
1497
  /** Set scale applied to engine time
1506
1498
  * - 0 freezes the game like a pause, gameUpdatePost and input still run so the game can set it back
1499
+ * - Above 1 the fixed step runs that many updates each frame, so a large scale costs as many updates
1507
1500
  * @param {number} scale - 0 or more
1508
1501
  * @memberof Settings */
1509
1502
  export function setTimeScale(scale: number): void;
@@ -1563,6 +1556,7 @@ declare module "littlejsengine" {
1563
1556
  * @memberof Settings */
1564
1557
  export function getCanvasPixelRatio(): number;
1565
1558
  /** Set default font used for text rendering
1559
+ * - A family name with spaces or digits goes in quotes, as "'Press Start 2P'", or the canvas does not take it
1566
1560
  * @param {string} font
1567
1561
  * @memberof Settings */
1568
1562
  export function setFontDefault(font: string): void;
@@ -1732,7 +1726,8 @@ declare module "littlejsengine" {
1732
1726
  * @param {boolean} enable
1733
1727
  * @memberof Settings */
1734
1728
  export function setVibrateEnable(enable: boolean): void;
1735
- /** Set if audio is enabled, false turns all sound off
1729
+ /** Set if audio is enabled, false turns all sound off; a setting for before sounds are made, since a sound made
1730
+ * while it is off has nothing to play and one already playing goes on; to mute while the game runs, setSoundVolume(0)
1736
1731
  * @param {boolean} enable
1737
1732
  * @memberof Settings */
1738
1733
  export function setSoundEnable(enable: boolean): void;
@@ -1835,7 +1830,7 @@ declare module "littlejsengine" {
1835
1830
  * @param {...number} values
1836
1831
  * @return {number}
1837
1832
  * @memberof Math */
1838
- export function hypot(...values: number[]): number;
1833
+ export const hypot: (...values: number[]) => number;
1839
1834
  /** Returns log2 of value passed in
1840
1835
  * @param {number} x
1841
1836
  * @return {number}
@@ -2073,7 +2068,7 @@ declare module "littlejsengine" {
2073
2068
  * @return {number}
2074
2069
  * @memberof Utilities */
2075
2070
  export function noise1D(x: number): number;
2076
- /** 2D value noise — returns a smooth value in [0, 1] for any real (x, y).
2071
+ /** 2D value noise — returns a smooth value in [0, 1] for any real (x, y)
2077
2072
  * @param {number} x
2078
2073
  * @param {number} y
2079
2074
  * @return {number}
@@ -2921,6 +2916,11 @@ declare module "littlejsengine" {
2921
2916
  /** @property {WebGLProgram|undefined} - The 3D program, compiled by the 3D plugin the same way, read only
2922
2917
  * @type {WebGLProgram|undefined} */
2923
2918
  program3D: WebGLProgram | undefined;
2919
+ /** Let go of this shader: its compiled programs are freed and it leaves the engine's list of shaders, which
2920
+ * keeps every one made for a lost context, so a scene made again and again, or an editor trying snippets, does
2921
+ * not keep them all; calling it again does nothing, and a draw with it afterwards compiles it again and takes it
2922
+ * back, so only let go of one no object still draws with when it should stay freed */
2923
+ dispose(): void;
2924
2924
  }
2925
2925
  /**
2926
2926
  * LittleJS Drawing System
@@ -3236,7 +3236,7 @@ declare module "littlejsengine" {
3236
3236
  export function setShader(shader?: Shader): void;
3237
3237
  /** Set an extra canvas to composite behind the engine canvases when combining
3238
3238
  * Plugins that insert their own canvas below the LittleJS canvases should set
3239
- * this so it appears in screenshots and video capture
3239
+ * this so it appears in screenshots
3240
3240
  * @param {HTMLCanvasElement} [canvas]
3241
3241
  * @memberof Draw */
3242
3242
  export function setBackgroundCanvas(canvas?: HTMLCanvasElement): void;
@@ -3760,7 +3760,6 @@ declare module "littlejsengine" {
3760
3760
  * - The output node is disconnected from everything else first, so it only feeds the speakers
3761
3761
  * - The two ends of a chain must already be connected to each other, like effectA.connect(effectB)
3762
3762
  * - Call with no arguments to remove the effect, an effect that was the master goes back to feeding the master gain
3763
- * - Debug video capture records the end of the master chain, but loses its tap if the effect changes mid-capture
3764
3763
  * @param {AudioNode|AudioEffectNodes} [input] - Node or effect the master gain connects to
3765
3764
  * @param {AudioNode|AudioEffectNodes} [output] - Node or effect that connects to the audio destination, defaults to the input's output
3766
3765
  * @memberof Audio */
@@ -3774,7 +3773,7 @@ declare module "littlejsengine" {
3774
3773
  * @memberof Audio */
3775
3774
  export function audioIsRunning(): boolean;
3776
3775
  /**
3777
- * @callback SoundLoadCallback - Function called when sound is loaded
3776
+ * @callback SoundLoadCallback - Function called once a sound has loaded, or failed to, which sound.isLoaded() tells
3778
3777
  * @param {Sound} sound
3779
3778
  * @memberof Audio
3780
3779
  */
@@ -3803,7 +3802,8 @@ declare module "littlejsengine" {
3803
3802
  * @param {number} [randomness] - How much to randomize frequency each time sound plays, for zzfx sounds it overrides the array's own randomness, which is used if undefined
3804
3803
  * @param {number} [range=soundDefaultRange] - World space max range of sound
3805
3804
  * @param {number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering
3806
- * @param {SoundLoadCallback} [onloadCallback] - callback function to call when sound is loaded
3805
+ * @param {SoundLoadCallback} [onloadCallback] - Called once the sound has loaded, or its file failed to, so a
3806
+ * game counting its sounds goes on; isLoaded says which
3807
3807
  */
3808
3808
  constructor(asset?: string | URL | (number | undefined)[], randomness?: number, range?: number, taper?: number, onloadCallback?: SoundLoadCallback);
3809
3809
  loadedPercent: number;
@@ -3893,7 +3893,7 @@ declare module "littlejsengine" {
3893
3893
  * @return {boolean} - True if sound is loaded and ready to play
3894
3894
  */
3895
3895
  isLoaded(): boolean;
3896
- /** Loads a sound from a URL and decodes it into sample data.
3896
+ /** Loads a sound from a URL and decodes it into sample data
3897
3897
  * @param {string} filename
3898
3898
  * @return {Promise} */
3899
3899
  loadSound(filename: string): Promise<any>;
@@ -3925,11 +3925,11 @@ declare module "littlejsengine" {
3925
3925
  /** @property {Sound} - The sound object */
3926
3926
  sound: Sound;
3927
3927
  /** @property {number} - How much to scale volume by */
3928
- volume: number;
3928
+ volume: any;
3929
3929
  /** @property {number} - The playback rate to use */
3930
- rate: number;
3930
+ rate: any;
3931
3931
  /** @property {number} - How much to apply stereo panning */
3932
- pan: number;
3932
+ pan: any;
3933
3933
  /** @property {boolean} - Should the sound loop */
3934
3934
  loop: boolean;
3935
3935
  /** @property {number|undefined} - Where it is in the sound while not playing, in the sound's own seconds, undefined while playing
@@ -4082,8 +4082,8 @@ declare module "littlejsengine" {
4082
4082
  * @param {number} [release] - Release time, how fast sound fades out (seconds)
4083
4083
  * @param {number} [shape] - Shape of the sound wave
4084
4084
  * @param {number} [shapeCurve] - Squareness of wave (0=square, 1=normal, 2=pointy)
4085
- * @param {number} [slide] - How much to slide frequency (kHz/s)
4086
- * @param {number} [deltaSlide] - How much to change slide (kHz/s/s)
4085
+ * @param {number} [slide] - How much to slide frequency, 1 is about 500 Hz a second, as ZzFX has it
4086
+ * @param {number} [deltaSlide] - How much to change slide each second, in the units of slide
4087
4087
  * @param {number} [pitchJump] - Frequency of pitch jump (Hz)
4088
4088
  * @param {number} [pitchJumpTime] - Time of pitch jump (seconds)
4089
4089
  * @param {number} [repeatTime] - Resets some parameters periodically (seconds)
@@ -4094,7 +4094,8 @@ declare module "littlejsengine" {
4094
4094
  * @param {number} [sustainVolume] - Volume level for sustain (percent)
4095
4095
  * @param {number} [decay] - Decay time, how long to reach sustain after attack (seconds)
4096
4096
  * @param {number} [tremolo] - Trembling effect, rate controlled by repeat time (percent)
4097
- * @param {number} [filter] - Filter cutoff frequency, positive for HPF, negative for LPF (Hz)
4097
+ * @param {number} [filter] - Filter cutoff, positive for HPF, negative for LPF; the cutoff is about twice this in
4098
+ * Hz, as ZzFX has it, and its resonance can take the samples past 1
4098
4099
  * @return {Float32Array} - The audio samples
4099
4100
  * @memberof Audio */
4100
4101
  export function zzfxG(volume?: number, randomness?: number, frequency?: number, attack?: number, sustain?: number, release?: number, shape?: number, shapeCurve?: number, slide?: number, deltaSlide?: number, pitchJump?: number, pitchJumpTime?: number, repeatTime?: number, noise?: number, modulation?: number, bitCrush?: number, delay?: number, sustainVolume?: number, decay?: number, tremolo?: number, filter?: number): Float32Array;
@@ -4167,6 +4168,9 @@ declare module "littlejsengine" {
4167
4168
  shader: Shader | undefined;
4168
4169
  /** @property {boolean} - Does this object draw into the light system's shadow map; false for a floor layer, a background, a pickup */
4169
4170
  castShadow: boolean;
4171
+ /** @property {boolean} - Does this object draw into the light system's background map, which a
4172
+ * DirectionalLight lights only at its edges facing the light; for a background layer, with castShadow false */
4173
+ castBackgroundShadow: boolean;
4170
4174
  /** @property {number} - With the light system, how much it lights itself: 0 lit only by the lights, 1 full
4171
4175
  * brightness in its own colors whatever the lights do, between partly; drawn into the lightmap through
4172
4176
  * renderEmissive, as 3D's emissive. Exact for solid pixels; a partly transparent one is self lit by its alpha
@@ -4230,15 +4234,19 @@ declare module "littlejsengine" {
4230
4234
  /** Update the object transform, called automatically by engine even when paused
4231
4235
  * @param {boolean} [updateChildren] - Also update the children's transforms */
4232
4236
  updateTransforms(updateChildren?: boolean): void;
4233
- /** Update the object physics, called automatically by engine once each frame. Can be overridden to stop or change how physics works for an object. */
4237
+ /** Update the object physics, called automatically by engine once each frame. Can be overridden to stop or change how physics works for an object
4238
+ * - With many solids each mover finds those near it through a grid, which follows a solid after its own physics
4239
+ * update: a solid an override moves for another object, a lift carrying a crate, is found there from the next
4240
+ * update on */
4234
4241
  updatePhysics(): void;
4235
- /** Update the object, called automatically by engine once each frame. Does nothing by default. */
4242
+ /** Update the object, called automatically by engine once each frame. Does nothing by default */
4236
4243
  update(): void;
4237
4244
  /** Render the object, draws a tile by default, automatically called each frame, sorted by renderOrder */
4238
4245
  render(): void;
4239
- /** Optional hook called during the light system plugin's lightmap pass to draw this object's lightmap contribution. Does nothing by default. */
4246
+ /** Optional hook called during the light system plugin's lightmap pass to draw this object's lightmap contribution. Does nothing by default */
4240
4247
  renderLight(): void;
4241
- /** Draw this object into the light system's shadow map, called during its shadow pass when castShadow is set.
4248
+ /** Draw this object into the light system's shadow map, called during its shadow pass when castShadow is set, and into
4249
+ * its background map when castBackgroundShadow is set and a DirectionalLight is out.
4242
4250
  * Calls render() by default so the object casts its own shape; override to cast a different one, like a blob at a character's feet so its body stays lit;
4243
4251
  * screen space WebGL draws in render() are skipped during the pass */
4244
4252
  renderShadow(): void;
@@ -4265,19 +4273,23 @@ declare module "littlejsengine" {
4265
4273
  * @param {Vector2} vec - world space vector
4266
4274
  * @return {Vector2} */
4267
4275
  worldToLocalVector(vec: Vector2): Vector2;
4268
- /** Called to check if a tile collision should be resolved. Return true for physics to resolve the collision or false to ignore and resolve it manually.
4276
+ /** Called to check if a tile collision should be resolved. Return true for physics to resolve the collision or false to ignore and resolve it manually
4269
4277
  * - Called for each solid tile the physics tests, which can be several times a frame for the same tile, and for
4270
4278
  * positions it only tries, so keep it free of side effects or guard them to once a frame
4271
4279
  * - this.pos has already moved, so a check on where it came from, like a one way platform, needs the position
4272
4280
  * saved in update, as the platformer example does
4281
+ * - For the point of impact, like sparks where a bullet hit, raycast from where this frame's move started,
4282
+ * this.pos minus this.velocity, to this.pos with tileCollisionRaycast, as the platformer's Bullet does
4273
4283
  * @param {number} tileData - the value of the tile at the position
4274
4284
  * @param {Vector2} pos - the tile's bottom left corner in world space
4275
4285
  * @return {boolean} - true if the collision should be resolved by modifying it's position and velocity */
4276
4286
  collideWithTile(tileData: number, pos: Vector2): boolean;
4277
- /** Called by the engine to check if an object collision should be resolved. Return true for physics to resolve the collision or false to ignore and resolve it manually.
4287
+ /** Called by the engine to check if an object collision should be resolved. Return true for physics to resolve the collision or false to ignore and resolve it manually
4278
4288
  * - Both objects of a touching pair are asked once a frame, whichever order they update in; an object that
4279
4289
  * destroys itself here is gone at the end of the frame and is still asked about the pairs left this frame, so a
4280
4290
  * bullet that should hit one thing checks its own destroyed flag first
4291
+ * - With many solids each mover finds those near it through a grid, which follows the other object after this
4292
+ * returns; a third object moved here is found where it is now from the next update on
4281
4293
  * @param {EngineObject} object - the object to test against
4282
4294
  * @param {Vector3} [push] - what it would take to move this object clear, a Vector3 from the 3D plugin, undefined in 2D
4283
4295
  * @return {boolean} - true if the collision should be resolved by modifying it's position and velocity
@@ -4781,7 +4793,7 @@ declare module "littlejsengine" {
4781
4793
  * @param {number} [angleSpeed] - How fast are particles rotating, in radians per frame (at 60fps)
4782
4794
  * @param {number} [damping] - How much to dampen particle speed, per-frame velocity multiplier (1 = no damping, .9 = lose 10% speed each frame)
4783
4795
  * @param {number} [angleDamping] - How much to dampen particle angular speed, per-frame multiplier (1 = no damping)
4784
- * @param {number} [gravityScale] - How much gravity effect particles
4796
+ * @param {number} [gravityScale] - How much gravity affects particles
4785
4797
  * @param {number} [particleConeAngle] - Half angle each side of the emitter's angle for a particle's start angle, PI is any angle
4786
4798
  * @param {number} [fadeRate] - Fraction of life spent fading: half at fade-in (start), half at fade-out (end). e.g. .2 = 10% fade-in, 80% full opacity, 10% fade-out
4787
4799
  * @param {number} [randomness] - Apply extra randomness percent
@@ -4796,7 +4808,8 @@ declare module "littlejsengine" {
4796
4808
  emitCircle: boolean;
4797
4809
  /** @property {Vector2} - World space size of the emitter, x is the diameter when emitCircle is set */
4798
4810
  emitSize: Vector2;
4799
- /** @property {number} - How long to stay alive (0 is forever) */
4811
+ /** @property {number} - How long to emit for in seconds, 0 is forever; raised while its particles are still
4812
+ * alive, it emits again for the added time */
4800
4813
  emitTime: number;
4801
4814
  /** @property {number} - How many particles per second to spawn, does not emit if 0 */
4802
4815
  emitRate: number;
@@ -4857,12 +4870,17 @@ declare module "littlejsengine" {
4857
4870
  velocityInheritance: number;
4858
4871
  /** @property {number} - Particles owed to the emit rate, starts at one so the first comes out at once */
4859
4872
  emitTimeBuffer: number;
4873
+ /** @property {number} - Seconds of its emit time it has emitted for, counted by its updates
4874
+ * @type {number} */
4875
+ emitElapsed: number;
4860
4876
  /** @property {Array<Particle>} - Array of particles for this emitter
4861
4877
  * @type {Array<Particle>} */
4862
4878
  particles: Array<Particle>;
4863
4879
  /** @type {Vector2|undefined} */
4864
4880
  previousPos: Vector2 | undefined;
4865
4881
  previousAngle: number;
4882
+ emitFrom: Vector2;
4883
+ emitBehind: number;
4866
4884
  /** Spawn one particle
4867
4885
  * @return {Particle} */
4868
4886
  emitParticle(): Particle;
@@ -4966,6 +4984,7 @@ declare module "littlejsengine" {
4966
4984
  * - Call this after creating all medals
4967
4985
  * - Loads which medals are unlocked from the save, and writes the catalog back
4968
4986
  * - A medal a service like Newgrounds holds is left as it is, see Medal.isLocal
4987
+ * - A medal unlocked before the first call stays unlocked and is saved by it
4969
4988
  * @param {string} saveName - The localStorage key the medals are kept under, a different one from the game's own
4970
4989
  * readSaveData and writeSaveData, or each would overwrite the other
4971
4990
  * @memberof Medals */
@@ -5097,10 +5116,12 @@ declare module "littlejsengine" {
5097
5116
  cryptoKey: CryptoKey | undefined;
5098
5117
  /** @property {string} - Hostname sent with the view the plugin logs when it starts */
5099
5118
  host: string;
5100
- /** @property {Array} - Medals fetched from Newgrounds, empty until ready, with the unlocks only when logged in */
5101
- medals: any[];
5102
- /** @property {Array} - Scoreboards fetched from Newgrounds, empty until ready */
5103
- scoreboards: any[];
5119
+ /** @property {Array<Object>} - Medals fetched from Newgrounds, empty until ready, with the unlocks only when logged in
5120
+ * @type {Array<Object>} */
5121
+ medals: Array<any>;
5122
+ /** @property {Array<Object>} - Scoreboards fetched from Newgrounds, empty until ready
5123
+ * @type {Array<Object>} */
5124
+ scoreboards: Array<any>;
5104
5125
  /** @property {{id: number, name: string, url: string, supporter: boolean}|null} - The logged in player once ready, null when not logged in
5105
5126
  * @type {{id: number, name: string, url: string, supporter: boolean}|null} */
5106
5127
  user: {
@@ -5176,6 +5197,123 @@ declare module "littlejsengine" {
5176
5197
  * @type {number|undefined} */
5177
5198
  value: number | undefined;
5178
5199
  }
5200
+ /**
5201
+ * LittleJS Wavedash Plugin
5202
+ * - The Wavedash twin of the Newgrounds plugin: achievements and leaderboards, the same shape so a game can switch
5203
+ * - Wavedash serves the game's page and puts its SDK in window.Wavedash before the game runs, so nothing is bundled;
5204
+ * off Wavedash (local, itch, GitHub Pages) there is none, and every call does nothing
5205
+ * - Make the plugin when the game can draw, at the end of gameInit: Wavedash.init is called then, and until it is
5206
+ * Wavedash keeps its loading screen over the game
5207
+ * - WavedashMedal is a Medal with the identifier of its Wavedash achievement; on Wavedash an unlock is sent as that
5208
+ * achievement and Wavedash shows its own toast in place of the engine's popup, off it the medal unlocks as any does
5209
+ * - Wavedash refuses an achievement until it has loaded the player's, a moment after launch, so refused and earlier
5210
+ * unlocks are sent again every two seconds until it takes them; medals unlocked before, in the save, are sent too
5211
+ * - Leaderboards are made from code: give the plugin a table of them, each with how it sorts and shows its scores,
5212
+ * and they are made at once, so each one exists from the first launch
5213
+ * - The SDK checks its arguments' types and throws on a wrong one, so every call passes real booleans and whole
5214
+ * numbers and is caught; a game built with its own minifier keeps the SDK's names, see REFERENCE
5215
+ * @namespace Wavedash
5216
+ */
5217
+ /** Global Wavedash plugin object
5218
+ * @type {WavedashPlugin}
5219
+ * @memberof Wavedash */
5220
+ export let wavedash: WavedashPlugin;
5221
+ /**
5222
+ * Wavedash plugin: starts the Wavedash SDK, sends achievements and posts and reads leaderboards
5223
+ * @memberof Wavedash
5224
+ * @example
5225
+ * // at the end of gameInit, with the leaderboards the game posts to
5226
+ * new WavedashPlugin({LEVEL_1: {lowerWins: true, display: 'milliseconds'}, HIGH_SCORE: {}});
5227
+ * wavedash.postScore('LEVEL_1', timeMs);
5228
+ */
5229
+ export class WavedashPlugin {
5230
+ /** Start the Wavedash SDK when the game is on Wavedash, and make its leaderboards
5231
+ * @param {Object<string, {lowerWins?: boolean, display?: string}>} [leaderboards] - The game's leaderboards by
5232
+ * name: lowerWins for times and golf, where a lower score is better, higher wins when left out; display how
5233
+ * Wavedash shows a score, 'number', 'seconds', 'milliseconds' or 'ticks' (60 a second), 'number' when left out
5234
+ */
5235
+ constructor(leaderboards?: {
5236
+ [x: string]: {
5237
+ lowerWins?: boolean;
5238
+ display?: string;
5239
+ };
5240
+ });
5241
+ /** @property {Object<string, Promise<string|undefined>>} - Each leaderboard's id by its name, once Wavedash
5242
+ * has made or found it, undefined when it could not
5243
+ * @type {Object<string, Promise<string|undefined>>} */
5244
+ leaderboards: {
5245
+ [x: string]: Promise<string | undefined>;
5246
+ };
5247
+ /** @type {Object<string, {lowerWins?: boolean, display?: string}>} */
5248
+ leaderboardSettings: {
5249
+ [x: string]: {
5250
+ lowerWins?: boolean;
5251
+ display?: string;
5252
+ };
5253
+ };
5254
+ /** @type {Set<string>} */
5255
+ achievementsSent: Set<string>;
5256
+ /** @type {Object<string, number>} */
5257
+ achievementTries: {
5258
+ [x: string]: number;
5259
+ };
5260
+ /** @type {number|undefined} */
5261
+ achievementRetry: number | undefined;
5262
+ /** Whether the game is on Wavedash, its SDK on the page
5263
+ * @return {boolean} */
5264
+ isActive(): boolean;
5265
+ /** Call the SDK, undefined off Wavedash; a call that throws, as on an argument of the wrong type, says so in
5266
+ * the console and gives undefined
5267
+ * @param {string} name - The SDK function
5268
+ * @param {...*} args
5269
+ * @return {*}
5270
+ * @ignore */
5271
+ call(name: string, ...args: any[]): any;
5272
+ /** A leaderboard's id by its name, made on Wavedash the first time it is asked for, with the settings it was given
5273
+ * @param {string} name
5274
+ * @return {Promise<string|undefined>}
5275
+ * @ignore */
5276
+ leaderboard(name: string): Promise<string | undefined>;
5277
+ /** Post a score to a leaderboard, Wavedash keeping the player's best; off Wavedash it does nothing
5278
+ * - A leaderboard not in the table given to the plugin is made the first time, higher wins and shown as a number
5279
+ * @param {string} name - The leaderboard's name
5280
+ * @param {number} score - A whole number, milliseconds for a time
5281
+ * @return {Promise<boolean>} - Whether it was posted */
5282
+ postScore(name: string, score: number): Promise<boolean>;
5283
+ /** Read a leaderboard's entries, undefined off Wavedash or when it could not be read
5284
+ * @param {string} name - The leaderboard's name
5285
+ * @param {number} [offset] - How many entries to skip over
5286
+ * @param {number} [limit] - How many entries to read
5287
+ * @param {boolean} [friendsOnly] - Only the player and their friends
5288
+ * @return {Promise<Array<Object>|undefined>} - The entries, as Wavedash gives them */
5289
+ getScores(name: string, offset?: number, limit?: number, friendsOnly?: boolean): Promise<Array<any> | undefined>;
5290
+ /** Send every unlocked WavedashMedal's achievement Wavedash has not taken yet, again every two seconds while it
5291
+ * refuses some, as it does until it has loaded the player's achievements; one refused for about a minute is
5292
+ * taken as an identifier Wavedash does not have, said once in the console, and not sent again this visit
5293
+ * @ignore */
5294
+ sendAchievements(): void;
5295
+ }
5296
+ /**
5297
+ * WavedashMedal: a medal that is also a Wavedash achievement, unlocked on Wavedash by its identifier
5298
+ * @extends Medal
5299
+ * @memberof Wavedash
5300
+ * @example
5301
+ * const medal_finish = new WavedashMedal(0, 'ACH_01_FINISH', 'Finish', 'Finish a level');
5302
+ * medal_finish.unlock(); // Wavedash's toast on Wavedash, the engine's popup anywhere else
5303
+ */
5304
+ export class WavedashMedal extends Medal {
5305
+ /** Create a WavedashMedal and add it to the list of medals
5306
+ * @param {number} id - The unique identifier of the medal, as for any Medal
5307
+ * @param {string} achievement - The identifier of its Wavedash achievement, as made with the Wavedash CLI
5308
+ * @param {string} name - Name of the medal
5309
+ * @param {string} [description] - Description of the medal
5310
+ * @param {string} [icon] - Icon for the medal
5311
+ * @param {string} [src] - Image location for the medal
5312
+ */
5313
+ constructor(id: number, achievement: string, name: string, description?: string, icon?: string, src?: string);
5314
+ /** @property {string} - The identifier of its Wavedash achievement */
5315
+ achievement: string;
5316
+ }
5179
5317
  /**
5180
5318
  * LittleJS Post Processing Plugin
5181
5319
  * - Supports shadertoy style post processing shaders
@@ -5408,6 +5546,8 @@ declare module "littlejsengine" {
5408
5546
  * setShadowTransparent lets its color tint the light
5409
5547
  * - Set light.glow for a soft hazy glow over a light, like a lamp at night; it is added over the lit scene after the
5410
5548
  * lightmap, so it shows in the dark and sits in front of everything there
5549
+ * - A DirectionalLight is a sun: one per scene, it lights everything from one direction, foreground casters throw long
5550
+ * shadows and objects with castBackgroundShadow are lit only at their edges facing it
5411
5551
  * - Must be constructed BEFORE PostProcessPlugin so post-process sees lit pixels
5412
5552
  * @namespace LightSystem
5413
5553
  */
@@ -5425,7 +5565,7 @@ declare module "littlejsengine" {
5425
5565
  * @memberof LightSystem
5426
5566
  */
5427
5567
  export class LightSystemPlugin {
5428
- /** Create the global light system plugin.
5568
+ /** Create the global light system plugin
5429
5569
  * @param {Vector2} [textureSize] - Size of the lightmap texture (defaults to following mainCanvasSize, which is css pixels, so the lightmap is not scaled by canvasPixelRatio; pass mainCanvasSize.scale(getCanvasPixelRatio()) for a full resolution lightmap)
5430
5570
  * @param {Color} [ambientColor] - Color applied to unlit areas of the scene (defaults to BLACK = pitch dark). Set a small RGB like rgb(0.1,0.1,0.15) for a faint "moonlight" baseline so unlit areas aren't fully black.
5431
5571
  * @example
@@ -5435,6 +5575,7 @@ declare module "littlejsengine" {
5435
5575
  constructor(textureSize?: Vector2, ambientColor?: Color);
5436
5576
  /** @property {boolean} - When false, the render pass is skipped entirely */
5437
5577
  enabled: boolean;
5578
+ shadersFailed: boolean;
5438
5579
  /** @property {Color} - Baseline color applied to unlit areas of the scene. Defaults to BLACK (pitch dark). Set to a small RGB for a faint ambient. The lightmap is cleared to this color each frame, then lights add on top, then the result multiplies the scene. */
5439
5580
  ambientColor: Color;
5440
5581
  /** @property {Vector2} - Size of the lightmap texture, follows mainCanvasSize (css pixels, so it is not scaled by canvasPixelRatio) unless a size was passed */
@@ -5478,6 +5619,10 @@ declare module "littlejsengine" {
5478
5619
  /** @property {WebGLTexture|undefined} - The shadow map, casters drawn black on white around the camera, read only
5479
5620
  * @type {WebGLTexture|undefined} */
5480
5621
  shadowMap: WebGLTexture | undefined;
5622
+ /** @property {WebGLTexture|undefined} - The background map, objects with castBackgroundShadow drawn black on
5623
+ * white, the shadow map's size and place, made by a directional light when something casts into it and kept while the light is, read only
5624
+ * @type {WebGLTexture|undefined} */
5625
+ backgroundMap: WebGLTexture | undefined;
5481
5626
  /** @property {WebGLTexture|undefined} - One of the two textures each light's shadow is built in
5482
5627
  * @type {WebGLTexture|undefined} */
5483
5628
  shadowTextureA: WebGLTexture | undefined;
@@ -5503,6 +5648,26 @@ declare module "littlejsengine" {
5503
5648
  shadowMapOrigin: Vector2;
5504
5649
  /** @property {number} - World size the shadow map covers, set each shadow pass */
5505
5650
  shadowMapWorldSize: number;
5651
+ /** @property {DirectionalLight|undefined} - The scene's directional light, a sun, or undefined, read only
5652
+ * @type {DirectionalLight|undefined} */
5653
+ directionalLight: DirectionalLight | undefined;
5654
+ /** @property {number} - Pixels across the square textures a directional light is built in, covering the
5655
+ * shadow map's area; larger is sharper and slower; a power of two, as shadowMapSize, so their texels line up */
5656
+ directionalTextureSize: number;
5657
+ /** @property {WebGLTexture|undefined} - The directional light as built this frame, white where it reaches,
5658
+ * over the shadow map's area, read only
5659
+ * @type {WebGLTexture|undefined} */
5660
+ directionalTexture: WebGLTexture | undefined;
5661
+ /** @type {WebGLTexture|undefined} */
5662
+ directionalTextureA: WebGLTexture | undefined;
5663
+ /** @type {WebGLTexture|undefined} */
5664
+ directionalTextureB: WebGLTexture | undefined;
5665
+ directionalTextureSizeAllocated: number;
5666
+ backgroundCasters: boolean;
5667
+ /** @type {Object<string, WebGLProgram|WebGLVertexArrayObject>} */
5668
+ directionalPrograms: {
5669
+ [x: string]: WebGLProgram | WebGLVertexArrayObject;
5670
+ };
5506
5671
  shadowMapSizeAllocated: number;
5507
5672
  shadowTextureSizeAllocated: number;
5508
5673
  /** Bring the sizes of the textures it makes down to what the device can make: shadowMapSize, shadowTextureSize
@@ -5567,6 +5732,34 @@ declare module "littlejsengine" {
5567
5732
  * called by LightSystemPlugin after the lightmap is applied */
5568
5733
  renderGlow(): void;
5569
5734
  }
5735
+ /**
5736
+ * A DirectionalLight is a sun for the 2D light system: it lights the whole scene from one direction, added into the
5737
+ * lightmap with the point lights
5738
+ * - One at a time, made after the LightSystemPlugin, lightSystem.directionalLight is the one; a debug build asserts on
5739
+ * a second while the first lives, a release build destroys the first
5740
+ * - Its castShadow lets foreground casters, objects with castShadow, throw long shadows across open space, fading out
5741
+ * by shadowLength; a light does not need lightSystem.shadows for that
5742
+ * - Objects with castBackgroundShadow, a background layer, are dark to it inside and lit at the edges that face it,
5743
+ * fading in by backgroundDepth
5744
+ * @extends EngineObject
5745
+ * @memberof LightSystem
5746
+ * @example
5747
+ * new DirectionalLight(vec2(-1, 1), hsl(.1, .3, 1)); // a warm sun up and to the left, shining down and to the right
5748
+ */
5749
+ export class DirectionalLight extends EngineObject {
5750
+ /** Create the scene's directional light
5751
+ * @param {Vector2} [sunDirection] - Toward the sun, it shines the other way, as render3D.sunDirection
5752
+ * @param {Color} [color] - Color of the light; alpha modulates intensity */
5753
+ constructor(sunDirection?: Vector2, color?: Color);
5754
+ /** @property {Vector2} - Toward the sun, it shines the other way, as render3D.sunDirection */
5755
+ sunDirection: Vector2;
5756
+ /** @property {number} - World units a long shadow reaches before it has faded out; a caster casts only from
5757
+ * inside the shadow map, shadowMapScale views across, so past (shadowMapScale - 1) / 2 of a view beyond the
5758
+ * screen it throws none in */
5759
+ shadowLength: number;
5760
+ /** @property {number} - World units the light gets into a background area from its edges facing it */
5761
+ backgroundDepth: number;
5762
+ }
5570
5763
  /**
5571
5764
  * LittleJS Audio Effects Plugin
5572
5765
  * - Web Audio effects with a wet/dry mix: filter, reverb, delay, distortion, compressor
@@ -6057,6 +6250,7 @@ declare module "littlejsengine" {
6057
6250
  textLineWidth: number;
6058
6251
  /** @property {boolean} - Should this object be drawn */
6059
6252
  visible: boolean;
6253
+ uiUpdatePass: number;
6060
6254
  /** @property {Array<UIObject>} - A list of this object's children
6061
6255
  * @type {Array<UIObject>} */
6062
6256
  children: Array<UIObject>;
@@ -6203,7 +6397,7 @@ declare module "littlejsengine" {
6203
6397
  * @param {string} [text]
6204
6398
  */
6205
6399
  constructor(pos?: Vector2, size?: Vector2, text?: string);
6206
- /** @property {number} - Max length of input (0 = no limit) */
6400
+ /** @property {number} - Max length of input in characters as a reader counts them (0 = no limit) */
6207
6401
  maxLength: number;
6208
6402
  text: string;
6209
6403
  /** Stop editing the text */
@@ -6549,6 +6743,10 @@ declare module "littlejsengine" {
6549
6743
  * - Provides interface for Box2D body and fixture functions
6550
6744
  * - Each object can have multiple fixtures and joints
6551
6745
  * - Angular values are clockwise like angle: angular velocity, torque, joint angles, limits and motor speeds
6746
+ * - Box2D moves the body, so the EngineObject physics fields do nothing on it: velocity, angleVelocity, damping,
6747
+ * angleDamping, mass, friction, restitution and gravityScale; use setLinearVelocity, setAngularVelocity,
6748
+ * setLinearDamping, setAngularDamping, setMass, the friction and restitution of its shapes and setGravityScale.
6749
+ * A debug build warns once when one of them is set
6552
6750
  * @extends EngineObject
6553
6751
  * @memberof Box2D
6554
6752
  */
@@ -6575,7 +6773,7 @@ declare module "littlejsengine" {
6575
6773
  * @type {Array<Array<Vector2>>} */
6576
6774
  edgeLoops: Array<Array<Vector2>>;
6577
6775
  edgeListFixtures: Map<any, any>;
6578
- /** Draws all this object's fixtures
6776
+ /** Draw all this object's fixtures
6579
6777
  * @param {Color} [color]
6580
6778
  * @param {Color} [lineColor]
6581
6779
  * @param {number} [lineWidth]
@@ -6649,8 +6847,8 @@ declare module "littlejsengine" {
6649
6847
  * @param {number} [friction]
6650
6848
  * @param {number} [restitution]
6651
6849
  * @param {boolean} [isSensor]
6652
- * @return {Object} - The fixture made, Box2D's own */
6653
- addCircle(diameter?: number, offset?: Vector2, density?: number, friction?: number, restitution?: number, isSensor?: boolean): any;
6850
+ * @return {Object|undefined} - The fixture made, Box2D's own, undefined for a circle too big to make */
6851
+ addCircle(diameter?: number, offset?: Vector2, density?: number, friction?: number, restitution?: number, isSensor?: boolean): any | undefined;
6654
6852
  /** Add an edge shape to the body
6655
6853
  * @param {Vector2} point1
6656
6854
  * @param {Vector2} point2
@@ -6718,10 +6916,12 @@ declare module "littlejsengine" {
6718
6916
  /** Sets the angular velocity, clockwise like angle
6719
6917
  * @param {number} angularVelocity */
6720
6918
  setAngularVelocity(angularVelocity: number): void;
6721
- /** Sets the linear damping
6919
+ /** Sets the linear damping, Box2D's: a rate, 0 none and larger slows it faster, with no upper limit, where the
6920
+ * damping of an EngineObject is the fraction it keeps each frame and does nothing on a Box2dObject
6722
6921
  * @param {number} damping */
6723
6922
  setLinearDamping(damping: number): void;
6724
- /** Sets the angular damping
6923
+ /** Sets the angular damping, Box2D's: a rate, 0 none and larger slows its turning faster, with no upper limit;
6924
+ * angleDamping does nothing on a Box2dObject
6725
6925
  * @param {number} damping */
6726
6926
  setAngularDamping(damping: number): void;
6727
6927
  /** Sets the gravity scale
@@ -6991,10 +7191,10 @@ declare module "littlejsengine" {
6991
7191
  /** Get the frequency in Hertz
6992
7192
  * @return {number} */
6993
7193
  getFrequency(): number;
6994
- /** Set the damping ratio
7194
+ /** Set how much the spring is damped, 0 for none and 1 to stop it bouncing
6995
7195
  * @param {number} ratio */
6996
7196
  setDampingRatio(ratio: number): void;
6997
- /** Get the damping ratio
7197
+ /** Get how much the spring is damped, 0 for none and 1 to stop it bouncing
6998
7198
  * @return {number} */
6999
7199
  getDampingRatio(): number;
7000
7200
  }
@@ -7100,7 +7300,7 @@ declare module "littlejsengine" {
7100
7300
  /** Set the max motor torque, a magnitude
7101
7301
  * @param {number} torque */
7102
7302
  setMaxMotorTorque(torque: number): void;
7103
- /** Get the max motor torque
7303
+ /** Get the most torque the motor can apply, a magnitude
7104
7304
  * @return {number} */
7105
7305
  getMaxMotorTorque(): number;
7106
7306
  /** Get the motor torque over the last step, clockwise like angle
@@ -7200,10 +7400,10 @@ declare module "littlejsengine" {
7200
7400
  /** Enable/disable the joint motor
7201
7401
  * @param {boolean} [enable] */
7202
7402
  enableMotor(enable?: boolean): void;
7203
- /** Set the motor speed
7403
+ /** Set the speed the motor drives the bodies apart along the axis, in meters per second
7204
7404
  * @param {number} speed */
7205
7405
  setMotorSpeed(speed: number): void;
7206
- /** Get the motor speed
7406
+ /** Get the speed the motor drives the bodies apart along the axis, in meters per second
7207
7407
  * @return {number} */
7208
7408
  getMotorSpeed(): number;
7209
7409
  /** Set the maximum motor force
@@ -7264,7 +7464,7 @@ declare module "littlejsengine" {
7264
7464
  /** Set the maximum motor torque, a magnitude
7265
7465
  * @param {number} torque */
7266
7466
  setMaxMotorTorque(torque: number): void;
7267
- /** Get the max motor torque
7467
+ /** Get the most torque the wheel's motor can apply, a magnitude
7268
7468
  * @return {number} */
7269
7469
  getMaxMotorTorque(): number;
7270
7470
  /** Get the motor torque over the last step, clockwise like angle
@@ -7277,10 +7477,10 @@ declare module "littlejsengine" {
7277
7477
  /** Get the spring frequency in Hertz
7278
7478
  * @return {number} */
7279
7479
  getSpringFrequencyHz(): number;
7280
- /** Set the spring damping ratio
7480
+ /** Set how much the suspension spring is damped, 0 for none and 1 to stop it bouncing
7281
7481
  * @param {number} ratio */
7282
7482
  setSpringDampingRatio(ratio: number): void;
7283
- /** Get the spring damping ratio
7483
+ /** Get how much the suspension spring is damped, 0 for none and 1 to stop it bouncing
7284
7484
  * @return {number} */
7285
7485
  getSpringDampingRatio(): number;
7286
7486
  }
@@ -7313,10 +7513,10 @@ declare module "littlejsengine" {
7313
7513
  /** Get the frequency in Hertz
7314
7514
  * @return {number} */
7315
7515
  getFrequency(): number;
7316
- /** Set the damping ratio
7516
+ /** Set how much the weld's spring is damped, 0 for none and 1 to stop it bouncing
7317
7517
  * @param {number} ratio */
7318
7518
  setDampingRatio(ratio: number): void;
7319
- /** Get the damping ratio
7519
+ /** Get how much the weld's spring is damped, 0 for none and 1 to stop it bouncing
7320
7520
  * @return {number} */
7321
7521
  getDampingRatio(): number;
7322
7522
  }
@@ -7406,10 +7606,10 @@ declare module "littlejsengine" {
7406
7606
  * @param {Box2dObject} objectA
7407
7607
  * @param {Box2dObject} objectB */
7408
7608
  constructor(objectA: Box2dObject, objectB: Box2dObject);
7409
- /** Set the target linear offset, in frame A, in meters.
7609
+ /** Set the target linear offset, in frame A, in meters
7410
7610
  * @param {Vector2} offset */
7411
7611
  setLinearOffset(offset: Vector2): void;
7412
- /** Get the target linear offset, in frame A, in meters.
7612
+ /** Get the target linear offset, in frame A, in meters
7413
7613
  * @return {Vector2} */
7414
7614
  getLinearOffset(): Vector2;
7415
7615
  /** Set the target angular offset, objectB angle minus objectA angle, clockwise like angle
@@ -7647,10 +7847,10 @@ declare module "littlejsengine" {
7647
7847
  * the last iteration of a loop or pingPong, and again each time a restart plays through; then() sets it
7648
7848
  * @type {undefined|function():void} */
7649
7849
  onComplete: undefined | (() => void);
7650
- /** Continuation when a pass ends, set by loop() and pingPong() to start the next iteration.
7850
+ /** Continuation when a pass ends, set by loop() and pingPong() to start the next iteration
7651
7851
  * @private */
7652
7852
  private thenCallback;
7653
- /** Remaining iterations including the current run (loop/pingPong only).
7853
+ /** Remaining iterations including the current run (loop/pingPong only)
7654
7854
  * @private */
7655
7855
  private loopRemaining;
7656
7856
  /** Whether it is running, see isActive
@@ -7673,7 +7873,7 @@ declare module "littlejsengine" {
7673
7873
  target: {
7674
7874
  destroyed?: boolean;
7675
7875
  } | undefined;
7676
- /** Set the easing curve and return this for chaining.
7876
+ /** Set the easing curve and return this for chaining
7677
7877
  * @param {function(number):number} easeFn
7678
7878
  * @return {Tween<T>} */
7679
7879
  setEase(easeFn: (arg0: number) => number): Tween<T>;
@@ -7707,9 +7907,9 @@ declare module "littlejsengine" {
7707
7907
  * @param {number} [count=Infinity]
7708
7908
  * @return {Tween<T>} */
7709
7909
  pingPong(count?: number): Tween<T>;
7710
- /** Pause this tween. While paused, tweenUpdate skips it. */
7910
+ /** Pause this tween. While paused, tweenUpdate skips it */
7711
7911
  pause(): void;
7712
- /** Resume a paused tween. */
7912
+ /** Resume a paused tween */
7713
7913
  resume(): void;
7714
7914
  /** Reset this tween to the start: life back to duration, pause cleared,
7715
7915
  * re-added to the active list if previously stopped, and the callback
@@ -7720,7 +7920,7 @@ declare module "littlejsengine" {
7720
7920
  * after restart to repeat it. The `then` callback is kept and is called
7721
7921
  * again when it completes. */
7722
7922
  restart(): void;
7723
- /** True if this tween is in the active list and not paused.
7923
+ /** True if this tween is in the active list and not paused
7724
7924
  * @return {boolean} */
7725
7925
  isActive(): boolean;
7726
7926
  /** Get how far this tween has progressed, from 0 (just started) to 1
@@ -7891,7 +8091,7 @@ declare module "littlejsengine" {
7891
8091
  * @return {function(OffscreenCanvasRenderingContext2D, Vector2): void}
7892
8092
  * @memberof Parallax */
7893
8093
  export function parallaxMountains(topColor?: Color, bottomColor?: Color, seed?: number): (arg0: OffscreenCanvasRenderingContext2D, arg1: Vector2) => void;
7894
- /** Grid pathfinder using A* with two optional smoothing passes.
8094
+ /** Grid pathfinder using A* with two optional smoothing passes
7895
8095
  * @memberof PathFinding
7896
8096
  * @example
7897
8097
  * // Tile-layer driven (most common):
@@ -7953,16 +8153,16 @@ declare module "littlejsengine" {
7953
8153
  * @param {number} y - Tile y
7954
8154
  * @return {number} */
7955
8155
  getCost(x: number, y: number): number;
7956
- /** Get the node at tile coords, or null if out of bounds.
8156
+ /** Get the node at tile coords, or null if out of bounds
7957
8157
  * @param {number} x
7958
8158
  * @param {number} y
7959
8159
  * @return {PathFinderNode|null} */
7960
8160
  getNode(x: number, y: number): PathFinderNode | null;
7961
- /** Convert a world-space position to integer tile coords (no clamping).
8161
+ /** Convert a world-space position to integer tile coords (no clamping)
7962
8162
  * @param {Vector2} worldPos
7963
8163
  * @return {Vector2} */
7964
8164
  worldToTile(worldPos: Vector2): Vector2;
7965
- /** Convert integer tile coords to the world-space center of that tile.
8165
+ /** Convert integer tile coords to the world-space center of that tile
7966
8166
  * @param {number} x
7967
8167
  * @param {number} y
7968
8168
  * @return {Vector2} */
@@ -8092,9 +8292,9 @@ declare module "littlejsengine" {
8092
8292
  heapIndex: number;
8093
8293
  /** Clear what a search left on this node, keeping walkable and cost */
8094
8294
  resetSearch(): void;
8095
- /** Reset per-search state and walkability (called by buildNodeData). */
8295
+ /** Reset per-search state and walkability (called by buildNodeData) */
8096
8296
  reset(): void;
8097
- /** True if walkable and not blocked by cost.
8297
+ /** True if walkable and not blocked by cost
8098
8298
  * @return {boolean} */
8099
8299
  isClear(): boolean;
8100
8300
  }
@@ -8589,8 +8789,9 @@ declare module "littlejsengine" {
8589
8789
  * - The 3D scene draws under the 2D sprites, so HUD and text land on top
8590
8790
  * - Lighting is the sun plus ambient, with optional extra lights, fog and shadows
8591
8791
  * - Any object or draw can bring its own Shader, a mainImage snippet the lighting then applies to
8592
- * - Build shapes with buildBox, buildSphere, buildGrid and buildLathe; the other builders, terrain, particles,
8593
- * camera controls and the OBJ loader are in the Render3D Extras plugin, which goes after this one
8792
+ * - Meshes and the basic builders are in render3dMesh.js, EngineObject3D, instancing and lights in
8793
+ * render3dObject.js, both right after this one; the other builders, terrain, particles, camera controls and the
8794
+ * OBJ loader are in the Render3D Extras plugin, which goes after those
8594
8795
  * - Requires the Math3D plugin
8595
8796
  * @namespace Render3D
8596
8797
  */
@@ -8685,6 +8886,18 @@ declare module "littlejsengine" {
8685
8886
  /** @property {Mesh|undefined} - Sky dome from buildSky or setSky, drawn around the camera behind everything
8686
8887
  * @type {Mesh|undefined} */
8687
8888
  sky: Mesh | undefined;
8889
+ /** @property {CubeMap|undefined} - A cube map drawn as the sky, behind everything, in place of the sky dome;
8890
+ * an orthographic camera looks the same way through every pixel, so it sees one color of it; fog fades to
8891
+ * fogColor, not to the sky box, so with fog set fogColor to its horizon's color
8892
+ * @type {CubeMap|undefined} */
8893
+ skyBox: CubeMap | undefined;
8894
+ /** @property {CubeMap|undefined} - The world around, what reflective surfaces reflect: an object's
8895
+ * reflectivity says how much and its shininess how sharp, the same shininess that tightens its highlight:
8896
+ * 10000 a mirror, 1000 polished, 10 a wide blur; undefined reflects the sky's colors as setSky gave them; a cube map holds GPU
8897
+ * memory until its dispose(), so one made again and again, as for a sky that changes, disposes the one it
8898
+ * replaces, or a captured one is captured into again
8899
+ * @type {CubeMap|undefined} */
8900
+ environment: CubeMap | undefined;
8688
8901
  /** @property {boolean} - Draw the 3D scene on top of the 2D scene instead of under it */
8689
8902
  renderAfter2D: boolean;
8690
8903
  /** @property {boolean} - Draw see through things far to near so they blend correctly */
@@ -8745,6 +8958,19 @@ declare module "littlejsengine" {
8745
8958
  shadowShader: WebGLProgram | undefined;
8746
8959
  /** @type {WebGLVertexArrayObject|undefined} */
8747
8960
  vao: WebGLVertexArrayObject | undefined;
8961
+ /** @type {Set<CubeMap>} */
8962
+ cubeCaptures: Set<CubeMap>;
8963
+ /** @type {CubeMap|undefined} */
8964
+ capturingCube: CubeMap | undefined;
8965
+ /** @type {WebGLFramebuffer|undefined} */
8966
+ captureFramebuffer: WebGLFramebuffer | undefined;
8967
+ /** @type {WebGLRenderbuffer|undefined} */
8968
+ captureDepth: WebGLRenderbuffer | undefined;
8969
+ captureDepthSize: number;
8970
+ /** @type {WebGLProgram|undefined} */
8971
+ skyBoxProgram: WebGLProgram | undefined;
8972
+ /** @type {WebGLVertexArrayObject|undefined} */
8973
+ skyBoxVao: WebGLVertexArrayObject | undefined;
8748
8974
  /** @type {WebGLTexture|undefined} */
8749
8975
  whiteTexture: WebGLTexture | undefined;
8750
8976
  /** @type {Map<number, WebGLSampler>} */
@@ -8764,7 +8990,10 @@ declare module "littlejsengine" {
8764
8990
  cameraDepthHeight: number;
8765
8991
  depthPass: boolean;
8766
8992
  contextGeneration: number;
8767
- uniforms: Map<any, any>;
8993
+ /** @type {WeakMap<WebGLProgram, Object<string, WebGLUniformLocation|null>>} */
8994
+ uniforms: WeakMap<WebGLProgram, {
8995
+ [x: string]: WebGLUniformLocation | null;
8996
+ }>;
8768
8997
  /** @type {Object<string, Array<number>>} */
8769
8998
  uniformValues: {
8770
8999
  [x: string]: Array<number>;
@@ -8861,6 +9090,10 @@ declare module "littlejsengine" {
8861
9090
  /** Emissive map for the next draws, set from each object's emissiveMap
8862
9091
  * @return {TextureInfo|undefined} */
8863
9092
  get emissiveMap(): TextureInfo | undefined;
9093
+ set environmentMap(arg: CubeMap | undefined);
9094
+ /** The cube map the next draws reflect in place of render3D.environment, set from each object's environment
9095
+ * @return {CubeMap|undefined} */
9096
+ get environmentMap(): CubeMap | undefined;
8864
9097
  set emissiveMapColor(arg: Color);
8865
9098
  /** Multiplies the emissive map, set from each object's emissiveMapColor; compared by its rgb, so a Color
8866
9099
  * changed in place is seen when it is set again, and undefined is white
@@ -9003,7 +9236,8 @@ declare module "littlejsengine" {
9003
9236
  /** Draw the queued transparent draws far to near with the state each was drawn under, called automatically at the
9004
9237
  * end of the transparent stage */
9005
9238
  flushTransparentQueue(): void;
9006
- /** Draw render3D.sky around the camera, unlit, unfogged and behind everything, called automatically by the pass */
9239
+ /** Draw render3D.skyBox, or render3D.sky around the camera, unlit, unfogged and behind everything, called
9240
+ * automatically by the pass */
9007
9241
  drawSky(): void;
9008
9242
  /** Rebuild the light's view projection around the shadow center, called automatically each frame shadows are on */
9009
9243
  updateShadowMatrix(): void;
@@ -9090,6 +9324,78 @@ declare module "littlejsengine" {
9090
9324
  * @return {void} */
9091
9325
  drawSoftShadow(pos: Vector3, size?: number, floorHeight?: number | HeightMap | ((arg0: number, arg1: number) => number), color?: Color, lift?: number): void;
9092
9326
  }
9327
+ /**
9328
+ * CubeMap - Six square images all around a point, the world far away: what reflective surfaces reflect as
9329
+ * render3D.environment, and the sky as render3D.skyBox
9330
+ * - makeCubeMap paints one from a function of direction, loadCubeMap loads six images
9331
+ * - Made with no faces it is drawn from the scene: capture(pos3D) draws everything around that point into it in the
9332
+ * next frame's 3D pass, six views of the whole scene, so capture once for a still scene or now and then for one
9333
+ * that moves
9334
+ * - Its faces are in WebGL's order and lay out, +x, -x, +y, -y, +z, -z: WebGL's cube is left handed, so in this right
9335
+ * handed world a face seen from the middle is mirrored; loadCubeMap turns a sky box set's images to it
9336
+ * @memberof Render3D
9337
+ * @example
9338
+ * render3D.environment = render3D.skyBox = makeCubeMap(64, (d)=> hsl(.6, .8, .4 + d.y * .4));
9339
+ * @example
9340
+ * // a chrome ball that reflects the scene around it, captured once
9341
+ * const ball = new EngineObject3D(vec3(0, 1, 0), render3D.sphereMesh, undefined, BLACK);
9342
+ * ball.reflectivity = 1;
9343
+ * ball.shininess = 1e4;
9344
+ * render3D.environment = new CubeMap(128);
9345
+ * render3D.environment.capture(ball.pos3D);
9346
+ */
9347
+ export class CubeMap {
9348
+ /** Make a cube map from its six faces, as makeCubeMap and loadCubeMap do, or with none to capture the scene into
9349
+ * @param {number} size - Pixels a side of each face
9350
+ * @param {Array<Uint8Array|HTMLImageElement|HTMLCanvasElement|ImageBitmap|OffscreenCanvas>} [faces] - +x, -x,
9351
+ * +y, -y, +z and -z, RGBA pixels row by row or images; none for a cube map drawn by capture */
9352
+ constructor(size: number, faces?: (Uint8Array | OffscreenCanvas | ImageBitmap | HTMLCanvasElement | HTMLImageElement)[]);
9353
+ /** @property {number} - Pixels a side of each face */
9354
+ size: number;
9355
+ /** @property {Array<Uint8Array|HTMLImageElement|HTMLCanvasElement|ImageBitmap|OffscreenCanvas>|undefined} -
9356
+ * Its faces, kept to upload again after a lost context, undefined for one drawn by capture
9357
+ * @type {Array<Uint8Array|HTMLImageElement|HTMLCanvasElement|ImageBitmap|OffscreenCanvas>|undefined} */
9358
+ faces: Array<Uint8Array | HTMLImageElement | HTMLCanvasElement | ImageBitmap | OffscreenCanvas> | undefined;
9359
+ /** @property {Vector3|undefined} - Where it was last captured from, and is captured from again after a lost
9360
+ * context
9361
+ * @type {Vector3|undefined} */
9362
+ capturePos: Vector3 | undefined;
9363
+ /** @type {WebGLTexture|undefined} */
9364
+ glTexture: WebGLTexture | undefined;
9365
+ contextGeneration: number;
9366
+ /** Draw the scene around a point into a cube map made with no faces, in the next frame's 3D pass
9367
+ * - Every object of the layer render3D.renderAfter2D picks is drawn, with the sky and the render callbacks; the
9368
+ * camera's near and far planes, the lights and the fog are the scene's
9369
+ * - It is six more draws of the scene, so capture once for a still scene, or every few frames for a moving one
9370
+ * - A closed mesh around the point, like the ball that reflects it, is not seen from inside, so it hides nothing
9371
+ * - While it is drawn, what would reflect it reflects the sky's colors in its place
9372
+ * - It is seen from one point, so it suits what is near that point best, give each mirror its own with
9373
+ * obj.environment
9374
+ * @param {Vector3} pos3D - The point it is seen from */
9375
+ capture(pos3D: Vector3): void;
9376
+ /** Free its texture, which is made again if it is used after */
9377
+ dispose(): void;
9378
+ }
9379
+ /** Make a cube map by asking a function the color of each direction
9380
+ * - The function gets a unit Vector3 for each pixel of each face and gives a Color
9381
+ * - It runs size * size * 6 times, so a size of 64 or 128 makes one at once, larger takes a moment
9382
+ * @param {number} size - Pixels a side of each face
9383
+ * @param {function(Vector3): Color} colorOf - The color seen looking that way
9384
+ * @return {CubeMap}
9385
+ * @example
9386
+ * // a sky, blue above and pale at the horizon, with a sun
9387
+ * const sun = vec3(1, 1, -1).normalize();
9388
+ * render3D.environment = makeCubeMap(64, (d)=> hsl(.6, .7, .9 - max(d.y, 0) * .5).lerp(WHITE, max(0, d.dot(sun)) ** 64));
9389
+ * @memberof Render3D */
9390
+ export function makeCubeMap(size: number, colorOf: (arg0: Vector3) => Color): CubeMap;
9391
+ /** Load a cube map from six square images of one size
9392
+ * - The images are a sky box set as three.js's CubeTextureLoader takes them, and show the same: each face seen from
9393
+ * inside as its image is drawn
9394
+ * @param {Array<string>} sources - The images of +x, -x, +y, -y, +z and -z, as a sky box set names them right,
9395
+ * left, top, bottom, front and back
9396
+ * @return {Promise<CubeMap>}
9397
+ * @memberof Render3D */
9398
+ export function loadCubeMap(sources: Array<string>): Promise<CubeMap>;
9093
9399
  /**
9094
9400
  * Camera3D - Position, rotation and lens for the 3D view
9095
9401
  * - Looks down its -Z axis, rotation is vec3(pitch, yaw, roll)
@@ -9108,7 +9414,8 @@ declare module "littlejsengine" {
9108
9414
  far: number;
9109
9415
  /** @property {number} - Visible height in world units for an orthographic view, 0 is perspective */
9110
9416
  orthographic: number;
9111
- /** @property {boolean} - Line the 3D camera up with the 2D camera, so 3D things at z=0 sit on the 2D sprites */
9417
+ /** @property {boolean} - Line the 3D camera up with the 2D camera, so 3D things at z=0 sit on the 2D sprites;
9418
+ * it lines up with the 2D view of the main canvas, whatever canvas size a screenToRay is given */
9112
9419
  align2D: boolean;
9113
9420
  /** Returns the camera's world transform
9114
9421
  * @return {Matrix4} */
@@ -9238,6 +9545,10 @@ declare module "littlejsengine" {
9238
9545
  emissiveMap: TextureInfo | undefined;
9239
9546
  /** @property {Color} - Multiplies the emissive map, as glTF's emissiveFactor */
9240
9547
  emissiveMapColor: Color;
9548
+ /** @property {CubeMap|undefined} - What it reflects in place of render3D.environment, as a mirror captures
9549
+ * the scene from its own middle
9550
+ * @type {CubeMap|undefined} */
9551
+ environment: CubeMap | undefined;
9241
9552
  /** @property {boolean} - Collide as the sphere that fits size3D instead of as the size3D box, so it rolls
9242
9553
  * around corners */
9243
9554
  collideAsSphere3D: boolean;
@@ -9260,6 +9571,10 @@ declare module "littlejsengine" {
9260
9571
  matrixParent: EngineObject3D | undefined;
9261
9572
  matrixParentVersion: number;
9262
9573
  movePass: number;
9574
+ collideFrom: Vector3;
9575
+ collideFromPass: number;
9576
+ /** @type {EngineObject3D|undefined} */
9577
+ drawOwner: EngineObject3D | undefined;
9263
9578
  /** Called by a VoxelMap to ask whether a block stops this object, a hook to let one through or react to it
9264
9579
  * @param {number} type - The block's type, 1 to 255
9265
9580
  * @param {Vector3} cell - The block's cell in the map
@@ -9282,6 +9597,13 @@ declare module "littlejsengine" {
9282
9597
  * cheap to call
9283
9598
  * @return {Matrix4} */
9284
9599
  getMatrix(): Matrix4;
9600
+ set roughness(arg: number);
9601
+ /** How rough the surface is, 0 a mirror to 1 matte, as glTF and three.js's MeshStandardMaterial have it: another
9602
+ * way to set shininess, which is what is kept, shininess = 2 / roughness^4 - 2 and at least 1; it sets both the
9603
+ * highlight and how blurred a reflection is; read back it is the same up to about .9, above which shininess is 1
9604
+ * and it reads .9
9605
+ * @return {number} */
9606
+ get roughness(): number;
9285
9607
  /** Turn the object so its -Z axis points at a world space target, sets pitch and yaw and clears roll
9286
9608
  * @param {Vector3} target */
9287
9609
  lookAt(target: Vector3): void;
@@ -9365,6 +9687,7 @@ declare module "littlejsengine" {
9365
9687
  pointCount: number;
9366
9688
  data: ArrayBuffer;
9367
9689
  } | undefined;
9690
+ vertexDataPacked: boolean;
9368
9691
  instanceCount: number;
9369
9692
  /** @type {Float32Array|undefined} */
9370
9693
  instanceData: Float32Array | undefined;
@@ -9950,7 +10273,8 @@ declare module "littlejsengine" {
9950
10273
  chunkTransparentMeshes: Array<Mesh | undefined>;
9951
10274
  /** @type {Array<Vector3>} */
9952
10275
  chunkCenters: Array<Vector3>;
9953
- chunksChanged: Set<any>;
10276
+ /** @type {Set<number>} */
10277
+ chunksChanged: Set<number>;
9954
10278
  /** @type {Array<{faces: Array<number>, seeThrough: boolean, transparent: boolean, doubleSided: boolean}|undefined>} */
9955
10279
  blockTypes: Array<{
9956
10280
  faces: Array<number>;
@@ -9958,7 +10282,8 @@ declare module "littlejsengine" {
9958
10282
  transparent: boolean;
9959
10283
  doubleSided: boolean;
9960
10284
  } | undefined>;
9961
- tiles: Map<any, any>;
10285
+ /** @type {Map<number, Array<Vector2>>} */
10286
+ tiles: Map<number, Array<Vector2>>;
9962
10287
  /** The block type at a cell, 0 for empty or outside the map
9963
10288
  * @param {Vector3} cell
9964
10289
  * @return {number} */
@@ -10050,7 +10375,8 @@ declare module "littlejsengine" {
10050
10375
  * @ignore */
10051
10376
  levelRaycast3D(ray: Ray3D): number | undefined;
10052
10377
  /** Where a short move goes into a block, for a particle's move in one frame: the part of the move made before it,
10053
- * 0 to 1, and the normal of the face it comes in through; undefined when it hits none, or starts inside one
10378
+ * 0 to 1, and the normal of the face it comes in through; undefined when it hits none, or starts inside one; a
10379
+ * move that starts on a block's face, coming in, hits it at 0
10054
10380
  * @param {Vector3} from
10055
10381
  * @param {Vector3} to
10056
10382
  * @return {{distance: number, normal: Vector3}|undefined}
@@ -10315,7 +10641,8 @@ declare module "littlejsengine" {
10315
10641
  /** @property {boolean} - Flatten the spawn area across the way it emits, its own up: a sphere becomes a disc
10316
10642
  * and a box a flat rectangle, for rain from a sheet of sky or flames from a patch of ground */
10317
10643
  emitFlat: boolean;
10318
- /** @property {number} - How long to keep emitting, 0 is forever */
10644
+ /** @property {number} - How long to keep emitting, 0 is forever; raised while its particles are still alive,
10645
+ * it emits again for the added time */
10319
10646
  emitTime: number;
10320
10647
  /** @property {number} - Particles per second, 0 does not emit */
10321
10648
  emitRate: number;
@@ -10381,10 +10708,16 @@ declare module "littlejsengine" {
10381
10708
  * @type {Vector3|undefined} */
10382
10709
  worldPos3D: Vector3 | undefined;
10383
10710
  emitTimeBuffer: number;
10711
+ emitElapsed: number;
10712
+ /** @type {Vector3|undefined} */
10713
+ emitFrom: Vector3 | undefined;
10714
+ emitBehind: number;
10384
10715
  /** Spawn one particle now */
10385
10716
  emitParticle(): void;
10386
- particleCall(callback: any, k: any, level: any, pos: any): any;
10387
- particleCollide(k: any, x: any, y: any, z: any): boolean;
10717
+ /** @private */
10718
+ private particleCall;
10719
+ /** @private */
10720
+ private particleCollide;
10388
10721
  }
10389
10722
  /**
10390
10723
  * Trail3D - A ribbon through where the object has been, thinning and fading with age
@@ -10506,8 +10839,9 @@ declare module "littlejsengine" {
10506
10839
  /** @property {number} - Seconds the flare takes to fade out or in when the sun is hidden or shows again */
10507
10840
  fadeTime: number;
10508
10841
  /** @property {number} - How much of the sun shows, 0 hidden, off the screen or behind the camera to 1 in
10509
- * plain view, eased */
10842
+ * plain view, eased; the first update sets it at once, so a sun hidden from the start never shows */
10510
10843
  visible: number;
10844
+ visibleFound: boolean;
10511
10845
  madeKey: string;
10512
10846
  /** @type {Array<LensFlareElement>} */
10513
10847
  made: Array<LensFlareElement>;
@@ -10558,6 +10892,11 @@ declare module "littlejsengine" {
10558
10892
  * it is doubleSided
10559
10893
  * @return {boolean} */
10560
10894
  isHidden(): boolean;
10895
+ /** Ease visible toward whether the sun shows over some seconds; the first time it is found at once, from the
10896
+ * camera as it is, its matrices made, by the first update or the first draw, whichever comes first
10897
+ * @param {number} seconds
10898
+ * @ignore */
10899
+ updateVisible(seconds: number): void;
10561
10900
  }
10562
10901
  /**
10563
10902
  * Collect the EngineObject3D objects whose boxes overlap a sphere or a box, the 3D twin of engineObjectsCollect
@@ -10629,7 +10968,14 @@ declare module "littlejsengine" {
10629
10968
  /** @property {Array<GLTFAnimation>} - The animations, play one through createObject's GLTFObject
10630
10969
  * @type {Array<GLTFAnimation>} */
10631
10970
  animations: Array<GLTFAnimation>;
10632
- nodeTree: any;
10971
+ /** @type {{nodes: Array<Object>, parents: Array<number|undefined>, restInverse: Array<Matrix4>,
10972
+ * restPose: Array<Matrix4|undefined>}|undefined} */
10973
+ nodeTree: {
10974
+ nodes: Array<any>;
10975
+ parents: Array<number | undefined>;
10976
+ restInverse: Array<Matrix4>;
10977
+ restPose: Array<Matrix4 | undefined>;
10978
+ } | undefined;
10633
10979
  modelMatrix: Matrix4;
10634
10980
  /** @property {Mesh} - Every part combined, each tinted with its material color; the texture is textureInfo,
10635
10981
  * and blending and unlit stay with the parts, which createObject draws */
@@ -10751,6 +11097,9 @@ declare module "littlejsengine" {
10751
11097
  emissiveMap: TextureInfo | undefined;
10752
11098
  /** @property {Color} - The emissiveFactor, which multiplies the emissive map */
10753
11099
  emissiveMapColor: Color;
11100
+ /** @property {number} - The material's roughnessFactor, 0 a mirror to 1 matte, 1 when it has none as the
11101
+ * format says; the object createObject makes takes it as its roughness, which sets its shininess */
11102
+ roughness: number;
10754
11103
  /** @property {GLTFSkin|undefined} - For a skinned mesh, what bends it: mesh is its resting pose, and the
10755
11104
  * object createObject makes bends a copy of its own to each pose
10756
11105
  * @type {GLTFSkin|undefined} */
@@ -10865,7 +11214,7 @@ declare module "littlejsengine" {
10865
11214
  * is fetched then
10866
11215
  * - A file the model needs that is not found is named in the error, and an image that can not be read is named in
10867
11216
  * a warning and left out
10868
- * @param {ArrayBuffer|Object|string} data - GLB bytes, or the glTF JSON as bytes, text or an object
11217
+ * @param {ArrayBuffer|ArrayBufferView|Object<string, any>|string} data - GLB bytes, or the glTF JSON as bytes, text or an object
10869
11218
  * @param {string} [baseUrl] - Where the .bin and image files are, with its trailing slash; loadGLTF passes the file's folder
10870
11219
  * @param {Map<string, Blob>} [files] - The files it refers to, by their paths, in place of fetching them
10871
11220
  * @return {Promise<GLTFModel>}
@@ -10875,7 +11224,9 @@ declare module "littlejsengine" {
10875
11224
  * const gltf = [...files.values()].find((file)=> file.name.endsWith('.gltf'));
10876
11225
  * const model = await parseGLTF(await gltf.text(), '', files);
10877
11226
  * @memberof GLTF */
10878
- export function parseGLTF(data: ArrayBuffer | any | string, baseUrl?: string, files?: Map<string, Blob>): Promise<GLTFModel>;
11227
+ export function parseGLTF(data: ArrayBuffer | ArrayBufferView | {
11228
+ [x: string]: any;
11229
+ } | string, baseUrl?: string, files?: Map<string, Blob>): Promise<GLTFModel>;
10879
11230
  /** Load a glTF or GLB model, the .bin and images of a .gltf from beside it
10880
11231
  * - A texture only OPAQUE materials use loads with its alpha set to 1, so the 3D pass cuts no holes in it
10881
11232
  * @param {string} url
@@ -10963,9 +11314,10 @@ declare module "littlejsengine" {
10963
11314
  * are added before its objects are made, one the game added itself keeps its place
10964
11315
  * - A level may set the scene too, in a scene block beside its objects: sky, three colors for straight up, the
10965
11316
  * horizon and straight down, ambient, how much of them lights the scene, .5 when not given, sunDirection and
10966
- * sunColor, fog, its start and end, fogColor, the horizon color when not given, shadows, and lensFlare, the
10967
- * sun's lens flare; what the block leaves out stays as the game set it, and a level with no block changes
10968
- * nothing
11317
+ * sunColor, fog, its start and end, fogColor, the horizon color when not given, shadows, lensFlare, the
11318
+ * sun's lens flare, and skyBox and environment, each six image urls as loadCubeMap takes them, which load in
11319
+ * the background and are set when they have; what the block leaves out stays as the game set it, and a level
11320
+ * with no block changes nothing
10969
11321
  * @param {Level3D} level - The level, the level editor edits this same object
10970
11322
  * @return {Array<any>} - What each object's type made, a function that made nothing is left out
10971
11323
  * @memberof Level3D */
@@ -11032,13 +11384,22 @@ declare module "littlejsengine" {
11032
11384
  prefabName: string;
11033
11385
  /** @property {boolean} - Are its parts its children, moving with it as one body */
11034
11386
  attached: boolean;
11035
- /** @property {Array<any>} - What the prefab's objects made, in the prefab's order */
11036
- parts: any[];
11387
+ /** @property {Array<EngineObject3D>} - What the prefab's objects made, in the prefab's order
11388
+ * @type {Array<EngineObject3D>} */
11389
+ parts: Array<EngineObject3D>;
11037
11390
  /** @property {Vector3} - From the prefab's origin to the handle, in the prefab's own space: nothing for
11038
11391
  * separate parts, and for an attached prefab the middle of the box around its parts, where its handle
11039
11392
  * is, as an object's place is the middle of its body */
11040
11393
  originOffset: Vector3;
11041
- partObjects: any[];
11394
+ /** @type {Array<{id?: number, type: string, pos?: Array<number>, rotation?: Array<number>, scale?: Array<number>|number, properties?: Object}>} */
11395
+ partObjects: Array<{
11396
+ id?: number;
11397
+ type: string;
11398
+ pos?: Array<number>;
11399
+ rotation?: Array<number>;
11400
+ scale?: Array<number> | number;
11401
+ properties?: any;
11402
+ }>;
11042
11403
  partsPlaced: string;
11043
11404
  partsMade: boolean;
11044
11405
  /** Put the instance with its prefab's origin at a place, turned and sized as the handle is: where a level's
@@ -11277,9 +11638,12 @@ declare module "littlejsengine" {
11277
11638
  * - Accepts TexturePacker json (hash and array) and Aseprite json
11278
11639
  * - Frames tagged in Aseprite or named like run_0, run_1 group into animations
11279
11640
  * @param {Object} data - Parsed atlas json data
11280
- * @return {Array<Object>} List of {name, frames} groups in atlas order
11641
+ * @return {Array<{name: string, frames: Array<Object>}>} List of {name, frames} groups in atlas order
11281
11642
  * @memberof TextureSheets */
11282
- export function parseAtlas(data: any): Array<any>;
11643
+ export function parseAtlas(data: any): {
11644
+ name: string;
11645
+ frames: Array<any>;
11646
+ }[];
11283
11647
  /** Wait for everything started by loadSprite and loadAtlas to finish packing
11284
11648
  * @return {Promise}
11285
11649
  * @example
@@ -11437,8 +11801,9 @@ declare module "littlejsengine" {
11437
11801
  * @memberof ParticleEffects */
11438
11802
  export function particleEffectApply3D(emitter: ParticleEmitter3D, effect: any): void;
11439
11803
  /** An effect with a 2D emitter's settings, to save, build again, or build in 3D with particleEffect3D; its tile is
11440
- * left out, since a hand made emitter's tile is its own texture and not one an effect can name, and so is its
11441
- * scale, which an effect does not keep: pass it again with options.scale
11804
+ * left out, since a hand made emitter's tile is its own texture and not one an effect can name, and so are its
11805
+ * scale, which an effect does not keep: pass it again with options.scale, and its renderOrder, which an effect takes
11806
+ * from additive; a finished emitter's emit time is the time it emitted for
11442
11807
  * @param {ParticleEmitter} emitter
11443
11808
  * @param {string} [name]
11444
11809
  * @return {Object}
@@ -11448,7 +11813,7 @@ declare module "littlejsengine" {
11448
11813
  * @param {string} name
11449
11814
  * @param {function(Particle, number): void} update - Pushes a 2D particle, given the strength
11450
11815
  * @param {function(Particle3D, number): void} [update3D] - The same for a 3D particle, none leaves 3D alone
11451
- * @param {number} [min] - Strength range the designer offers
11816
+ * @param {number} [min] - Strength range the designer offers, and the range a strength is clamped to
11452
11817
  * @param {number} [max]
11453
11818
  * @param {number} [value] - Strength when first added
11454
11819
  * @param {string} [description]