@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
@@ -0,0 +1,150 @@
1
+ import { RpgClientEngine } from './RpgClientEngine';
2
+
3
+ /**
4
+ * RpgResource class
5
+ *
6
+ * Provides a unified API to access resource file links (images and sounds) in the game.
7
+ * Resources are stored as Maps of resource IDs to file paths/URLs.
8
+ *
9
+ * ## Design
10
+ *
11
+ * RpgResource acts as a facade over the engine's resource storage, providing
12
+ * easy access to resource file links. It maintains Maps that are synchronized
13
+ * with the engine's internal storage, but only stores the file paths/URLs,
14
+ * not the full resource objects.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { RpgResource } from '@rpgjs/client'
19
+ *
20
+ * // Get spritesheet image link
21
+ * const imageLink = RpgResource.spritesheets.get('hero')
22
+ *
23
+ * // Get sound file link
24
+ * const soundLink = RpgResource.sounds.get('town-music')
25
+ *
26
+ * // Set a new resource link
27
+ * RpgResource.spritesheets.set('new-sprite', './assets/new-sprite.png')
28
+ * ```
29
+ */
30
+ export class RpgResource {
31
+ private static engine: RpgClientEngine | null = null;
32
+ private static _spritesheets: Map<string, string> = new Map();
33
+ private static _sounds: Map<string, string> = new Map();
34
+
35
+ /**
36
+ * Initialize RpgResource with the engine instance
37
+ *
38
+ * This is called automatically by the engine during initialization.
39
+ * It synchronizes the resource Maps with the engine's internal storage.
40
+ *
41
+ * @param engine - The RpgClientEngine instance
42
+ */
43
+ static init(engine: RpgClientEngine): void {
44
+ RpgResource.engine = engine;
45
+ RpgResource.syncResources();
46
+ }
47
+
48
+ /**
49
+ * Synchronize resource Maps with the engine's internal storage
50
+ *
51
+ * Extracts file links from spritesheets and sounds stored in the engine
52
+ * and updates the Maps accordingly.
53
+ *
54
+ * @private
55
+ */
56
+ private static syncResources(): void {
57
+ if (!RpgResource.engine) {
58
+ return;
59
+ }
60
+
61
+ // Sync spritesheets
62
+ RpgResource._spritesheets.clear();
63
+ RpgResource.engine.spritesheets.forEach((spritesheet, id) => {
64
+ // Extract image path from spritesheet
65
+ const imageLink = spritesheet?.image || spritesheet?.imageSource || undefined;
66
+ if (imageLink) {
67
+ RpgResource._spritesheets.set(id, imageLink);
68
+ }
69
+ });
70
+
71
+ // Sync sounds
72
+ RpgResource._sounds.clear();
73
+ RpgResource.engine.sounds.forEach((sound, id) => {
74
+ // Extract src path from sound
75
+ let soundLink: string | undefined;
76
+
77
+ // If it's a Howler instance, try to get src from _src or src property
78
+ if (sound && typeof sound === 'object') {
79
+ if (sound._src && Array.isArray(sound._src) && sound._src.length > 0) {
80
+ soundLink = sound._src[0];
81
+ } else if (sound.src && typeof sound.src === 'string') {
82
+ soundLink = sound.src;
83
+ } else if (sound.src && Array.isArray(sound.src) && sound.src.length > 0) {
84
+ soundLink = sound.src[0];
85
+ }
86
+ }
87
+
88
+ if (soundLink) {
89
+ RpgResource._sounds.set(id, soundLink);
90
+ }
91
+ });
92
+ }
93
+
94
+ /**
95
+ * Get/Set image links for spritesheets
96
+ *
97
+ * Map of spritesheet IDs to their image file paths/URLs.
98
+ * This Map is synchronized with the engine's spritesheet storage.
99
+ *
100
+ * @type {Map<string, string>}
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * // Get an image link
105
+ * const imageLink = RpgResource.spritesheets.get('hero')
106
+ *
107
+ * // Set a new image link
108
+ * RpgResource.spritesheets.set('new-sprite', './assets/new-sprite.png')
109
+ *
110
+ * // Check if a spritesheet exists
111
+ * if (RpgResource.spritesheets.has('monster')) {
112
+ * const link = RpgResource.spritesheets.get('monster')
113
+ * }
114
+ * ```
115
+ */
116
+ static get spritesheets(): Map<string, string> {
117
+ // Sync before returning to ensure we have the latest data
118
+ RpgResource.syncResources();
119
+ return RpgResource._spritesheets;
120
+ }
121
+
122
+ /**
123
+ * Get/Set sound file links
124
+ *
125
+ * Map of sound IDs to their audio file paths/URLs.
126
+ * This Map is synchronized with the engine's sound storage.
127
+ *
128
+ * @type {Map<string, string>}
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * // Get a sound link
133
+ * const soundLink = RpgResource.sounds.get('town-music')
134
+ *
135
+ * // Set a new sound link
136
+ * RpgResource.sounds.set('new-sound', './assets/new-sound.ogg')
137
+ *
138
+ * // Iterate over all sounds
139
+ * RpgResource.sounds.forEach((link, id) => {
140
+ * console.log(`Sound ${id}: ${link}`)
141
+ * })
142
+ * ```
143
+ */
144
+ static get sounds(): Map<string, string> {
145
+ // Sync before returning to ensure we have the latest data
146
+ RpgResource.syncResources();
147
+ return RpgResource._sounds;
148
+ }
149
+ }
150
+
package/src/RpgClient.ts CHANGED
@@ -1,9 +1,11 @@
1
- import { ComponentFunction } from 'canvasengine'
1
+ import { ComponentFunction, Signal } from 'canvasengine'
2
2
  import { RpgClientEngine } from './RpgClientEngine'
