summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElizabeth Hunt <elizabeth.hunt@simponic.xyz>2023-08-23 19:44:59 -0600
committerElizabeth Hunt <elizabeth.hunt@simponic.xyz>2023-08-23 19:44:59 -0600
commitdec7b614d895a1b507137e4a96a8999ff63aa179 (patch)
tree827437755bf9674db51818ee59d919c74a4ea2fc
parentd64ffb5016119e54f0e20d05ae8ac9c96955d9d5 (diff)
downloadjumpstorm-dec7b614d895a1b507137e4a96a8999ff63aa179.tar.gz
jumpstorm-dec7b614d895a1b507137e4a96a8999ff63aa179.zip
holy fuck we actually got somewhere
-rw-r--r--client/src/JumpStorm.ts97
-rw-r--r--client/src/components/GameCanvas.svelte17
-rw-r--r--client/tsconfig.json5
-rw-r--r--client/vite.config.ts10
-rw-r--r--engine/Game.ts4
-rw-r--r--engine/components/Control.ts4
-rw-r--r--engine/config/constants.ts4
-rw-r--r--engine/entities/Entity.ts18
-rw-r--r--engine/entities/Floor.ts4
-rw-r--r--engine/entities/Player.ts20
-rw-r--r--engine/entities/index.ts7
-rw-r--r--engine/entities/names.ts4
-rw-r--r--engine/network/index.ts29
-rw-r--r--engine/systems/Input.ts5
-rw-r--r--engine/systems/NetworkUpdate.ts31
-rw-r--r--engine/utils/coding.ts27
-rw-r--r--engine/utils/index.ts1
-rw-r--r--server/src/server.ts162
-rw-r--r--server/tsconfig.json15
-rw-r--r--tsconfig.engine.json15
20 files changed, 346 insertions, 133 deletions
diff --git a/client/src/JumpStorm.ts b/client/src/JumpStorm.ts
index ae99b8e..01cc8d8 100644
--- a/client/src/JumpStorm.ts
+++ b/client/src/JumpStorm.ts
@@ -1,4 +1,5 @@
import { Game } from "@engine/Game";
+import { Entity } from "@engine/entities";
import { Grid } from "@engine/structures";
import {
WallBounds,
@@ -7,67 +8,116 @@ import {
Physics,
Input,
Collision,
- MessageQueueProvider,
- MessagePublisher,
NetworkUpdate,
} from "@engine/systems";
+import {
+ type MessageQueueProvider,
+ type MessagePublisher,
+ type MessageProcessor,
+ type Message,
+ type EntityAddBody,
+ MessageType,
+} from "@engine/network";
+import { stringify, parse } from "@engine/utils";
+
+class ClientMessageProcessor implements MessageProcessor {
+ private game: Game;
+
+ constructor(game: Game) {
+ this.game = game;
+ }
+
+ public process(message: Message) {
+ switch (message.type) {
+ case MessageType.NEW_ENTITY:
+ const entityAddBody = message.body as unknown as EntityAddBody;
+ this.game.addEntity(
+ Entity.from(entityAddBody.entityName, entityAddBody.args),
+ );
+ break;
+ }
+
+ console.log(message);
+ }
+}
class ClientSocketMessageQueueProvider implements MessageQueueProvider {
private socket: WebSocket;
- private messages: any[];
+ private messages: Message[];
constructor(socket: WebSocket) {
this.socket = socket;
this.messages = [];
this.socket.addEventListener("message", (e) => {
- console.log(e);
+ const message = parse<Message>(e.data);
+ this.messages.push(message);
});
}
- getNewMessages() {
+ public getNewMessages() {
return this.messages;
}
- clearMessages() {
+ public clearMessages() {
this.messages = [];
}
}
class ClientSocketMessagePublisher implements MessagePublisher {
private socket: WebSocket;
- private messages: any[];
+ private messages: Message[];
constructor(socket: WebSocket) {
this.socket = socket;
this.messages = [];
-
- this.socket.addEventListener("message", (e) => {
- console.log(e);
- });
}
- addMessage(_message: any) {}
+ public addMessage(message: Message) {
+ this.messages.push(message);
+ }
- publish() {}
+ public publish() {
+ this.messages.forEach((message: Message) =>
+ this.socket.send(stringify(message)),
+ );
+ }
}
export class JumpStorm {
private game: Game;
+ private clientId: string;
+
+ constructor(game: Game) {
+ this.game = game;
+ }
- constructor(ctx: CanvasRenderingContext2D) {
- this.game = new Game();
+ public async init(
+ ctx: CanvasRenderingContext2D,
+ httpMethod: string,
+ wsMethod: string,
+ host: string,
+ ) {
+ await fetch(`${httpMethod}://${host}/assign`)
+ .then((resp) => {
+ if (resp.ok) {
+ return resp.text();
+ }
+ throw resp;
+ })
+ .then((cookie) => {
+ this.clientId = cookie;
+ });
- const socket = new WebSocket("ws://localhost:8080");
- setInterval(() => socket.send(JSON.stringify({ x: 1 })), 1_000);
+ const grid = new Grid();
+
+ const socket = new WebSocket(`${wsMethod}://${host}/game`);
const clientSocketMessageQueueProvider =
new ClientSocketMessageQueueProvider(socket);
const clientSocketMessagePublisher = new ClientSocketMessagePublisher(
- socket
+ socket,
);
-
- const grid = new Grid();
-
+ const clientMessageProcessor = new ClientMessageProcessor(this.game);
[
this.createInputSystem(),
new FacingDirection(),
@@ -76,7 +126,8 @@ export class JumpStorm {
new WallBounds(ctx.canvas.width),
new NetworkUpdate(
clientSocketMessageQueueProvider,
- clientSocketMessagePublisher
+ clientSocketMessagePublisher,
+ clientMessageProcessor,
),
new Render(ctx),
].forEach((system) => this.game.addSystem(system));
@@ -93,7 +144,7 @@ export class JumpStorm {
}
private createInputSystem(): Input {
- const inputSystem = new Input();
+ const inputSystem = new Input(this.clientId);
window.addEventListener("keydown", (e) => {
if (!e.repeat) {
diff --git a/client/src/components/GameCanvas.svelte b/client/src/components/GameCanvas.svelte
index ae8c1b0..ed16f33 100644
--- a/client/src/components/GameCanvas.svelte
+++ b/client/src/components/GameCanvas.svelte
@@ -1,6 +1,7 @@
<script lang="ts">
import { onMount } from "svelte";
import { loadAssets } from "@engine/config";
+ import { Game } from "@engine/Game";
import { JumpStorm } from "../JumpStorm";
let canvas: HTMLCanvasElement;
@@ -9,16 +10,18 @@
export let width: number;
export let height: number;
- let jumpStorm: JumpStorm;
-
- onMount(() => {
+ onMount(async () => {
ctx = canvas.getContext("2d");
ctx.imageSmoothingEnabled = false;
- loadAssets().then(() => {
- jumpStorm = new JumpStorm(ctx);
- jumpStorm.play();
- });
+ await loadAssets();
+
+ const game = new Game();
+ const jumpStorm = new JumpStorm(game);
+
+ const url = new URL(document.location);
+ await jumpStorm.init(ctx, "http", "ws", url.host + "/api");
+ jumpStorm.play();
});
</script>
diff --git a/client/tsconfig.json b/client/tsconfig.json
index 781d1b3..fadebb0 100644
--- a/client/tsconfig.json
+++ b/client/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "@tsconfig/svelte/tsconfig.json",
+ "extends": ["@tsconfig/svelte/tsconfig.json", "../tsconfig.engine.json"],
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
@@ -24,8 +24,5 @@
"src/**/*.js",
"src/**/*.svelte"
],
- "paths": {
- "@engine/*": ["../engine/*"]
- },
"references": [{ "path": "./tsconfig.node.json" }]
}
diff --git a/client/vite.config.ts b/client/vite.config.ts
index 0307338..cdf1ab1 100644
--- a/client/vite.config.ts
+++ b/client/vite.config.ts
@@ -4,6 +4,16 @@ import { fileURLToPath, URL } from "node:url";
// https://vitejs.dev/config/
export default defineConfig({
+ server: {
+ proxy: {
+ "/api": {
+ target: "http://localhost:8080",
+ ws: true,
+ rewrite: (path) => path.replace(/^\/api/, ""),
+ },
+ },
+ },
+ cors: true,
plugins: [svelte()],
resolve: {
alias: {
diff --git a/engine/Game.ts b/engine/Game.ts
index 8dc5db7..301c8df 100644
--- a/engine/Game.ts
+++ b/engine/Game.ts
@@ -60,7 +60,7 @@ export class Game {
return this.systems.get(name);
}
- public doGameLoop = (timeStamp: number) => {
+ public doGameLoop(timeStamp: number) {
if (!this.running) {
return;
}
@@ -86,5 +86,5 @@ export class Game {
this.systemOrder.forEach((systemName) => {
this.systems.get(systemName)?.update(dt, this);
});
- };
+ }
}
diff --git a/engine/components/Control.ts b/engine/components/Control.ts
index a3621b0..a8dae59 100644
--- a/engine/components/Control.ts
+++ b/engine/components/Control.ts
@@ -2,13 +2,15 @@ import { Component, ComponentNames, Velocity } from ".";
export class Control extends Component {
public controlVelocityComponent: Velocity;
+ public controllableBy: string;
constructor(
+ controllableBy: string,
controlVelocityComponent: Velocity = new Velocity(),
- controllableBy: string
) {
super(ComponentNames.Control);
+ this.controllableBy = controllableBy;
this.controlVelocityComponent = controlVelocityComponent;
}
}
diff --git a/engine/config/constants.ts b/engine/config/constants.ts
index fa3f81b..e93986b 100644
--- a/engine/config/constants.ts
+++ b/engine/config/constants.ts
@@ -14,7 +14,7 @@ export namespace KeyConstants {
// value -> [key] from KeyActions
export const ActionKeys: Map<Action, string[]> = Object.keys(
- KeyActions
+ KeyActions,
).reduce((acc: Map<Action, string[]>, key) => {
const action = KeyActions[key];
@@ -42,6 +42,4 @@ export namespace Miscellaneous {
export const DEFAULT_GRID_WIDTH = 30;
export const DEFAULT_GRID_HEIGHT = 30;
-
- export const SERVER_TICK_RATE = 5 / 100;
}
diff --git a/engine/entities/Entity.ts b/engine/entities/Entity.ts
index 4e9df78..88982cb 100644
--- a/engine/entities/Entity.ts
+++ b/engine/entities/Entity.ts
@@ -1,10 +1,13 @@
+import { EntityNames, Player } from ".";
import type { Component } from "../components";
export abstract class Entity {
- public readonly id: string;
- public readonly components: Map<string, Component>;
+ public id: string;
+ public components: Map<string, Component>;
+ public name: string;
- constructor(id: string = crypto.randomUUID()) {
+ constructor(name: string, id: string = crypto.randomUUID()) {
+ this.name = name;
this.id = id;
this.components = new Map();
}
@@ -27,4 +30,13 @@ export abstract class Entity {
public hasComponent(name: string): boolean {
return this.components.has(name);
}
+
+ static from(entityName: string, args: any): Entity {
+ switch (entityName) {
+ case EntityNames.Player:
+ return new Player(args.playerId);
+ default:
+ throw new Error(".from() Entity type not implemented: " + entityName);
+ }
+ }
}
diff --git a/engine/entities/Floor.ts b/engine/entities/Floor.ts
index b204ce0..6cfc276 100644
--- a/engine/entities/Floor.ts
+++ b/engine/entities/Floor.ts
@@ -1,7 +1,7 @@
import { IMAGES, SPRITE_SPECS, Sprites, type SpriteSpec } from "../config";
import { BoundingBox, Sprite } from "../components";
import { TopCollidable } from "../components/TopCollidable";
-import { Entity } from "../entities";
+import { Entity, EntityNames } from "../entities";
export class Floor extends Entity {
private static spriteSpec: SpriteSpec = SPRITE_SPECS.get(
@@ -9,7 +9,7 @@ export class Floor extends Entity {
) as SpriteSpec;
constructor(width: number) {
- super();
+ super(EntityNames.Floor);
this.addComponent(
new Sprite(
diff --git a/engine/entities/Player.ts b/engine/entities/Player.ts
index 03fa69b..cfe4dd2 100644
--- a/engine/entities/Player.ts
+++ b/engine/entities/Player.ts
@@ -1,4 +1,4 @@
-import { Entity } from ".";
+import { Entity, EntityNames } from ".";
import { IMAGES, SPRITE_SPECS, Sprites, type SpriteSpec } from "../config";
import {
Jump,
@@ -21,11 +21,11 @@ export class Player extends Entity {
private static MOI: number = 100;
private static spriteSpec: SpriteSpec = SPRITE_SPECS.get(
- Sprites.COFFEE
+ Sprites.COFFEE,
) as SpriteSpec;
- constructor() {
- super();
+ constructor(playerId: string) {
+ super(EntityNames.Player);
this.addComponent(
new BoundingBox(
@@ -34,12 +34,12 @@ export class Player extends Entity {
y: 100,
},
{ width: Player.spriteSpec.width, height: Player.spriteSpec.height },
- 0
- )
+ 0,
+ ),
);
this.addComponent(
- new Velocity({ dCartesian: { dx: 0, dy: 0 }, dTheta: 0 })
+ new Velocity({ dCartesian: { dx: 0, dy: 0 }, dTheta: 0 }),
);
this.addComponent(new Mass(Player.MASS));
@@ -48,7 +48,7 @@ export class Player extends Entity {
this.addComponent(new Gravity());
this.addComponent(new Jump());
- this.addComponent(new Control());
+ this.addComponent(new Control(playerId));
this.addComponent(new Collide());
this.addComponent(new WallBounded());
@@ -64,8 +64,8 @@ export class Player extends Entity {
{ x: 0, y: 0 },
{ width: Player.spriteSpec.width, height: Player.spriteSpec.height },
Player.spriteSpec.msPerFrame,
- Player.spriteSpec.frames
- )
+ Player.spriteSpec.frames,
+ ),
);
this.addComponent(new FacingDirection(leftSprite, rightSprite));
diff --git a/engine/entities/index.ts b/engine/entities/index.ts
index a921512..dd3dba9 100644
--- a/engine/entities/index.ts
+++ b/engine/entities/index.ts
@@ -1,3 +1,4 @@
-export * from "./Entity";
-export * from "./Floor";
-export * from "./Player";
+export * from "./Entity";
+export * from "./Floor";
+export * from "./Player";
+export * from "./names";
diff --git a/engine/entities/names.ts b/engine/entities/names.ts
new file mode 100644
index 0000000..21594c8
--- /dev/null
+++ b/engine/entities/names.ts
@@ -0,0 +1,4 @@
+export namespace EntityNames {
+ export const Player = "Player";
+ export const Floor = "Floor";
+}
diff --git a/engine/network/index.ts b/engine/network/index.ts
new file mode 100644
index 0000000..1726ffc
--- /dev/null
+++ b/engine/network/index.ts
@@ -0,0 +1,29 @@
+export enum MessageType {
+ NEW_ENTITY = "NEW_ENTITY",
+ REMOVE_ENTITY = "REMOVE_ENTITY",
+ UPDATE_ENTITY = "UPDATE_ENTITY",
+}
+
+export type EntityAddBody = {
+ entityName: string;
+ args: any;
+};
+
+export type Message = {
+ type: MessageType;
+ body: any;
+};
+
+export interface MessageQueueProvider {
+ getNewMessages(): Message[];
+ clearMessages(): void;
+}
+
+export interface MessagePublisher {
+ addMessage(message: Message): void;
+ publish(): void;
+}
+
+export interface MessageProcessor {
+ process(message: Message): void;
+}
diff --git a/engine/systems/Input.ts b/engine/systems/Input.ts
index d9b7133..a32ba9a 100644
--- a/engine/systems/Input.ts
+++ b/engine/systems/Input.ts
@@ -12,12 +12,14 @@ import { Action } from "../interfaces";
import { System, SystemNames } from ".";
export class Input extends System {
+ public clientId: string;
private keys: Set<string>;
private actionTimeStamps: Map<Action, number>;
- constructor() {
+ constructor(clientId: string) {
super(SystemNames.Input);
+ this.clientId = clientId;
this.keys = new Set<string>();
this.actionTimeStamps = new Map<Action, number>();
}
@@ -42,6 +44,7 @@ export class Input extends System {
const controlComponent = entity.getComponent<Control>(
ComponentNames.Control,
);
+ if (controlComponent.controllableBy != this.clientId) return;
if (this.hasSomeKey(KeyConstants.ActionKeys.get(Action.MOVE_RIGHT))) {
controlComponent.controlVelocityComponent.velocity.dCartesian.dx +=
diff --git a/engine/systems/NetworkUpdate.ts b/engine/systems/NetworkUpdate.ts
index cdd6de7..6c1d3e4 100644
--- a/engine/systems/NetworkUpdate.ts
+++ b/engine/systems/NetworkUpdate.ts
@@ -1,43 +1,44 @@
import { System, SystemNames } from ".";
import { Game } from "../Game";
import { ComponentNames, NetworkUpdateable } from "../components";
-
-export interface MessageQueueProvider {
- getNewMessages(): any[];
- clearMessages(): void;
-}
-
-export interface MessagePublisher {
- addMessage(message: any): void;
- publish(): void;
-}
+import {
+ type MessageQueueProvider,
+ type MessagePublisher,
+ type MessageProcessor,
+} from "../network";
export class NetworkUpdate extends System {
private queueProvider: MessageQueueProvider;
private publisher: MessagePublisher;
+ private messageProcessor: MessageProcessor;
constructor(
queueProvider: MessageQueueProvider,
- publisher: MessagePublisher
+ publisher: MessagePublisher,
+ messageProcessor: MessageProcessor,
) {
super(SystemNames.NetworkUpdate);
this.queueProvider = queueProvider;
this.publisher = publisher;
+ this.messageProcessor = messageProcessor;
}
public update(_dt: number, game: Game) {
- const messages = this.queueProvider.getNewMessages();
- if (messages.length) console.log(messages);
+ this.queueProvider
+ .getNewMessages()
+ .forEach((message) => this.messageProcessor.process(message));
this.queueProvider.clearMessages();
game.forEachEntityWithComponent(
ComponentNames.NetworkUpdateable,
(entity) => {
const networkUpdateComponent = entity.getComponent<NetworkUpdateable>(
- ComponentNames.NetworkUpdateable
+ ComponentNames.NetworkUpdateable,
);
- }
+ },
);
+
+ this.publisher.publish();
}
}
diff --git a/engine/utils/coding.ts b/engine/utils/coding.ts
new file mode 100644
index 0000000..4c1b17f
--- /dev/null
+++ b/engine/utils/coding.ts
@@ -0,0 +1,27 @@
+const replacer = (_key: any, value: any) => {
+ if (value instanceof Map) {
+ return {
+ dataType: "Map",
+ value: Array.from(value.entries()),
+ };
+ } else {
+ return value;
+ }
+};
+
+const reviver = (_key: any, value: any) => {
+ if (typeof value === "object" && value !== null) {
+ if (value.dataType === "Map") {
+ return new Map(value.value);
+ }
+ }
+ return value;
+};
+
+export const stringify = (obj: any) => {
+ return JSON.stringify(obj, replacer);
+};
+
+export const parse = <T>(str: string) => {
+ return JSON.parse(str, reviver) as unknown as T;
+};
diff --git a/engine/utils/index.ts b/engine/utils/index.ts
index 82a0d05..b70734f 100644
--- a/engine/utils/index.ts
+++ b/engine/utils/index.ts
@@ -1,3 +1,4 @@
export * from "./rotateVector";
export * from "./dotProduct";
export * from "./clamp";
+export * from "./coding";
diff --git a/server/src/server.ts b/server/src/server.ts
index 713d3ed..b3eb1ea 100644
--- a/server/src/server.ts
+++ b/server/src/server.ts
@@ -1,109 +1,179 @@
import { Game } from "@engine/Game";
-import { Floor, Player } from "@engine/entities";
+import { EntityNames, Player } from "@engine/entities";
+import { WallBounds, Physics, Collision, NetworkUpdate } from "@engine/systems";
import {
- WallBounds,
- Physics,
- Collision,
- NetworkUpdate,
- MessageQueueProvider,
- MessagePublisher,
-} from "@engine/systems";
+ type MessageQueueProvider,
+ type MessagePublisher,
+ MessageType,
+ type MessageProcessor,
+ type Message,
+} from "@engine/network";
+import { stringify, parse } from "@engine/utils";
import { Grid } from "@engine/structures";
import { Miscellaneous } from "@engine/config";
import { Server } from "bun";
+const SERVER_PORT = 8080;
+const SERVER_TICK_RATE = (1 / 100) * 1000;
+const GAME_TOPIC = "game";
+
+type SessionData = { sessionId: string };
+
+interface ServerMessage extends Message {
+ sessionData: SessionData;
+}
+
class ServerSocketMessageReceiver implements MessageQueueProvider {
- private messages: any[];
+ private messages: ServerMessage[];
constructor() {
this.messages = [];
}
- addMessage(message: any) {
+ public addMessage(message: ServerMessage) {
this.messages.push(message);
}
- getNewMessages() {
+ public getNewMessages() {
return this.messages;
}
- clearMessages() {
+ public clearMessages() {
this.messages = [];
}
}
+class ServerMessageProcessor implements MessageProcessor {
+ constructor() {}
+
+ public process(_message: ServerMessage) {}
+}
+
class ServerSocketMessagePublisher implements MessagePublisher {
- private server: Server;
- private messages: any[];
+ private server?: Server;
+ private messages: Message[];
+
+ constructor(server?: Server) {
+ if (server) {
+ this.server = server;
+ }
- constructor(server: Server) {
- this.server = server;
this.messages = [];
}
- addMessage(_message: any) {}
+ public setServer(server: Server) {
+ this.server = server;
+ }
+
+ public addMessage(message: Message) {
+ this.messages.push(message);
+ }
- publish() {}
+ public publish() {
+ this.messages.forEach(
+ (message) => this.server?.publish(GAME_TOPIC, stringify(message)),
+ );
+
+ this.messages = [];
+ }
}
const game = new Game();
const messageReceiver = new ServerSocketMessageReceiver();
+const messagePublisher = new ServerSocketMessagePublisher();
+const messageProcessor = new ServerMessageProcessor();
+const sessionControllableEntities: Map<string, Set<string>> = new Map();
-const server = Bun.serve<{ sessionId: string }>({
- port: 8080,
- fetch: async (req, server): Promise<string> => {
- const sessionId = crypto.randomUUID();
-
- server.upgrade(req, {
- headers: {
- "Set-Cookie": `SessionId=${sessionId}`,
- },
- data: {
- sessionId,
- },
- });
-
- return sessionId;
+const server = Bun.serve<SessionData>({
+ port: SERVER_PORT,
+ fetch: async (req, server): Promise<Response> => {
+ const url = new URL(req.url);
+
+ const headers = new Headers();
+ headers.set("Access-Control-Allow-Origin", "*");
+
+ if (url.pathname == "/assign") {
+ const sessionId = crypto.randomUUID();
+ headers.set("Set-Cookie", `SessionId=${sessionId};`);
+
+ return new Response(sessionId, { headers });
+ }
+
+ const cookie = req.headers.get("cookie");
+ if (!cookie) {
+ return new Response("No session", { headers, status: 401 });
+ }
+
+ const sessionId = cookie.split(";").at(0)!.split("SessionId=").at(1);
+
+ if (url.pathname == "/game") {
+ headers.set(
+ "Set-Cookie",
+ `SessionId=${sessionId}; HttpOnly; SameSite=Strict;`,
+ );
+ server.upgrade(req, {
+ headers,
+ data: {
+ sessionId,
+ },
+ });
+
+ return new Response("upgraded", { headers });
+ }
+ if (url.pathname == "/me") {
+ return new Response(sessionId, { headers });
+ }
+
+ return new Response("Not found", { headers, status: 404 });
},
websocket: {
open(ws) {
const { sessionId } = ws.data;
if (sessionControllableEntities.has(sessionId)) {
+ // no need to add player
return;
}
- const player = new Player();
+ const player = new Player(sessionId);
game.addEntity(player);
-
sessionControllableEntities.set(sessionId, new Set(player.id));
+
+ messagePublisher.addMessage({
+ type: MessageType.NEW_ENTITY,
+ body: {
+ entityName: EntityNames.Player,
+ args: { playerId: sessionId },
+ },
+ });
+
+ ws.subscribe(GAME_TOPIC);
},
message(ws, message) {
- console.log(JSON.parse(message));
- messageReceiver.addMessage(message);
+ if (typeof message == "string") {
+ const receivedMessage = parse<ServerMessage>(message);
+ receivedMessage.sessionData = ws.data;
+
+ messageReceiver.addMessage(receivedMessage);
+ }
},
- close(ws) {},
+ close(_ws) {},
},
});
-const messagePublisher = new ServerSocketMessagePublisher(server);
+messagePublisher.setServer(server);
[
new Physics(),
new Collision(new Grid()),
new WallBounds(Miscellaneous.WIDTH),
- new NetworkUpdate(messageReceiver, messagePublisher),
+ new NetworkUpdate(messageReceiver, messagePublisher, messageProcessor),
].forEach((system) => game.addSystem(system));
-[new Floor(160), new Player()].forEach((entity) => game.addEntity(entity));
-
game.start();
-
setInterval(() => {
game.doGameLoop(performance.now());
-}, Miscellaneous.SERVER_TICK_RATE);
-
-const sessionControllableEntities: Map<string, Set<string>> = new Map();
+}, SERVER_TICK_RATE);
console.log(`Listening on ${server.hostname}:${server.port}`);
diff --git a/server/tsconfig.json b/server/tsconfig.json
index 8cc9ad3..52f0ddc 100644
--- a/server/tsconfig.json
+++ b/server/tsconfig.json
@@ -1,4 +1,5 @@
{
+ "extends": "../tsconfig.engine.json",
"compilerOptions": {
// add Bun type definitions
"types": ["bun-types"],
@@ -21,18 +22,6 @@
// best practices
"strict": true,
"forceConsistentCasingInFileNames": true,
- "skipLibCheck": true,
-
- // engine path
- "paths": {
- "@engine/*": ["../engine/*"],
- "@engine/components": ["../engine/components"],
- "@engine/config": ["../engine/config"],
- "@engine/entities": ["../engine/entities"],
- "@engine/interfaces": ["../engine/interfaces"],
- "@engine/structures": ["../engine/structures"],
- "@engine/systems": ["../engine/systems"],
- "@engine/utils": ["../engine/utils"],
- }
+ "skipLibCheck": true
}
}
diff --git a/tsconfig.engine.json b/tsconfig.engine.json
new file mode 100644
index 0000000..52482a2
--- /dev/null
+++ b/tsconfig.engine.json
@@ -0,0 +1,15 @@
+{
+ "compilerOptions": {
+ "paths": {
+ "@engine/*": ["./engine/*"],
+ "@engine/components": ["./engine/components"],
+ "@engine/config": ["./engine/config"],
+ "@engine/entities": ["./engine/entities"],
+ "@engine/interfaces": ["./engine/interfaces"],
+ "@engine/structures": ["./engine/structures"],
+ "@engine/systems": ["./engine/systems"],
+ "@engine/utils": ["./engine/utils"],
+ "@engine/network": ["./engine/network"]
+ }
+ }
+}