@phalanx-engine/client 0.1.0
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/README.md +1037 -0
- package/dist/DesyncDetector.d.ts +80 -0
- package/dist/DesyncDetector.d.ts.map +1 -0
- package/dist/DesyncDetector.js +93 -0
- package/dist/DesyncDetector.js.map +1 -0
- package/dist/DeterministicRandom.d.ts +78 -0
- package/dist/DeterministicRandom.d.ts.map +1 -0
- package/dist/DeterministicRandom.js +122 -0
- package/dist/DeterministicRandom.js.map +1 -0
- package/dist/EventEmitter.d.ts +65 -0
- package/dist/EventEmitter.d.ts.map +1 -0
- package/dist/EventEmitter.js +102 -0
- package/dist/EventEmitter.js.map +1 -0
- package/dist/FixedMath.d.ts +22 -0
- package/dist/FixedMath.d.ts.map +1 -0
- package/dist/FixedMath.js +26 -0
- package/dist/FixedMath.js.map +1 -0
- package/dist/PhalanxClient.d.ts +335 -0
- package/dist/PhalanxClient.d.ts.map +1 -0
- package/dist/PhalanxClient.js +844 -0
- package/dist/PhalanxClient.js.map +1 -0
- package/dist/RenderLoop.d.ts +95 -0
- package/dist/RenderLoop.d.ts.map +1 -0
- package/dist/RenderLoop.js +192 -0
- package/dist/RenderLoop.js.map +1 -0
- package/dist/SocketManager.d.ts +228 -0
- package/dist/SocketManager.d.ts.map +1 -0
- package/dist/SocketManager.js +584 -0
- package/dist/SocketManager.js.map +1 -0
- package/dist/StateHasher.d.ts +76 -0
- package/dist/StateHasher.d.ts.map +1 -0
- package/dist/StateHasher.js +129 -0
- package/dist/StateHasher.js.map +1 -0
- package/dist/auth/AuthManager.d.ts +188 -0
- package/dist/auth/AuthManager.d.ts.map +1 -0
- package/dist/auth/AuthManager.js +462 -0
- package/dist/auth/AuthManager.js.map +1 -0
- package/dist/auth/adapters/GoogleOAuthAdapter.d.ts +164 -0
- package/dist/auth/adapters/GoogleOAuthAdapter.d.ts.map +1 -0
- package/dist/auth/adapters/GoogleOAuthAdapter.js +521 -0
- package/dist/auth/adapters/GoogleOAuthAdapter.js.map +1 -0
- package/dist/auth/index.d.ts +45 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +54 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/storage.d.ts +56 -0
- package/dist/auth/storage.d.ts.map +1 -0
- package/dist/auth/storage.js +78 -0
- package/dist/auth/storage.js.map +1 -0
- package/dist/auth/types.d.ts +212 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +7 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/index.d.ts +70 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +83 -0
- package/dist/index.js.map +1 -0
- package/dist/recovery/BrowserLifecycle.d.ts +33 -0
- package/dist/recovery/BrowserLifecycle.d.ts.map +1 -0
- package/dist/recovery/BrowserLifecycle.js +62 -0
- package/dist/recovery/BrowserLifecycle.js.map +1 -0
- package/dist/recovery/GuestPlayerIdStore.d.ts +17 -0
- package/dist/recovery/GuestPlayerIdStore.d.ts.map +1 -0
- package/dist/recovery/GuestPlayerIdStore.js +31 -0
- package/dist/recovery/GuestPlayerIdStore.js.map +1 -0
- package/dist/recovery/KeyValueStorage.d.ts +32 -0
- package/dist/recovery/KeyValueStorage.d.ts.map +1 -0
- package/dist/recovery/KeyValueStorage.js +58 -0
- package/dist/recovery/KeyValueStorage.js.map +1 -0
- package/dist/recovery/MobileTransport.d.ts +12 -0
- package/dist/recovery/MobileTransport.d.ts.map +1 -0
- package/dist/recovery/MobileTransport.js +24 -0
- package/dist/recovery/MobileTransport.js.map +1 -0
- package/dist/recovery/NetworkQuality.d.ts +22 -0
- package/dist/recovery/NetworkQuality.d.ts.map +1 -0
- package/dist/recovery/NetworkQuality.js +35 -0
- package/dist/recovery/NetworkQuality.js.map +1 -0
- package/dist/recovery/RoomPersistence.d.ts +55 -0
- package/dist/recovery/RoomPersistence.d.ts.map +1 -0
- package/dist/recovery/RoomPersistence.js +68 -0
- package/dist/recovery/RoomPersistence.js.map +1 -0
- package/dist/recovery/RoomRecoveryController.d.ts +146 -0
- package/dist/recovery/RoomRecoveryController.d.ts.map +1 -0
- package/dist/recovery/RoomRecoveryController.js +348 -0
- package/dist/recovery/RoomRecoveryController.js.map +1 -0
- package/dist/recovery/index.d.ts +13 -0
- package/dist/recovery/index.d.ts.map +1 -0
- package/dist/recovery/index.js +8 -0
- package/dist/recovery/index.js.map +1 -0
- package/dist/types.d.ts +501 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DesyncDetector - Handles desync detection for lockstep synchronization
|
|
3
|
+
*
|
|
4
|
+
* Stores local state hashes and compares them with remote hashes
|
|
5
|
+
* received from other players via the server.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from './EventEmitter.js';
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for desync detection
|
|
10
|
+
*/
|
|
11
|
+
export interface DesyncConfig {
|
|
12
|
+
/** Whether desync detection is enabled */
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
/** Maximum number of hashes to store (default: 100) */
|
|
15
|
+
maxStoredHashes?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Event emitted when a desync is detected
|
|
19
|
+
*/
|
|
20
|
+
export interface DesyncEvent {
|
|
21
|
+
/** The tick where desync occurred */
|
|
22
|
+
tick: number;
|
|
23
|
+
/** The local hash for this tick */
|
|
24
|
+
localHash: string;
|
|
25
|
+
/** Hashes from all players (playerId -> hash) */
|
|
26
|
+
remoteHashes: Record<string, string>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Events emitted by DesyncDetector
|
|
30
|
+
*/
|
|
31
|
+
export interface DesyncDetectorEvents {
|
|
32
|
+
desync: (event: DesyncEvent) => void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* DesyncDetector - Internal class for managing desync detection
|
|
36
|
+
*
|
|
37
|
+
* The game computes state hashes and submits them via the client.
|
|
38
|
+
* This class stores local hashes and compares with remote hashes
|
|
39
|
+
* when the server broadcasts a comparison.
|
|
40
|
+
*/
|
|
41
|
+
export declare class DesyncDetector extends EventEmitter<DesyncDetectorEvents> {
|
|
42
|
+
private config;
|
|
43
|
+
private hashHistory;
|
|
44
|
+
/**
|
|
45
|
+
* Configure the desync detector
|
|
46
|
+
*/
|
|
47
|
+
configure(config: Partial<DesyncConfig>): void;
|
|
48
|
+
/**
|
|
49
|
+
* Check if desync detection is enabled
|
|
50
|
+
*/
|
|
51
|
+
isEnabled(): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Record local hash (called by game via client.submitStateHash)
|
|
54
|
+
* @param tick - The tick this hash is for
|
|
55
|
+
* @param hash - Hash computed by game
|
|
56
|
+
*/
|
|
57
|
+
recordLocalHash(tick: number, hash: string): void;
|
|
58
|
+
/**
|
|
59
|
+
* Get local hash for a specific tick
|
|
60
|
+
* @param tick - The tick to get hash for
|
|
61
|
+
* @returns The hash string or undefined if not found
|
|
62
|
+
*/
|
|
63
|
+
getLocalHash(tick: number): string | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Compare local hash with remote hashes
|
|
66
|
+
* @param tick - The tick to compare
|
|
67
|
+
* @param remoteHashes - Hashes from all players (playerId -> hash)
|
|
68
|
+
* @returns true if all hashes match, false if desync detected
|
|
69
|
+
*/
|
|
70
|
+
compareWithRemote(tick: number, remoteHashes: Record<string, string>): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Clear all stored hashes
|
|
73
|
+
*/
|
|
74
|
+
clear(): void;
|
|
75
|
+
/**
|
|
76
|
+
* Get the current configuration
|
|
77
|
+
*/
|
|
78
|
+
getConfig(): Required<DesyncConfig>;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=DesyncDetector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DesyncDetector.d.ts","sourceRoot":"","sources":["../src/DesyncDetector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,uDAAuD;IACvD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CACtC;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IACpE,OAAO,CAAC,MAAM,CAGZ;IACF,OAAO,CAAC,WAAW,CAAkC;IAErD;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI;IAS9C;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;;;OAIG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAYjD;;;;OAIG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI9C;;;;;OAKG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO;IAiB9E;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,SAAS,IAAI,QAAQ,CAAC,YAAY,CAAC;CAGpC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DesyncDetector - Handles desync detection for lockstep synchronization
|
|
3
|
+
*
|
|
4
|
+
* Stores local state hashes and compares them with remote hashes
|
|
5
|
+
* received from other players via the server.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from './EventEmitter.js';
|
|
8
|
+
/**
|
|
9
|
+
* DesyncDetector - Internal class for managing desync detection
|
|
10
|
+
*
|
|
11
|
+
* The game computes state hashes and submits them via the client.
|
|
12
|
+
* This class stores local hashes and compares with remote hashes
|
|
13
|
+
* when the server broadcasts a comparison.
|
|
14
|
+
*/
|
|
15
|
+
export class DesyncDetector extends EventEmitter {
|
|
16
|
+
config = {
|
|
17
|
+
enabled: true,
|
|
18
|
+
maxStoredHashes: 100,
|
|
19
|
+
};
|
|
20
|
+
hashHistory = new Map();
|
|
21
|
+
/**
|
|
22
|
+
* Configure the desync detector
|
|
23
|
+
*/
|
|
24
|
+
configure(config) {
|
|
25
|
+
if (config.enabled !== undefined) {
|
|
26
|
+
this.config.enabled = config.enabled;
|
|
27
|
+
}
|
|
28
|
+
if (config.maxStoredHashes !== undefined) {
|
|
29
|
+
this.config.maxStoredHashes = config.maxStoredHashes;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Check if desync detection is enabled
|
|
34
|
+
*/
|
|
35
|
+
isEnabled() {
|
|
36
|
+
return this.config.enabled;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Record local hash (called by game via client.submitStateHash)
|
|
40
|
+
* @param tick - The tick this hash is for
|
|
41
|
+
* @param hash - Hash computed by game
|
|
42
|
+
*/
|
|
43
|
+
recordLocalHash(tick, hash) {
|
|
44
|
+
if (!this.config.enabled)
|
|
45
|
+
return;
|
|
46
|
+
this.hashHistory.set(tick, hash);
|
|
47
|
+
// Prune old hashes
|
|
48
|
+
if (this.hashHistory.size > this.config.maxStoredHashes) {
|
|
49
|
+
const oldestTick = Math.min(...this.hashHistory.keys());
|
|
50
|
+
this.hashHistory.delete(oldestTick);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get local hash for a specific tick
|
|
55
|
+
* @param tick - The tick to get hash for
|
|
56
|
+
* @returns The hash string or undefined if not found
|
|
57
|
+
*/
|
|
58
|
+
getLocalHash(tick) {
|
|
59
|
+
return this.hashHistory.get(tick);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Compare local hash with remote hashes
|
|
63
|
+
* @param tick - The tick to compare
|
|
64
|
+
* @param remoteHashes - Hashes from all players (playerId -> hash)
|
|
65
|
+
* @returns true if all hashes match, false if desync detected
|
|
66
|
+
*/
|
|
67
|
+
compareWithRemote(tick, remoteHashes) {
|
|
68
|
+
const localHash = this.hashHistory.get(tick);
|
|
69
|
+
if (!localHash) {
|
|
70
|
+
// Can't compare - no local hash for this tick
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
const allMatch = Object.values(remoteHashes).every((h) => h === localHash);
|
|
74
|
+
if (!allMatch) {
|
|
75
|
+
this.emit('desync', { tick, localHash, remoteHashes });
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Clear all stored hashes
|
|
82
|
+
*/
|
|
83
|
+
clear() {
|
|
84
|
+
this.hashHistory.clear();
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get the current configuration
|
|
88
|
+
*/
|
|
89
|
+
getConfig() {
|
|
90
|
+
return { ...this.config };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=DesyncDetector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DesyncDetector.js","sourceRoot":"","sources":["../src/DesyncDetector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AA+BjD;;;;;;GAMG;AACH,MAAM,OAAO,cAAe,SAAQ,YAAkC;IAC5D,MAAM,GAA2B;QACvC,OAAO,EAAE,IAAI;QACb,eAAe,EAAE,GAAG;KACrB,CAAC;IACM,WAAW,GAAwB,IAAI,GAAG,EAAE,CAAC;IAErD;;OAEG;IACH,SAAS,CAAC,MAA6B;QACrC,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QACvC,CAAC;QACD,IAAI,MAAM,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;QACvD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,eAAe,CAAC,IAAY,EAAE,IAAY;QACxC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO;QAEjC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAEjC,mBAAmB;QACnB,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YACxD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;YACxD,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,YAAY,CAAC,IAAY;QACvB,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED;;;;;OAKG;IACH,iBAAiB,CAAC,IAAY,EAAE,YAAoC;QAClE,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,8CAA8C;YAC9C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;QAE3E,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;YACvD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;CACF"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import prand from 'pure-rand';
|
|
2
|
+
/**
|
|
3
|
+
* Deterministic Random Number Generator
|
|
4
|
+
*
|
|
5
|
+
* Wrapper around pure-rand library for deterministic pseudo-random number generation.
|
|
6
|
+
* All clients initialized with the same seed will produce identical sequences.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const rng = new DeterministicRandom(12345);
|
|
11
|
+
* const damage = rng.intRange(10, 20); // Same on all clients with same seed
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare class DeterministicRandom {
|
|
15
|
+
private rng;
|
|
16
|
+
/**
|
|
17
|
+
* Create a new deterministic RNG with the given seed
|
|
18
|
+
* @param seed - A number seed value
|
|
19
|
+
*/
|
|
20
|
+
constructor(seed: number);
|
|
21
|
+
/**
|
|
22
|
+
* Generate next random 32-bit integer and advance state
|
|
23
|
+
*/
|
|
24
|
+
private nextInt;
|
|
25
|
+
/**
|
|
26
|
+
* Get next random float in range [0, 1)
|
|
27
|
+
*/
|
|
28
|
+
float(): number;
|
|
29
|
+
/**
|
|
30
|
+
* Get next random float in range [min, max)
|
|
31
|
+
* @param min - Minimum value (inclusive)
|
|
32
|
+
* @param max - Maximum value (exclusive)
|
|
33
|
+
*/
|
|
34
|
+
floatRange(min: number, max: number): number;
|
|
35
|
+
/**
|
|
36
|
+
* Get next random integer in range [min, max]
|
|
37
|
+
* @param min - Minimum value (inclusive)
|
|
38
|
+
* @param max - Maximum value (inclusive)
|
|
39
|
+
*/
|
|
40
|
+
intRange(min: number, max: number): number;
|
|
41
|
+
/**
|
|
42
|
+
* Get next random integer in range [0, max)
|
|
43
|
+
* @param max - Maximum value (exclusive)
|
|
44
|
+
*/
|
|
45
|
+
int(max: number): number;
|
|
46
|
+
/**
|
|
47
|
+
* Get next random boolean
|
|
48
|
+
* @param probability - Probability of true (default 0.5)
|
|
49
|
+
*/
|
|
50
|
+
boolean(probability?: number): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Get a random element from an array
|
|
53
|
+
* @param array - Array to pick from
|
|
54
|
+
*/
|
|
55
|
+
pick<T>(array: readonly T[]): T;
|
|
56
|
+
/**
|
|
57
|
+
* Shuffle an array in place using Fisher-Yates algorithm
|
|
58
|
+
* @param array - Array to shuffle
|
|
59
|
+
* @returns The same array, shuffled
|
|
60
|
+
*/
|
|
61
|
+
shuffle<T>(array: T[]): T[];
|
|
62
|
+
/**
|
|
63
|
+
* Create a fork of this RNG with independent state
|
|
64
|
+
* Useful for parallel simulations that need separate random streams
|
|
65
|
+
*/
|
|
66
|
+
fork(): DeterministicRandom;
|
|
67
|
+
/**
|
|
68
|
+
* Get current generator for serialization
|
|
69
|
+
* Note: pure-rand generators are immutable, so this returns a copy
|
|
70
|
+
*/
|
|
71
|
+
getGenerator(): prand.RandomGenerator;
|
|
72
|
+
/**
|
|
73
|
+
* Set generator from previously saved state
|
|
74
|
+
* @param generator - Previously saved generator
|
|
75
|
+
*/
|
|
76
|
+
setGenerator(generator: prand.RandomGenerator): void;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=DeterministicRandom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeterministicRandom.d.ts","sourceRoot":"","sources":["../src/DeterministicRandom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,WAAW,CAAC;AAE9B;;;;;;;;;;;GAWG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,GAAG,CAAwB;IAEnC;;;OAGG;gBACS,IAAI,EAAE,MAAM;IAKxB;;OAEG;IACH,OAAO,CAAC,OAAO;IAMf;;OAEG;IACH,KAAK,IAAI,MAAM;IAMf;;;;OAIG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IAI5C;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IAQ1C;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAIxB;;;OAGG;IACH,OAAO,CAAC,WAAW,GAAE,MAAY,GAAG,OAAO;IAI3C;;;OAGG;IACH,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC;IAO/B;;;;OAIG;IACH,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE;IAU3B;;;OAGG;IACH,IAAI,IAAI,mBAAmB;IAM3B;;;OAGG;IACH,YAAY,IAAI,KAAK,CAAC,eAAe;IAIrC;;;OAGG;IACH,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,eAAe,GAAG,IAAI;CAGrD"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import prand from 'pure-rand';
|
|
2
|
+
/**
|
|
3
|
+
* Deterministic Random Number Generator
|
|
4
|
+
*
|
|
5
|
+
* Wrapper around pure-rand library for deterministic pseudo-random number generation.
|
|
6
|
+
* All clients initialized with the same seed will produce identical sequences.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const rng = new DeterministicRandom(12345);
|
|
11
|
+
* const damage = rng.intRange(10, 20); // Same on all clients with same seed
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export class DeterministicRandom {
|
|
15
|
+
rng;
|
|
16
|
+
/**
|
|
17
|
+
* Create a new deterministic RNG with the given seed
|
|
18
|
+
* @param seed - A number seed value
|
|
19
|
+
*/
|
|
20
|
+
constructor(seed) {
|
|
21
|
+
// Use xoroshiro128+ algorithm - fast and high quality
|
|
22
|
+
this.rng = prand.xoroshiro128plus(seed);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Generate next random 32-bit integer and advance state
|
|
26
|
+
*/
|
|
27
|
+
nextInt() {
|
|
28
|
+
const [value, next] = this.rng.next();
|
|
29
|
+
this.rng = next;
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get next random float in range [0, 1)
|
|
34
|
+
*/
|
|
35
|
+
float() {
|
|
36
|
+
// Use unsigned 32-bit integer for conversion
|
|
37
|
+
const value = this.nextInt() >>> 0;
|
|
38
|
+
return value / 0x100000000;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get next random float in range [min, max)
|
|
42
|
+
* @param min - Minimum value (inclusive)
|
|
43
|
+
* @param max - Maximum value (exclusive)
|
|
44
|
+
*/
|
|
45
|
+
floatRange(min, max) {
|
|
46
|
+
return min + this.float() * (max - min);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get next random integer in range [min, max]
|
|
50
|
+
* @param min - Minimum value (inclusive)
|
|
51
|
+
* @param max - Maximum value (inclusive)
|
|
52
|
+
*/
|
|
53
|
+
intRange(min, max) {
|
|
54
|
+
min = Math.floor(min);
|
|
55
|
+
max = Math.floor(max);
|
|
56
|
+
const [value, next] = prand.uniformIntDistribution(min, max)(this.rng);
|
|
57
|
+
this.rng = next;
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get next random integer in range [0, max)
|
|
62
|
+
* @param max - Maximum value (exclusive)
|
|
63
|
+
*/
|
|
64
|
+
int(max) {
|
|
65
|
+
return this.intRange(0, max - 1);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get next random boolean
|
|
69
|
+
* @param probability - Probability of true (default 0.5)
|
|
70
|
+
*/
|
|
71
|
+
boolean(probability = 0.5) {
|
|
72
|
+
return this.float() < probability;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get a random element from an array
|
|
76
|
+
* @param array - Array to pick from
|
|
77
|
+
*/
|
|
78
|
+
pick(array) {
|
|
79
|
+
if (array.length === 0) {
|
|
80
|
+
throw new Error('Cannot pick from empty array');
|
|
81
|
+
}
|
|
82
|
+
return array[this.intRange(0, array.length - 1)];
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Shuffle an array in place using Fisher-Yates algorithm
|
|
86
|
+
* @param array - Array to shuffle
|
|
87
|
+
* @returns The same array, shuffled
|
|
88
|
+
*/
|
|
89
|
+
shuffle(array) {
|
|
90
|
+
for (let i = array.length - 1; i > 0; i--) {
|
|
91
|
+
const j = this.intRange(0, i);
|
|
92
|
+
const temp = array[i];
|
|
93
|
+
array[i] = array[j];
|
|
94
|
+
array[j] = temp;
|
|
95
|
+
}
|
|
96
|
+
return array;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Create a fork of this RNG with independent state
|
|
100
|
+
* Useful for parallel simulations that need separate random streams
|
|
101
|
+
*/
|
|
102
|
+
fork() {
|
|
103
|
+
// Generate a new seed from current state
|
|
104
|
+
const newSeed = this.nextInt();
|
|
105
|
+
return new DeterministicRandom(newSeed >>> 0);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get current generator for serialization
|
|
109
|
+
* Note: pure-rand generators are immutable, so this returns a copy
|
|
110
|
+
*/
|
|
111
|
+
getGenerator() {
|
|
112
|
+
return this.rng;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Set generator from previously saved state
|
|
116
|
+
* @param generator - Previously saved generator
|
|
117
|
+
*/
|
|
118
|
+
setGenerator(generator) {
|
|
119
|
+
this.rng = generator;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=DeterministicRandom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeterministicRandom.js","sourceRoot":"","sources":["../src/DeterministicRandom.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EventEmitter - Generic typed event emitter
|
|
3
|
+
*
|
|
4
|
+
* Provides a type-safe event subscription system with support for:
|
|
5
|
+
* - Multiple handlers per event
|
|
6
|
+
* - One-time handlers (once)
|
|
7
|
+
* - Unsubscribe functions
|
|
8
|
+
* - Removing all listeners
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Generic event emitter with type-safe event handling
|
|
12
|
+
* @typeParam TEvents - Interface mapping event names to handler signatures
|
|
13
|
+
*/
|
|
14
|
+
export declare class EventEmitter<TEvents extends {
|
|
15
|
+
[K in keyof TEvents]: (...args: any[]) => void;
|
|
16
|
+
}> {
|
|
17
|
+
private handlers;
|
|
18
|
+
/**
|
|
19
|
+
* Subscribe to an event
|
|
20
|
+
* @param event Event name
|
|
21
|
+
* @param handler Event handler function
|
|
22
|
+
* @returns Unsubscribe function
|
|
23
|
+
*/
|
|
24
|
+
on<K extends keyof TEvents>(event: K, handler: TEvents[K]): () => void;
|
|
25
|
+
/**
|
|
26
|
+
* Subscribe to an event once (automatically unsubscribes after first call)
|
|
27
|
+
* @param event Event name
|
|
28
|
+
* @param handler Event handler function
|
|
29
|
+
*/
|
|
30
|
+
once<K extends keyof TEvents>(event: K, handler: TEvents[K]): void;
|
|
31
|
+
/**
|
|
32
|
+
* Unsubscribe from an event
|
|
33
|
+
* @param event Event name
|
|
34
|
+
* @param handler Event handler function to remove
|
|
35
|
+
*/
|
|
36
|
+
off<K extends keyof TEvents>(event: K, handler: TEvents[K]): void;
|
|
37
|
+
/**
|
|
38
|
+
* Remove all event listeners
|
|
39
|
+
*/
|
|
40
|
+
removeAllListeners(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Remove all listeners for a specific event
|
|
43
|
+
* @param event Event name
|
|
44
|
+
*/
|
|
45
|
+
removeListeners<K extends keyof TEvents>(event: K): void;
|
|
46
|
+
/**
|
|
47
|
+
* Emit an event to all subscribers
|
|
48
|
+
* @param event Event name
|
|
49
|
+
* @param args Event arguments
|
|
50
|
+
*/
|
|
51
|
+
protected emit<K extends keyof TEvents>(event: K, ...args: Parameters<TEvents[K]>): void;
|
|
52
|
+
/**
|
|
53
|
+
* Check if there are any listeners for an event
|
|
54
|
+
* @param event Event name
|
|
55
|
+
* @returns True if there are listeners
|
|
56
|
+
*/
|
|
57
|
+
hasListeners<K extends keyof TEvents>(event: K): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Get the number of listeners for an event
|
|
60
|
+
* @param event Event name
|
|
61
|
+
* @returns Number of listeners
|
|
62
|
+
*/
|
|
63
|
+
listenerCount<K extends keyof TEvents>(event: K): number;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=EventEmitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventEmitter.d.ts","sourceRoot":"","sources":["../src/EventEmitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;GAGG;AAEH,qBAAa,YAAY,CAEvB,OAAO,SAAS;KAAG,CAAC,IAAI,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI;CAAE;IAGlE,OAAO,CAAC,QAAQ,CAA2C;IAE3D;;;;;OAKG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAYtE;;;;OAIG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;IASlE;;;;OAIG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;IAKjE;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAI1B;;;OAGG;IACH,eAAe,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAIxD;;;;OAIG;IACH,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EACpC,KAAK,EAAE,CAAC,EACR,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAC9B,IAAI;IAaP;;;;OAIG;IACH,YAAY,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO;IAKxD;;;;OAIG;IACH,aAAa,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM;CAGzD"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EventEmitter - Generic typed event emitter
|
|
3
|
+
*
|
|
4
|
+
* Provides a type-safe event subscription system with support for:
|
|
5
|
+
* - Multiple handlers per event
|
|
6
|
+
* - One-time handlers (once)
|
|
7
|
+
* - Unsubscribe functions
|
|
8
|
+
* - Removing all listeners
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Generic event emitter with type-safe event handling
|
|
12
|
+
* @typeParam TEvents - Interface mapping event names to handler signatures
|
|
13
|
+
*/
|
|
14
|
+
export class EventEmitter {
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
+
handlers = new Map();
|
|
17
|
+
/**
|
|
18
|
+
* Subscribe to an event
|
|
19
|
+
* @param event Event name
|
|
20
|
+
* @param handler Event handler function
|
|
21
|
+
* @returns Unsubscribe function
|
|
22
|
+
*/
|
|
23
|
+
on(event, handler) {
|
|
24
|
+
if (!this.handlers.has(event)) {
|
|
25
|
+
this.handlers.set(event, new Set());
|
|
26
|
+
}
|
|
27
|
+
this.handlers.get(event).add(handler);
|
|
28
|
+
return () => {
|
|
29
|
+
this.off(event, handler);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Subscribe to an event once (automatically unsubscribes after first call)
|
|
34
|
+
* @param event Event name
|
|
35
|
+
* @param handler Event handler function
|
|
36
|
+
*/
|
|
37
|
+
once(event, handler) {
|
|
38
|
+
const wrapper = ((...args) => {
|
|
39
|
+
this.off(event, wrapper);
|
|
40
|
+
handler(...args);
|
|
41
|
+
});
|
|
42
|
+
this.on(event, wrapper);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Unsubscribe from an event
|
|
46
|
+
* @param event Event name
|
|
47
|
+
* @param handler Event handler function to remove
|
|
48
|
+
*/
|
|
49
|
+
off(event, handler) {
|
|
50
|
+
const eventHandlers = this.handlers.get(event);
|
|
51
|
+
eventHandlers?.delete(handler);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Remove all event listeners
|
|
55
|
+
*/
|
|
56
|
+
removeAllListeners() {
|
|
57
|
+
this.handlers.clear();
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Remove all listeners for a specific event
|
|
61
|
+
* @param event Event name
|
|
62
|
+
*/
|
|
63
|
+
removeListeners(event) {
|
|
64
|
+
this.handlers.delete(event);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Emit an event to all subscribers
|
|
68
|
+
* @param event Event name
|
|
69
|
+
* @param args Event arguments
|
|
70
|
+
*/
|
|
71
|
+
emit(event, ...args) {
|
|
72
|
+
const eventHandlers = this.handlers.get(event);
|
|
73
|
+
if (eventHandlers) {
|
|
74
|
+
for (const handler of eventHandlers) {
|
|
75
|
+
try {
|
|
76
|
+
handler(...args);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error(`Error in event handler for ${String(event)}:`, error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Check if there are any listeners for an event
|
|
86
|
+
* @param event Event name
|
|
87
|
+
* @returns True if there are listeners
|
|
88
|
+
*/
|
|
89
|
+
hasListeners(event) {
|
|
90
|
+
const eventHandlers = this.handlers.get(event);
|
|
91
|
+
return eventHandlers !== undefined && eventHandlers.size > 0;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get the number of listeners for an event
|
|
95
|
+
* @param event Event name
|
|
96
|
+
* @returns Number of listeners
|
|
97
|
+
*/
|
|
98
|
+
listenerCount(event) {
|
|
99
|
+
return this.handlers.get(event)?.size ?? 0;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=EventEmitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventEmitter.js","sourceRoot":"","sources":["../src/EventEmitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;GAGG;AAEH,MAAM,OAAO,YAAY;IAIvB,8DAA8D;IACtD,QAAQ,GAAiC,IAAI,GAAG,EAAE,CAAC;IAE3D;;;;;OAKG;IACH,EAAE,CAA0B,KAAQ,EAAE,OAAmB;QACvD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QACtC,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAEvC,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC3B,CAAC,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,IAAI,CAA0B,KAAQ,EAAE,OAAmB;QACzD,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,IAA4B,EAAE,EAAE;YACnD,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACxB,OAAqD,CAAC,GAAG,IAAI,CAAC,CAAC;QAClE,CAAC,CAAe,CAAC;QAEjB,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IACH,GAAG,CAA0B,KAAQ,EAAE,OAAmB;QACxD,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/C,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED;;;OAGG;IACH,eAAe,CAA0B,KAAQ;QAC/C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACO,IAAI,CACZ,KAAQ,EACR,GAAG,IAA4B;QAE/B,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,aAAa,EAAE,CAAC;YAClB,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;gBACpC,IAAI,CAAC;oBACF,OAAqD,CAAC,GAAG,IAAI,CAAC,CAAC;gBAClE,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACvE,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,YAAY,CAA0B,KAAQ;QAC5C,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/C,OAAO,aAAa,KAAK,SAAS,IAAI,aAAa,CAAC,IAAI,GAAG,CAAC,CAAC;IAC/D,CAAC;IAED;;;;OAIG;IACH,aAAa,CAA0B,KAAQ;QAC7C,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC;IAC7C,CAAC;CACF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixed-Point Math Module
|
|
3
|
+
*
|
|
4
|
+
* Re-exports from phalanx-math for convenience.
|
|
5
|
+
* The canonical implementation is in phalanx-math.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { FP, FPVector3 } from '@phalanx-engine/client';
|
|
10
|
+
*
|
|
11
|
+
* const position = FPVector3.FromFloat(10.5, 0, 20.3);
|
|
12
|
+
* const target = FPVector3.FromFloat(5.0, 0, 10.0);
|
|
13
|
+
*
|
|
14
|
+
* const distance = FPVector3.Distance(position, target);
|
|
15
|
+
*
|
|
16
|
+
* // Convert back to number for display
|
|
17
|
+
* console.log(FP.ToFloat(distance));
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export { FixedPoint, FP, FPVector2, FPVector3, } from '@phalanx-engine/math';
|
|
21
|
+
export type { FPVector2 as FPVector2Interface, FPVector3 as FPVector3Interface } from '@phalanx-engine/math';
|
|
22
|
+
//# sourceMappingURL=FixedMath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FixedMath.d.ts","sourceRoot":"","sources":["../src/FixedMath.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAEL,UAAU,EAEV,EAAE,EACF,SAAS,EACT,SAAS,GACV,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EAAE,SAAS,IAAI,kBAAkB,EAAE,SAAS,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixed-Point Math Module
|
|
3
|
+
*
|
|
4
|
+
* Re-exports from phalanx-math for convenience.
|
|
5
|
+
* The canonical implementation is in phalanx-math.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { FP, FPVector3 } from '@phalanx-engine/client';
|
|
10
|
+
*
|
|
11
|
+
* const position = FPVector3.FromFloat(10.5, 0, 20.3);
|
|
12
|
+
* const target = FPVector3.FromFloat(5.0, 0, 10.0);
|
|
13
|
+
*
|
|
14
|
+
* const distance = FPVector3.Distance(position, target);
|
|
15
|
+
*
|
|
16
|
+
* // Convert back to number for display
|
|
17
|
+
* console.log(FP.ToFloat(distance));
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
// Re-export everything from phalanx-math
|
|
21
|
+
export {
|
|
22
|
+
// Core type
|
|
23
|
+
FixedPoint,
|
|
24
|
+
// Unified API (Unity/Quantum style)
|
|
25
|
+
FP, FPVector2, FPVector3, } from '@phalanx-engine/math';
|
|
26
|
+
//# sourceMappingURL=FixedMath.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FixedMath.js","sourceRoot":"","sources":["../src/FixedMath.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,yCAAyC;AACzC,OAAO;AACL,YAAY;AACZ,UAAU;AACV,oCAAoC;AACpC,EAAE,EACF,SAAS,EACT,SAAS,GACV,MAAM,sBAAsB,CAAC"}
|