@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.
- package/dist/Gui/DialogGui.d.ts +5 -0
- package/dist/Gui/GameoverGui.d.ts +23 -0
- package/dist/Gui/Gui.d.ts +6 -0
- package/dist/Gui/MenuGui.d.ts +22 -3
- package/dist/Gui/NotificationGui.d.ts +1 -2
- package/dist/Gui/SaveLoadGui.d.ts +13 -0
- package/dist/Gui/ShopGui.d.ts +28 -3
- package/dist/Gui/TitleGui.d.ts +23 -0
- package/dist/Gui/index.d.ts +10 -1
- package/dist/Player/BattleManager.d.ts +34 -12
- package/dist/Player/ClassManager.d.ts +46 -13
- package/dist/Player/ComponentManager.d.ts +123 -0
- package/dist/Player/Components.d.ts +345 -0
- package/dist/Player/EffectManager.d.ts +86 -0
- package/dist/Player/ElementManager.d.ts +104 -0
- package/dist/Player/GoldManager.d.ts +22 -0
- package/dist/Player/GuiManager.d.ts +259 -0
- package/dist/Player/ItemFixture.d.ts +6 -0
- package/dist/Player/ItemManager.d.ts +450 -9
- package/dist/Player/MoveManager.d.ts +324 -69
- package/dist/Player/ParameterManager.d.ts +344 -14
- package/dist/Player/Player.d.ts +460 -8
- package/dist/Player/SkillManager.d.ts +197 -15
- package/dist/Player/StateManager.d.ts +89 -25
- package/dist/Player/VariableManager.d.ts +74 -0
- package/dist/RpgServer.d.ts +502 -64
- package/dist/RpgServerEngine.d.ts +2 -1
- package/dist/decorators/event.d.ts +46 -0
- package/dist/decorators/map.d.ts +287 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +21653 -20900
- package/dist/index.js.map +1 -1
- package/dist/logs/log.d.ts +2 -3
- package/dist/module.d.ts +43 -1
- package/dist/presets/index.d.ts +0 -9
- package/dist/rooms/BaseRoom.d.ts +132 -0
- package/dist/rooms/lobby.d.ts +10 -2
- package/dist/rooms/map.d.ts +1236 -17
- package/dist/services/save.d.ts +43 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/localStorage.d.ts +23 -0
- package/package.json +14 -10
- package/src/Gui/DialogGui.ts +19 -4
- package/src/Gui/GameoverGui.ts +39 -0
- package/src/Gui/Gui.ts +23 -1
- package/src/Gui/MenuGui.ts +155 -6
- package/src/Gui/NotificationGui.ts +1 -2
- package/src/Gui/SaveLoadGui.ts +60 -0
- package/src/Gui/ShopGui.ts +146 -16
- package/src/Gui/TitleGui.ts +39 -0
- package/src/Gui/index.ts +15 -2
- package/src/Player/BattleManager.ts +91 -49
- package/src/Player/ClassManager.ts +118 -50
- package/src/Player/ComponentManager.ts +425 -19
- package/src/Player/Components.ts +380 -0
- package/src/Player/EffectManager.ts +81 -44
- package/src/Player/ElementManager.ts +109 -86
- package/src/Player/GoldManager.ts +32 -35
- package/src/Player/GuiManager.ts +308 -150
- package/src/Player/ItemFixture.ts +4 -5
- package/src/Player/ItemManager.ts +774 -355
- package/src/Player/MoveManager.ts +1544 -774
- package/src/Player/ParameterManager.ts +546 -104
- package/src/Player/Player.ts +1163 -88
- package/src/Player/SkillManager.ts +520 -195
- package/src/Player/StateManager.ts +170 -182
- package/src/Player/VariableManager.ts +101 -63
- package/src/RpgServer.ts +525 -63
- package/src/core/context.ts +1 -0
- package/src/decorators/event.ts +61 -0
- package/src/decorators/map.ts +327 -0
- package/src/index.ts +11 -1
- package/src/logs/log.ts +10 -3
- package/src/module.ts +126 -3
- package/src/presets/index.ts +1 -10
- package/src/rooms/BaseRoom.ts +232 -0
- package/src/rooms/lobby.ts +25 -7
- package/src/rooms/map.ts +2502 -194
- package/src/services/save.ts +147 -0
- package/src/storage/index.ts +1 -0
- package/src/storage/localStorage.ts +76 -0
- package/tests/battle.spec.ts +375 -0
- package/tests/change-map.spec.ts +72 -0
- package/tests/class.spec.ts +274 -0
- package/tests/effect.spec.ts +219 -0
- package/tests/element.spec.ts +221 -0
- package/tests/event.spec.ts +80 -0
- package/tests/gold.spec.ts +99 -0
- package/tests/item.spec.ts +609 -0
- package/tests/module.spec.ts +38 -0
- package/tests/move.spec.ts +601 -0
- package/tests/player-param.spec.ts +28 -0
- package/tests/prediction-reconciliation.spec.ts +182 -0
- package/tests/random-move.spec.ts +65 -0
- package/tests/skill.spec.ts +658 -0
- package/tests/state.spec.ts +467 -0
- package/tests/variable.spec.ts +185 -0
- package/tests/world-maps.spec.ts +896 -0
- package/vite.config.ts +16 -0
- package/dist/Player/Event.d.ts +0 -0
- 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
|
+
});
|