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

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 +502 -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 +21653 -20900
  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 +1236 -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 +525 -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 +2502 -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
@@ -0,0 +1,182 @@
1
+ import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
2
+ import { testing, type TestingFixture } from "@rpgjs/testing";
3
+ import { createModule, defineModule, Direction } from "@rpgjs/common";
4
+ import { RpgPlayer, RpgServer } from "../src";
5
+
6
+ const serverModule = defineModule<RpgServer>({
7
+ maps: [
8
+ {
9
+ id: "test-map",
10
+ file: "",
11
+ },
12
+ ],
13
+ player: {
14
+ async onConnected(player) {
15
+ await player.changeMap("test-map", { x: 100, y: 100 });
16
+ },
17
+ },
18
+ });
19
+
20
+ let fixture: TestingFixture;
21
+ let client: any;
22
+ let player: RpgPlayer;
23
+ let serverMap: any;
24
+
25
+ beforeEach(async () => {
26
+ const module = createModule("PredictionServerModule", [
27
+ {
28
+ server: serverModule,
29
+ },
30
+ ]);
31
+ fixture = await testing(module);
32
+ client = await fixture.createClient();
33
+ player = await client.waitForMapChange("test-map");
34
+ serverMap = fixture.server.subRoom as any;
35
+ });
36
+
37
+ afterEach(async () => {
38
+ await fixture.clear();
39
+ });
40
+
41
+ describe("Prediction + Reconciliation Server Protocol", () => {
42
+ test("should reply pong with server tick", () => {
43
+ const emitSpy = vi.spyOn(player, "emit");
44
+ const payload = {
45
+ clientTime: 1234,
46
+ clientFrame: 42,
47
+ };
48
+
49
+ serverMap.onPing(player, payload);
50
+
51
+ expect(emitSpy).toHaveBeenCalledWith(
52
+ "pong",
53
+ expect.objectContaining({
54
+ clientTime: payload.clientTime,
55
+ clientFrame: payload.clientFrame,
56
+ serverTick: serverMap.getTick(),
57
+ }),
58
+ );
59
+ });
60
+
61
+ test("should include authoritative ack metadata in sync interceptor", async () => {
62
+ const frame = 7;
63
+ await serverMap.onInput(player, {
64
+ input: Direction.Right,
65
+ frame,
66
+ tick: 0,
67
+ timestamp: Date.now(),
68
+ });
69
+ await serverMap.processInput(player.id);
70
+
71
+ const intercepted = serverMap.interceptorPacket(
72
+ player,
73
+ { type: "sync", value: {} },
74
+ player.conn,
75
+ );
76
+
77
+ expect(intercepted?.value?.ack).toEqual(
78
+ expect.objectContaining({
79
+ frame,
80
+ serverTick: expect.any(Number),
81
+ x: expect.any(Number),
82
+ y: expect.any(Number),
83
+ direction: expect.any(String),
84
+ }),
85
+ );
86
+ });
87
+
88
+ test("should align ack position with the synced local player payload when available", () => {
89
+ player._lastFramePositions = {
90
+ frame: 21,
91
+ position: {
92
+ x: 0,
93
+ y: 0,
94
+ direction: Direction.Down,
95
+ },
96
+ serverTick: 1,
97
+ };
98
+
99
+ const intercepted = serverMap.interceptorPacket(
100
+ player,
101
+ {
102
+ type: "sync",
103
+ value: {
104
+ players: {
105
+ [player.id]: {
106
+ x: 321,
107
+ y: 45,
108
+ direction: Direction.Left,
109
+ },
110
+ },
111
+ },
112
+ },
113
+ player.conn,
114
+ );
115
+
116
+ expect(intercepted?.value?.ack).toEqual(
117
+ expect.objectContaining({
118
+ frame: 21,
119
+ x: 321,
120
+ y: 45,
121
+ direction: Direction.Left,
122
+ serverTick: serverMap.getTick(),
123
+ }),
124
+ );
125
+ });
126
+
127
+ test("should queue trajectory frames and replay them progressively on server ticks", async () => {
128
+ const baseTs = Date.now();
129
+ await serverMap.onInput(player, {
130
+ input: Direction.Right,
131
+ frame: 3,
132
+ tick: 3,
133
+ timestamp: baseTs + 32,
134
+ trajectory: [
135
+ {
136
+ input: Direction.Right,
137
+ frame: 1,
138
+ tick: 1,
139
+ timestamp: baseTs,
140
+ x: 101,
141
+ y: 100,
142
+ direction: Direction.Right,
143
+ },
144
+ {
145
+ input: Direction.Right,
146
+ frame: 2,
147
+ tick: 2,
148
+ timestamp: baseTs + 16,
149
+ x: 102,
150
+ y: 100,
151
+ direction: Direction.Right,
152
+ },
153
+ {
154
+ input: Direction.Right,
155
+ frame: 3,
156
+ tick: 3,
157
+ timestamp: baseTs + 32,
158
+ x: 103,
159
+ y: 100,
160
+ direction: Direction.Right,
161
+ },
162
+ ],
163
+ });
164
+
165
+ expect(player.pendingInputs.map((entry: any) => entry.frame)).toEqual([1, 2, 3]);
166
+
167
+ await serverMap.processInput(player.id);
168
+ expect(player._lastFramePositions?.frame).toBe(1);
169
+ expect(player._lastFramePositions?.position?.x).toBe(101);
170
+ expect(player.pendingInputs.map((entry: any) => entry.frame)).toEqual([2, 3]);
171
+
172
+ await serverMap.processInput(player.id);
173
+ expect(player._lastFramePositions?.frame).toBe(2);
174
+ expect(player._lastFramePositions?.position?.x).toBe(102);
175
+ expect(player.pendingInputs.map((entry: any) => entry.frame)).toEqual([3]);
176
+
177
+ await serverMap.processInput(player.id);
178
+ expect(player._lastFramePositions?.frame).toBe(3);
179
+ expect(player._lastFramePositions?.position?.x).toBe(103);
180
+ expect(player.pendingInputs).toHaveLength(0);
181
+ });
182
+ });
@@ -0,0 +1,65 @@
1
+
2
+ import { test, expect, describe, vi } from "vitest";
3
+ import { Direction } from "@rpgjs/common";
4
+ import { Move } from "../src/Player/MoveManager";
5
+
6
+ describe("Improved Random Movement Unit Tests", () => {
7
+ test("Move.random(repeat) should return array of identical directions", () => {
8
+ // Mock Math.random to return a fixed value
9
+ const randomSpy = vi.spyOn(Math, 'random').mockReturnValue(0.1); // Should map to index 0 (Right)
10
+
11
+ const directions = Move.random(5);
12
+
13
+ expect(directions).toHaveLength(5);
14
+ expect(directions.every(d => d === Direction.Right)).toBe(true);
15
+
16
+ randomSpy.mockRestore();
17
+ });
18
+
19
+ test("Move.random(repeat) should produce different directions with different random values", () => {
20
+ const randomSpy = vi.spyOn(Math, 'random');
21
+
22
+ randomSpy.mockReturnValue(0.1); // Right
23
+ const rightDirs = Move.random(1);
24
+ expect(rightDirs[0]).toBe(Direction.Right);
25
+
26
+ randomSpy.mockReturnValue(0.3); // Left
27
+ const leftDirs = Move.random(1);
28
+ expect(leftDirs[0]).toBe(Direction.Left);
29
+
30
+ randomSpy.mockReturnValue(0.6); // Up
31
+ const upDirs = Move.random(1);
32
+ expect(upDirs[0]).toBe(Direction.Up);
33
+
34
+ randomSpy.mockReturnValue(0.9); // Down
35
+ const downDirs = Move.random(1);
36
+ expect(downDirs[0]).toBe(Direction.Down);
37
+
38
+ randomSpy.mockRestore();
39
+ });
40
+
41
+ test("Move.tileRandom(repeat) should return consistent direction for tiles", () => {
42
+ // Mock Math.random to return a fixed value
43
+ const randomSpy = vi.spyOn(Math, 'random').mockReturnValue(0.1); // Should map to index 0 (Right)
44
+
45
+ const mockPlayer = {
46
+ speed: 3
47
+ } as any;
48
+
49
+ const mockMap = {
50
+ tileWidth: 32,
51
+ tileHeight: 32
52
+ } as any;
53
+
54
+ const callback = Move.tileRandom(3);
55
+ const directions = callback(mockPlayer, mockMap);
56
+
57
+ // repeatTile = Math.floor(32 / 3) * 3 = 10 * 3 = 30
58
+ // So we expect 30 directions, all Right
59
+
60
+ expect(directions.length).toBe(30);
61
+ expect(directions.every(d => d === Direction.Right)).toBe(true);
62
+
63
+ randomSpy.mockRestore();
64
+ });
65
+ });