@rpgjs/server 5.0.0-alpha.4 → 5.0.0-alpha.40

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 (101) hide show
  1. package/dist/Gui/DialogGui.d.ts +5 -0
  2. package/dist/Gui/GameoverGui.d.ts +23 -0
  3. package/dist/Gui/Gui.d.ts +6 -0
  4. package/dist/Gui/MenuGui.d.ts +22 -3
  5. package/dist/Gui/NotificationGui.d.ts +1 -2
  6. package/dist/Gui/SaveLoadGui.d.ts +13 -0
  7. package/dist/Gui/ShopGui.d.ts +28 -3
  8. package/dist/Gui/TitleGui.d.ts +23 -0
  9. package/dist/Gui/index.d.ts +10 -1
  10. package/dist/Player/BattleManager.d.ts +34 -12
  11. package/dist/Player/ClassManager.d.ts +46 -13
  12. package/dist/Player/ComponentManager.d.ts +123 -0
  13. package/dist/Player/Components.d.ts +345 -0
  14. package/dist/Player/EffectManager.d.ts +86 -0
  15. package/dist/Player/ElementManager.d.ts +104 -0
  16. package/dist/Player/GoldManager.d.ts +22 -0
  17. package/dist/Player/GuiManager.d.ts +259 -0
  18. package/dist/Player/ItemFixture.d.ts +6 -0
  19. package/dist/Player/ItemManager.d.ts +450 -9
  20. package/dist/Player/MoveManager.d.ts +324 -69
  21. package/dist/Player/ParameterManager.d.ts +344 -14
  22. package/dist/Player/Player.d.ts +460 -8
  23. package/dist/Player/SkillManager.d.ts +197 -15
  24. package/dist/Player/StateManager.d.ts +89 -25
  25. package/dist/Player/VariableManager.d.ts +74 -0
  26. package/dist/RpgServer.d.ts +464 -64
  27. package/dist/RpgServerEngine.d.ts +2 -1
  28. package/dist/decorators/event.d.ts +46 -0
  29. package/dist/decorators/map.d.ts +287 -0
  30. package/dist/index.d.ts +10 -0
  31. package/dist/index.js +21491 -20802
  32. package/dist/index.js.map +1 -1
  33. package/dist/logs/log.d.ts +2 -3
  34. package/dist/module.d.ts +43 -1
  35. package/dist/presets/index.d.ts +0 -9
  36. package/dist/rooms/BaseRoom.d.ts +132 -0
  37. package/dist/rooms/lobby.d.ts +10 -2
  38. package/dist/rooms/map.d.ts +1232 -17
  39. package/dist/services/save.d.ts +43 -0
  40. package/dist/storage/index.d.ts +1 -0
  41. package/dist/storage/localStorage.d.ts +23 -0
  42. package/package.json +14 -10
  43. package/src/Gui/DialogGui.ts +19 -4
  44. package/src/Gui/GameoverGui.ts +39 -0
  45. package/src/Gui/Gui.ts +23 -1
  46. package/src/Gui/MenuGui.ts +155 -6
  47. package/src/Gui/NotificationGui.ts +1 -2
  48. package/src/Gui/SaveLoadGui.ts +60 -0
  49. package/src/Gui/ShopGui.ts +146 -16
  50. package/src/Gui/TitleGui.ts +39 -0
  51. package/src/Gui/index.ts +15 -2
  52. package/src/Player/BattleManager.ts +91 -49
  53. package/src/Player/ClassManager.ts +118 -50
  54. package/src/Player/ComponentManager.ts +425 -19
  55. package/src/Player/Components.ts +380 -0
  56. package/src/Player/EffectManager.ts +81 -44
  57. package/src/Player/ElementManager.ts +109 -86
  58. package/src/Player/GoldManager.ts +32 -35
  59. package/src/Player/GuiManager.ts +308 -150
  60. package/src/Player/ItemFixture.ts +4 -5
  61. package/src/Player/ItemManager.ts +774 -355
  62. package/src/Player/MoveManager.ts +1544 -774
  63. package/src/Player/ParameterManager.ts +546 -104
  64. package/src/Player/Player.ts +1163 -88
  65. package/src/Player/SkillManager.ts +520 -195
  66. package/src/Player/StateManager.ts +170 -182
  67. package/src/Player/VariableManager.ts +101 -63
  68. package/src/RpgServer.ts +483 -63
  69. package/src/core/context.ts +1 -0
  70. package/src/decorators/event.ts +61 -0
  71. package/src/decorators/map.ts +327 -0
  72. package/src/index.ts +11 -1
  73. package/src/logs/log.ts +10 -3
  74. package/src/module.ts +126 -3
  75. package/src/presets/index.ts +1 -10
  76. package/src/rooms/BaseRoom.ts +232 -0
  77. package/src/rooms/lobby.ts +25 -7
  78. package/src/rooms/map.ts +2473 -194
  79. package/src/services/save.ts +147 -0
  80. package/src/storage/index.ts +1 -0
  81. package/src/storage/localStorage.ts +76 -0
  82. package/tests/battle.spec.ts +375 -0
  83. package/tests/change-map.spec.ts +72 -0
  84. package/tests/class.spec.ts +274 -0
  85. package/tests/effect.spec.ts +219 -0
  86. package/tests/element.spec.ts +221 -0
  87. package/tests/event.spec.ts +80 -0
  88. package/tests/gold.spec.ts +99 -0
  89. package/tests/item.spec.ts +609 -0
  90. package/tests/module.spec.ts +38 -0
  91. package/tests/move.spec.ts +601 -0
  92. package/tests/player-param.spec.ts +28 -0
  93. package/tests/prediction-reconciliation.spec.ts +182 -0
  94. package/tests/random-move.spec.ts +65 -0
  95. package/tests/skill.spec.ts +658 -0
  96. package/tests/state.spec.ts +467 -0
  97. package/tests/variable.spec.ts +185 -0
  98. package/tests/world-maps.spec.ts +896 -0
  99. package/vite.config.ts +16 -0
  100. package/dist/Player/Event.d.ts +0 -0
  101. package/src/Player/Event.ts +0 -0
