@rpgjs/client 5.0.0-beta.25 → 5.0.0-beta.27

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 (73) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/dist/Game/Map.d.ts +1 -0
  3. package/dist/Game/Map.js +5 -0
  4. package/dist/Game/Map.js.map +1 -1
  5. package/dist/Game/Object.js.map +1 -1
  6. package/dist/Gui/Gui.d.ts +2 -2
  7. package/dist/Gui/Gui.js.map +1 -1
  8. package/dist/RpgClient.d.ts +2 -1
  9. package/dist/RpgClientEngine.d.ts +76 -0
  10. package/dist/RpgClientEngine.js +59 -4
  11. package/dist/RpgClientEngine.js.map +1 -1
  12. package/dist/components/scenes/draw-map.ce.js +5 -2
  13. package/dist/components/scenes/draw-map.ce.js.map +1 -1
  14. package/dist/components/scenes/weather-lifecycle-compat.d.ts +0 -0
  15. package/dist/components/scenes/weather-lifecycle-compat.js +11 -0
  16. package/dist/components/scenes/weather-lifecycle-compat.js.map +1 -0
  17. package/dist/components/scenes/weather-tick-lifecycle.d.ts +17 -0
  18. package/dist/components/scenes/weather-tick-lifecycle.js +44 -0
  19. package/dist/components/scenes/weather-tick-lifecycle.js.map +1 -0
  20. package/dist/components/scenes/weather-tick-lifecycle.spec.d.ts +1 -0
  21. package/dist/core/inject.d.ts +4 -4
  22. package/dist/core/inject.js.map +1 -1
  23. package/dist/core/setup.d.ts +3 -3
  24. package/dist/core/setup.js +1 -1
  25. package/dist/core/setup.js.map +1 -1
  26. package/dist/core/setup.spec.d.ts +1 -0
  27. package/dist/i18n.d.ts +2 -1
  28. package/dist/i18n.js +1 -0
  29. package/dist/i18n.js.map +1 -1
  30. package/dist/index.d.ts +3 -1
  31. package/dist/index.js +3 -2
  32. package/dist/module.d.ts +2 -2
  33. package/dist/module.js.map +1 -1
  34. package/dist/public-api-types.spec.d.ts +1 -0
  35. package/dist/services/AbstractSocket.d.ts +3 -3
  36. package/dist/services/AbstractSocket.js.map +1 -1
  37. package/dist/services/loadMap.d.ts +13 -9
  38. package/dist/services/loadMap.js +4 -3
  39. package/dist/services/loadMap.js.map +1 -1
  40. package/dist/services/mapStreaming.d.ts +71 -0
  41. package/dist/services/mapStreaming.js +210 -0
  42. package/dist/services/mapStreaming.js.map +1 -0
  43. package/dist/services/mapStreaming.spec.d.ts +1 -0
  44. package/dist/services/mmorpg.d.ts +10 -26
  45. package/dist/services/mmorpg.js +2 -2
  46. package/dist/services/mmorpg.js.map +1 -1
  47. package/dist/services/standalone.d.ts +2 -98
  48. package/dist/services/standalone.js.map +1 -1
  49. package/package.json +3 -3
  50. package/src/Game/Map.ts +7 -0
  51. package/src/Game/Object.spec.ts +1 -1
  52. package/src/Game/Object.ts +4 -4
  53. package/src/Gui/Gui.ts +3 -3
  54. package/src/RpgClient.ts +2 -1
  55. package/src/RpgClientEngine.ts +147 -6
  56. package/src/components/scenes/draw-map.ce +4 -1
  57. package/src/components/scenes/weather-lifecycle-compat.ts +8 -0
  58. package/src/components/scenes/weather-tick-lifecycle.spec.ts +60 -0
  59. package/src/components/scenes/weather-tick-lifecycle.ts +69 -0
  60. package/src/core/inject.ts +6 -5
  61. package/src/core/setup.spec.ts +35 -0
  62. package/src/core/setup.ts +8 -6
  63. package/src/i18n.spec.ts +2 -1
  64. package/src/i18n.ts +1 -0
  65. package/src/index.ts +14 -1
  66. package/src/module.ts +2 -2
  67. package/src/public-api-types.spec.ts +19 -0
  68. package/src/services/AbstractSocket.ts +2 -2
  69. package/src/services/loadMap.ts +16 -9
  70. package/src/services/mapStreaming.spec.ts +240 -0
  71. package/src/services/mapStreaming.ts +277 -0
  72. package/src/services/mmorpg.ts +21 -9
  73. package/src/services/standalone.ts +4 -5
