@lagless/create 0.0.33

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 (67) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +123 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  6. package/package.json +59 -0
  7. package/templates/.nxignore +1 -0
  8. package/templates/pixi-react/AGENTS.md +41 -0
  9. package/templates/pixi-react/CLAUDE.md +79 -0
  10. package/templates/pixi-react/README.md +151 -0
  11. package/templates/pixi-react/__packageName__-backend/bunfig.toml +4 -0
  12. package/templates/pixi-react/__packageName__-backend/package.json +19 -0
  13. package/templates/pixi-react/__packageName__-backend/src/game-hooks.ts +47 -0
  14. package/templates/pixi-react/__packageName__-backend/src/main.ts +28 -0
  15. package/templates/pixi-react/__packageName__-backend/tsconfig.json +19 -0
  16. package/templates/pixi-react/__packageName__-frontend/index.html +23 -0
  17. package/templates/pixi-react/__packageName__-frontend/package.json +33 -0
  18. package/templates/pixi-react/__packageName__-frontend/src/app/app.tsx +7 -0
  19. package/templates/pixi-react/__packageName__-frontend/src/app/components/debug-panel.tsx +18 -0
  20. package/templates/pixi-react/__packageName__-frontend/src/app/game-view/game-scene.tsx +14 -0
  21. package/templates/pixi-react/__packageName__-frontend/src/app/game-view/game-view.tsx +46 -0
  22. package/templates/pixi-react/__packageName__-frontend/src/app/game-view/grid-background.tsx +33 -0
  23. package/templates/pixi-react/__packageName__-frontend/src/app/game-view/player-view.tsx +59 -0
  24. package/templates/pixi-react/__packageName__-frontend/src/app/game-view/runner-provider.tsx +180 -0
  25. package/templates/pixi-react/__packageName__-frontend/src/app/hooks/use-start-match.ts +53 -0
  26. package/templates/pixi-react/__packageName__-frontend/src/app/hooks/use-start-multiplayer-match.ts +138 -0
  27. package/templates/pixi-react/__packageName__-frontend/src/app/router.tsx +25 -0
  28. package/templates/pixi-react/__packageName__-frontend/src/app/screens/game.screen.tsx +6 -0
  29. package/templates/pixi-react/__packageName__-frontend/src/app/screens/title.screen.tsx +104 -0
  30. package/templates/pixi-react/__packageName__-frontend/src/main.tsx +7 -0
  31. package/templates/pixi-react/__packageName__-frontend/src/styles.css +24 -0
  32. package/templates/pixi-react/__packageName__-frontend/tsconfig.json +22 -0
  33. package/templates/pixi-react/__packageName__-frontend/vite.config.ts +37 -0
  34. package/templates/pixi-react/__packageName__-simulation/.swcrc +27 -0
  35. package/templates/pixi-react/__packageName__-simulation/package.json +23 -0
  36. package/templates/pixi-react/__packageName__-simulation/src/index.ts +4 -0
  37. package/templates/pixi-react/__packageName__-simulation/src/lib/arena.ts +8 -0
  38. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/GameState.ts +29 -0
  39. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/MoveInput.ts +23 -0
  40. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/MovingFilter.ts +15 -0
  41. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/PlayerBody.ts +55 -0
  42. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/PlayerFilter.ts +15 -0
  43. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/PlayerJoined.ts +24 -0
  44. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/PlayerLeft.ts +23 -0
  45. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/PlayerResource.ts +83 -0
  46. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/ReportHash.ts +23 -0
  47. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/Transform2d.ts +65 -0
  48. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/Velocity2d.ts +55 -0
  49. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/__ProjectName__.core.ts +22 -0
  50. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/__ProjectName__.runner.ts +16 -0
  51. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/__ProjectName__InputRegistry.ts +8 -0
  52. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/code-gen/index.ts +16 -0
  53. package/templates/pixi-react/__packageName__-simulation/src/lib/schema/ecs.yaml +52 -0
  54. package/templates/pixi-react/__packageName__-simulation/src/lib/signals/index.ts +5 -0
  55. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/apply-move-input.system.ts +23 -0
  56. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/boundary.system.ts +34 -0
  57. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/damping.system.ts +18 -0
  58. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/hash-verification.system.ts +17 -0
  59. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/index.ts +20 -0
  60. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/integrate.system.ts +18 -0
  61. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/player-connection.system.ts +47 -0
  62. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/player-leave.system.ts +21 -0
  63. package/templates/pixi-react/__packageName__-simulation/src/lib/systems/save-prev-transform.system.ts +17 -0
  64. package/templates/pixi-react/__packageName__-simulation/tsconfig.json +22 -0
  65. package/templates/pixi-react/package.json +8 -0
  66. package/templates/pixi-react/pnpm-workspace.yaml +4 -0
  67. package/templates/pixi-react/tsconfig.base.json +21 -0
