@rpgjs/client 5.0.0-alpha.2 → 5.0.0-alpha.20

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 (163) hide show
  1. package/dist/Game/AnimationManager.d.ts +8 -0
  2. package/dist/Game/Map.d.ts +7 -1
  3. package/dist/Gui/Gui.d.ts +128 -5
  4. package/dist/RpgClient.d.ts +217 -59
  5. package/dist/RpgClientEngine.d.ts +345 -6
  6. package/dist/Sound.d.ts +199 -0
  7. package/dist/components/animations/index.d.ts +4 -0
  8. package/dist/components/dynamics/parse-value.d.ts +1 -0
  9. package/dist/components/gui/index.d.ts +3 -3
  10. package/dist/components/index.d.ts +3 -1
  11. package/dist/components/prebuilt/index.d.ts +18 -0
  12. package/dist/index.d.ts +4 -1
  13. package/dist/index.js +9 -4
  14. package/dist/index.js.map +1 -1
  15. package/dist/index10.js +149 -4
  16. package/dist/index10.js.map +1 -1
  17. package/dist/index11.js +21 -7
  18. package/dist/index11.js.map +1 -1
  19. package/dist/index12.js +6 -4
  20. package/dist/index12.js.map +1 -1
  21. package/dist/index13.js +11 -14
  22. package/dist/index13.js.map +1 -1
  23. package/dist/index14.js +8 -40
  24. package/dist/index14.js.map +1 -1
  25. package/dist/index15.js +187 -180
  26. package/dist/index15.js.map +1 -1
  27. package/dist/index16.js +104 -7
  28. package/dist/index16.js.map +1 -1
  29. package/dist/index17.js +82 -372
  30. package/dist/index17.js.map +1 -1
  31. package/dist/index18.js +361 -26
  32. package/dist/index18.js.map +1 -1
  33. package/dist/index19.js +46 -20
  34. package/dist/index19.js.map +1 -1
  35. package/dist/index2.js +683 -32
  36. package/dist/index2.js.map +1 -1
  37. package/dist/index20.js +5 -2417
  38. package/dist/index20.js.map +1 -1
  39. package/dist/index21.js +383 -97
  40. package/dist/index21.js.map +1 -1
  41. package/dist/index22.js +41 -104
  42. package/dist/index22.js.map +1 -1
  43. package/dist/index23.js +21 -67
  44. package/dist/index23.js.map +1 -1
  45. package/dist/index24.js +2632 -20
  46. package/dist/index24.js.map +1 -1
  47. package/dist/index25.js +107 -34
  48. package/dist/index25.js.map +1 -1
  49. package/dist/index26.js +69 -3
  50. package/dist/index26.js.map +1 -1
  51. package/dist/index27.js +17 -318
  52. package/dist/index27.js.map +1 -1
  53. package/dist/index28.js +24 -22
  54. package/dist/index28.js.map +1 -1
  55. package/dist/index29.js +92 -8
  56. package/dist/index29.js.map +1 -1
  57. package/dist/index3.js +68 -8
  58. package/dist/index3.js.map +1 -1
  59. package/dist/index30.js +37 -7
  60. package/dist/index30.js.map +1 -1
  61. package/dist/index31.js +18 -168
  62. package/dist/index31.js.map +1 -1
  63. package/dist/index32.js +3 -499
  64. package/dist/index32.js.map +1 -1
  65. package/dist/index33.js +332 -9
  66. package/dist/index33.js.map +1 -1
  67. package/dist/index34.js +24 -4400
  68. package/dist/index34.js.map +1 -1
  69. package/dist/index35.js +6 -311
  70. package/dist/index35.js.map +1 -1
  71. package/dist/index36.js +8 -88
  72. package/dist/index36.js.map +1 -1
  73. package/dist/index37.js +182 -56
  74. package/dist/index37.js.map +1 -1
  75. package/dist/index38.js +500 -16
  76. package/dist/index38.js.map +1 -1
  77. package/dist/index39.js +10 -18
  78. package/dist/index39.js.map +1 -1
  79. package/dist/index4.js +23 -5
  80. package/dist/index4.js.map +1 -1
  81. package/dist/index40.js +7 -0
  82. package/dist/index40.js.map +1 -0
  83. package/dist/index41.js +3690 -0
  84. package/dist/index41.js.map +1 -0
  85. package/dist/index42.js +77 -0
  86. package/dist/index42.js.map +1 -0
  87. package/dist/index43.js +6 -0
  88. package/dist/index43.js.map +1 -0
  89. package/dist/index44.js +20 -0
  90. package/dist/index44.js.map +1 -0
  91. package/dist/index45.js +146 -0
  92. package/dist/index45.js.map +1 -0
  93. package/dist/index46.js +12 -0
  94. package/dist/index46.js.map +1 -0
  95. package/dist/index47.js +113 -0
  96. package/dist/index47.js.map +1 -0
  97. package/dist/index48.js +136 -0
  98. package/dist/index48.js.map +1 -0
  99. package/dist/index49.js +137 -0
  100. package/dist/index49.js.map +1 -0
  101. package/dist/index5.js +2 -1
  102. package/dist/index5.js.map +1 -1
  103. package/dist/index50.js +112 -0
  104. package/dist/index50.js.map +1 -0
  105. package/dist/index51.js +141 -0
  106. package/dist/index51.js.map +1 -0
  107. package/dist/index52.js +9 -0
  108. package/dist/index52.js.map +1 -0
  109. package/dist/index53.js +54 -0
  110. package/dist/index53.js.map +1 -0
  111. package/dist/index6.js +1 -1
  112. package/dist/index6.js.map +1 -1
  113. package/dist/index7.js +11 -3
  114. package/dist/index7.js.map +1 -1
  115. package/dist/index8.js +68 -7
  116. package/dist/index8.js.map +1 -1
  117. package/dist/index9.js +230 -15
  118. package/dist/index9.js.map +1 -1
  119. package/dist/presets/animation.d.ts +31 -0
  120. package/dist/presets/faceset.d.ts +30 -0
  121. package/dist/presets/index.d.ts +103 -0
  122. package/dist/presets/lpc.d.ts +89 -0
  123. package/dist/services/loadMap.d.ts +123 -2
  124. package/dist/services/mmorpg.d.ts +9 -4
  125. package/dist/services/standalone.d.ts +51 -2
  126. package/package.json +22 -18
  127. package/src/Game/{EffectManager.ts → AnimationManager.ts} +3 -2
  128. package/src/Game/Map.ts +20 -2
  129. package/src/Game/Object.ts +163 -9
  130. package/src/Gui/Gui.ts +300 -17
  131. package/src/RpgClient.ts +222 -58
  132. package/src/RpgClientEngine.ts +804 -36
  133. package/src/Sound.ts +253 -0
  134. package/src/components/{effects → animations}/animation.ce +3 -6
  135. package/src/components/{effects → animations}/index.ts +1 -1
  136. package/src/components/character.ce +165 -37
  137. package/src/components/dynamics/parse-value.ts +80 -0
  138. package/src/components/dynamics/text.ce +183 -0
  139. package/src/components/gui/box.ce +17 -0
  140. package/src/components/gui/dialogbox/index.ce +73 -35
  141. package/src/components/gui/dialogbox/selection.ce +16 -1
  142. package/src/components/gui/index.ts +3 -4
  143. package/src/components/index.ts +5 -1
  144. package/src/components/prebuilt/hp-bar.ce +255 -0
  145. package/src/components/prebuilt/index.ts +21 -0
  146. package/src/components/scenes/draw-map.ce +6 -23
  147. package/src/components/scenes/event-layer.ce +9 -3
  148. package/src/core/setup.ts +2 -0
  149. package/src/index.ts +5 -2
  150. package/src/module.ts +72 -6
  151. package/src/presets/animation.ts +46 -0
  152. package/src/presets/faceset.ts +60 -0
  153. package/src/presets/index.ts +7 -1
  154. package/src/presets/lpc.ts +108 -0
  155. package/src/services/loadMap.ts +132 -3
  156. package/src/services/mmorpg.ts +27 -5
  157. package/src/services/standalone.ts +68 -6
  158. package/tsconfig.json +1 -1
  159. package/vite.config.ts +1 -1
  160. package/dist/Game/EffectManager.d.ts +0 -5
  161. package/dist/components/effects/index.d.ts +0 -4
  162. package/src/components/scenes/element-map.ce +0 -23
  163. /package/src/components/{effects → animations}/hit.ce +0 -0