@@ -241,6 +241,7 @@ var RpgClientEngine = class {
241
241
  this.sceneMap.configureClientPrediction(this.predictionEnabled);
242
242
  this.sceneMap.loadPhysic();
243
243
  this.resolveSceneMapComponent();
244
+ this.loadMapService.initialize?.();
244
245
  inject(SaveClientService).initialize();
245
246
  this.initListeners();
246
247
  this.guiService._initialize();
@@ -624,11 +625,15 @@ var RpgClientEngine = class {
624
625
  this.callConnectError(error);
625
626
  });
626
627
  }
627
- beginMapTransfer(nextMapId) {
628
+ beginMapTransfer(nextMapId, continueMovement = false) {
629
+ this.pendingMapTransferInput = continueMovement ? this.latestDirectionalInput : void 0;
628
630
  this.mapTransitionInProgress = true;
629
631
  this.currentMapRoomId = nextMapId;
630
632
  this.sceneResetQueued = false;
631
- this.clearClientPredictionStates();
633
+ this.clearMapTransferPredictionStates();
634
+ }
635
+ resetSceneForMapTransfer(nextMapId) {
636
+ this.sceneMap.data.set(null);
632
637
  this.sceneMap.weatherState.set(null);
633
638
  this.sceneMap.lightingState.set(null);
634
639
  this.sceneMap.clearLightSpots();
@@ -664,7 +669,7 @@ var RpgClientEngine = class {
664
669
  }
665
670
  handleChangeMap(data) {
666
671
  const nextMapId = typeof data?.mapId === "string" ? data.mapId : void 0;
667
- this.beginMapTransfer(nextMapId);
672
+ this.beginMapTransfer(nextMapId, data?.continueMovement === true);
668
673
  const transferToken = typeof data?.transferToken === "string" ? data.transferToken : void 0;
669
674
  this.loadScene(data.mapId, transferToken);
670
675
  }
@@ -763,7 +768,11 @@ var RpgClientEngine = class {
763
768
  }
764
769
  async loadScene(mapId, transferToken) {
765
770
  await lastValueFrom(this.hooks.callHooks("client-sceneMap-onBeforeLoading", this.sceneMap));
766
- this.clearClientPredictionStates();
771
+ this.activeMapStreamController?.detach();
772
+ this.activeMapStreamController = void 0;
773
+ if (this.mapTransitionInProgress) this.resetSceneForMapTransfer(mapId);
774
+ if (this.mapTransitionInProgress) this.clearMapTransferPredictionStates();
775
+ else this.clearClientPredictionStates();
767
776
  this.mapLoadCompleted$.next(false);
768
777
  this.playerIdReceived$.next(false);
769
778
  this.playersReceived$.next(false);
@@ -778,6 +787,7 @@ var RpgClientEngine = class {
778
787
  await this.webSocket.reconnect();
779
788
  } catch (error) {
780
789
  this.mapTransitionInProgress = false;
790
+ this.pendingMapTransferInput = void 0;
781
791
  this.stopPingPong();
782
792
  await this.callConnectError(error);
783
793
  throw error;
@@ -795,6 +805,23 @@ var RpgClientEngine = class {
795
805
  this.mapTransitionInProgress = false;
796
806
  this.sceneMap.configureClientPrediction(this.predictionEnabled);
797
807
  this.sceneMap.loadPhysic();
808
+ if (res?.streamController) {
809
+ const controller = res.streamController;
810
+ this.activeMapStreamController = controller;
811
+ controller.attach(this.sceneMap);
812
+ }
813
+ const transferInput = this.pendingMapTransferInput;
814
+ this.pendingMapTransferInput = void 0;
815
+ if (transferInput !== void 0) this.resumeMapTransferMovement(transferInput, mapId);
816
+ }
817
+ async resumeMapTransferMovement(input, mapId) {
818
+ const repeatCount = 4;
819
+ const repeatIntervalMs = 50;
820
+ for (let index = 0; index < repeatCount; index += 1) {
821
+ if (this.mapTransitionInProgress || this.currentMapRoomId !== mapId) return;
822
+ await this.processInput({ input });
823
+ if (index < repeatCount - 1) await new Promise((resolve) => setTimeout(resolve, repeatIntervalMs));
824
+ }
798
825
  }
799
826
  addSpriteSheet(spritesheetClass, id) {
800
827
  this.spritesheets.set(id || spritesheetClass.id, spritesheetClass);
@@ -1400,6 +1427,7 @@ var RpgClientEngine = class {
1400
1427
  const timestamp = Date.now();
1401
1428
  const movementInput = isDashInput(input) ? normalizeDashInput(input, currentPlayer?.direction?.()) : input;
1402
1429
  if (!movementInput) return;
1430
+ if (!isDashInput(movementInput)) this.latestDirectionalInput = movementInput;
1403
1431
  if (isDashInput(movementInput)) {
1404
1432
  const cooldown = movementInput.cooldown ?? DEFAULT_DASH_COOLDOWN_MS;
1405
1433
  if (timestamp < this.dashLockedUntil) return;
@@ -1432,6 +1460,25 @@ var RpgClientEngine = class {
1432
1460
  this.emitMovePacket(movementInput, frame, tick, timestamp, true);
1433
1461
  this.lastInputTime = isDashInput(movementInput) ? Date.now() + (movementInput.duration ?? DEFAULT_DASH_DURATION_MS) : Date.now();
1434
1462
  }
1463
+ /**
1464
+ * Start a predicted dash for the current player and send it through the
1465
+ * authoritative movement channel.
1466
+ *
1467
+ * @title processDash
1468
+ * @method processDash(input?: Partial<RpgDashInput>): Promise<void>
1469
+ * @param input - Optional direction, speed, duration, and cooldown overrides.
1470
+ * @returns A promise resolved after the dash input has been processed locally.
1471
+ * @memberof RpgClientEngine
1472
+ * @example
1473
+ * ```ts
1474
+ * await engine.processDash({
1475
+ * direction: { x: 1, y: 0 },
1476
+ * additionalSpeed: 10,
1477
+ * duration: 220,
1478
+ * cooldown: 600,
1479
+ * })
1480
+ * ```
1481
+ */
1435
1482
  async processDash(input = {}) {
1436
1483
  const currentPlayer = this.sceneMap.getCurrentPlayer();
1437
1484
  const dashInput = normalizeDashInput(input, typeof currentPlayer?.direction === "function" ? currentPlayer.direction() : currentPlayer?.direction);
@@ -1707,6 +1754,14 @@ var RpgClientEngine = class {
1707
1754
  this.lastMovePathSentAt = 0;
1708
1755
  this.lastMovePathSentFrame = 0;
1709
1756
  }
1757
+ clearMapTransferPredictionStates() {
1758
+ this.prediction?.clearPendingInputs();
1759
+ this.frameOffset = 0;
1760
+ this.pendingPredictionFrames = [];
1761
+ this.lastClientPhysicsStepAt = 0;
1762
+ this.lastMovePathSentAt = 0;
1763
+ this.lastMovePathSentFrame = this.inputFrameCounter;
1764
+ }
1710
1765
  /**
1711
1766
  * Stop local movement immediately and discard pending predicted movement.
1712
1767
  *