@rpgjs/client 5.0.0-alpha.9 → 5.0.0-beta.1

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 (304) hide show
  1. package/dist/Game/AnimationManager.d.ts +8 -0
  2. package/dist/Game/AnimationManager.js +26 -0
  3. package/dist/Game/AnimationManager.js.map +1 -0
  4. package/dist/Game/Event.d.ts +1 -1
  5. package/dist/Game/Event.js +12 -0
  6. package/dist/Game/Event.js.map +1 -0
  7. package/dist/Game/Map.d.ts +23 -2
  8. package/dist/Game/Map.js +80 -0
  9. package/dist/Game/Map.js.map +1 -0
  10. package/dist/Game/Object.d.ts +157 -0
  11. package/dist/Game/Object.js +211 -0
  12. package/dist/Game/Object.js.map +1 -0
  13. package/dist/Game/Player.d.ts +1 -1
  14. package/dist/Game/Player.js +12 -0
  15. package/dist/Game/Player.js.map +1 -0
  16. package/dist/Gui/Gui.d.ts +177 -5
  17. package/dist/Gui/Gui.js +445 -0
  18. package/dist/Gui/Gui.js.map +1 -0
  19. package/dist/Gui/NotificationManager.d.ts +23 -0
  20. package/dist/Gui/NotificationManager.js +49 -0
  21. package/dist/Gui/NotificationManager.js.map +1 -0
  22. package/dist/Resource.d.ts +97 -0
  23. package/dist/Resource.js +133 -0
  24. package/dist/Resource.js.map +1 -0
  25. package/dist/RpgClient.d.ts +238 -11
  26. package/dist/RpgClientEngine.d.ts +615 -14
  27. package/dist/RpgClientEngine.js +1334 -0
  28. package/dist/RpgClientEngine.js.map +1 -0
  29. package/dist/Sound.d.ts +199 -0
  30. package/dist/Sound.js +167 -0
  31. package/dist/Sound.js.map +1 -0
  32. package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js +9 -0
  33. package/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js +6 -0
  34. package/dist/components/animations/animation.ce.js +24 -0
  35. package/dist/components/animations/animation.ce.js.map +1 -0
  36. package/dist/components/animations/hit.ce.js +70 -0
  37. package/dist/components/animations/hit.ce.js.map +1 -0
  38. package/dist/components/animations/index.d.ts +4 -0
  39. package/dist/components/animations/index.js +11 -0
  40. package/dist/components/animations/index.js.map +1 -0
  41. package/dist/components/character.ce.js +392 -0
  42. package/dist/components/character.ce.js.map +1 -0
  43. package/dist/components/dynamics/parse-value.d.ts +1 -0
  44. package/dist/components/dynamics/parse-value.js +44 -0
  45. package/dist/components/dynamics/parse-value.js.map +1 -0
  46. package/dist/components/dynamics/text.ce.js +73 -0
  47. package/dist/components/dynamics/text.ce.js.map +1 -0
  48. package/dist/components/gui/box.ce.js +28 -0
  49. package/dist/components/gui/box.ce.js.map +1 -0
  50. package/dist/components/gui/dialogbox/index.ce.js +205 -0
  51. package/dist/components/gui/dialogbox/index.ce.js.map +1 -0
  52. package/dist/components/gui/gameover.ce.js +193 -0
  53. package/dist/components/gui/gameover.ce.js.map +1 -0
  54. package/dist/components/gui/hud/hud.ce.js +92 -0
  55. package/dist/components/gui/hud/hud.ce.js.map +1 -0
  56. package/dist/components/gui/index.d.ts +15 -3
  57. package/dist/components/gui/index.js +14 -0
  58. package/dist/components/gui/menu/equip-menu.ce.js +481 -0
  59. package/dist/components/gui/menu/equip-menu.ce.js.map +1 -0
  60. package/dist/components/gui/menu/exit-menu.ce.js +54 -0
  61. package/dist/components/gui/menu/exit-menu.ce.js.map +1 -0
  62. package/dist/components/gui/menu/items-menu.ce.js +344 -0
  63. package/dist/components/gui/menu/items-menu.ce.js.map +1 -0
  64. package/dist/components/gui/menu/main-menu.ce.js +417 -0
  65. package/dist/components/gui/menu/main-menu.ce.js.map +1 -0
  66. package/dist/components/gui/menu/options-menu.ce.js +48 -0
  67. package/dist/components/gui/menu/options-menu.ce.js.map +1 -0
  68. package/dist/components/gui/menu/skills-menu.ce.js +107 -0
  69. package/dist/components/gui/menu/skills-menu.ce.js.map +1 -0
  70. package/dist/components/gui/mobile/index.d.ts +8 -0
  71. package/dist/components/gui/mobile/index.js +21 -0
  72. package/dist/components/gui/mobile/index.js.map +1 -0
  73. package/dist/components/gui/mobile/mobile.ce.js +78 -0
  74. package/dist/components/gui/mobile/mobile.ce.js.map +1 -0
  75. package/dist/components/gui/notification/notification.ce.js +64 -0
  76. package/dist/components/gui/notification/notification.ce.js.map +1 -0
  77. package/dist/components/gui/save-load.ce.js +389 -0
  78. package/dist/components/gui/save-load.ce.js.map +1 -0
  79. package/dist/components/gui/shop/shop.ce.js +652 -0
  80. package/dist/components/gui/shop/shop.ce.js.map +1 -0
  81. package/dist/components/gui/title-screen.ce.js +190 -0
  82. package/dist/components/gui/title-screen.ce.js.map +1 -0
  83. package/dist/components/index.d.ts +1 -0
  84. package/dist/components/index.js +4 -0
  85. package/dist/components/prebuilt/hp-bar.ce.js +116 -0
  86. package/dist/components/prebuilt/hp-bar.ce.js.map +1 -0
  87. package/dist/components/prebuilt/index.d.ts +19 -0
  88. package/dist/components/prebuilt/index.js +2 -0
  89. package/dist/components/prebuilt/light-halo.ce.js +94 -0
  90. package/dist/components/prebuilt/light-halo.ce.js.map +1 -0
  91. package/dist/components/scenes/canvas.ce.js +60 -0
  92. package/dist/components/scenes/canvas.ce.js.map +1 -0
  93. package/dist/components/scenes/draw-map.ce.js +89 -0
  94. package/dist/components/scenes/draw-map.ce.js.map +1 -0
  95. package/dist/components/scenes/event-layer.ce.js +28 -0
  96. package/dist/components/scenes/event-layer.ce.js.map +1 -0
  97. package/dist/core/inject.js +18 -0
  98. package/dist/core/inject.js.map +1 -0
  99. package/dist/core/setup.js +16 -0
  100. package/dist/core/setup.js.map +1 -0
  101. package/dist/index.d.ts +15 -1
  102. package/dist/index.js +44 -14
  103. package/dist/module.d.ts +43 -4
  104. package/dist/module.js +176 -0
  105. package/dist/module.js.map +1 -0
  106. package/dist/node_modules/.pnpm/@signe_di@2.9.0/node_modules/@signe/di/dist/index.js +277 -0
  107. package/dist/node_modules/.pnpm/@signe_di@2.9.0/node_modules/@signe/di/dist/index.js.map +1 -0
  108. package/dist/node_modules/.pnpm/@signe_reactive@2.8.3/node_modules/@signe/reactive/dist/index.js +457 -0
  109. package/dist/node_modules/.pnpm/@signe_reactive@2.8.3/node_modules/@signe/reactive/dist/index.js.map +1 -0
  110. package/dist/node_modules/.pnpm/@signe_reactive@2.9.0/node_modules/@signe/reactive/dist/index.js +463 -0
  111. package/dist/node_modules/.pnpm/@signe_reactive@2.9.0/node_modules/@signe/reactive/dist/index.js.map +1 -0
  112. package/dist/node_modules/.pnpm/@signe_room@2.9.0/node_modules/@signe/room/dist/index.js +2191 -0
  113. package/dist/node_modules/.pnpm/@signe_room@2.9.0/node_modules/@signe/room/dist/index.js.map +1 -0
  114. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/chunk-7QVYU63E.js +10 -0
  115. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/chunk-7QVYU63E.js.map +1 -0
  116. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/client/index.js +91 -0
  117. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/client/index.js.map +1 -0
  118. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/index.js +325 -0
  119. package/dist/node_modules/.pnpm/@signe_sync@2.9.0/node_modules/@signe/sync/dist/index.js.map +1 -0
  120. package/dist/node_modules/.pnpm/dset@3.1.4/node_modules/dset/dist/index.js +14 -0
  121. package/dist/node_modules/.pnpm/dset@3.1.4/node_modules/dset/dist/index.js.map +1 -0
  122. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-HAC622V3.js +115 -0
  123. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-HAC622V3.js.map +1 -0
  124. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-S74YV6PU.js +401 -0
  125. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/chunk-S74YV6PU.js.map +1 -0
  126. package/dist/node_modules/.pnpm/partysocket@1.1.3/node_modules/partysocket/dist/index.js +2 -0
  127. package/dist/node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/index.js +3756 -0
  128. package/dist/node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/index.js.map +1 -0
  129. package/dist/presets/animation.d.ts +31 -0
  130. package/dist/presets/animation.js +39 -0
  131. package/dist/presets/animation.js.map +1 -0
  132. package/dist/presets/faceset.d.ts +30 -0
  133. package/dist/presets/faceset.js +51 -0
  134. package/dist/presets/faceset.js.map +1 -0
  135. package/dist/presets/icon.d.ts +20 -0
  136. package/dist/presets/icon.js +15 -0
  137. package/dist/presets/icon.js.map +1 -0
  138. package/dist/presets/index.d.ts +123 -0
  139. package/dist/presets/index.js +17 -0
  140. package/dist/presets/index.js.map +1 -0
  141. package/dist/presets/lpc.d.ts +89 -0
  142. package/dist/presets/lpc.js +98 -0
  143. package/dist/presets/lpc.js.map +1 -0
  144. package/dist/presets/rmspritesheet.js +42 -0
  145. package/dist/presets/rmspritesheet.js.map +1 -0
  146. package/dist/services/AbstractSocket.d.ts +9 -5
  147. package/dist/services/AbstractSocket.js +11 -0
  148. package/dist/services/AbstractSocket.js.map +1 -0
  149. package/dist/services/keyboardControls.d.ts +15 -0
  150. package/dist/services/keyboardControls.js +23 -0
  151. package/dist/services/keyboardControls.js.map +1 -0
  152. package/dist/services/loadMap.js +123 -0
  153. package/dist/services/loadMap.js.map +1 -0
  154. package/dist/services/mmorpg.d.ts +21 -9
  155. package/dist/services/mmorpg.js +131 -0
  156. package/dist/services/mmorpg.js.map +1 -0
  157. package/dist/services/save.d.ts +19 -0
  158. package/dist/services/save.js +77 -0
  159. package/dist/services/save.js.map +1 -0
  160. package/dist/services/standalone.d.ts +67 -7
  161. package/dist/services/standalone.js +168 -0
  162. package/dist/services/standalone.js.map +1 -0
  163. package/dist/utils/getEntityProp.d.ts +39 -0
  164. package/dist/utils/getEntityProp.js +52 -0
  165. package/dist/utils/getEntityProp.js.map +1 -0
  166. package/package.json +13 -9
  167. package/src/Game/{EffectManager.ts → AnimationManager.ts} +3 -2
  168. package/src/Game/Event.ts +1 -1
  169. package/src/Game/Map.ts +95 -3
  170. package/src/Game/Object.ts +330 -14
  171. package/src/Game/Player.ts +1 -1
  172. package/src/Gui/Gui.ts +506 -18
  173. package/src/Gui/NotificationManager.ts +69 -0
  174. package/src/Resource.ts +150 -0
  175. package/src/RpgClient.ts +246 -12
  176. package/src/RpgClientEngine.ts +1641 -62
  177. package/src/Sound.ts +253 -0
  178. package/src/components/{effects → animations}/animation.ce +3 -6
  179. package/src/components/{effects → animations}/index.ts +1 -1
  180. package/src/components/character.ce +387 -52
  181. package/src/components/dynamics/parse-value.ts +80 -0
  182. package/src/components/dynamics/text.ce +183 -0
  183. package/src/components/gui/box.ce +17 -0
  184. package/src/components/gui/dialogbox/index.ce +204 -187
  185. package/src/components/gui/gameover.ce +158 -0
  186. package/src/components/gui/hud/hud.ce +61 -0
  187. package/src/components/gui/index.ts +30 -4
  188. package/src/components/gui/menu/equip-menu.ce +410 -0
  189. package/src/components/gui/menu/exit-menu.ce +41 -0
  190. package/src/components/gui/menu/items-menu.ce +317 -0
  191. package/src/components/gui/menu/main-menu.ce +294 -0
  192. package/src/components/gui/menu/options-menu.ce +35 -0
  193. package/src/components/gui/menu/skills-menu.ce +83 -0
  194. package/src/components/gui/mobile/index.ts +24 -0
  195. package/src/components/gui/mobile/mobile.ce +80 -0
  196. package/src/components/gui/notification/notification.ce +51 -0
  197. package/src/components/gui/save-load.ce +208 -0
  198. package/src/components/gui/shop/shop.ce +493 -0
  199. package/src/components/gui/title-screen.ce +163 -0
  200. package/src/components/index.ts +3 -0
  201. package/src/components/prebuilt/hp-bar.ce +255 -0
  202. package/src/components/prebuilt/index.ts +24 -0
  203. package/src/components/prebuilt/light-halo.ce +148 -0
  204. package/src/components/scenes/canvas.ce +20 -15
  205. package/src/components/scenes/draw-map.ce +60 -13
  206. package/src/components/scenes/event-layer.ce +7 -0
  207. package/src/components/scenes/transition.ce +60 -0
  208. package/src/index.ts +16 -2
  209. package/src/module.ts +127 -9
  210. package/src/presets/animation.ts +46 -0
  211. package/src/presets/faceset.ts +60 -0
  212. package/src/presets/icon.ts +17 -0
  213. package/src/presets/index.ts +9 -1
  214. package/src/presets/lpc.ts +108 -0
  215. package/src/services/AbstractSocket.ts +10 -2
  216. package/src/services/keyboardControls.ts +20 -0
  217. package/src/services/loadMap.ts +1 -1
  218. package/src/services/mmorpg.ts +100 -12
  219. package/src/services/save.ts +103 -0
  220. package/src/services/standalone.ts +110 -18
  221. package/src/utils/getEntityProp.ts +87 -0
  222. package/vite.config.ts +4 -2
  223. package/dist/Game/EffectManager.d.ts +0 -5
  224. package/dist/components/effects/index.d.ts +0 -4
  225. package/dist/index.js.map +0 -1
  226. package/dist/index10.js +0 -8
  227. package/dist/index10.js.map +0 -1
  228. package/dist/index11.js +0 -10
  229. package/dist/index11.js.map +0 -1
  230. package/dist/index12.js +0 -8
  231. package/dist/index12.js.map +0 -1
  232. package/dist/index13.js +0 -17
  233. package/dist/index13.js.map +0 -1
  234. package/dist/index14.js +0 -107
  235. package/dist/index14.js.map +0 -1
  236. package/dist/index15.js +0 -50
  237. package/dist/index15.js.map +0 -1
  238. package/dist/index16.js +0 -191
  239. package/dist/index16.js.map +0 -1
  240. package/dist/index17.js +0 -9
  241. package/dist/index17.js.map +0 -1
  242. package/dist/index18.js +0 -387
  243. package/dist/index18.js.map +0 -1
  244. package/dist/index19.js +0 -31
  245. package/dist/index19.js.map +0 -1
  246. package/dist/index2.js +0 -181
  247. package/dist/index2.js.map +0 -1
  248. package/dist/index20.js +0 -24
  249. package/dist/index20.js.map +0 -1
  250. package/dist/index21.js +0 -2421
  251. package/dist/index21.js.map +0 -1
  252. package/dist/index22.js +0 -114
  253. package/dist/index22.js.map +0 -1
  254. package/dist/index23.js +0 -109
  255. package/dist/index23.js.map +0 -1
  256. package/dist/index24.js +0 -71
  257. package/dist/index24.js.map +0 -1
  258. package/dist/index25.js +0 -21
  259. package/dist/index25.js.map +0 -1
  260. package/dist/index26.js +0 -41
  261. package/dist/index26.js.map +0 -1
  262. package/dist/index27.js +0 -5
  263. package/dist/index27.js.map +0 -1
  264. package/dist/index28.js +0 -322
  265. package/dist/index28.js.map +0 -1
  266. package/dist/index29.js +0 -27
  267. package/dist/index29.js.map +0 -1
  268. package/dist/index3.js +0 -87
  269. package/dist/index3.js.map +0 -1
  270. package/dist/index30.js +0 -11
  271. package/dist/index30.js.map +0 -1
  272. package/dist/index31.js +0 -11
  273. package/dist/index31.js.map +0 -1
  274. package/dist/index32.js +0 -174
  275. package/dist/index32.js.map +0 -1
  276. package/dist/index33.js +0 -501
  277. package/dist/index33.js.map +0 -1
  278. package/dist/index34.js +0 -12
  279. package/dist/index34.js.map +0 -1
  280. package/dist/index35.js +0 -4403
  281. package/dist/index35.js.map +0 -1
  282. package/dist/index36.js +0 -316
  283. package/dist/index36.js.map +0 -1
  284. package/dist/index37.js +0 -61
  285. package/dist/index37.js.map +0 -1
  286. package/dist/index38.js +0 -20
  287. package/dist/index38.js.map +0 -1
  288. package/dist/index39.js +0 -20
  289. package/dist/index39.js.map +0 -1
  290. package/dist/index4.js +0 -67
  291. package/dist/index4.js.map +0 -1
  292. package/dist/index5.js +0 -16
  293. package/dist/index5.js.map +0 -1
  294. package/dist/index6.js +0 -17
  295. package/dist/index6.js.map +0 -1
  296. package/dist/index7.js +0 -39
  297. package/dist/index7.js.map +0 -1
  298. package/dist/index8.js +0 -108
  299. package/dist/index8.js.map +0 -1
  300. package/dist/index9.js +0 -76
  301. package/dist/index9.js.map +0 -1
  302. package/src/components/gui/dialogbox/itemMenu.ce +0 -23
  303. package/src/components/gui/dialogbox/selection.ce +0 -67
  304. /package/src/components/{effects → animations}/hit.ce +0 -0