package/src/RpgServer.ts CHANGED
@@ -1,17 +1,45 @@
1
+ import { MapOptions } from "./decorators/map"
1
2
  import { RpgPlayer } from "./Player/Player"
2
3
  import { type RpgMap } from "./rooms/map"
3
4
  import { RpgServerEngine } from "./RpgServerEngine"
5
+ import { WorldMapConfig, RpgShape } from "@rpgjs/common"
6
+ import { RpgEvent } from "./Player/Player"
4
7
 
5
- type RpgShape = any
6
- type RpgClassMap<T> = any
7
- type RpgClassEvent<T> = any
8
- type RpgEvent = any
8
+ type RpgClassMap<T> = new () => T
9
+ type RpgClassEvent<T> = RpgEvent
9
10
  type MatchMakerOption = any
10
11
  type RpgMatchMaker = any
11
12
  type IStoreState = any
12
- type TiledMap = any
13
- type WorldMap = any
14
- type MapOptions = any
13
+
14
+ /**
15
+ * Interface for world map configuration
16
+ *
17
+ * Represents a world that contains multiple maps with their spatial relationships.
18
+ * This is typically used with Tiled Map Editor's world files.
19
+ *
20
+ * @interface WorldMap
21
+ * @example
22
+ * ```ts
23
+ * const worldMap: WorldMap = {
24
+ * id: 'my-world',
25
+ * maps: [
26
+ * { id: 'map1', worldX: 0, worldY: 0, width: 800, height: 600 },
27
+ * { id: 'map2', worldX: 800, worldY: 0, width: 800, height: 600 }
28
+ * ]
29
+ * }
30
+ * ```
31
+ */
32
+ export interface WorldMap {
33
+ /** Optional world identifier */
34
+ id?: string;
35
+ /** Array of map configurations that belong to this world */
36
+ maps: WorldMapConfig[];
37
+ /** Only show adjacent maps (used by Tiled Map Editor) */
38
+ onlyShowAdjacentMaps?: boolean;
39
+ /** Type identifier (used by Tiled Map Editor, should be 'world') */
40
+ type?: 'world';
41
+ }
42
+
15
43
 