3
3
  import { Loader, Container } from 'pixi.js'
4
+ import { RpgClientObject } from './Game/Object'
5
+ import { type MapPhysicsEntityContext, type MapPhysicsInitContext } from '@rpgjs/common'
4
6
 
5
7
  type RpgClass<T = any> = new (...args: any[]) => T
6
- type RpgComponent = Container
8
+ type RpgComponent = RpgClientObject
7
9
  type SceneMap = Container
8
10
 
9
11
  export interface RpgClientEngineHooks {
@@ -196,6 +198,41 @@ export interface RpgSceneMapHooks extends RpgSceneHooks<SceneMap> {
196
198
  * @memberof RpgSceneHooks
197
199
  */
198
200
  onMapLoading?: (scene: SceneMap, loader: Loader) => any
201
+
202
+ /**
203
+ * Called when client physics has been initialized for the current map.
204
+ *
205
+ * Use this hook to initialize shared physics extensions based on map data
206
+ * (for example, tile-based collision rules used by client prediction).
207
+ *
208
+ * @prop { (scene: SceneMap, context: MapPhysicsInitContext) => any } [onPhysicsInit]
209
+ * @memberof RpgSceneMapHooks
210
+ */
211
+ onPhysicsInit?: (scene: SceneMap, context: MapPhysicsInitContext) => any
212
+
213
+ /**
214
+ * Called when a character physics body is added to the map.
215
+ *
216
+ * @prop { (scene: SceneMap, context: MapPhysicsEntityContext) => any } [onPhysicsEntityAdd]
217
+ * @memberof RpgSceneMapHooks
218
+ */
219
+ onPhysicsEntityAdd?: (scene: SceneMap, context: MapPhysicsEntityContext) => any
220
+
221
+ /**
222
+ * Called when a character physics body is removed from the map.
223
+ *
224
+ * @prop { (scene: SceneMap, context: MapPhysicsEntityContext) => any } [onPhysicsEntityRemove]
225
+ * @memberof RpgSceneMapHooks
226
+ */
227
+ onPhysicsEntityRemove?: (scene: SceneMap, context: MapPhysicsEntityContext) => any
228
+
229
+ /**
230
+ * Called when the physics world is reset (e.g. before a map physics reload).
231
+ *
232
+ * @prop { (scene: SceneMap) => any } [onPhysicsReset]
233
+ * @memberof RpgSceneMapHooks
234
+ */
235
+ onPhysicsReset?: (scene: SceneMap) => any
199
236
  }
200
237
 
201
238
  export interface RpgClient {
@@ -305,34 +342,203 @@ export interface RpgClient {
305
342
  spritesheets?: any[],
306
343
 
307
344
  /**
308
- * Array containing the list of VueJS components
345
+ * Resolver function for dynamically creating spritesheets
346
+ *
347
+ * This function is called when a spritesheet is requested but not found in the cache.
348
+ * It can be synchronous (returns directly) or asynchronous (returns a Promise).
349
+ * The resolved spritesheet is automatically cached for future use.
350
+ *
351
+ * ```ts
352
+ * import { defineModule, RpgClient } from '@rpgjs/client'
353
+ *
354
+ * defineModule<RpgClient>({
355
+ * spritesheetResolver: (id: string) => {
356
+ * // Synchronous resolver
357
+ * if (id === 'dynamic-sprite') {
358
+ * return {
359
+ * id: 'dynamic-sprite',
360
+ * image: 'path/to/image.png',
361
+ * framesWidth: 32,
362
+ * framesHeight: 32
363
+ * };
364
+ * }
365
+ * return undefined;
366
+ * }
367
+ * })
368
+ *
369
+ * // Or asynchronous resolver
370
+ * defineModule<RpgClient>({
371
+ * spritesheetResolver: async (id: string) => {
372
+ * const response = await fetch(`/api/spritesheets/${id}`);
373
+ * const data = await response.json();
374
+ * return data;
375
+ * }
376
+ * })
377
+ * ```
378
+ *
379
+ * @prop {(id: string) => any | Promise<any>} [spritesheetResolver]
380
+ * @memberof RpgClient
381
+ * */
382
+ spritesheetResolver?: (id: string) => any | Promise<any>,
383
+
384
+ /**
385
+ * Resolver function for dynamically loading sounds
309
386
  *
387
+ * The resolver is called when a sound is requested but not found in the cache.
388
+ * It can be synchronous (returns directly) or asynchronous (returns a Promise).
389
+ * The resolved sound is automatically cached for future use.
390
+ *
391
+ * ```ts
392
+ * import { defineModule, RpgClient } from '@rpgjs/client'
393
+ *
394
+ * defineModule<RpgClient>({
395
+ * soundResolver: (id: string) => {
396
+ * if (id === 'dynamic-sound') {
397
+ * return { id: 'dynamic-sound', src: 'path/to/sound.mp3' };
398
+ * }
399
+ * return undefined;
400
+ * }
401
+ * })
402
+ * ```
403
+ *
404
+ * @prop {(id: string) => any | Promise<any>} [soundResolver]
405
+ * @memberof RpgClient
406
+ * */
407
+ soundResolver?: (id: string) => any | Promise<any>,
408
+
409
+ /**
410
+ * Array containing the list of GUI components
411
+ *
412
+ * ```ts
413
+ * import { defineModule, RpgClient } from '@rpgjs/client'
414
+ * import InventoryComponent from './inventory.ce'
415
+ *
416
+ * defineModule<RpgClient>({
417
+ * gui: [
418
+ * {
419
+ * id: 'inventory',
420
+ * component: InventoryComponent,
421
+ * autoDisplay: true,
422
+ * dependencies: () => [playerSignal, inventorySignal]
423
+ * }
424
+ * ]
425
+ * })
426
+ * ```
310
427
  *
311
428
  * [Guide: Create GUI](/guide/create-gui.html)
312
429
  *
313
- * @prop {Array<Component of CanvasEngine>} [gui]
430
+ * @prop {Array<GuiOptions>} [gui]
314
431
  * @memberof RpgClient
315
432
  * */
316
- gui?: ComponentFunction[],
433
+ gui?: ({
434
+ id: string,
435
+ component: ComponentFunction,
436
+ /**
437
+ * Auto display the GUI when added to the system
438
+ * @default false
439
+ */
440
+ autoDisplay?: boolean,
441
+ /**
442
+ * Function that returns an array of Signal dependencies
443
+ * The GUI will only display when all dependencies are resolved (!= undefined)
444
+ */
445
+ dependencies?: () => Signal[]
446
+ /**
447
+ * Attach the GUI to sprites instead of displaying globally
448
+ *
449
+ * When set to `true`, the GUI component will be rendered directly on each sprite
450
+ * in the game world, rather than being displayed as a fixed overlay on the screen.
451
+ * This is useful for tooltips, health bars, name tags, or any UI element that
452
+ * should follow a specific sprite.
453
+ *
454
+ * The GUI will be rendered in the `character.ce` component for each sprite.
455
+ * You can control the display state of attached GUIs from the server side using
456
+ * `player.showAttachedGui()` and `player.hideAttachedGui()` methods.
457
+ *
458
+ * @default false
459
+ * @example
460
+ * ```ts
461
+ * import { defineModule, RpgClient } from '@rpgjs/client'
462
+ * import TooltipComponent from './tooltip.ce'
463
+ *
464
+ * defineModule<RpgClient>({
465
+ * gui: [
466
+ * {
467
+ * id: "my-tooltip",
468
+ * component: TooltipComponent,
469
+ * attachToSprite: true
470
+ * }
471
+ * ]
472
+ * })
473
+ * ```
474
+ *
475
+ * On the server side, control the display:
476
+ * ```ts
477
+ * // Show the tooltip for this player
478
+ * player.showAttachedGui()
479
+ *
480
+ * // Hide the tooltip for this player
481
+ * player.hideAttachedGui()
482
+ *
483
+ * // Show tooltip for other players
484
+ * player.showAttachedGui([otherPlayer1, otherPlayer2])
485
+ * ```
486
+ */
487
+ attachToSprite?: boolean
488
+ } | any)[],
317
489
 
318
490
  /**
319
491
  * Array containing the list of sounds
320
- * Each element is a simple object containing sound definitions
492
+ * Each element can be:
493
+ * - A simple object containing sound definitions
494
+ * - A class decorated with @Sound
321
495
  *
322
496
  * ```ts
323
- * import { defineModule, RpgClient } from '@rpgjs/client'
497
+ * import { defineModule, RpgClient, Sound } from '@rpgjs/client'
324
498
  *
499
+ * // Using simple objects
325
500
  * defineModule<RpgClient>({
326
501
  * sounds: [
327
502
  * {
328
- * town: require('./assets/Town_Theme.ogg'),
329
- * battle: require('./assets/Battle_Theme.ogg')
503
+ * id: 'typewriter',
504
+ * src: 'typewriter.wav'
505
+ * },
506
+ * {
507
+ * id: 'cursor',
508
+ * src: 'cursor.wav'
330
509
  * }
331
510
  * ]
332
511
  * })
512
+ *
513
+ * // Using @Sound decorator
514
+ * @Sound({
515
+ * id: 'town-music',
516
+ * sound: require('./sound/town.ogg'),
517
+ * loop: true,
518
+ * volume: 0.5
519
+ * })
520
+ * export class TownMusic {}
521
+ *
522
+ * defineModule<RpgClient>({
523
+ * sounds: [TownMusic]
524
+ * })
525
+ *
526
+ * // Multiple sounds in one class
527
+ * @Sound({
528
+ * sounds: {
529
+ * hero: require('./assets/hero.ogg'),
530
+ * monster: require('./assets/monster.ogg')
531
+ * },
532
+ * loop: true
533
+ * })
534
+ * export class CharacterSounds {}
535
+ *
536
+ * defineModule<RpgClient>({
537
+ * sounds: [CharacterSounds]
538
+ * })
333
539
  * ```
334
540
  *
335
- * @prop {Array<Object>} [sounds]
541
+ * @prop {Array<Object | Class>} [sounds]
336
542
  * @memberof RpgClient
337
543
  * */
338
544
  sounds?: any[],
@@ -382,8 +588,36 @@ export interface RpgClient {
382
588
  map: RpgSceneMapHooks
383
589
  }
384
590
 
385
- effects?: {
591
+ sceneMap?: RpgSceneMapHooks
592
+
593
+ /**
594
+ * Array containing the list of component animations
595
+ * Each element defines a temporary component to display for animations like hits, effects, etc.
596
+ *
597
+ * ```ts
598
+ * import { defineModule, RpgClient } from '@rpgjs/client'
599
+ * import HitComponent from './hit.ce'
600
+ * import ExplosionComponent from './explosion.ce'
601
+ *
602
+ * defineModule<RpgClient>({
603
+ * componentAnimations: [
604
+ * {
605
+ * id: 'hit',
606
+ * component: HitComponent
607
+ * },
608
+ * {
609
+ * id: 'explosion',
610
+ * component: ExplosionComponent
611
+ * }
612
+ * ]
613
+ * })
614
+ * ```
615
+ *
616
+ * @prop {Array<{id: string, component: ComponentFunction}>} [componentAnimations]
617
+ * @memberof RpgClient
618
+ * */
619
+ componentAnimations?: {
386
620
  id: string,
387
621
  component: ComponentFunction
388
622
  }[]
389
- }
623
+ }