@@ -1,10 +1,11 @@
1
- import { Context } from '@signe/di';
2
1
  import { AbstractWebsocket } from './services/AbstractSocket';
3
- import { EffectManager } from './Game/EffectManager';
2
+ import { Direction } from '@rpgjs/common';
3
+ import { RpgClientMap } from './Game/Map';
4
+ import { AnimationManager } from './Game/AnimationManager';
4
5
  import { Observable } from 'rxjs';
5
6
  import * as PIXI from "pixi.js";
6
7
  export declare class RpgClientEngine<T = any> {
7
- context: Context;
8
+ context: any;
8
9
  private guiService;
9
10
  private webSocket;
10
11
  private loadMapService;
@@ -18,33 +19,392 @@ export declare class RpgClientEngine<T = any> {
18
19
  height: import('canvasengine').WritableSignal<string>;
19
20
  spritesheets: Map<string, any>;
20
21
  sounds: Map<string, any>;
21
- effects: any[];
22
+ componentAnimations: any[];
23
+ private spritesheetResolver?;
24
+ private soundResolver?;
22
25
  particleSettings: {
23
26
  emitters: any[];
24
27
  };
25
28
  renderer: PIXI.Renderer;
26
29
  tick: Observable<number>;
30
+ private canvasApp?;
31
+ private canvasElement?;
27
32
  playerIdSignal: import('canvasengine').WritableSignal<string | null>;
28
33
  spriteComponentsBehind: import('canvasengine').WritableArraySignal<any[]>;
29
34
  spriteComponentsInFront: import('canvasengine').WritableArraySignal<any[]>;
30
- constructor(context: Context);
35
+ /** ID of the sprite that the camera should follow. null means follow the current player */
36
+ cameraFollowTargetId: import('canvasengine').WritableSignal<string | null>;
37
+ /** Trigger for map shake animation */
38
+ mapShakeTrigger: import('canvasengine').Trigger<any>;
39
+ controlsReady: import('canvasengine').WritableSignal<undefined>;
40
+ gamePause: import('canvasengine').WritableSignal<boolean>;
41
+ private predictionEnabled;
42
+ private prediction?;
43
+ private readonly SERVER_CORRECTION_THRESHOLD;
44
+ private inputFrameCounter;
45
+ private pendingPredictionFrames;
46
+ private lastClientPhysicsStepAt;
47
+ private frameOffset;
48
+ private rtt;
49
+ private pingInterval;
50
+ private readonly PING_INTERVAL_MS;
51
+ private lastInputTime;
52
+ private readonly MOVE_PATH_RESEND_INTERVAL_MS;
53
+ private readonly MAX_MOVE_TRAJECTORY_POINTS;
54
+ private lastMovePathSentAt;
55
+ private lastMovePathSentFrame;
56
+ private mapLoadCompleted$;
57
+ private playerIdReceived$;
58
+ private playersReceived$;
59
+ private eventsReceived$;
60
+ private onAfterLoadingSubscription?;
61
+ private sceneResetQueued;
62
+ private tickSubscriptions;
63
+ private resizeHandler?;
64
+ private notificationManager;
65
+ constructor(context: any);
66
+ /**
67
+ * Assigns a CanvasEngine KeyboardControls instance to the dependency injection context
68
+ *
69
+ * This method registers a KeyboardControls instance from CanvasEngine into the DI container,
70
+ * making it available for injection throughout the application. The particularity is that
71
+ * this method is automatically called when a sprite is displayed on the map, allowing the
72
+ * controls to be automatically associated with the active sprite.
73
+ *
74
+ * ## Design
75
+ *
76
+ * - The instance is stored in the DI context under the `KeyboardControls` token
77
+ * - It's automatically assigned when a sprite component mounts (in `character.ce`)
78
+ * - The controls instance comes from the CanvasEngine component's directives
79
+ * - Once registered, it can be retrieved using `inject(KeyboardControls)` from anywhere
80
+ *
81
+ * @param controlInstance - The CanvasEngine KeyboardControls instance to register
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * // The method is automatically called when a sprite is displayed:
86
+ * // client.setKeyboardControls(element.directives.controls)
87
+ *
88
+ * // Later, retrieve and use the controls instance:
89
+ * import { Input, inject, KeyboardControls } from '@rpgjs/client'
90
+ *
91
+ * const controls = inject(KeyboardControls)
92
+ * const control = controls.getControl(Input.Enter)
93
+ *
94
+ * if (control) {
95
+ * console.log(control.actionName) // 'action'
96
+ * }
97
+ * ```
98
+ */
99
+ setKeyboardControls(controlInstance: any): void;
31
100
  start(): Promise<void>;
101
+ private prepareSyncPayload;
102
+ private normalizeAckWithSyncState;
32
103
  private initListeners;
104
+ /**
105
+ * Start periodic ping/pong for client-server synchronization
106
+ *
107
+ * Sends ping requests to the server to measure round-trip time (RTT) and
108
+ * calculate the frame offset between client and server ticks.
109
+ *
110
+ * ## Design
111
+ *
112
+ * - Sends ping every 5 seconds
113
+ * - Measures RTT for latency compensation
114
+ * - Calculates frame offset to map client frames to server ticks
115
+ * - Used for accurate server reconciliation
116
+ *
117
+ * @example
118
+ * ```ts
119
+ * // Called automatically when connection opens
120
+ * this.startPingPong();
121
+ * ```
122
+ */
123
+ private startPingPong;
124
+ /**
125
+ * Stop periodic ping/pong
126
+ *
127
+ * Stops the ping interval when disconnecting or changing maps.
128
+ *
129
+ * @example
130
+ * ```ts
131
+ * // Called automatically when connection closes
132
+ * this.stopPingPong();
133
+ * ```
134
+ */
135
+ private stopPingPong;
136
+ /**
137
+ * Send a ping request to the server
138
+ *
139
+ * Sends current client time and frame counter to the server,
140
+ * which will respond with its server tick for synchronization.
141
+ *
142
+ * @example
143
+ * ```ts
144
+ * // Send a ping to measure RTT
145
+ * this.sendPing();
146
+ * ```
147
+ */
148
+ private sendPing;
33
149
  private loadScene;
34
150
  addSpriteSheet<T = any>(spritesheetClass: any, id?: string): any;
151
+ /**
152
+ * Set a resolver function for spritesheets
153
+ *
154
+ * The resolver is called when a spritesheet is requested but not found in the cache.
155
+ * It can be synchronous (returns directly) or asynchronous (returns a Promise).
156
+ * The resolved spritesheet is automatically cached for future use.
157
+ *
158
+ * @param resolver - Function that takes a spritesheet ID and returns a spritesheet or Promise of spritesheet
159
+ *
160
+ * @example
161
+ * ```ts
162
+ * // Synchronous resolver
163
+ * engine.setSpritesheetResolver((id) => {
164
+ * if (id === 'dynamic-sprite') {
165
+ * return { id: 'dynamic-sprite', image: 'path/to/image.png', framesWidth: 32, framesHeight: 32 };
166
+ * }
167
+ * return undefined;
168
+ * });
169
+ *
170
+ * // Asynchronous resolver (loading from API)
171
+ * engine.setSpritesheetResolver(async (id) => {
172
+ * const response = await fetch(`/api/spritesheets/${id}`);
173
+ * const data = await response.json();
174
+ * return data;
175
+ * });
176
+ * ```
177
+ */
178
+ setSpritesheetResolver(resolver: (id: string) => any | Promise<any>): void;
179
+ /**
180
+ * Get a spritesheet by ID, using resolver if not found in cache
181
+ *
182
+ * This method first checks if the spritesheet exists in the cache.
183
+ * If not found and a resolver is set, it calls the resolver to create the spritesheet.
184
+ * The resolved spritesheet is automatically cached for future use.
185
+ *
186
+ * @param id - The spritesheet ID to retrieve
187
+ * @returns The spritesheet if found or created, or undefined if not found and no resolver
188
+ * @returns Promise<any> if the resolver is asynchronous
189
+ *
190
+ * @example
191
+ * ```ts
192
+ * // Synchronous usage
193
+ * const spritesheet = engine.getSpriteSheet('my-sprite');
194
+ *
195
+ * // Asynchronous usage (when resolver returns Promise)
196
+ * const spritesheet = await engine.getSpriteSheet('dynamic-sprite');
197
+ * ```
198
+ */
199
+ getSpriteSheet(id: string): any | Promise<any>;
200
+ /**
201
+ * Add a sound to the engine
202
+ *
203
+ * Adds a sound to the engine's sound cache. The sound can be:
204
+ * - A simple object with `id` and `src` properties
205
+ * - A Howler instance
206
+ * - An object with a `play()` method
207
+ *
208
+ * If the sound has a `src` property, a Howler instance will be created automatically.
209
+ *
210
+ * @param sound - The sound object or Howler instance
211
+ * @param id - Optional sound ID (if not provided, uses sound.id)
212
+ * @returns The added sound
213
+ *
214
+ * @example
215
+ * ```ts
216
+ * // Simple sound object
217
+ * engine.addSound({ id: 'click', src: 'click.mp3' });
218
+ *
219
+ * // With explicit ID
220
+ * engine.addSound({ src: 'music.mp3' }, 'background-music');
221
+ * ```
222
+ */
35
223
  addSound(sound: any, id?: string): any;
224
+ /**
225
+ * Set a resolver function for sounds
226
+ *
227
+ * The resolver is called when a sound is requested but not found in the cache.
228
+ * It can be synchronous (returns directly) or asynchronous (returns a Promise).
229
+ * The resolved sound is automatically cached for future use.
230
+ *
231
+ * @param resolver - Function that takes a sound ID and returns a sound or Promise of sound
232
+ *
233
+ * @example
234
+ * ```ts
235
+ * // Synchronous resolver
236
+ * engine.setSoundResolver((id) => {
237
+ * if (id === 'dynamic-sound') {
238
+ * return { id: 'dynamic-sound', src: 'path/to/sound.mp3' };
239
+ * }
240
+ * return undefined;
241
+ * });
242
+ *
243
+ * // Asynchronous resolver (loading from API)
244
+ * engine.setSoundResolver(async (id) => {
245
+ * const response = await fetch(`/api/sounds/${id}`);
246
+ * const data = await response.json();
247
+ * return data;
248
+ * });
249
+ * ```
250
+ */
251
+ setSoundResolver(resolver: (id: string) => any | Promise<any>): void;
252
+ /**
253
+ * Get a sound by ID, using resolver if not found in cache
254
+ *
255
+ * This method first checks if the sound exists in the cache.
256
+ * If not found and a resolver is set, it calls the resolver to create the sound.
257
+ * The resolved sound is automatically cached for future use.
258
+ *
259
+ * @param id - The sound ID to retrieve
260
+ * @returns The sound if found or created, or undefined if not found and no resolver
261
+ * @returns Promise<any> if the resolver is asynchronous
262
+ *
263
+ * @example
264
+ * ```ts
265
+ * // Synchronous usage
266
+ * const sound = engine.getSound('my-sound');
267
+ *
268
+ * // Asynchronous usage (when resolver returns Promise)
269
+ * const sound = await engine.getSound('dynamic-sound');
270
+ * ```
271
+ */
272
+ getSound(id: string): any | Promise<any>;
273
+ /**
274
+ * Play a sound by its ID
275
+ *
276
+ * This method retrieves a sound from the cache or resolver and plays it.
277
+ * If the sound is not found, it will attempt to resolve it using the soundResolver.
278
+ * Uses Howler.js for audio playback instead of native Audio elements.
279
+ *
280
+ * @param soundId - The sound ID to play
281
+ * @param options - Optional sound configuration
282
+ * @param options.volume - Volume level (0.0 to 1.0, overrides sound default)
283
+ * @param options.loop - Whether the sound should loop (overrides sound default)
284
+ *
285
+ * @example
286
+ * ```ts
287
+ * // Play a sound synchronously
288
+ * engine.playSound('item-pickup');
289
+ *
290
+ * // Play a sound with volume and loop
291
+ * engine.playSound('background-music', { volume: 0.5, loop: true });
292
+ *
293
+ * // Play a sound asynchronously (when resolver returns Promise)
294
+ * await engine.playSound('dynamic-sound', { volume: 0.8 });
295
+ * ```
296
+ */
297
+ playSound(soundId: string, options?: {
298
+ volume?: number;
299
+ loop?: boolean;
300
+ }): Promise<void>;
301
+ /**
302
+ * Stop a sound that is currently playing
303
+ *
304
+ * This method stops a sound that was previously started with `playSound()`.
305
+ *
306
+ * @param soundId - The sound ID to stop
307
+ *
308
+ * @example
309
+ * ```ts
310
+ * // Start a looping sound
311
+ * engine.playSound('background-music', { loop: true });
312
+ *
313
+ * // Later, stop it
314
+ * engine.stopSound('background-music');
315
+ * ```
316
+ */
317
+ stopSound(soundId: string): void;
318
+ /**
319
+ * Stop all currently playing sounds
320
+ *
321
+ * This method stops all sounds that are currently playing.
322
+ * Useful when changing maps to prevent sound overlap.
323
+ *
324
+ * @example
325
+ * ```ts
326
+ * // Stop all sounds
327
+ * engine.stopAllSounds();
328
+ * ```
329
+ */
330
+ stopAllSounds(): void;
331
+ /**
332
+ * Set the camera to follow a specific sprite
333
+ *
334
+ * This method changes which sprite the camera viewport should follow.
335
+ * The camera will smoothly animate to the target sprite if smoothMove options are provided.
336
+ *
337
+ * ## Design
338
+ *
339
+ * The camera follow target is stored in a signal that is read by sprite components.
340
+ * Each sprite checks if it should be followed by comparing its ID with the target ID.
341
+ * When smoothMove options are provided, the viewport animation is handled by CanvasEngine's
342
+ * viewport system.
343
+ *
344
+ * @param targetId - The ID of the sprite to follow. Set to null to follow the current player
345
+ * @param smoothMove - Animation options. Can be a boolean (default: true) or an object with time and ease
346
+ * @param smoothMove.time - Duration of the animation in milliseconds (optional)
347
+ * @param smoothMove.ease - Easing function name from https://easings.net (optional)
348
+ *
349
+ * @example
350
+ * ```ts
351
+ * // Follow another player with default smooth animation
352
+ * engine.setCameraFollow(otherPlayerId, true);
353
+ *
354
+ * // Follow an event with custom smooth animation
355
+ * engine.setCameraFollow(eventId, {
356
+ * time: 1000,
357
+ * ease: "easeInOutQuad"
358
+ * });
359
+ *
360
+ * // Follow without animation (instant)
361
+ * engine.setCameraFollow(targetId, false);
362
+ *
363
+ * // Return to following current player
364
+ * engine.setCameraFollow(null);
365
+ * ```
366
+ */
367
+ setCameraFollow(targetId: string | null, smoothMove?: boolean | {
368
+ time?: number;
369
+ ease?: string;
370
+ }): void;
36
371
  addParticle(particle: any): any;
37
372
  /**
38
373
  * Add a component to render behind sprites
39
374
  * Components added with this method will be displayed with a lower z-index than the sprite
40
375
  *
41
- * @param component - The component to add behind sprites
42
- * @returns The added component
376
+ * Supports multiple formats:
377
+ * 1. Direct component: `ShadowComponent`
378
+ * 2. Configuration object: `{ component: LightHalo, props: {...} }`
379
+ * 3. With dynamic props: `{ component: LightHalo, props: (object) => {...} }`
380
+ * 4. With dependencies: `{ component: HealthBar, dependencies: (object) => [object.hp, object.param.maxHp] }`
381
+ *
382
+ * Components with dependencies will only be displayed when all dependencies are resolved (!= undefined).
383
+ * The object (sprite) is passed to the dependencies function to allow sprite-specific dependency resolution.
384
+ *
385
+ * @param component - The component to add behind sprites, or a configuration object
386
+ * @param component.component - The component function to render
387
+ * @param component.props - Static props object or function that receives the sprite object and returns props
388
+ * @param component.dependencies - Function that receives the sprite object and returns an array of Signals
389
+ * @returns The added component or configuration
43
390
  *
44
391
  * @example
45
392
  * ```ts
46
393
  * // Add a shadow component behind all sprites
47
394
  * engine.addSpriteComponentBehind(ShadowComponent);
395
+ *
396
+ * // Add a component with static props
397
+ * engine.addSpriteComponentBehind({
398
+ * component: LightHalo,
399
+ * props: { radius: 30 }
400
+ * });
401
+ *
402
+ * // Add a component with dynamic props and dependencies
403
+ * engine.addSpriteComponentBehind({
404
+ * component: HealthBar,
405
+ * props: (object) => ({ hp: object.hp(), maxHp: object.param.maxHp() }),
406
+ * dependencies: (object) => [object.hp, object.param.maxHp]
407
+ * });
48
408
  * ```
49
409
  */
50
410
  addSpriteComponentBehind(component: any): any;
@@ -52,31 +412,272 @@ export declare class RpgClientEngine<T = any> {
52
412
  * Add a component to render in front of sprites
53
413
  * Components added with this method will be displayed with a higher z-index than the sprite
54
414
  *
55
- * @param component - The component to add in front of sprites
56
- * @returns The added component
415
+ * Supports multiple formats:
416
+ * 1. Direct component: `HealthBarComponent`
417
+ * 2. Configuration object: `{ component: StatusIndicator, props: {...} }`
418
+ * 3. With dynamic props: `{ component: HealthBar, props: (object) => {...} }`
419
+ * 4. With dependencies: `{ component: HealthBar, dependencies: (object) => [object.hp, object.param.maxHp] }`
420
+ *
421
+ * Components with dependencies will only be displayed when all dependencies are resolved (!= undefined).
422
+ * The object (sprite) is passed to the dependencies function to allow sprite-specific dependency resolution.
423
+ *
424
+ * @param component - The component to add in front of sprites, or a configuration object
425
+ * @param component.component - The component function to render
426
+ * @param component.props - Static props object or function that receives the sprite object and returns props
427
+ * @param component.dependencies - Function that receives the sprite object and returns an array of Signals
428
+ * @returns The added component or configuration
57
429
  *
58
430
  * @example
59
431
  * ```ts
60
432
  * // Add a health bar component in front of all sprites
61
433
  * engine.addSpriteComponentInFront(HealthBarComponent);
434
+ *
435
+ * // Add a component with static props
436
+ * engine.addSpriteComponentInFront({
437
+ * component: StatusIndicator,
438
+ * props: { type: 'poison' }
439
+ * });
440
+ *
441
+ * // Add a component with dynamic props and dependencies
442
+ * engine.addSpriteComponentInFront({
443
+ * component: HealthBar,
444
+ * props: (object) => ({ hp: object.hp(), maxHp: object.param.maxHp() }),
445
+ * dependencies: (object) => [object.hp, object.param.maxHp]
446
+ * });
62
447
  * ```
63
448
  */
64
- addSpriteComponentInFront(component: any): any;
65
- addEffect(effect: {
449
+ addSpriteComponentInFront(component: any | {
450
+ component: any;
451
+ props: (object: any) => any;
452
+ dependencies?: (object: any) => any[];
453
+ }): any;
454
+ /**
455
+ * Add a component animation to the engine
456
+ *
457
+ * Component animations are temporary visual effects that can be displayed
458
+ * on sprites or objects, such as hit indicators, spell effects, or status animations.
459
+ *
460
+ * @param componentAnimation - The component animation configuration
461
+ * @param componentAnimation.id - Unique identifier for the animation
462
+ * @param componentAnimation.component - The component function to render
463
+ * @returns The added component animation configuration
464
+ *
465
+ * @example
466
+ * ```ts
467
+ * // Add a hit animation component
468
+ * engine.addComponentAnimation({
469
+ * id: 'hit',
470
+ * component: HitComponent
471
+ * });
472
+ *
473
+ * // Add an explosion effect component
474
+ * engine.addComponentAnimation({
475
+ * id: 'explosion',
476
+ * component: ExplosionComponent
477
+ * });
478
+ * ```
479
+ */
480
+ addComponentAnimation(componentAnimation: {
66
481
  component: any;
67
482
  id: string;
68
483
  }): {
69
484
  component: any;
70
485
  id: string;
71
486
  };
72
- getEffect(id: string): EffectManager;
487
+ /**
488
+ * Get a component animation by its ID
489
+ *
490
+ * Retrieves the EffectManager instance for a specific component animation,
491
+ * which can be used to display the animation on sprites or objects.
492
+ *
493
+ * @param id - The unique identifier of the component animation
494
+ * @returns The EffectManager instance for the animation
495
+ * @throws Error if the component animation is not found
496
+ *
497
+ * @example
498
+ * ```ts
499
+ * // Get the hit animation and display it
500
+ * const hitAnimation = engine.getComponentAnimation('hit');
501
+ * hitAnimation.displayEffect({ text: "Critical!" }, player);
502
+ * ```
503
+ */
504
+ getComponentAnimation(id: string): AnimationManager;
505
+ /**
506
+ * Start a transition
507
+ *
508
+ * Convenience method to display a transition by its ID using the GUI system.
509
+ *
510
+ * @param id - The unique identifier of the transition to start
511
+ * @param props - Props to pass to the transition component
512
+ *
513
+ * @example
514
+ * ```ts
515
+ * // Start a fade transition
516
+ * engine.startTransition('fade', { duration: 1000, color: 'black' });
517
+ *
518
+ * // Start with onFinish callback
519
+ * engine.startTransition('fade', {
520
+ * duration: 1000,
521
+ * onFinish: () => console.log('Fade complete')
522
+ * });
523
+ * ```
524
+ */
525
+ startTransition(id: string, props?: any): void;
73
526
  processInput({ input }: {
74
- input: number;
75
- }): void;
527
+ input: Direction;
528
+ }): Promise<void>;
76
529
  processAction({ action }: {
77
530
  action: number;
78
531
  }): void;
79
532
  get PIXI(): typeof PIXI;
80
533
  get socket(): AbstractWebsocket;
81
534
  get playerId(): string | null;
535
+ get scene(): RpgClientMap;
536
+ private getPhysicsTick;
537
+ private ensureCurrentPlayerBody;
538
+ private stepClientPhysicsTick;
539
+ private flushPendingPredictedStates;
540
+ private buildPendingMoveTrajectory;
541
+ private emitMovePacket;
542
+ private flushPendingMovePath;
543
+ private getLocalPlayerState;
544
+ private applyAuthoritativeState;
545
+ private initializePredictionController;
546
+ getCurrentPlayer(): import('.').RpgClientPlayer;
547
+ emitSceneMapHook(hookName: string, ...args: any[]): void;
548
+ /**
549
+ * Setup RxJS observer to wait for all conditions before calling onAfterLoading hook
550
+ *
551
+ * This method uses RxJS `combineLatest` to wait for all conditions to be met,
552
+ * regardless of the order in which they arrive:
553
+ * 1. The map loading is completed (loadMapService.load is finished)
554
+ * 2. We received a player ID (pId)
555
+ * 3. Players array has at least one element
556
+ * 4. Events property is present in the sync data
557
+ *
558
+ * Once all conditions are met, it uses `switchMap` to call the onAfterLoading hook once.
559
+ *
560
+ * ## Design
561
+ *
562
+ * Uses BehaviorSubjects to track each condition state, allowing events to arrive
563
+ * in any order. The `combineLatest` operator waits until all observables emit `true`,
564
+ * then `take(1)` ensures the hook is called only once, and `switchMap` handles
565
+ * the hook execution.
566
+ *
567
+ * @example
568
+ * ```ts
569
+ * // Called automatically in loadScene to setup the observer
570
+ * this.setupOnAfterLoadingObserver();
571
+ * ```
572
+ */
573
+ private setupOnAfterLoadingObserver;
574
+ /**
575
+ * Clear client prediction states for cleanup
576
+ *
577
+ * Removes old prediction states and input history to prevent memory leaks.
578
+ * Should be called when changing maps or disconnecting.
579
+ *
580
+ * @example
581
+ * ```ts
582
+ * // Clear prediction states when changing maps
583
+ * engine.clearClientPredictionStates();
584
+ * ```
585
+ */
586
+ clearClientPredictionStates(): void;
587
+ /**
588
+ * Trigger a flash animation on a sprite
589
+ *
590
+ * This method allows you to trigger a flash effect on any sprite from client-side code.
591
+ * The flash can be configured with various options including type (alpha, tint, or both),
592
+ * duration, cycles, and color.
593
+ *
594
+ * ## Design
595
+ *
596
+ * The flash is applied directly to the sprite object using its flash trigger.
597
+ * This is useful for client-side visual feedback, UI interactions, or local effects
598
+ * that don't need to be synchronized with the server.
599
+ *
600
+ * @param spriteId - The ID of the sprite to flash. If not provided, flashes the current player
601
+ * @param options - Flash configuration options
602
+ * @param options.type - Type of flash effect: 'alpha' (opacity), 'tint' (color), or 'both' (default: 'alpha')
603
+ * @param options.duration - Duration of the flash animation in milliseconds (default: 300)
604
+ * @param options.cycles - Number of flash cycles (flash on/off) (default: 1)
605
+ * @param options.alpha - Alpha value when flashing, from 0 to 1 (default: 0.3)
606
+ * @param options.tint - Tint color when flashing as hex value or color name (default: 0xffffff - white)
607
+ *
608
+ * @example
609
+ * ```ts
610
+ * // Flash the current player with default settings
611
+ * engine.flash();
612
+ *
613
+ * // Flash a specific sprite with red tint
614
+ * engine.flash('sprite-id', { type: 'tint', tint: 0xff0000 });
615
+ *
616
+ * // Flash with both alpha and tint for dramatic effect
617
+ * engine.flash(undefined, {
618
+ * type: 'both',
619
+ * alpha: 0.5,
620
+ * tint: 0xff0000,
621
+ * duration: 200,
622
+ * cycles: 2
623
+ * });
624
+ *
625
+ * // Quick damage flash on current player
626
+ * engine.flash(undefined, {
627
+ * type: 'tint',
628
+ * tint: 'red',
629
+ * duration: 150,
630
+ * cycles: 1
631
+ * });
632
+ * ```
633
+ */
634
+ flash(spriteId?: string, options?: {
635
+ type?: 'alpha' | 'tint' | 'both';
636
+ duration?: number;
637
+ cycles?: number;
638
+ alpha?: number;
639
+ tint?: number | string;
640
+ }): void;
641
+ private applyServerAck;
642
+ private reconcilePrediction;
643
+ /**
644
+ * Replay unacknowledged inputs from a given frame to resimulate client prediction
645
+ * after applying server authority at a certain frame.
646
+ *
647
+ * @param startFrame - The last server-acknowledged frame
648
+ *
649
+ * @example
650
+ * ```ts
651
+ * // After applying a server correction at frame N
652
+ * this.replayUnackedInputsFromFrame(N);
653
+ * ```
654
+ */
655
+ private replayUnackedInputsFromFrame;
656
+ /**
657
+ * Clear all client resources and reset state
658
+ *
659
+ * This method should be called to clean up all client-side resources when
660
+ * shutting down or resetting the client engine. It:
661
+ * - Destroys the PIXI renderer
662
+ * - Stops all sounds
663
+ * - Cleans up subscriptions and event listeners
664
+ * - Resets scene map
665
+ * - Stops ping/pong interval
666
+ * - Clears prediction states
667
+ *
668
+ * ## Design
669
+ *
670
+ * This method is used primarily in testing environments to ensure clean
671
+ * state between tests. In production, the client engine typically persists
672
+ * for the lifetime of the application.
673
+ *
674
+ * @example
675
+ * ```ts
676
+ * // In test cleanup
677
+ * afterEach(() => {
678
+ * clientEngine.clear();
679
+ * });
680
+ * ```
681
+ */
682
+ clear(): void;
82
683
  }