16
44
  export interface RpgServerEngineHooks {
17
45
  /**
@@ -150,6 +178,14 @@ export interface RpgPlayerHooks {
150
178
  */
151
179
  onConnected?: (player: RpgPlayer) => any
152
180
 
181
+ /**
182
+ * When the player starts the game from the lobby
183
+ *
184
+ * @prop { (player: RpgPlayer) => any } [onStart]
185
+ * @memberof RpgPlayerHooks
186
+ */
187
+ onStart?: (player: RpgPlayer) => any
188
+
153
189
  /**
154
190
  * When the player presses a key on the client side
155
191
  *
@@ -227,20 +263,322 @@ export interface RpgPlayerHooks {
227
263
  canChangeMap?: (player: RpgPlayer, nextMap: RpgClassMap<RpgMap>) => boolean | Promise<boolean>
228
264
  }
229
265
 
266
+ /**
267
+ * Event hooks interface for handling various event lifecycle methods
268
+ *
269
+ * @interface RpgEventHooks
270
+ * @since 4.0.0
271
+ */
230
272
  export interface RpgEventHooks {
273
+ /**
274
+ * Called as soon as the event is created on the map
275
+ *
276
+ * @param {RpgEvent} event - The event instance being initialized
277
+ * @returns {any}
278
+ * @memberof RpgEventHooks
279
+ * @example
280
+ * ```ts
281
+ * const eventHooks: RpgEventHooks = {
282
+ * onInit(event) {
283
+ * console.log(`Event ${event.name} initialized`)
284
+ * event.graphic('default-sprite')
285
+ * }
286
+ * }
287
+ * ```
288
+ */
231
289
  onInit?: (event: RpgEvent) => any,
290
+
291
+ /**
292
+ * Called when the event collides with a player and the player presses the action key
293
+ *
294
+ * @param {RpgEvent} event - The event being interacted with
295
+ * @param {RpgPlayer} player - The player performing the action
296
+ * @returns {any}
297
+ * @memberof RpgEventHooks
298
+ * @example
299
+ * ```ts
300
+ * const eventHooks: RpgEventHooks = {
301
+ * onAction(event, player) {
302
+ * player.showText('You activated the chest!')
303
+ * player.addItem('POTION', 1)
304
+ * }
305
+ * }
306
+ * ```
307
+ */
232
308
  onAction?: (event: RpgEvent, player: RpgPlayer) => any
309
+
310
+ /**
311
+ * Called before an event object is created and added to the map
312
+ * Allows modification of event properties before instantiation
313
+ *
314
+ * @param {any} object - The event object data before creation
315
+ * @param {RpgMap} map - The map where the event will be created
316
+ * @returns {any}
317
+ * @memberof RpgEventHooks
318
+ * @example
319
+ * ```ts
320
+ * const eventHooks: RpgEventHooks = {
321
+ * onBeforeCreated(object, map) {
322
+ * // Modify event properties based on map conditions
323
+ * if (map.id === 'dungeon') {
324
+ * object.graphic = 'monster-sprite'
325
+ * }
326
+ * }
327
+ * }
328
+ * ```
329
+ */
233
330
  onBeforeCreated?: (object: any, map: RpgMap) => any
331
+
332
+ /**
333
+ * Called when a player or another event enters a shape attached to this event
334
+ *
335
+ * @param {RpgEvent} event - The event with the attached shape
336
+ * @param {RpgPlayer} player - The player entering the shape
337
+ * @param {RpgShape} shape - The shape being entered
338
+ * @returns {any}
339
+ * @since 4.1.0
340
+ * @memberof RpgEventHooks
341
+ * @example
342
+ * ```ts
343
+ * const eventHooks: RpgEventHooks = {
344
+ * onDetectInShape(event, player, shape) {
345
+ * console.log(`Player ${player.name} entered detection zone`)
346
+ * player.showText('You are being watched...')
347
+ * }
348
+ * }
349
+ * ```
350
+ */
234
351
  onDetectInShape?: (event: RpgEvent, player: RpgPlayer, shape: RpgShape) => any
352
+
353
+ /**
354
+ * Called when a player or another event leaves a shape attached to this event
355
+ *
356
+ * @param {RpgEvent} event - The event with the attached shape
357
+ * @param {RpgPlayer} player - The player leaving the shape
358
+ * @param {RpgShape} shape - The shape being left
359
+ * @returns {any}
360
+ * @since 4.1.0
361
+ * @memberof RpgEventHooks
362
+ * @example
363
+ * ```ts
364
+ * const eventHooks: RpgEventHooks = {
365
+ * onDetectOutShape(event, player, shape) {
366
+ * console.log(`Player ${player.name} left detection zone`)
367
+ * player.showText('You escaped the watch...')
368
+ * }
369
+ * }
370
+ * ```
371
+ */
235
372
  onDetectOutShape?: (event: RpgEvent, player: RpgPlayer, shape: RpgShape) => any
373
+
374
+ /**
375
+ * Called when the event enters a shape on the map
376
+ *
377
+ * @param {RpgEvent} event - The event entering the shape
378
+ * @param {RpgShape} shape - The shape being entered
379
+ * @returns {any}
380
+ * @memberof RpgEventHooks
381
+ * @example
382
+ * ```ts
383
+ * const eventHooks: RpgEventHooks = {
384
+ * onInShape(event, shape) {
385
+ * console.log(`Event entered shape: ${shape.id}`)
386
+ * event.speed = 1 // Slow down in this area
387
+ * }
388
+ * }
389
+ * ```
390
+ */
236
391
  onInShape?: (event: RpgEvent, shape: RpgShape) => any
392
+
393
+ /**
394
+ * Called when the event leaves a shape on the map
395
+ *
396
+ * @param {RpgEvent} event - The event leaving the shape
397
+ * @param {RpgShape} shape - The shape being left
398
+ * @returns {any}
399
+ * @memberof RpgEventHooks
400
+ * @example
401
+ * ```ts
402
+ * const eventHooks: RpgEventHooks = {
403
+ * onOutShape(event, shape) {
404
+ * console.log(`Event left shape: ${shape.id}`)
405
+ * event.speed = 3 // Resume normal speed
406
+ * }
407
+ * }
408
+ * ```
409
+ */
237
410
  onOutShape?: (event: RpgEvent, shape: RpgShape) => any
411
+
412
+ /**
413
+ * Called when the event collides with a player (without requiring action key press)
414
+ *
415
+ * @param {RpgEvent} event - The event touching the player
416
+ * @param {RpgPlayer} player - The player being touched
417
+ * @returns {any}
418
+ * @memberof RpgEventHooks
419
+ * @example
420
+ * ```ts
421
+ * const eventHooks: RpgEventHooks = {
422
+ * onPlayerTouch(event, player) {
423
+ * player.hp -= 10 // Damage on touch
424
+ * player.showText('Ouch! You touched a spike!')
425
+ * }
426
+ * }
427
+ * ```
428
+ */
238
429
  onPlayerTouch?: (event: RpgEvent, player: RpgPlayer) => any
430
+
431
+ /**
432
+ * Called whenever any event on the map (including itself) is executed or changes state
433
+ * Useful for creating reactive events that respond to map state changes
434
+ *
435
+ * @param {RpgEvent} event - The event listening for changes
436
+ * @param {RpgPlayer} player - The player involved in the change
437
+ * @returns {any}
438
+ * @memberof RpgEventHooks
439
+ * @example
440
+ * ```ts
441
+ * const eventHooks: RpgEventHooks = {
442
+ * onChanges(event, player) {
443
+ * // Change chest graphic based on game state
444
+ * if (player.getVariable('BATTLE_END')) {
445
+ * event.graphic('chest-open')
446
+ * } else {
447
+ * event.graphic('chest-close')
448
+ * }
449
+ * }
450
+ * }
451
+ * ```
452
+ */
239
453
  onChanges?: (event: RpgEvent, player: RpgPlayer) => any
240
454
  }
241
455
 
456
+ /**
457
+ * Map hooks interface for handling map lifecycle events
458
+ *
459
+ * These hooks are global hooks that apply to all maps in the game.
460
+ * They are defined in the RpgModule configuration and executed for every map instance.
461
+ *
462
+ * @interface RpgMapHooks
463
+ * @since 4.0.0
464
+ */
242
465
  export interface RpgMapHooks {
243
- onBeforeUpdate<T = RpgMap>(mapData: any, map: T): T
466
+ /**
467
+ * Called before a map is updated with new data
468
+ * Allows modification of map data before the update is applied
469
+ *
470
+ * The `mapData` parameter contains the loaded map data (retrieved from request body)
471
+ * You can modify the map before the update is processed
472
+ *
473
+ * @template T - Type of the incoming map data
474
+ * @template U - Type of the map instance (defaults to RpgMap)
475
+ * @param {T} mapData - The map data loaded from external source (e.g., request body)
476
+ * @param {U} map - The current map instance being updated
477
+ * @returns {U | Promise<U>} The modified map instance or a promise resolving to it
478
+ * @memberof RpgMapHooks
479
+ * @example
480
+ * ```ts
481
+ * const mapHooks: RpgMapHooks = {
482
+ * onBeforeUpdate(mapData, map) {
483
+ * // Modify map properties based on incoming data
484
+ * if (mapData.weather === 'rain') {
485
+ * map.setWeatherEffect('rain')
486
+ * }
487
+ *
488
+ * // Add custom properties from external data
489
+ * map.customProperty = mapData.customValue
490
+ *
491
+ * return map
492
+ * }
493
+ * }
494
+ * ```
495
+ *
496
+ * @example
497
+ * ```ts
498
+ * // Async example with database operations
499
+ * const mapHooks: RpgMapHooks = {
500
+ * async onBeforeUpdate(mapData, map) {
501
+ * // Load additional data from database
502
+ * const additionalData = await database.getMapExtras(map.id)
503
+ *
504
+ * // Apply modifications
505
+ * map.events = [...map.events, ...additionalData.events]
506
+ * map.npcs = additionalData.npcs
507
+ *
508
+ * return map
509
+ * }
510
+ * }
511
+ * ```
512
+ */
513
+ onBeforeUpdate<T, U = RpgMap>(mapData: T, map: U): U | Promise<U>
514
+
515
+ /**
516
+ * Called when a map is loaded and initialized
517
+ *
518
+ * This hook is executed once when the map data is loaded and ready.
519
+ * It applies to all maps globally. Use this to initialize map-specific properties
520
+ * or setup that should happen for every map.
521
+ *
522
+ * @param {RpgMap} map - The map instance that was loaded
523
+ * @returns {any}
524
+ * @memberof RpgMapHooks
525
+ * @example
526
+ * ```ts
527
+ * const mapHooks: RpgMapHooks = {
528
+ * onLoad(map: RpgMap) {
529
+ * console.log(`Map ${map.id} loaded`)
530
+ * // Initialize global map properties
531
+ * }
532
+ * }
533
+ * ```
534
+ */
535
+ onLoad?: (map: RpgMap) => any
536
+
537
+ /**
538
+ * Called when a player joins any map
539
+ *
540
+ * This hook is executed each time a player joins any map in the game.
541
+ * It applies globally to all maps. Use this to perform actions that should
542
+ * happen whenever a player enters any map.
543
+ *
544
+ * @param {RpgPlayer} player - The player joining the map
545
+ * @param {RpgMap} map - The map instance the player joined
546
+ * @returns {any}
547
+ * @memberof RpgMapHooks
548
+ * @example
549
+ * ```ts
550
+ * const mapHooks: RpgMapHooks = {
551
+ * onJoin(player: RpgPlayer, map: RpgMap) {
552
+ * console.log(`${player.name} joined map ${map.id}`)
553
+ * // Perform global actions when player joins any map
554
+ * }
555
+ * }
556
+ * ```
557
+ */
558
+ onJoin?: (player: RpgPlayer, map: RpgMap) => any
559
+
560
+ /**
561
+ * Called when a player leaves any map
562
+ *
563
+ * This hook is executed each time a player leaves any map in the game.
564
+ * It applies globally to all maps. Use this to perform cleanup or actions
565
+ * that should happen whenever a player exits any map.
566
+ *
567
+ * @param {RpgPlayer} player - The player leaving the map
568
+ * @param {RpgMap} map - The map instance the player left
569
+ * @returns {any}
570
+ * @memberof RpgMapHooks
571
+ * @example
572
+ * ```ts
573
+ * const mapHooks: RpgMapHooks = {
574
+ * onLeave(player: RpgPlayer, map: RpgMap) {
575
+ * console.log(`${player.name} left map ${map.id}`)
576
+ * // Perform global cleanup when player leaves any map
577
+ * }
578
+ * }
579
+ * ```
580
+ */
581
+ onLeave?: (player: RpgPlayer, map: RpgMap) => any
244
582
  }
245
583
 
246
584
  export interface RpgServer {
@@ -254,14 +592,14 @@ export interface RpgServer {
254
592
  * @example
255
593
  *
256
594
  * ```ts
257
- * import { RpgServer, RpgModule } from '@rpgjs/server'
595
+ * import { RpgServer } from '@rpgjs/server'
596
+ * import { defineModule } from '@rpgjs/common'
258
597
  *
259
- * @RpgModule<RpgServer>({
598
+ * export default defineModule<RpgServer>({
260
599
  * hooks: {
261
600
  * player: ['onAuth']
262
601
  * }
263
602
  * })
264
- * class RpgServerEngine { }
265
603
  * ```
266
604
  *
267
605
  * Emit the hook:
@@ -301,18 +639,18 @@ export interface RpgServer {
301
639
  * Object containing the hooks concerning the engine
302
640
  *
303
641
  * ```ts
304
- * import { RpgServerEngine, RpgServerEngineHooks, RpgModule, RpgClient } from '@rpgjs/server'
642
+ * import { RpgServerEngine, RpgServerEngineHooks, RpgServer } from '@rpgjs/server'
643
+ * import { defineModule } from '@rpgjs/common'
305
644
  *
306
- * const engine: RpgEngineHooks = {
645
+ * const engine: RpgServerEngineHooks = {
307
646
  * onStart(server: RpgServerEngine) {
308
647
  * console.log('server is started')
309
648
  * }
310
649
  * }
311
650
  *
312
- * @RpgModule<RpgServer>({
651
+ * export default defineModule<RpgServer>({
313
652
  * engine
314
653
  * })
315
- * class RpgServerModule {}
316
654
  * ```
317
655
  *
318
656
  * @prop {RpgServerEngineHooks} [engine]
@@ -324,7 +662,8 @@ export interface RpgServer {
324
662
  * Give the `player` object hooks. Each time a player connects, an instance of `RpgPlayer` is created.
325
663
  *
326
664
  * ```ts
327
- * import { RpgPlayer, RpgServer, RpgPlayerHooks, RpgModule } from '@rpgjs/server'
665
+ * import { RpgPlayer, RpgServer, RpgPlayerHooks } from '@rpgjs/server'
666
+ * import { defineModule } from '@rpgjs/common'
328
667
  *
329
668
  * const player: RpgPlayerHooks = {
330
669
  * onConnected(player: RpgPlayer) {
@@ -332,10 +671,9 @@ export interface RpgServer {
332
671
  * }
333
672
  * }
334
673
  *
335
- * @RpgModule<RpgServer>({
674
+ * export default defineModule<RpgServer>({
336
675
  * player
337
676
  * })
338
- * class RpgServerEngine { }
339
677
  * ```
340
678
  *
341
679
  * @prop {RpgClassPlayer<RpgPlayer>} [player]
@@ -347,28 +685,30 @@ export interface RpgServer {
347
685
  * References all data in the server. it is mainly used to retrieve data according to their identifier
348
686
  *
349
687
  * ```ts
350
- * import { RpgServer, RpgModule } from '@rpgjs/server'
688
+ * import { RpgServer } from '@rpgjs/server'
689
+ * import { defineModule } from '@rpgjs/common'
351
690
  * import { Potion } from 'my-database/items/potion'
352
691
  *
353
- * @RpgModule<RpgServer>({
692
+ * export default defineModule<RpgServer>({
354
693
  * database: {
355
694
  * Potion
356
695
  * }
357
696
  * })
358
- * class RpgServerEngine { }
359
697
  * ```
360
698
  *
361
- * @prop { { [dataName]: data } } [database]
699
+ * @prop { { [dataName]: data } | (engine: RpgMap) => { [dataName]: data } | Promise<{ [dataName]: data }> } [database]
362
700
  * @memberof RpgServer
363
701
  * */
364
- database?: object | any[],
702
+ database?: object | any[] | ((engine: RpgMap) => object | any[] | Promise<object | any[]>),
365
703
 
366
704
  /**
367
- * Array of all maps. Each element is an `RpgMap` class
705
+ * Array of all maps. Each element can be either a class (decorated with `@MapData` or not) or a `MapOptions` object
368
706
  *
369
707
  * ```ts
370
- * import { RpgMap, MapData, RpgServer, RpgModule } from '@rpgjs/server'
708
+ * import { RpgMap, MapData, RpgServer } from '@rpgjs/server'
709
+ * import { defineModule } from '@rpgjs/common'
371
710
  *
711
+ * // Class that extends RpgMap (optional)
372
712
  * @MapData({
373
713
  * id: 'town',
374
714
  * file: require('./tmx/mymap.tmx'),
@@ -376,18 +716,29 @@ export interface RpgServer {
376
716
  * })
377
717
  * class TownMap extends RpgMap { }
378
718
  *
379
- * @RpgModule<RpgServer>({
719
+ * // Or a simple class without extending RpgMap
720
+ * @MapData({
721
+ * id: 'map',
722
+ * file: '',
723
+ * events: [{ event: Event() }]
724
+ * })
725
+ * class SimpleMap {}
726
+ *
727
+ * export default defineModule<RpgServer>({
380
728
  * maps: [
381
- * TownMap
729
+ * TownMap,
730
+ * SimpleMap
382
731
  * ]
383
732
  * })
384
- * class RpgServerEngine { }
385
733
  * ```
386
734
  *
387
735
  * It is possible to just give the object as well
388
736
  *
389
737
  * ```ts
390
- * @RpgModule<RpgServer>({
738
+ * import { RpgServer } from '@rpgjs/server'
739
+ * import { defineModule } from '@rpgjs/common'
740
+ *
741
+ * export default defineModule<RpgServer>({
391
742
  * maps: [
392
743
  * {
393
744
  * id: 'town',
@@ -396,25 +747,65 @@ export interface RpgServer {
396
747
  * }
397
748
  * ]
398
749
  * })
399
- * class RpgServerEngine { }
400
750
  * ```
401
751
  *
402
752
  * Since version 3.0.0-beta.8, you can just pass the path to the file. The identifier will then be the name of the file
403
753
  *
404
754
  * ```ts
405
- * @RpgModule<RpgServer>({
755
+ * import { RpgServer } from '@rpgjs/server'
756
+ * import { defineModule } from '@rpgjs/common'
757
+ *
758
+ * export default defineModule<RpgServer>({
406
759
  * maps: [
407
760
  * require('./tmx/mymap.tmx') // id is "mymap"
408
761
  * ]
409
762
  * })
410
- * class RpgServerEngine { }
411
763
  * ```
412
764
  *
413
- * @prop {RpgClassMap<RpgMap>[]} [maps]
765
+ * @prop {(new () => any) | MapOptions)[]} [maps]
414
766
  * @memberof RpgServer
415
767
  * */
416
- maps?: RpgClassMap<RpgMap>[] | MapOptions[] | string[] | TiledMap[],
768
+ maps?: ((new () => any) | MapOptions)[],
417
769
 
770
+ /**
771
+ * Global map hooks that apply to all maps in the game
772
+ *
773
+ * These hooks are executed for every map instance and allow you to define
774
+ * global behavior that should happen for all maps. They are different from
775
+ * map-specific hooks defined in `@MapData` which only apply to a specific map class.
776
+ *
777
+ * ```ts
778
+ * import { RpgServer, RpgMapHooks, RpgMap, RpgPlayer } from '@rpgjs/server'
779
+ * import { defineModule } from '@rpgjs/common'
780
+ *
781
+ * const mapHooks: RpgMapHooks = {
782
+ * onLoad(map: RpgMap) {
783
+ * console.log(`Map ${map.id} loaded`)
784
+ * // Initialize global map properties
785
+ * },
786
+ * onJoin(player: RpgPlayer, map: RpgMap) {
787
+ * console.log(`${player.name} joined map ${map.id}`)
788
+ * // Perform global actions when player joins any map
789
+ * },
790
+ * onLeave(player: RpgPlayer, map: RpgMap) {
791
+ * console.log(`${player.name} left map ${map.id}`)
792
+ * // Perform global cleanup when player leaves any map
793
+ * },
794
+ * onBeforeUpdate(mapData, map) {
795
+ * // Modify map data before update
796
+ * return map
797
+ * }
798
+ * }
799
+ *
800
+ * export default defineModule<RpgServer>({
801
+ * map: mapHooks
802
+ * })
803
+ * ```
804
+ *
805
+ * @prop {RpgMapHooks} [map]
806
+ * @memberof RpgServer
807
+ * @since 4.0.0
808
+ * */
418
809
  map?: RpgMapHooks
419
810
 
420
811
  event?: RpgEventHooks
@@ -430,41 +821,62 @@ export interface RpgServer {
430
821
  events?: RpgClassEvent<RpgEvent>[]
431
822
 
432
823
  /**
433
- * Loads the content of a `.world` file from Tiled Map Editor into the map scene
824
+ * Array of world map configurations
434
825
  *
435
- * > Note, that if the map already exists (i.e. you have already defined an RpgMap), the world will retrieve the already existing map. Otherwise it will create a new map
826
+ * Loads the content of a `.world` file from Tiled Map Editor into the map scene.
827
+ * Each world contains multiple maps with their spatial relationships.
436
828
  *
437
- * @prop {object[]} [worldMaps]
438
- * object is
439
- * ```ts
440
- * {
441
- * id?: string
442
- * maps: {
443
- * id?: string
444
- * properties?: object
445
- * fileName: string;
446
- height: number;
447
- width: number;
448
- x: number;
449
- y: number;
450
- * }[],
451
- onlyShowAdjacentMaps: boolean, // only for Tiled Map Editor
452
- type: 'world' // only for Tiled Map Editor
453
- * }
454
- * ```
829
+ * > Note: If a map already exists (i.e. you have already defined an RpgMap),
830
+ * > the world will retrieve the already existing map. Otherwise it will create a new map.
831
+ *
832
+ * @prop {WorldMap[]} [worldMaps]
455
833
  * @since 3.0.0-beta.8
834
+ * @memberof RpgServer
456
835
  * @example
457
836
  * ```ts
837
+ * import { RpgServer } from '@rpgjs/server'
838
+ * import { defineModule } from '@rpgjs/common'
458
839
  * import myworld from 'myworld.world'
459
840
  *
460
- * @RpgModule<RpgServer>({
461
- * worldMaps: [
462
- * myworld
463
- * ]
841
+ * export default defineModule<RpgServer>({
842
+ * worldMaps: [
843
+ * myworld
844
+ * ]
845
+ * })
846
+ * ```
847
+ *
848
+ * @example
849
+ * ```ts
850
+ * import { RpgServer } from '@rpgjs/server'
851
+ * import { defineModule } from '@rpgjs/common'
852
+ *
853
+ * // Manual world configuration
854
+ * export default defineModule<RpgServer>({
855
+ * worldMaps: [
856
+ * {
857
+ * id: 'my-world',
858
+ * maps: [
859
+ * {
860
+ * id: 'map1',
861
+ * worldX: 0,
862
+ * worldY: 0,
863
+ * width: 800,
864
+ * height: 600,
865
+ * tileWidth: 32,
866
+ * tileHeight: 32
867
+ * },
868
+ * {
869
+ * id: 'map2',
870
+ * worldX: 800,
871
+ * worldY: 0,
872
+ * width: 800,
873
+ * height: 600
874
+ * }
875
+ * ]
876
+ * }
877
+ * ]
464
878
  * })
465
- * class RpgServerEngine { }
466
879
  * ```
467
- * @memberof RpgServer
468
880
  */
469
881
  worldMaps?: WorldMap[]
470
882
 
@@ -489,11 +901,12 @@ export interface RpgServer {
489
901
  * Example:
490
902
  *
491
903
  * ```ts
492
- * import { RpgModule, RpgServer, Presets } from '@rpgjs/server'
904
+ * import { RpgServer, Presets } from '@rpgjs/server'
905
+ * import { defineModule } from '@rpgjs/common'
493
906
  *
494
907
  * const { ATK, PDEF } = Presets
495
908
  *
496
- * @RpgModule<RpgServer>({
909
+ * export default defineModule<RpgServer>({
497
910
  * damageFormulas: {
498
911
  * damagePhysic(a, b) {
499
912
  * let damage = a[ATK] - b[PDEF]
@@ -502,7 +915,6 @@ export interface RpgServer {
502
915
  * }
503
916
  * }
504
917
  * })
505
- * class RpgServerEngine { }
506
918
  * ```
507
919
  * @prop {object} damageFormulas
508
920
  * @memberof RpgServer
@@ -514,6 +926,10 @@ export interface RpgServer {
514
926
  coefficientElements?: (a, b, bDef) => number
515
927
  }
516
928
 
929
+ /*
930
+ * Scalability configuration for the server
931
+ * @deprecated
932
+ */
517
933
  scalability?: {
518
934
  matchMaker: MatchMakerOption,
519
935
  stateStore: IStoreState
@@ -522,4 +938,8 @@ export interface RpgServer {
522
938
  doChangeServer(store: IStoreState, matchMaker: RpgMatchMaker, player: RpgPlayer): Promise<boolean> | boolean
523
939
  }
524
940
  }
941
+
942
+ throttleSync?: number
943
+ throttleStorage?: number
944
+ sessionExpiryTime?: number
525
945
  }