@@ -0,0 +1,104 @@
1
+ import { FC } from 'react';
2
+ import { useStartMatch } from '../hooks/use-start-match';
3
+ import { useStartMultiplayerMatch } from '../hooks/use-start-multiplayer-match';
4
+
5
+ export const TitleScreen: FC = () => {
6
+ const { isBusy, startMatch } = useStartMatch();
7
+ const multiplayer = useStartMultiplayerMatch();
8
+
9
+ const isMultiplayerBusy = multiplayer.state !== 'idle';
10
+
11
+ return (
12
+ <div style={styles.screen}>
13
+ <div style={styles.title}><%= projectName %></div>
14
+ <div style={styles.subtitle}>Multiplayer Game</div>
15
+ <div style={styles.actions}>
16
+ <button style={styles.button} onClick={startMatch} disabled={isMultiplayerBusy || isBusy}>
17
+ {isBusy ? 'Starting...' : 'Play Local'}
18
+ </button>
19
+ <button
20
+ style={styles.buttonPrimary}
21
+ onClick={isMultiplayerBusy ? multiplayer.cancel : multiplayer.startMatch}
22
+ disabled={isBusy}
23
+ >
24
+ {multiplayer.state === 'queuing' && `In Queue${multiplayer.queuePosition ? ` #${multiplayer.queuePosition}` : ''}...`}
25
+ {multiplayer.state === 'connecting' && 'Connecting...'}
26
+ {multiplayer.state === 'error' && `Error: ${multiplayer.error}`}
27
+ {multiplayer.state === 'idle' && 'Play Online'}
28
+ </button>
29
+ </div>
30
+ <div style={styles.controls}>
31
+ <div style={styles.controlsTitle}>Controls</div>
32
+ <div>WASD / Arrow Keys — Move</div>
33
+ <div>F3 — Debug Panel</div>
34
+ </div>
35
+ </div>
36
+ );
37
+ };
38
+
39
+ const styles: Record<string, React.CSSProperties> = {
40
+ screen: {
41
+ position: 'fixed',
42
+ top: 0,
43
+ left: 0,
44
+ width: '100%',
45
+ height: '100%',
46
+ display: 'flex',
47
+ flexDirection: 'column',
48
+ alignItems: 'center',
49
+ justifyContent: 'center',
50
+ background: '#0a0a1a',
51
+ fontFamily: "'Courier New', monospace",
52
+ color: '#e0e0e0',
53
+ },
54
+ title: {
55
+ fontSize: 48,
56
+ fontWeight: 'bold',
57
+ color: '#88aaff',
58
+ marginBottom: 8,
59
+ },
60
+ subtitle: {
61
+ fontSize: 16,
62
+ color: '#666',
63
+ marginBottom: 48,
64
+ },
65
+ actions: {
66
+ display: 'flex',
67
+ flexDirection: 'column',
68
+ gap: 16,
69
+ alignItems: 'center',
70
+ },
71
+ button: {
72
+ padding: '12px 32px',
73
+ fontSize: 18,
74
+ cursor: 'pointer',
75
+ background: '#222',
76
+ color: '#e0e0e0',
77
+ border: '2px solid #555',
78
+ borderRadius: 6,
79
+ fontFamily: "'Courier New', monospace",
80
+ minWidth: 220,
81
+ },
82
+ buttonPrimary: {
83
+ padding: '12px 32px',
84
+ fontSize: 18,
85
+ cursor: 'pointer',
86
+ background: '#1a3a6a',
87
+ color: '#88aaff',
88
+ border: '2px solid #4488ff',
89
+ borderRadius: 6,
90
+ fontFamily: "'Courier New', monospace",
91
+ minWidth: 220,
92
+ },
93
+ controls: {
94
+ marginTop: 48,
95
+ textAlign: 'center' as const,
96
+ color: '#555',
97
+ fontSize: 13,
98
+ },
99
+ controlsTitle: {
100
+ color: '#888',
101
+ fontWeight: 'bold',
102
+ marginBottom: 4,
103
+ },
104
+ };
@@ -0,0 +1,7 @@
1
+ import './styles.css';
2
+ import '@abraham/reflection';
3
+ import * as ReactDOM from 'react-dom/client';
4
+ import { App } from './app/app';
5
+
6
+ const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
7
+ root.render(<App />);
@@ -0,0 +1,24 @@
1
+ *, *::before, *::after {
2
+ box-sizing: border-box;
3
+ }
4
+
5
+ * {
6
+ margin: 0;
7
+ }
8
+
9
+ body {
10
+ -webkit-font-smoothing: antialiased;
11
+ }
12
+
13
+ img, picture, video, canvas, svg {
14
+ display: block;
15
+ max-width: 100%;
16
+ }
17
+
18
+ input, button, textarea, select {
19
+ font: inherit;
20
+ }
21
+
22
+ #root {
23
+ isolation: isolate;
24
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "experimentalDecorators": true,
12
+ "emitDecoratorMetadata": true,
13
+ "resolveJsonModule": true,
14
+ "isolatedModules": true,
15
+ "noEmit": true,
16
+ "jsx": "react-jsx",
17
+ "baseUrl": ".",
18
+ "types": ["node", "vite/client"]
19
+ },
20
+ "include": ["src/**/*.ts", "src/**/*.tsx"],
21
+ "exclude": ["node_modules", "dist"]
22
+ }
@@ -0,0 +1,37 @@
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react-swc';
3
+ import wasm from 'vite-plugin-wasm';
4
+ import topLevelAwait from 'vite-plugin-top-level-await';
5
+
6
+ export default defineConfig(() => ({
7
+ root: __dirname,
8
+ server: {
9
+ port: <%= frontendPort %>,
10
+ host: true,
11
+ },
12
+ preview: {
13
+ port: <%= frontendPort %>,
14
+ host: 'localhost',
15
+ },
16
+ plugins: [
17
+ wasm(),
18
+ topLevelAwait(),
19
+ react({
20
+ tsDecorators: true,
21
+ useAtYourOwnRisk_mutateSwcOptions: (options) => {
22
+ options.jsc!.transform!.decoratorMetadata = true;
23
+ },
24
+ }),
25
+ ],
26
+ build: {
27
+ outDir: './dist',
28
+ emptyOutDir: true,
29
+ reportCompressedSize: true,
30
+ commonjsOptions: {
31
+ transformMixedEsModules: true,
32
+ },
33
+ },
34
+ optimizeDeps: {
35
+ exclude: ['@lagless/deterministic-math'],
36
+ },
37
+ }));
@@ -0,0 +1,27 @@
1
+ {
2
+ "jsc": {
3
+ "target": "es2017",
4
+ "parser": {
5
+ "syntax": "typescript",
6
+ "decorators": true,
7
+ "dynamicImport": true
8
+ },
9
+ "transform": {
10
+ "decoratorMetadata": true,
11
+ "legacyDecorator": true
12
+ },
13
+ "keepClassNames": true,
14
+ "externalHelpers": true,
15
+ "loose": true
16
+ },
17
+ "module": {
18
+ "type": "es6"
19
+ },
20
+ "sourceMaps": true,
21
+ "exclude": [
22
+ "jest.config.ts",
23
+ ".*\\.spec.tsx?$",
24
+ ".*\\.test.tsx?$",
25
+ "./*.js$"
26
+ ]
27
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "<%= packageName %>-simulation",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "type": "module",
6
+ "main": "./src/index.ts",
7
+ "types": "./src/index.ts",
8
+ "exports": {
9
+ "./package.json": "./package.json",
10
+ ".": {
11
+ "types": "./src/index.ts",
12
+ "import": "./src/index.ts",
13
+ "default": "./src/index.ts"
14
+ }
15
+ },
16
+ "dependencies": {
17
+ "@lagless/core": "^<%= laglessVersion %>",
18
+ "@lagless/math": "^<%= laglessVersion %>",
19
+ "@lagless/binary": "^<%= laglessVersion %>",
20
+ "@lagless/misc": "^<%= laglessVersion %>",
21
+ "@swc/helpers": "~0.5.11"
22
+ }
23
+ }
@@ -0,0 +1,4 @@
1
+ export * from './lib/schema/code-gen/index.js';
2
+ export * from './lib/systems/index.js';
3
+ export * from './lib/signals/index.js';
4
+ export * from './lib/arena.js';
@@ -0,0 +1,8 @@
1
+ export const <%= projectName %>Arena = {
2
+ width: 800,
3
+ height: 600,
4
+ playerRadius: 20,
5
+ moveSpeed: 3.0,
6
+ damping: 0.85,
7
+ hashReportInterval: 120,
8
+ } as const;
@@ -0,0 +1,29 @@
1
+ // Generated by @lagless/codegen. Do not edit manually.
2
+ import { MemoryTracker } from '@lagless/binary';
3
+
4
+ export class GameState {
5
+ public static readonly schema = {
6
+ gamePhase: Uint8Array,
7
+ };
8
+
9
+ public readonly safe = {} as {
10
+ gamePhase: number;
11
+ };
12
+
13
+ constructor(buffer: ArrayBuffer, memTracker: MemoryTracker) {
14
+ const gamePhaseArray = new Uint8Array(buffer, memTracker.ptr, 1);
15
+ memTracker.add(1);
16
+
17
+ Object.defineProperty(this.safe, 'gamePhase', {
18
+ get: () => gamePhaseArray[0],
19
+ set: (v: number) => { gamePhaseArray[0] = v; },
20
+ enumerable: true,
21
+ });
22
+ }
23
+
24
+ public static calculateSize(_maxEntities: number, memTracker: MemoryTracker): void {
25
+ memTracker.add(1);
26
+ }
27
+ }
28
+
29
+ Object.defineProperty(GameState, 'name', { value: 'GameState' });
@@ -0,0 +1,23 @@
1
+ // Generated by @lagless/codegen. Do not edit manually.
2
+ import { InputPayloadBuffer } from '@lagless/core';
3
+
4
+ export class MoveInput {
5
+ public static readonly id = 2;
6
+ public static readonly byteLength = 8;
7
+
8
+ public readonly schema!: {
9
+ directionX: number;
10
+ directionY: number;
11
+ };
12
+
13
+ public static encode(data: MoveInput['schema'], buffer: InputPayloadBuffer): void {
14
+ buffer.writeFloat32(data.directionX);
15
+ buffer.writeFloat32(data.directionY);
16
+ }
17
+
18
+ public static decode(buffer: InputPayloadBuffer): MoveInput['schema'] {
19
+ const directionX = buffer.readFloat32();
20
+ const directionY = buffer.readFloat32();
21
+ return { directionX, directionY };
22
+ }
23
+ }
@@ -0,0 +1,15 @@
1
+ // Generated by @lagless/codegen. Do not edit manually.
2
+ import { AbstractFilter, MemoryTracker } from '@lagless/binary';
3
+ import { Transform2d } from './Transform2d.js';
4
+ import { Velocity2d } from './Velocity2d.js';
5
+
6
+ export class MovingFilter extends AbstractFilter {
7
+ public static readonly includeMask = Transform2d.ID | Velocity2d.ID;
8
+ public static readonly excludeMask = 0;
9
+
10
+ constructor(maxEntities: number, buffer: ArrayBuffer, memTracker: MemoryTracker) {
11
+ super(maxEntities, Transform2d.ID | Velocity2d.ID, 0, buffer, memTracker);
12
+ }
13
+ }
14
+
15
+ Object.defineProperty(MovingFilter, 'name', { value: 'MovingFilter' });
@@ -0,0 +1,55 @@
1
+ // Generated by @lagless/codegen. Do not edit manually.
2
+ import { MemoryTracker } from '@lagless/binary';
3
+
4
+ export class PlayerBody {
5
+ public static readonly ID = 4;
6
+ public static readonly schema = {
7
+ playerSlot: Uint8Array,
8
+ radius: Float32Array,
9
+ };
10
+
11
+ public readonly unsafe = {} as {
12
+ playerSlot: Uint8Array;
13
+ radius: Float32Array;
14
+ };
15
+
16
+ private _cursorIndex = 0;
17
+ private readonly _cursor: {
18
+ readonly entity: number;
19
+ playerSlot: number;
20
+ radius: number;
21
+ };
22
+
23
+ public getCursor(index: number) {
24
+ this._cursorIndex = index;
25
+ return this._cursor;
26
+ }
27
+
28
+ constructor(maxEntities: number, buffer: ArrayBuffer, memTracker: MemoryTracker) {
29
+ for (const [fieldName, TypedArrayConstructor] of Object.entries(PlayerBody.schema)) {
30
+ const typedArray = new TypedArrayConstructor(buffer, memTracker.ptr, maxEntities);
31
+ this.unsafe[fieldName as keyof typeof PlayerBody.schema] =
32
+ typedArray as PlayerBody['unsafe'][keyof PlayerBody['unsafe']];
33
+ memTracker.add(typedArray.byteLength);
34
+ }
35
+
36
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
37
+ const self = this;
38
+
39
+ this._cursor = {
40
+ get entity(): number { return self._cursorIndex; },
41
+ get playerSlot(): number { return self.unsafe.playerSlot[self._cursorIndex]; },
42
+ set playerSlot(value: number) { self.unsafe.playerSlot[self._cursorIndex] = value; },
43
+ get radius(): number { return self.unsafe.radius[self._cursorIndex]; },
44
+ set radius(value: number) { self.unsafe.radius[self._cursorIndex] = value; },
45
+ };
46
+ }
47
+
48
+ public static calculateSize(maxEntities: number, memTracker: MemoryTracker): void {
49
+ for (const [, TypedArrayConstructor] of Object.entries(this.schema)) {
50
+ memTracker.add(maxEntities * TypedArrayConstructor.BYTES_PER_ELEMENT);
51
+ }
52
+ }
53
+ }
54
+
55
+ Object.defineProperty(PlayerBody, 'name', { value: 'PlayerBody' });
@@ -0,0 +1,15 @@
1
+ // Generated by @lagless/codegen. Do not edit manually.
2
+ import { AbstractFilter, MemoryTracker } from '@lagless/binary';
3
+ import { Transform2d } from './Transform2d.js';
4
+ import { PlayerBody } from './PlayerBody.js';
5
+
6
+ export class PlayerFilter extends AbstractFilter {
7
+ public static readonly includeMask = Transform2d.ID | PlayerBody.ID;
8
+ public static readonly excludeMask = 0;
9
+
10
+ constructor(maxEntities: number, buffer: ArrayBuffer, memTracker: MemoryTracker) {
11
+ super(maxEntities, Transform2d.ID | PlayerBody.ID, 0, buffer, memTracker);
12
+ }
13
+ }
14
+
15
+ Object.defineProperty(PlayerFilter, 'name', { value: 'PlayerFilter' });
@@ -0,0 +1,24 @@
1
+ // Generated by @lagless/codegen. Do not edit manually.
2
+ import { InputDef, InputByteLength, InputPayloadBuffer } from '@lagless/core';
3
+
4
+ export class PlayerJoined {
5
+ public static readonly id = 0;
6
+ public static readonly byteLength = 17;
7
+
8
+ public readonly schema!: {
9
+ slot: number;
10
+ playerId: Uint8Array;
11
+ };
12
+
13
+ public static encode(data: PlayerJoined['schema'], buffer: InputPayloadBuffer): void {
14
+ buffer.writeUint8(data.slot);
15
+ for (let i = 0; i < 16; i++) buffer.writeUint8(data.playerId[i]);
16
+ }
17
+
18
+ public static decode(buffer: InputPayloadBuffer): PlayerJoined['schema'] {
19
+ const slot = buffer.readUint8();
20
+ const playerId = new Uint8Array(16);
21
+ for (let i = 0; i < 16; i++) playerId[i] = buffer.readUint8();
22
+ return { slot, playerId };
23
+ }
24
+ }
@@ -0,0 +1,23 @@
1
+ // Generated by @lagless/codegen. Do not edit manually.
2
+ import { InputPayloadBuffer } from '@lagless/core';
3
+
4
+ export class PlayerLeft {
5
+ public static readonly id = 1;
6
+ public static readonly byteLength = 2;
7
+
8
+ public readonly schema!: {
9
+ slot: number;
10
+ reason: number;
11
+ };
12
+
13
+ public static encode(data: PlayerLeft['schema'], buffer: InputPayloadBuffer): void {
14
+ buffer.writeUint8(data.slot);
15
+ buffer.writeUint8(data.reason);
16
+ }
17
+
18
+ public static decode(buffer: InputPayloadBuffer): PlayerLeft['schema'] {
19
+ const slot = buffer.readUint8();
20
+ const reason = buffer.readUint8();
21
+ return { slot, reason };
22
+ }
23
+ }
@@ -0,0 +1,83 @@
1
+ // Generated by @lagless/codegen. Do not edit manually.
2
+ import { MemoryTracker } from '@lagless/binary';
3
+
4
+ export class PlayerResource {
5
+ public static readonly schema = {
6
+ id: { type: Uint8Array, length: 16 },
7
+ entity: Uint32Array,
8
+ connected: Uint8Array,
9
+ lastReportedHash: Uint32Array,
10
+ lastReportedHashTick: Uint32Array,
11
+ hashMismatchCount: Uint16Array,
12
+ };
13
+
14
+ public readonly safe = {} as {
15
+ entity: number;
16
+ connected: number;
17
+ lastReportedHash: number;
18
+ lastReportedHashTick: number;
19
+ hashMismatchCount: number;
20
+ };
21
+
22
+ public readonly unsafe = {} as {
23
+ id: Uint8Array;
24
+ };
25
+
26
+ constructor(playerIndex: number, buffer: ArrayBuffer, memTracker: MemoryTracker) {
27
+ // id: uint8[16]
28
+ const idArray = new Uint8Array(buffer, memTracker.ptr, 16);
29
+ memTracker.add(16);
30
+ (this.unsafe as Record<string, unknown>).id = idArray;
31
+
32
+ // entity: uint32
33
+ const entityArray = new Uint32Array(buffer, memTracker.ptr, 1);
34
+ memTracker.add(4);
35
+ Object.defineProperty(this.safe, 'entity', {
36
+ get: () => entityArray[0],
37
+ set: (v: number) => { entityArray[0] = v; },
38
+ enumerable: true,
39
+ });
40
+
41
+ // connected: uint8
42
+ const connectedArray = new Uint8Array(buffer, memTracker.ptr, 1);
43
+ memTracker.add(1);
44
+ Object.defineProperty(this.safe, 'connected', {
45
+ get: () => connectedArray[0],
46
+ set: (v: number) => { connectedArray[0] = v; },
47
+ enumerable: true,
48
+ });
49
+
50
+ // lastReportedHash: uint32
51
+ const lastReportedHashArray = new Uint32Array(buffer, memTracker.ptr, 1);
52
+ memTracker.add(4);
53
+ Object.defineProperty(this.safe, 'lastReportedHash', {
54
+ get: () => lastReportedHashArray[0],
55
+ set: (v: number) => { lastReportedHashArray[0] = v; },
56
+ enumerable: true,
57
+ });
58
+
59
+ // lastReportedHashTick: uint32
60
+ const lastReportedHashTickArray = new Uint32Array(buffer, memTracker.ptr, 1);
61
+ memTracker.add(4);
62
+ Object.defineProperty(this.safe, 'lastReportedHashTick', {
63
+ get: () => lastReportedHashTickArray[0],
64
+ set: (v: number) => { lastReportedHashTickArray[0] = v; },
65
+ enumerable: true,
66
+ });
67
+
68
+ // hashMismatchCount: uint16
69
+ const hashMismatchCountArray = new Uint16Array(buffer, memTracker.ptr, 1);
70
+ memTracker.add(2);
71
+ Object.defineProperty(this.safe, 'hashMismatchCount', {
72
+ get: () => hashMismatchCountArray[0],
73
+ set: (v: number) => { hashMismatchCountArray[0] = v; },
74
+ enumerable: true,
75
+ });
76
+ }
77
+
78
+ public static calculateSize(_maxEntities: number, memTracker: MemoryTracker): void {
79
+ memTracker.add(16 + 4 + 1 + 4 + 4 + 2);
80
+ }
81
+ }
82
+
83
+ Object.defineProperty(PlayerResource, 'name', { value: 'PlayerResource' });
@@ -0,0 +1,23 @@
1
+ // Generated by @lagless/codegen. Do not edit manually.
2
+ import { InputPayloadBuffer } from '@lagless/core';
3
+
4
+ export class ReportHash {
5
+ public static readonly id = 3;
6
+ public static readonly byteLength = 8;
7
+
8
+ public readonly schema!: {
9
+ hash: number;
10
+ atTick: number;
11
+ };
12
+
13
+ public static encode(data: ReportHash['schema'], buffer: InputPayloadBuffer): void {
14
+ buffer.writeUint32(data.hash);
15
+ buffer.writeUint32(data.atTick);
16
+ }
17
+
18
+ public static decode(buffer: InputPayloadBuffer): ReportHash['schema'] {
19
+ const hash = buffer.readUint32();
20
+ const atTick = buffer.readUint32();
21
+ return { hash, atTick };
22
+ }
23
+ }
@@ -0,0 +1,65 @@
1
+ // Generated by @lagless/codegen. Do not edit manually.
2
+ import { MemoryTracker } from '@lagless/binary';
3
+
4
+ export class Transform2d {
5
+ public static readonly ID = 1;
6
+ public static readonly schema = {
7
+ positionX: Float32Array,
8
+ positionY: Float32Array,
9
+ prevPositionX: Float32Array,
10
+ prevPositionY: Float32Array,
11
+ };
12
+
13
+ public readonly unsafe = {} as {
14
+ positionX: Float32Array;
15
+ positionY: Float32Array;
16
+ prevPositionX: Float32Array;
17
+ prevPositionY: Float32Array;
18
+ };
19
+
20
+ private _cursorIndex = 0;
21
+ private readonly _cursor: {
22
+ readonly entity: number;
23
+ positionX: number;
24
+ positionY: number;
25
+ prevPositionX: number;
26
+ prevPositionY: number;
27
+ };
28
+
29
+ public getCursor(index: number) {
30
+ this._cursorIndex = index;
31
+ return this._cursor;
32
+ }
33
+
34
+ constructor(maxEntities: number, buffer: ArrayBuffer, memTracker: MemoryTracker) {
35
+ for (const [fieldName, TypedArrayConstructor] of Object.entries(Transform2d.schema)) {
36
+ const typedArray = new TypedArrayConstructor(buffer, memTracker.ptr, maxEntities);
37
+ this.unsafe[fieldName as keyof typeof Transform2d.schema] =
38
+ typedArray as Transform2d['unsafe'][keyof Transform2d['unsafe']];
39
+ memTracker.add(typedArray.byteLength);
40
+ }
41
+
42
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
43
+ const self = this;
44
+
45
+ this._cursor = {
46
+ get entity(): number { return self._cursorIndex; },
47
+ get positionX(): number { return self.unsafe.positionX[self._cursorIndex]; },
48
+ set positionX(value: number) { self.unsafe.positionX[self._cursorIndex] = value; },
49
+ get positionY(): number { return self.unsafe.positionY[self._cursorIndex]; },
50
+ set positionY(value: number) { self.unsafe.positionY[self._cursorIndex] = value; },
51
+ get prevPositionX(): number { return self.unsafe.prevPositionX[self._cursorIndex]; },
52
+ set prevPositionX(value: number) { self.unsafe.prevPositionX[self._cursorIndex] = value; },
53
+ get prevPositionY(): number { return self.unsafe.prevPositionY[self._cursorIndex]; },
54
+ set prevPositionY(value: number) { self.unsafe.prevPositionY[self._cursorIndex] = value; },
55
+ };
56
+ }
57
+
58
+ public static calculateSize(maxEntities: number, memTracker: MemoryTracker): void {
59
+ for (const [, TypedArrayConstructor] of Object.entries(this.schema)) {
60
+ memTracker.add(maxEntities * TypedArrayConstructor.BYTES_PER_ELEMENT);
61
+ }
62
+ }
63
+ }
64
+
65
+ Object.defineProperty(Transform2d, 'name', { value: 'Transform2d' });