@@ -1,5 +1,10 @@
1
1
  import { Context } from '@signe/di';
2
- import { EffectManager } from './Game/EffectManager';
2
+ import { AbstractWebsocket } from './services/AbstractSocket';
3
+ import { Direction } from '@rpgjs/common';
4
+ import { RpgClientMap } from './Game/Map';
5
+ import { AnimationManager } from './Game/AnimationManager';
6
+ import { Observable } from 'rxjs';
7
+ import * as PIXI from "pixi.js";
3
8
  export declare class RpgClientEngine<T = any> {
4
9
  context: Context;
5
10
  private guiService;
@@ -15,29 +20,363 @@ export declare class RpgClientEngine<T = any> {
15
20
  height: import('canvasengine').WritableSignal<string>;
16
21
  spritesheets: Map<string, any>;
17
22
  sounds: Map<string, any>;
18
- effects: any[];
23
+ componentAnimations: any[];
24
+ private spritesheetResolver?;
25
+ private soundResolver?;
19
26
  particleSettings: {
20
27
  emitters: any[];
21
28
  };
29
+ renderer: PIXI.Renderer;
30
+ tick: Observable<number>;
31
+ playerIdSignal: import('canvasengine').WritableSignal<string | null>;
32
+ spriteComponentsBehind: import('canvasengine').WritableArraySignal<any[]>;
33
+ spriteComponentsInFront: import('canvasengine').WritableArraySignal<any[]>;
34
+ private predictionEnabled;
35
+ private prediction?;
36
+ private readonly SERVER_CORRECTION_THRESHOLD;
37
+ private inputFrameCounter;
38
+ private frameOffset;
39
+ private rtt;
40
+ private pingInterval;
41
+ private readonly PING_INTERVAL_MS;
42
+ private lastInputTime;
22
43
  constructor(context: Context);
23
44
  start(): Promise<void>;
24
45
  private initListeners;
46
+ /**
47
+ * Start periodic ping/pong for client-server synchronization
48
+ *
49
+ * Sends ping requests to the server to measure round-trip time (RTT) and
50
+ * calculate the frame offset between client and server ticks.
51
+ *
52
+ * ## Design
53
+ *
54
+ * - Sends ping every 5 seconds
55
+ * - Measures RTT for latency compensation
56
+ * - Calculates frame offset to map client frames to server ticks
57
+ * - Used for accurate server reconciliation
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * // Called automatically when connection opens
62
+ * this.startPingPong();
63
+ * ```
64
+ */
65
+ private startPingPong;
66
+ /**
67
+ * Stop periodic ping/pong
68
+ *
69
+ * Stops the ping interval when disconnecting or changing maps.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * // Called automatically when connection closes
74
+ * this.stopPingPong();
75
+ * ```
76
+ */
77
+ private stopPingPong;
78
+ /**
79
+ * Send a ping request to the server
80
+ *
81
+ * Sends current client time and frame counter to the server,
82
+ * which will respond with its server tick for synchronization.
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * // Send a ping to measure RTT
87
+ * this.sendPing();
88
+ * ```
89
+ */
90
+ private sendPing;
25
91
  private loadScene;
26
92
  addSpriteSheet<T = any>(spritesheetClass: any, id?: string): any;
93
+ /**
94
+ * Set a resolver function for spritesheets
95
+ *
96
+ * The resolver is called when a spritesheet is requested but not found in the cache.
97
+ * It can be synchronous (returns directly) or asynchronous (returns a Promise).
98
+ * The resolved spritesheet is automatically cached for future use.
99
+ *
100
+ * @param resolver - Function that takes a spritesheet ID and returns a spritesheet or Promise of spritesheet
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * // Synchronous resolver
105
+ * engine.setSpritesheetResolver((id) => {
106
+ * if (id === 'dynamic-sprite') {
107
+ * return { id: 'dynamic-sprite', image: 'path/to/image.png', framesWidth: 32, framesHeight: 32 };
108
+ * }
109
+ * return undefined;
110
+ * });
111
+ *
112
+ * // Asynchronous resolver (loading from API)
113
+ * engine.setSpritesheetResolver(async (id) => {
114
+ * const response = await fetch(`/api/spritesheets/${id}`);
115
+ * const data = await response.json();
116
+ * return data;
117
+ * });
118
+ * ```
119
+ */
120
+ setSpritesheetResolver(resolver: (id: string) => any | Promise<any>): void;
121
+ /**
122
+ * Get a spritesheet by ID, using resolver if not found in cache
123
+ *
124
+ * This method first checks if the spritesheet exists in the cache.
125
+ * If not found and a resolver is set, it calls the resolver to create the spritesheet.
126
+ * The resolved spritesheet is automatically cached for future use.
127
+ *
128
+ * @param id - The spritesheet ID to retrieve
129
+ * @returns The spritesheet if found or created, or undefined if not found and no resolver
130
+ * @returns Promise<any> if the resolver is asynchronous
131
+ *
132
+ * @example
133
+ * ```ts
134
+ * // Synchronous usage
135
+ * const spritesheet = engine.getSpriteSheet('my-sprite');
136
+ *
137
+ * // Asynchronous usage (when resolver returns Promise)
138
+ * const spritesheet = await engine.getSpriteSheet('dynamic-sprite');
139
+ * ```
140
+ */
141
+ getSpriteSheet(id: string): any | Promise<any>;
142
+ /**
143
+ * Add a sound to the engine
144
+ *
145
+ * Adds a sound to the engine's sound cache. The sound can be:
146
+ * - A simple object with `id` and `src` properties
147
+ * - A Howler instance
148
+ * - An object with a `play()` method
149
+ *
150
+ * If the sound has a `src` property, a Howler instance will be created automatically.
151
+ *
152
+ * @param sound - The sound object or Howler instance
153
+ * @param id - Optional sound ID (if not provided, uses sound.id)
154
+ * @returns The added sound
155
+ *
156
+ * @example
157
+ * ```ts
158
+ * // Simple sound object
159
+ * engine.addSound({ id: 'click', src: 'click.mp3' });
160
+ *
161
+ * // With explicit ID
162
+ * engine.addSound({ src: 'music.mp3' }, 'background-music');
163
+ * ```
164
+ */
27
165
  addSound(sound: any, id?: string): any;
166
+ /**
167
+ * Set a resolver function for sounds
168
+ *
169
+ * The resolver is called when a sound is requested but not found in the cache.
170
+ * It can be synchronous (returns directly) or asynchronous (returns a Promise).
171
+ * The resolved sound is automatically cached for future use.
172
+ *
173
+ * @param resolver - Function that takes a sound ID and returns a sound or Promise of sound
174
+ *
175
+ * @example
176
+ * ```ts
177
+ * // Synchronous resolver
178
+ * engine.setSoundResolver((id) => {
179
+ * if (id === 'dynamic-sound') {
180
+ * return { id: 'dynamic-sound', src: 'path/to/sound.mp3' };
181
+ * }
182
+ * return undefined;
183
+ * });
184
+ *
185
+ * // Asynchronous resolver (loading from API)
186
+ * engine.setSoundResolver(async (id) => {
187
+ * const response = await fetch(`/api/sounds/${id}`);
188
+ * const data = await response.json();
189
+ * return data;
190
+ * });
191
+ * ```
192
+ */
193
+ setSoundResolver(resolver: (id: string) => any | Promise<any>): void;
194
+ /**
195
+ * Get a sound by ID, using resolver if not found in cache
196
+ *
197
+ * This method first checks if the sound exists in the cache.
198
+ * If not found and a resolver is set, it calls the resolver to create the sound.
199
+ * The resolved sound is automatically cached for future use.
200
+ *
201
+ * @param id - The sound ID to retrieve
202
+ * @returns The sound if found or created, or undefined if not found and no resolver
203
+ * @returns Promise<any> if the resolver is asynchronous
204
+ *
205
+ * @example
206
+ * ```ts
207
+ * // Synchronous usage
208
+ * const sound = engine.getSound('my-sound');
209
+ *
210
+ * // Asynchronous usage (when resolver returns Promise)
211
+ * const sound = await engine.getSound('dynamic-sound');
212
+ * ```
213
+ */
214
+ getSound(id: string): any | Promise<any>;
215
+ /**
216
+ * Play a sound by its ID
217
+ *
218
+ * This method retrieves a sound from the cache or resolver and plays it.
219
+ * If the sound is not found, it will attempt to resolve it using the soundResolver.
220
+ * Uses Howler.js for audio playback instead of native Audio elements.
221
+ *
222
+ * @param soundId - The sound ID to play
223
+ * @param options - Optional sound configuration
224
+ * @param options.volume - Volume level (0.0 to 1.0, overrides sound default)
225
+ * @param options.loop - Whether the sound should loop (overrides sound default)
226
+ *
227
+ * @example
228
+ * ```ts
229
+ * // Play a sound synchronously
230
+ * engine.playSound('item-pickup');
231
+ *
232
+ * // Play a sound with volume and loop
233
+ * engine.playSound('background-music', { volume: 0.5, loop: true });
234
+ *
235
+ * // Play a sound asynchronously (when resolver returns Promise)
236
+ * await engine.playSound('dynamic-sound', { volume: 0.8 });
237
+ * ```
238
+ */
239
+ playSound(soundId: string, options?: {
240
+ volume?: number;
241
+ loop?: boolean;
242
+ }): Promise<void>;
243
+ /**
244
+ * Stop a sound that is currently playing
245
+ *
246
+ * This method stops a sound that was previously started with `playSound()`.
247
+ *
248
+ * @param soundId - The sound ID to stop
249
+ *
250
+ * @example
251
+ * ```ts
252
+ * // Start a looping sound
253
+ * engine.playSound('background-music', { loop: true });
254
+ *
255
+ * // Later, stop it
256
+ * engine.stopSound('background-music');
257
+ * ```
258
+ */
259
+ stopSound(soundId: string): void;
28
260
  addParticle(particle: any): any;
29
- addEffect(effect: {
261
+ /**
262
+ * Add a component to render behind sprites
263
+ * Components added with this method will be displayed with a lower z-index than the sprite
264
+ *
265
+ * @param component - The component to add behind sprites
266
+ * @returns The added component
267
+ *
268
+ * @example
269
+ * ```ts
270
+ * // Add a shadow component behind all sprites
271
+ * engine.addSpriteComponentBehind(ShadowComponent);
272
+ * ```
273
+ */
274
+ addSpriteComponentBehind(component: any): any;
275
+ /**
276
+ * Add a component to render in front of sprites
277
+ * Components added with this method will be displayed with a higher z-index than the sprite
278
+ *
279
+ * @param component - The component to add in front of sprites
280
+ * @returns The added component
281
+ *
282
+ * @example
283
+ * ```ts
284
+ * // Add a health bar component in front of all sprites
285
+ * engine.addSpriteComponentInFront(HealthBarComponent);
286
+ * ```
287
+ */
288
+ addSpriteComponentInFront(component: any): any;
289
+ /**
290
+ * Add a component animation to the engine
291
+ *
292
+ * Component animations are temporary visual effects that can be displayed
293
+ * on sprites or objects, such as hit indicators, spell effects, or status animations.
294
+ *
295
+ * @param componentAnimation - The component animation configuration
296
+ * @param componentAnimation.id - Unique identifier for the animation
297
+ * @param componentAnimation.component - The component function to render
298
+ * @returns The added component animation configuration
299
+ *
300
+ * @example
301
+ * ```ts
302
+ * // Add a hit animation component
303
+ * engine.addComponentAnimation({
304
+ * id: 'hit',
305
+ * component: HitComponent
306
+ * });
307
+ *
308
+ * // Add an explosion effect component
309
+ * engine.addComponentAnimation({
310
+ * id: 'explosion',
311
+ * component: ExplosionComponent
312
+ * });
313
+ * ```
314
+ */
315
+ addComponentAnimation(componentAnimation: {
30
316
  component: any;
31
317
  id: string;
32
318
  }): {
33
319
  component: any;
34
320
  id: string;
35
321
  };
36
- getEffect(id: string): EffectManager;
322
+ /**
323
+ * Get a component animation by its ID
324
+ *
325
+ * Retrieves the EffectManager instance for a specific component animation,
326
+ * which can be used to display the animation on sprites or objects.
327
+ *
328
+ * @param id - The unique identifier of the component animation
329
+ * @returns The EffectManager instance for the animation
330
+ * @throws Error if the component animation is not found
331
+ *
332
+ * @example
333
+ * ```ts
334
+ * // Get the hit animation and display it
335
+ * const hitAnimation = engine.getComponentAnimation('hit');
336
+ * hitAnimation.displayEffect({ text: "Critical!" }, player);
337
+ * ```
338
+ */
339
+ getComponentAnimation(id: string): AnimationManager;
37
340
  processInput({ input }: {
38
- input: number;
39
- }): void;
341
+ input: Direction;
342
+ }): Promise<void>;
40
343
  processAction({ action }: {
41
344
  action: number;
42
345
  }): void;
346
+ get PIXI(): typeof PIXI;
347
+ get socket(): AbstractWebsocket;
348
+ get playerId(): string | null;
349
+ get scene(): RpgClientMap;
350
+ private getPhysicsTick;
351
+ private getLocalPlayerState;
352
+ private applyAuthoritativeState;
353
+ private initializePredictionController;
354
+ getCurrentPlayer(): import('./Game/Player').RpgClientPlayer;
355
+ /**
356
+ * Clear client prediction states for cleanup
357
+ *
358
+ * Removes old prediction states and input history to prevent memory leaks.
359
+ * Should be called when changing maps or disconnecting.
360
+ *
361
+ * @example
362
+ * ```ts
363
+ * // Clear prediction states when changing maps
364
+ * engine.clearClientPredictionStates();
365
+ * ```
366
+ */
367
+ clearClientPredictionStates(): void;
368
+ private applyServerAck;
369
+ /**
370
+ * Replay unacknowledged inputs from a given frame to resimulate client prediction
371
+ * after applying server authority at a certain frame.
372
+ *
373
+ * @param startFrame - The last server-acknowledged frame
374
+ *
375
+ * @example
376
+ * ```ts
377
+ * // After applying a server correction at frame N
378
+ * this.replayUnackedInputsFromFrame(N);
379
+ * ```
380
+ */
381
+ private replayUnackedInputsFromFrame;
43
382
  }
@@ -0,0 +1,199 @@
1
+ import { Howler } from 'canvasengine';
2
+ import { RpgClientEngine } from './RpgClientEngine';
3
+ /**
4
+ * Sound decorator options
5
+ *
6
+ * Defines the configuration for a sound that can be played in the game.
7
+ * The sound can be a single file or multiple files (for different formats).
8
+ *
9
+ * @interface SoundOptions
10
+ */
11
+ export interface SoundOptions {
12
+ /**
13
+ * Sound identifier. Used to retrieve the sound later with RpgSound.get()
14
+ *
15
+ * @type {string}
16
+ */
17
+ id?: string;
18
+ /**
19
+ * Single sound file path. Use require() to wrap the path.
20
+ *
21
+ * @type {string}
22
+ * @example
23
+ * sound: require('./assets/sound.ogg')
24
+ */
25
+ sound?: string;
26
+ /**
27
+ * Multiple sounds with different IDs. The key is the sound ID and the value is the file path.
28
+ * Use require() to wrap each path.
29
+ *
30
+ * @type {{ [id: string]: string }}
31
+ * @example
32
+ * sounds: {
33
+ * hero: require('./assets/hero.ogg'),
34
+ * monster: require('./assets/monster.ogg')
35
+ * }
36
+ */
37
+ sounds?: {
38
+ [id: string]: string;
39
+ };
40
+ /**
41
+ * Whether the sound should loop when it finishes playing.
42
+ *
43
+ * @type {boolean}
44
+ * @default false
45
+ */
46
+ loop?: boolean;
47
+ /**
48
+ * Volume level (0.0 to 1.0).
49
+ *
50
+ * @type {number}
51
+ * @default 1.0
52
+ */
53
+ volume?: number;
54
+ }
55
+ /**
56
+ * Metadata stored on the class decorated with @Sound
57
+ *
58
+ * @interface SoundMetadata
59
+ */
60
+ interface SoundMetadata {
61
+ id?: string;
62
+ sound?: string;
63
+ sounds?: {
64
+ [id: string]: string;
65
+ };
66
+ loop?: boolean;
67
+ volume?: number;
68
+ }
69
+ /**
70
+ * Sound decorator
71
+ *
72
+ * Decorates a class to define a sound configuration. The decorated class can be
73
+ * added to the RpgClient module configuration, and the sound will be automatically
74
+ * registered and available through RpgSound.get().
75
+ *
76
+ * ## Design
77
+ *
78
+ * The decorator stores metadata on the class that is later used by the module loader
79
+ * to register sounds with the engine. The sound is created using Howler.js for
80
+ * advanced audio features like looping, volume control, and cross-browser compatibility.
81
+ *
82
+ * @param options - Sound configuration options
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * import { Sound } from '@rpgjs/client'
87
+ *
88
+ * @Sound({
89
+ * id: 'town-music',
90
+ * sound: require('./sound/town.ogg'),
91
+ * loop: true,
92
+ * volume: 0.5
93
+ * })
94
+ * export class TownMusic {}
95
+ *
96
+ * // Multiple sounds in one class
97
+ * @Sound({
98
+ * sounds: {
99
+ * hero: require('./assets/hero.ogg'),
100
+ * monster: require('./assets/monster.ogg')
101
+ * },
102
+ * loop: true
103
+ * })
104
+ * export class CharacterSounds {}
105
+ * ```
106
+ */
107
+ export declare function Sound(options: SoundOptions): <T extends {
108
+ new (...args: any[]): {};
109
+ }>(constructor: T) => T;
110
+ /**
111
+ * Get sound metadata from a decorated class
112
+ *
113
+ * @param soundClass - The class decorated with @Sound
114
+ * @returns The sound metadata or undefined
115
+ */
116
+ export declare function getSoundMetadata(soundClass: any): SoundMetadata | undefined;
117
+ /**
118
+ * RpgSound class
119
+ *
120
+ * Provides a unified API to manage sounds in the game. Uses Howler.js internally
121
+ * for advanced audio features. Sounds can be retrieved by ID and controlled
122
+ * using Howler.js methods.
123
+ *
124
+ * ## Design
125
+ *
126
+ * RpgSound acts as a facade over Howler.js, providing easy access to sounds
127
+ * registered in the engine. It supports both individual sound control and
128
+ * global sound management (volume, mute, etc.).
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * import { RpgSound } from '@rpgjs/client'
133
+ *
134
+ * // Play a sound
135
+ * RpgSound.get('town-music').play()
136
+ *
137
+ * // Control volume
138
+ * RpgSound.get('town-music').volume(0.5)
139
+ *
140
+ * // Stop a sound
141
+ * RpgSound.get('town-music').stop()
142
+ *
143
+ * // Global volume control
144
+ * RpgSound.global.volume(0.2)
145
+ * ```
146
+ */
147
+ export declare class RpgSound {
148
+ private static engine;
149
+ /**
150
+ * Initialize RpgSound with the engine instance
151
+ *
152
+ * This is called automatically by the engine during initialization.
153
+ *
154
+ * @param engine - The RpgClientEngine instance
155
+ */
156
+ static init(engine: RpgClientEngine): void;
157
+ /**
158
+ * Get a sound by its ID
159
+ *
160
+ * Retrieves a Howler sound instance from the engine's sound cache.
161
+ * The sound must be registered beforehand (via @Sound decorator or manually).
162
+ *
163
+ * @param id - The sound identifier
164
+ * @returns The Howler sound instance, or undefined if not found
165
+ *
166
+ * @example
167
+ * ```ts
168
+ * // Get and play a sound
169
+ * const sound = RpgSound.get('town-music');
170
+ * if (sound) {
171
+ * sound.play();
172
+ * }
173
+ *
174
+ * // Chain methods
175
+ * RpgSound.get('battle-theme')?.volume(0.8).play();
176
+ * ```
177
+ */
178
+ static get(id: string): any;
179
+ /**
180
+ * Global Howler instance for managing all sounds
181
+ *
182
+ * Provides access to Howler.js global methods for controlling all sounds
183
+ * at once (volume, mute, etc.).
184
+ *
185
+ * @example
186
+ * ```ts
187
+ * // Set global volume to 20%
188
+ * RpgSound.global.volume(0.2)
189
+ *
190
+ * // Mute all sounds
191
+ * RpgSound.global.mute(true)
192
+ *
193
+ * // Unmute all sounds
194
+ * RpgSound.global.mute(false)
195
+ * ```
196
+ */
197
+ static get global(): typeof Howler;
198
+ }
199
+ export {};
@@ -0,0 +1,4 @@
1
+ export declare const PrebuiltComponentAnimations: {
2
+ Hit: any;
3
+ Animation: any;
4
+ };
@@ -0,0 +1 @@
1
+ export declare const parseDynamicValue: (value: any, object?: any) => import('canvasengine').ComputedSignal<string>;
@@ -1,3 +1,3 @@
1
- export declare const PrebuiltGui: {
2
- Dialogbox: any;
3
- };
1
+ import { default as DialogboxComponent } from './dialogbox/index.ce';
2
+ import { default as BoxComponent } from './box.ce';
3
+ export { DialogboxComponent, BoxComponent };
@@ -1,2 +1,4 @@
1
1
  import { default as EventLayerComponent } from './scenes/event-layer.ce';
2
- export { EventLayerComponent };
2
+ import { default as CharacterComponent } from './character.ce';
3
+ export { HpBar } from './prebuilt';
4
+ export { EventLayerComponent, CharacterComponent };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Prebuilt sprite components for common UI elements
3
+ *
4
+ * This module exports ready-to-use components that can be attached
5
+ * to sprites using componentsInFront or componentsBehind configuration.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { HpBar } from '@rpgjs/client/components/prebuilt';
10
+ *
11
+ * export default defineModule<RpgClient>({
12
+ * sprite: {
13
+ * componentsInFront: [HpBar]
14
+ * }
15
+ * })
16
+ * ```
17
+ */
18
+ export { default as HpBar } from './hp-bar.ce';
package/dist/index.d.ts CHANGED
@@ -8,6 +8,9 @@ export * from './services/loadMap';
8
8
  export * from './module';
9
9
  export * from './Gui/Gui';
10
10
  export * from './components/gui';
11
- export * from './components/effects';
11
+ export * from './components/animations';
12
12
  export * from './presets';
13
13
  export * from './components';
14
+ export * from './components/gui';
15
+ export * from './Sound';
16
+ export { Context } from '@signe/di';
package/dist/index.js CHANGED
@@ -6,8 +6,13 @@ export { clearInject, context, inject, setInject } from './index6.js';
6
6
  export { LoadMapService, LoadMapToken, provideLoadMap } from './index7.js';
7
7
  export { GlobalConfigToken, provideClientGlobalConfig, provideClientModules, provideGlobalConfig } from './index8.js';
8
8
  export { RpgGui } from './index9.js';
9
- export { PrebuiltGui } from './index10.js';
10
- export { PrebuiltEffects } from './index11.js';
11
- export { Presets } from './index12.js';
12
- export { default as EventLayerComponent } from './index13.js';
9
+ export { default as DialogboxComponent } from './index10.js';
10
+ export { default as BoxComponent } from './index11.js';
11
+ export { PrebuiltComponentAnimations } from './index12.js';
12
+ export { Presets } from './index13.js';
13
+ export { default as EventLayerComponent } from './index14.js';
14
+ export { default as CharacterComponent } from './index15.js';
15
+ export { default as HpBar } from './index16.js';
16
+ export { RpgSound, Sound, getSoundMetadata } from './index17.js';
17
+ export { Context } from './index18.js';
13
18
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}