From dec7b614d895a1b507137e4a96a8999ff63aa179 Mon Sep 17 00:00:00 2001
From: Elizabeth Hunt <elizabeth.hunt@simponic.xyz>
Date: Wed, 23 Aug 2023 19:44:59 -0600
Subject: holy fuck we actually got somewhere

---
 client/src/components/GameCanvas.svelte | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

(limited to 'client/src/components/GameCanvas.svelte')

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>
 
-- 
cgit v1.2.3-70-g09d2


From 773ce84f4bf559337e132edd7fcce02a0a2598fd Mon Sep 17 00:00:00 2001
From: Elizabeth Hunt <elizabeth.hunt@simponic.xyz>
Date: Fri, 25 Aug 2023 16:48:17 -0600
Subject: prettier formatting

---
 .prettierrc                                        |   4 +
 client/.eslintrc.js                                |   6 +-
 client/index.html                                  |   2 +-
 client/public/css/colors.css                       |   2 +-
 client/public/css/style.css                        |  10 +-
 client/public/css/tf.css                           |   2 +-
 client/public/css/theme.css                        |   2 +-
 client/src/JumpStorm.ts                            |  69 +++++++++-----
 client/src/components/GameCanvas.svelte            |   5 +-
 client/src/components/LeaderBoard.svelte           |   2 +-
 client/src/main.ts                                 |   4 +-
 client/src/routes/Home.svelte                      |   3 +-
 client/svelte.config.js                            |   6 +-
 client/vite.config.ts                              |  22 ++---
 engine/Game.ts                                     |  10 +-
 engine/components/BoundingBox.ts                   |  22 ++---
 engine/components/Collide.ts                       |   2 +-
 engine/components/Control.ts                       |   4 +-
 engine/components/FacingDirection.ts               |   2 +-
 engine/components/Forces.ts                        |   6 +-
 engine/components/Gravity.ts                       |   4 +-
 engine/components/Jump.ts                          |   2 +-
 engine/components/Mass.ts                          |   2 +-
 engine/components/Moment.ts                        |   2 +-
 engine/components/NetworkUpdateable.ts             |   2 +-
 engine/components/Sprite.ts                        |  20 ++--
 engine/components/TopCollidable.ts                 |   2 +-
 engine/components/Velocity.ts                      |   8 +-
 engine/components/WallBounded.ts                   |   2 +-
 engine/components/index.ts                         |  32 +++----
 engine/components/names.ts                         |  28 +++---
 engine/config/assets.ts                            |  16 ++--
 engine/config/constants.ts                         |   6 +-
 engine/config/index.ts                             |   6 +-
 engine/config/sprites.ts                           |  16 ++--
 engine/entities/Entity.ts                          |  12 ++-
 engine/entities/Floor.ts                           |  24 ++---
 engine/entities/Player.ts                          |  24 ++---
 engine/entities/index.ts                           |   8 +-
 engine/entities/names.ts                           |   4 +-
 engine/interfaces/Action.ts                        |   2 +-
 engine/interfaces/Direction.ts                     |   8 +-
 engine/interfaces/Draw.ts                          |   2 +-
 engine/interfaces/index.ts                         |   8 +-
 engine/network/index.ts                            |   6 +-
 engine/structures/Grid.ts                          |  16 ++--
 engine/structures/QuadTree.ts                      |  22 ++---
 .../RefreshingCollisionFinderBehavior.ts           |  10 +-
 engine/structures/index.ts                         |   6 +-
 engine/systems/Collision.ts                        |  54 +++++------
 engine/systems/FacingDirection.ts                  |  14 +--
 engine/systems/Input.ts                            |  20 ++--
 engine/systems/NetworkUpdate.ts                    |  16 ++--
 engine/systems/Physics.ts                          |  32 +++----
 engine/systems/Render.ts                           |  16 ++--
 engine/systems/System.ts                           |   2 +-
 engine/systems/WallBounds.ts                       |  20 ++--
 engine/systems/index.ts                            |  18 ++--
 engine/systems/names.ts                            |  14 +--
 engine/utils/coding.ts                             |   8 +-
 engine/utils/dotProduct.ts                         |   2 +-
 engine/utils/index.ts                              |   8 +-
 engine/utils/rotateVector.ts                       |   4 +-
 server/package.json                                |   3 +-
 server/src/server.ts                               | 104 +++++++++++++--------
 65 files changed, 429 insertions(+), 391 deletions(-)
 create mode 100644 .prettierrc

(limited to 'client/src/components/GameCanvas.svelte')

diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..32ebab4
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,4 @@
+{
+  "singleQuote": true,
+  "trailingComma": "none"
+}
diff --git a/client/.eslintrc.js b/client/.eslintrc.js
index f200fbf..a9b1e2d 100644
--- a/client/.eslintrc.js
+++ b/client/.eslintrc.js
@@ -1,11 +1,11 @@
 module.exports = {
   extends: [
     // add more generic rule sets here, such as:
-    "eslint:recommended",
-    "plugin:svelte/recommended",
+    'eslint:recommended',
+    'plugin:svelte/recommended'
   ],
   rules: {
     // override/add rules settings here, such as:
     // 'svelte/rule-name': 'error'
-  },
+  }
 };
diff --git a/client/index.html b/client/index.html
index 00b94e7..892a3af 100644
--- a/client/index.html
+++ b/client/index.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!doctype html>
 <html lang="en">
   <head>
     <meta charset="UTF-8" />
diff --git a/client/public/css/colors.css b/client/public/css/colors.css
index 067ddcd..6108028 100644
--- a/client/public/css/colors.css
+++ b/client/public/css/colors.css
@@ -10,7 +10,7 @@
   --orange: #af3a03;
 }
 
-[data-theme="dark"] {
+[data-theme='dark'] {
   --bg: #282828;
   --text: #f9f5d7;
   --red: #fb4934;
diff --git a/client/public/css/style.css b/client/public/css/style.css
index cdfef76..4dfe605 100644
--- a/client/public/css/style.css
+++ b/client/public/css/style.css
@@ -1,15 +1,15 @@
-@import url("./theme.css");
-@import url("./tf.css");
+@import url('./theme.css');
+@import url('./tf.css');
 
 @font-face {
-  font-family: "scientifica";
-  src: url("/fonts/scientifica.ttf");
+  font-family: 'scientifica';
+  src: url('/fonts/scientifica.ttf');
 }
 
 * {
   padding: 0;
   margin: 0;
-  font-family: "scientifica", monospace;
+  font-family: 'scientifica', monospace;
   transition: background 0.2s ease-in-out;
   font-smooth: never;
 }
diff --git a/client/public/css/tf.css b/client/public/css/tf.css
index c1acd72..855fe0d 100644
--- a/client/public/css/tf.css
+++ b/client/public/css/tf.css
@@ -17,7 +17,7 @@
     rgba(162, 254, 254, 1) 100%
   );
 
-  content: "";
+  content: '';
   width: 100%;
   height: 100%;
   top: 0;
diff --git a/client/public/css/theme.css b/client/public/css/theme.css
index c65b2a8..eeb15ee 100644
--- a/client/public/css/theme.css
+++ b/client/public/css/theme.css
@@ -1,4 +1,4 @@
-@import url("./colors.css");
+@import url('./colors.css');
 
 .primary {
   color: var(--aqua);
diff --git a/client/src/JumpStorm.ts b/client/src/JumpStorm.ts
index 01cc8d8..92bddcf 100644
--- a/client/src/JumpStorm.ts
+++ b/client/src/JumpStorm.ts
@@ -1,6 +1,6 @@
-import { Game } from "@engine/Game";
-import { Entity } from "@engine/entities";
-import { Grid } from "@engine/structures";
+import { Game } from '@engine/Game';
+import { Entity, Floor } from '@engine/entities';
+import { Grid } from '@engine/structures';
 import {
   WallBounds,
   FacingDirection,
@@ -8,17 +8,19 @@ import {
   Physics,
   Input,
   Collision,
-  NetworkUpdate,
-} from "@engine/systems";
+  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";
+  MessageType
+} from '@engine/network';
+import { stringify, parse } from '@engine/utils';
+import { BoundingBox, Sprite } from '@engine/components';
+import { Miscellaneous } from '@engine/config';
 
 class ClientMessageProcessor implements MessageProcessor {
   private game: Game;
@@ -29,14 +31,19 @@ class ClientMessageProcessor implements MessageProcessor {
 
   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),
+      case MessageType.NEW_ENTITIES:
+        const entityAdditions = message.body as unknown as EntityAddBody[];
+        entityAdditions.forEach((addBody) =>
+          this.game.addEntity(Entity.from(addBody.entityName, addBody.args))
         );
         break;
+      case MessageType.REMOVE_ENTITIES:
+        const ids = message.body as unknown as string[];
+        ids.forEach((id) => this.game.removeEntity(id));
+        break;
+      default:
+        break;
     }
-
     console.log(message);
   }
 }
@@ -49,9 +56,9 @@ class ClientSocketMessageQueueProvider implements MessageQueueProvider {
     this.socket = socket;
     this.messages = [];
 
-    this.socket.addEventListener("message", (e) => {
-      const message = parse<Message>(e.data);
-      this.messages.push(message);
+    this.socket.addEventListener('message', (e) => {
+      const messages = parse<Message[]>(e.data);
+      this.messages = this.messages.concat(messages);
     });
   }
 
@@ -79,7 +86,7 @@ class ClientSocketMessagePublisher implements MessagePublisher {
 
   public publish() {
     this.messages.forEach((message: Message) =>
-      this.socket.send(stringify(message)),
+      this.socket.send(stringify(message))
     );
   }
 }
@@ -96,7 +103,7 @@ export class JumpStorm {
     ctx: CanvasRenderingContext2D,
     httpMethod: string,
     wsMethod: string,
-    host: string,
+    host: string
   ) {
     await fetch(`${httpMethod}://${host}/assign`)
       .then((resp) => {
@@ -115,7 +122,7 @@ export class JumpStorm {
     const clientSocketMessageQueueProvider =
       new ClientSocketMessageQueueProvider(socket);
     const clientSocketMessagePublisher = new ClientSocketMessagePublisher(
-      socket,
+      socket
     );
     const clientMessageProcessor = new ClientMessageProcessor(this.game);
     [
@@ -123,14 +130,28 @@ export class JumpStorm {
       new FacingDirection(),
       new Physics(),
       new Collision(grid),
-      new WallBounds(ctx.canvas.width),
+      new WallBounds(),
       new NetworkUpdate(
         clientSocketMessageQueueProvider,
         clientSocketMessagePublisher,
-        clientMessageProcessor,
+        clientMessageProcessor
       ),
-      new Render(ctx),
+      new Render(ctx)
     ].forEach((system) => this.game.addSystem(system));
+
+    const floor = new Floor(160);
+    const floorHeight = 40;
+
+    floor.addComponent(
+      new BoundingBox(
+        {
+          x: Miscellaneous.WIDTH / 2,
+          y: Miscellaneous.HEIGHT - floorHeight / 2
+        },
+        { width: Miscellaneous.WIDTH, height: floorHeight }
+      )
+    );
+    this.game.addEntity(floor);
   }
 
   public play() {
@@ -146,13 +167,13 @@ export class JumpStorm {
   private createInputSystem(): Input {
     const inputSystem = new Input(this.clientId);
 
-    window.addEventListener("keydown", (e) => {
+    window.addEventListener('keydown', (e) => {
       if (!e.repeat) {
         inputSystem.keyPressed(e.key);
       }
     });
 
-    window.addEventListener("keyup", (e) => inputSystem.keyReleased(e.key));
+    window.addEventListener('keyup', (e) => inputSystem.keyReleased(e.key));
 
     return inputSystem;
   }
diff --git a/client/src/components/GameCanvas.svelte b/client/src/components/GameCanvas.svelte
index ed16f33..ea7dd15 100644
--- a/client/src/components/GameCanvas.svelte
+++ b/client/src/components/GameCanvas.svelte
@@ -3,7 +3,7 @@
   import { loadAssets } from "@engine/config";
   import { Game } from "@engine/Game";
   import { JumpStorm } from "../JumpStorm";
-  
+
   let canvas: HTMLCanvasElement;
   let ctx: CanvasRenderingContext2D;
 
@@ -19,8 +19,7 @@
     const game = new Game();
     const jumpStorm = new JumpStorm(game);
 
-    const url = new URL(document.location);
-    await jumpStorm.init(ctx, "http", "ws", url.host  + "/api");
+    await jumpStorm.init(ctx, "http", "ws", document.location.host + "/api");
     jumpStorm.play();
   });
 </script>
diff --git a/client/src/components/LeaderBoard.svelte b/client/src/components/LeaderBoard.svelte
index 8343c56..2f3e411 100644
--- a/client/src/components/LeaderBoard.svelte
+++ b/client/src/components/LeaderBoard.svelte
@@ -3,7 +3,7 @@
 
   const MAX_ENTRIES = 8;
 
-  export let entries: { name: string, score: number }[] = [];
+  export let entries: { name: string; score: number }[] = [];
 </script>
 
 <div class="leaderboard">
diff --git a/client/src/main.ts b/client/src/main.ts
index 5332616..aa7431f 100644
--- a/client/src/main.ts
+++ b/client/src/main.ts
@@ -1,7 +1,7 @@
-import App from "./App.svelte";
+import App from './App.svelte';
 
 const app = new App({
-  target: document.getElementById("app"),
+  target: document.getElementById('app')
 });
 
 export default app;
diff --git a/client/src/routes/Home.svelte b/client/src/routes/Home.svelte
index 9ada10e..71ad324 100644
--- a/client/src/routes/Home.svelte
+++ b/client/src/routes/Home.svelte
@@ -3,10 +3,9 @@
   import LeaderBoard from "../components/LeaderBoard.svelte";
 
   import { Miscellaneous } from "@engine/config";
-  
+
   let width: number = Miscellaneous.WIDTH;
   let height: number = Miscellaneous.HEIGHT;
-  
 </script>
 
 <div class="centered-game">
diff --git a/client/svelte.config.js b/client/svelte.config.js
index b0683fd..db735be 100644
--- a/client/svelte.config.js
+++ b/client/svelte.config.js
@@ -1,7 +1,7 @@
-import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
+import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
 
 export default {
   // Consult https://svelte.dev/docs#compile-time-svelte-preprocess
   // for more information about preprocessors
-  preprocess: vitePreprocess(),
-}
+  preprocess: vitePreprocess()
+};
diff --git a/client/vite.config.ts b/client/vite.config.ts
index cdf1ab1..d8b999c 100644
--- a/client/vite.config.ts
+++ b/client/vite.config.ts
@@ -1,23 +1,23 @@
-import { defineConfig } from "vite";
-import { svelte } from "@sveltejs/vite-plugin-svelte";
-import { fileURLToPath, URL } from "node:url";
+import { defineConfig } from 'vite';
+import { svelte } from '@sveltejs/vite-plugin-svelte';
+import { fileURLToPath, URL } from 'node:url';
 
 // https://vitejs.dev/config/
 export default defineConfig({
   server: {
     proxy: {
-      "/api": {
-        target: "http://localhost:8080",
+      '/api': {
+        target: 'http://localhost:8080',
         ws: true,
-        rewrite: (path) => path.replace(/^\/api/, ""),
-      },
-    },
+        rewrite: (path) => path.replace(/^\/api/, '')
+      }
+    }
   },
   cors: true,
   plugins: [svelte()],
   resolve: {
     alias: {
-      "@engine": fileURLToPath(new URL("../engine", import.meta.url)),
-    },
-  },
+      '@engine': fileURLToPath(new URL('../engine', import.meta.url))
+    }
+  }
 });
diff --git a/engine/Game.ts b/engine/Game.ts
index 301c8df..cdd3507 100644
--- a/engine/Game.ts
+++ b/engine/Game.ts
@@ -1,5 +1,5 @@
-import { Entity } from "./entities";
-import { System } from "./systems";
+import { Entity } from './entities';
+import { System } from './systems';
 
 export class Game {
   private systemOrder: string[];
@@ -39,7 +39,7 @@ export class Game {
 
   public forEachEntityWithComponent(
     componentName: string,
-    callback: (entity: Entity) => void,
+    callback: (entity: Entity) => void
   ) {
     this.componentEntities.get(componentName)?.forEach((entityId) => {
       const entity = this.getEntity(entityId);
@@ -75,12 +75,12 @@ export class Game {
         if (!this.componentEntities.has(component.name)) {
           this.componentEntities.set(
             component.name,
-            new Set<string>([entity.id]),
+            new Set<string>([entity.id])
           );
           return;
         }
         this.componentEntities.get(component.name)?.add(entity.id);
-      }),
+      })
     );
 
     this.systemOrder.forEach((systemName) => {
diff --git a/engine/components/BoundingBox.ts b/engine/components/BoundingBox.ts
index 26b404d..dbe083e 100644
--- a/engine/components/BoundingBox.ts
+++ b/engine/components/BoundingBox.ts
@@ -1,6 +1,6 @@
-import { Component, ComponentNames } from ".";
-import type { Coord2D, Dimension2D } from "../interfaces";
-import { dotProduct, rotateVector } from "../utils";
+import { Component, ComponentNames } from '.';
+import type { Coord2D, Dimension2D } from '../interfaces';
+import { dotProduct, rotateVector } from '../utils';
 
 export class BoundingBox extends Component {
   public center: Coord2D;
@@ -48,8 +48,8 @@ export class BoundingBox extends Component {
               const projection = dotProduct(normal, vertex);
               return [Math.min(min, projection), Math.max(max, projection)];
             },
-            [Infinity, -Infinity],
-          ),
+            [Infinity, -Infinity]
+          )
         );
 
         if (maxThis < minBox || maxBox < minThis) return false;
@@ -64,14 +64,14 @@ export class BoundingBox extends Component {
       { x: -this.dimension.width / 2, y: -this.dimension.height / 2 },
       { x: -this.dimension.width / 2, y: this.dimension.height / 2 },
       { x: this.dimension.width / 2, y: this.dimension.height / 2 },
-      { x: this.dimension.width / 2, y: -this.dimension.height / 2 },
+      { x: this.dimension.width / 2, y: -this.dimension.height / 2 }
     ]
       .map((vertex) => rotateVector(vertex, this.rotation)) // rotate
       .map((vertex) => {
         // translate
         return {
           x: vertex.x + this.center.x,
-          y: vertex.y + this.center.y,
+          y: vertex.y + this.center.y
         };
       });
   }
@@ -92,28 +92,28 @@ export class BoundingBox extends Component {
     if (rads <= Math.PI / 2) {
       return {
         width: Math.abs(height * Math.sin(rads) + width * Math.cos(rads)),
-        height: Math.abs(width * Math.sin(rads) + height * Math.cos(rads)),
+        height: Math.abs(width * Math.sin(rads) + height * Math.cos(rads))
       };
     }
 
     rads -= Math.PI / 2;
     return {
       width: Math.abs(height * Math.cos(rads) + width * Math.sin(rads)),
-      height: Math.abs(width * Math.cos(rads) + height * Math.sin(rads)),
+      height: Math.abs(width * Math.cos(rads) + height * Math.sin(rads))
     };
   }
 
   public getTopLeft(): Coord2D {
     return {
       x: this.center.x - this.dimension.width / 2,
-      y: this.center.y - this.dimension.height / 2,
+      y: this.center.y - this.dimension.height / 2
     };
   }
 
   public getBottomRight(): Coord2D {
     return {
       x: this.center.x + this.dimension.width / 2,
-      y: this.center.y + this.dimension.height / 2,
+      y: this.center.y + this.dimension.height / 2
     };
   }
 }
diff --git a/engine/components/Collide.ts b/engine/components/Collide.ts
index 889ecf8..ed72b92 100644
--- a/engine/components/Collide.ts
+++ b/engine/components/Collide.ts
@@ -1,4 +1,4 @@
-import { Component, ComponentNames } from ".";
+import { Component, ComponentNames } from '.';
 
 export class Collide extends Component {
   constructor() {
diff --git a/engine/components/Control.ts b/engine/components/Control.ts
index a8dae59..beec82c 100644
--- a/engine/components/Control.ts
+++ b/engine/components/Control.ts
@@ -1,4 +1,4 @@
-import { Component, ComponentNames, Velocity } from ".";
+import { Component, ComponentNames, Velocity } from '.';
 
 export class Control extends Component {
   public controlVelocityComponent: Velocity;
@@ -6,7 +6,7 @@ export class Control extends Component {
 
   constructor(
     controllableBy: string,
-    controlVelocityComponent: Velocity = new Velocity(),
+    controlVelocityComponent: Velocity = new Velocity()
   ) {
     super(ComponentNames.Control);
 
diff --git a/engine/components/FacingDirection.ts b/engine/components/FacingDirection.ts
index 1c701a3..8c2a9d2 100644
--- a/engine/components/FacingDirection.ts
+++ b/engine/components/FacingDirection.ts
@@ -1,4 +1,4 @@
-import { Component, ComponentNames, Sprite } from ".";
+import { Component, ComponentNames, Sprite } from '.';
 
 export class FacingDirection extends Component {
   public readonly facingLeftSprite: Sprite;
diff --git a/engine/components/Forces.ts b/engine/components/Forces.ts
index 91ae1c1..e397985 100644
--- a/engine/components/Forces.ts
+++ b/engine/components/Forces.ts
@@ -1,6 +1,6 @@
-import type { Force2D } from "../interfaces";
-import { Component } from "./Component";
-import { ComponentNames } from ".";
+import type { Force2D } from '../interfaces';
+import { Component } from './Component';
+import { ComponentNames } from '.';
 
 /**
  * A list of forces and torque, (in newtons, and newton-meters respectively)
diff --git a/engine/components/Gravity.ts b/engine/components/Gravity.ts
index 89fcb67..dd6dd2e 100644
--- a/engine/components/Gravity.ts
+++ b/engine/components/Gravity.ts
@@ -1,7 +1,7 @@
-import { ComponentNames, Component } from ".";
+import { ComponentNames, Component } from '.';
 
 export class Gravity extends Component {
-  private static DEFAULT_TERMINAL_VELOCITY = 5;
+  private static DEFAULT_TERMINAL_VELOCITY = 4.5;
 
   public terminalVelocity: number;
 
diff --git a/engine/components/Jump.ts b/engine/components/Jump.ts
index 0b40767..6cbfb08 100644
--- a/engine/components/Jump.ts
+++ b/engine/components/Jump.ts
@@ -1,4 +1,4 @@
-import { Component, ComponentNames } from ".";
+import { Component, ComponentNames } from '.';
 
 export class Jump extends Component {
   public canJump: boolean;
diff --git a/engine/components/Mass.ts b/engine/components/Mass.ts
index daa2d71..a7f98fd 100644
--- a/engine/components/Mass.ts
+++ b/engine/components/Mass.ts
@@ -1,4 +1,4 @@
-import { Component, ComponentNames } from ".";
+import { Component, ComponentNames } from '.';
 
 export class Mass extends Component {
   public mass: number;
diff --git a/engine/components/Moment.ts b/engine/components/Moment.ts
index 3d0dd2f..cd76294 100644
--- a/engine/components/Moment.ts
+++ b/engine/components/Moment.ts
@@ -1,4 +1,4 @@
-import { Component, ComponentNames } from ".";
+import { Component, ComponentNames } from '.';
 
 export class Moment extends Component {
   public inertia: number;
diff --git a/engine/components/NetworkUpdateable.ts b/engine/components/NetworkUpdateable.ts
index 980b064..7fb6d18 100644
--- a/engine/components/NetworkUpdateable.ts
+++ b/engine/components/NetworkUpdateable.ts
@@ -1,4 +1,4 @@
-import { Component, ComponentNames } from ".";
+import { Component, ComponentNames } from '.';
 
 export class NetworkUpdateable extends Component {
   public isPublish: boolean;
diff --git a/engine/components/Sprite.ts b/engine/components/Sprite.ts
index bdb4982..36b944e 100644
--- a/engine/components/Sprite.ts
+++ b/engine/components/Sprite.ts
@@ -1,5 +1,5 @@
-import { Component, ComponentNames } from ".";
-import type { Dimension2D, DrawArgs, Coord2D } from "../interfaces";
+import { Component, ComponentNames } from '.';
+import type { Dimension2D, DrawArgs, Coord2D } from '../interfaces';
 
 export class Sprite extends Component {
   private sheet: HTMLImageElement;
@@ -17,7 +17,7 @@ export class Sprite extends Component {
     spriteImgPos: Coord2D,
     spriteImgDimensions: Dimension2D,
     msPerFrame: number,
-    numFrames: number,
+    numFrames: number
   ) {
     super(ComponentNames.Sprite);
 
@@ -56,12 +56,12 @@ export class Sprite extends Component {
     ctx.drawImage(
       this.sheet,
       ...this.getSpriteArgs(),
-      ...this.getDrawArgs(drawArgs),
+      ...this.getDrawArgs(drawArgs)
     );
 
     if (tint) {
       ctx.globalAlpha = 0.5;
-      ctx.globalCompositeOperation = "source-atop";
+      ctx.globalCompositeOperation = 'source-atop';
       ctx.fillStyle = tint;
       ctx.fillRect(...this.getDrawArgs(drawArgs));
     }
@@ -74,19 +74,23 @@ export class Sprite extends Component {
       this.spriteImgPos.x + this.currentFrame * this.spriteImgDimensions.width,
       this.spriteImgPos.y,
       this.spriteImgDimensions.width,
-      this.spriteImgDimensions.height,
+      this.spriteImgDimensions.height
     ];
   }
 
   private getDrawArgs({
     center,
-    dimension,
+    dimension
   }: DrawArgs): [dx: number, dy: number, dw: number, dh: number] {
     return [
       center.x - dimension.width / 2,
       center.y - dimension.height / 2,
       dimension.width,
-      dimension.height,
+      dimension.height
     ];
   }
+
+  public getSpriteDimensions() {
+    return this.spriteImgDimensions;
+  }
 }
diff --git a/engine/components/TopCollidable.ts b/engine/components/TopCollidable.ts
index 7fb147d..05ce484 100644
--- a/engine/components/TopCollidable.ts
+++ b/engine/components/TopCollidable.ts
@@ -1,4 +1,4 @@
-import { Component, ComponentNames } from ".";
+import { Component, ComponentNames } from '.';
 
 export class TopCollidable extends Component {
   constructor() {
diff --git a/engine/components/Velocity.ts b/engine/components/Velocity.ts
index aec0c03..0071891 100644
--- a/engine/components/Velocity.ts
+++ b/engine/components/Velocity.ts
@@ -1,12 +1,12 @@
-import type { Velocity2D } from "../interfaces";
-import { Component } from "./Component";
-import { ComponentNames } from ".";
+import type { Velocity2D } from '../interfaces';
+import { Component } from './Component';
+import { ComponentNames } from '.';
 
 export class Velocity extends Component {
   public velocity: Velocity2D;
 
   constructor(
-    velocity: Velocity2D = { dCartesian: { dx: 0, dy: 0 }, dTheta: 0 },
+    velocity: Velocity2D = { dCartesian: { dx: 0, dy: 0 }, dTheta: 0 }
   ) {
     super(ComponentNames.Velocity);
 
diff --git a/engine/components/WallBounded.ts b/engine/components/WallBounded.ts
index 5f787e1..c1745a8 100644
--- a/engine/components/WallBounded.ts
+++ b/engine/components/WallBounded.ts
@@ -1,4 +1,4 @@
-import { Component, ComponentNames } from ".";
+import { Component, ComponentNames } from '.';
 
 export class WallBounded extends Component {
   constructor() {
diff --git a/engine/components/index.ts b/engine/components/index.ts
index 90f4965..6d7c1e5 100644
--- a/engine/components/index.ts
+++ b/engine/components/index.ts
@@ -1,16 +1,16 @@
-export * from "./Component";
-export * from "./BoundingBox";
-export * from "./Velocity";
-export * from "./Forces";
-export * from "./Sprite";
-export * from "./FacingDirection";
-export * from "./Jump";
-export * from "./TopCollidable";
-export * from "./Collide";
-export * from "./Control";
-export * from "./WallBounded";
-export * from "./Gravity";
-export * from "./Mass";
-export * from "./Moment";
-export * from "./NetworkUpdateable";
-export * from "./names";
+export * from './Component';
+export * from './BoundingBox';
+export * from './Velocity';
+export * from './Forces';
+export * from './Sprite';
+export * from './FacingDirection';
+export * from './Jump';
+export * from './TopCollidable';
+export * from './Collide';
+export * from './Control';
+export * from './WallBounded';
+export * from './Gravity';
+export * from './Mass';
+export * from './Moment';
+export * from './NetworkUpdateable';
+export * from './names';
diff --git a/engine/components/names.ts b/engine/components/names.ts
index 02ee064..97b4edd 100644
--- a/engine/components/names.ts
+++ b/engine/components/names.ts
@@ -1,16 +1,16 @@
 export namespace ComponentNames {
-  export const Sprite = "Sprite";
-  export const BoundingBox = "BoundingBox";
-  export const Velocity = "Velocity";
-  export const FacingDirection = "FacingDirection";
-  export const Control = "Control";
-  export const Jump = "Jump";
-  export const TopCollidable = "TopCollidable";
-  export const Collide = "Collide";
-  export const WallBounded = "WallBounded";
-  export const Gravity = "Gravity";
-  export const Forces = "Forces";
-  export const Mass = "Mass";
-  export const Moment = "Moment";
-  export const NetworkUpdateable = "NetworkUpdateable";
+  export const Sprite = 'Sprite';
+  export const BoundingBox = 'BoundingBox';
+  export const Velocity = 'Velocity';
+  export const FacingDirection = 'FacingDirection';
+  export const Control = 'Control';
+  export const Jump = 'Jump';
+  export const TopCollidable = 'TopCollidable';
+  export const Collide = 'Collide';
+  export const WallBounded = 'WallBounded';
+  export const Gravity = 'Gravity';
+  export const Forces = 'Forces';
+  export const Mass = 'Mass';
+  export const Moment = 'Moment';
+  export const NetworkUpdateable = 'NetworkUpdateable';
 }
diff --git a/engine/config/assets.ts b/engine/config/assets.ts
index 173bab3..289f181 100644
--- a/engine/config/assets.ts
+++ b/engine/config/assets.ts
@@ -1,10 +1,10 @@
-import type { SpriteSpec } from "./sprites";
-import { SPRITE_SPECS } from "./sprites";
+import type { SpriteSpec } from './sprites';
+import { SPRITE_SPECS } from './sprites';
 
 export const IMAGES = new Map<string, HTMLImageElement>();
 
 export const loadSpritesIntoImageElements = (
-  spriteSpecs: Partial<SpriteSpec>[],
+  spriteSpecs: Partial<SpriteSpec>[]
 ): Promise<void>[] => {
   const spritePromises: Promise<void>[] = [];
 
@@ -17,13 +17,13 @@ export const loadSpritesIntoImageElements = (
       spritePromises.push(
         new Promise((resolve) => {
           img.onload = () => resolve();
-        }),
+        })
       );
     }
 
     if (spriteSpec.states) {
       spritePromises.push(
-        ...loadSpritesIntoImageElements(Array.from(spriteSpec.states.values())),
+        ...loadSpritesIntoImageElements(Array.from(spriteSpec.states.values()))
       );
     }
   }
@@ -35,8 +35,8 @@ export const loadAssets = () =>
   Promise.all([
     ...loadSpritesIntoImageElements(
       Array.from(SPRITE_SPECS.keys()).map(
-        (key) => SPRITE_SPECS.get(key) as SpriteSpec,
-      ),
-    ),
+        (key) => SPRITE_SPECS.get(key) as SpriteSpec
+      )
+    )
     // TODO: Sound
   ]);
diff --git a/engine/config/constants.ts b/engine/config/constants.ts
index e93986b..45b0301 100644
--- a/engine/config/constants.ts
+++ b/engine/config/constants.ts
@@ -1,4 +1,4 @@
-import { Action } from "../interfaces";
+import { Action } from '../interfaces';
 
 export namespace KeyConstants {
   export const KeyActions: Record<string, Action> = {
@@ -10,11 +10,13 @@ export namespace KeyConstants {
 
     w: Action.JUMP,
     ArrowUp: Action.JUMP,
+
+    ' ': Action.JUMP
   };
 
   // value -> [key] from KeyActions
   export const ActionKeys: Map<Action, string[]> = Object.keys(
-    KeyActions,
+    KeyActions
   ).reduce((acc: Map<Action, string[]>, key) => {
     const action = KeyActions[key];
 
diff --git a/engine/config/index.ts b/engine/config/index.ts
index 7a1052a..03b2246 100644
--- a/engine/config/index.ts
+++ b/engine/config/index.ts
@@ -1,3 +1,3 @@
-export * from "./constants";
-export * from "./assets.ts";
-export * from "./sprites.ts";
+export * from './constants';
+export * from './assets.ts';
+export * from './sprites.ts';
diff --git a/engine/config/sprites.ts b/engine/config/sprites.ts
index 1f65c18..e5fcd31 100644
--- a/engine/config/sprites.ts
+++ b/engine/config/sprites.ts
@@ -1,7 +1,7 @@
 export enum Sprites {
   FLOOR,
   TRAMPOLINE,
-  COFFEE,
+  COFFEE
 }
 
 export interface SpriteSpec {
@@ -22,12 +22,12 @@ const floorSpriteSpec = {
   height: 40,
   frames: 3,
   msPerFrame: 125,
-  states: new Map<number, Partial<SpriteSpec>>(),
+  states: new Map<number, Partial<SpriteSpec>>()
 };
 [40, 80, 120, 160].forEach((width) => {
   floorSpriteSpec.states.set(width, {
     width,
-    sheet: `/assets/floor_tile_${width}.png`,
+    sheet: `/assets/floor_tile_${width}.png`
   });
 });
 SPRITE_SPECS.set(Sprites.FLOOR, floorSpriteSpec);
@@ -37,12 +37,12 @@ const coffeeSpriteSpec = {
   width: 60,
   height: 45,
   frames: 3,
-  states: new Map<string, Partial<SpriteSpec>>(),
+  states: new Map<string, Partial<SpriteSpec>>()
 };
-coffeeSpriteSpec.states.set("LEFT", {
-  sheet: "/assets/coffee_left.png",
+coffeeSpriteSpec.states.set('LEFT', {
+  sheet: '/assets/coffee_left.png'
 });
-coffeeSpriteSpec.states.set("RIGHT", {
-  sheet: "/assets/coffee_right.png",
+coffeeSpriteSpec.states.set('RIGHT', {
+  sheet: '/assets/coffee_right.png'
 });
 SPRITE_SPECS.set(Sprites.COFFEE, coffeeSpriteSpec);
diff --git a/engine/entities/Entity.ts b/engine/entities/Entity.ts
index 88982cb..b016fc0 100644
--- a/engine/entities/Entity.ts
+++ b/engine/entities/Entity.ts
@@ -1,5 +1,5 @@
-import { EntityNames, Player } from ".";
-import type { Component } from "../components";
+import { EntityNames, Player } from '.';
+import type { Component } from '../components';
 
 export abstract class Entity {
   public id: string;
@@ -18,7 +18,7 @@ export abstract class Entity {
 
   public getComponent<T extends Component>(name: string): T {
     if (!this.hasComponent(name)) {
-      throw new Error("Entity does not have component " + name);
+      throw new Error('Entity does not have component ' + name);
     }
     return this.components.get(name) as T;
   }
@@ -34,9 +34,11 @@ export abstract class Entity {
   static from(entityName: string, args: any): Entity {
     switch (entityName) {
       case EntityNames.Player:
-        return new Player(args.playerId);
+        const player = new Player(args.playerId);
+        player.id = args.id;
+        return player;
       default:
-        throw new Error(".from() Entity type not implemented: " + entityName);
+        throw new Error('.from() Entity type not implemented: ' + entityName);
     }
   }
 }
diff --git a/engine/entities/Floor.ts b/engine/entities/Floor.ts
index 6cfc276..6f9b13b 100644
--- a/engine/entities/Floor.ts
+++ b/engine/entities/Floor.ts
@@ -1,11 +1,11 @@
-import { IMAGES, SPRITE_SPECS, Sprites, type SpriteSpec } from "../config";
-import { BoundingBox, Sprite } from "../components";
-import { TopCollidable } from "../components/TopCollidable";
-import { Entity, EntityNames } from "../entities";
+import { IMAGES, SPRITE_SPECS, Sprites, type SpriteSpec } from '../config';
+import { BoundingBox, Sprite } from '../components';
+import { TopCollidable } from '../components/TopCollidable';
+import { Entity, EntityNames } from '../entities';
 
 export class Floor extends Entity {
   private static spriteSpec: SpriteSpec = SPRITE_SPECS.get(
-    Sprites.FLOOR,
+    Sprites.FLOOR
   ) as SpriteSpec;
 
   constructor(width: number) {
@@ -17,18 +17,8 @@ export class Floor extends Entity {
         { x: 0, y: 0 },
         { width, height: Floor.spriteSpec.height },
         Floor.spriteSpec.msPerFrame,
-        Floor.spriteSpec.frames,
-      ),
-    );
-
-    this.addComponent(
-      new BoundingBox(
-        {
-          x: 300,
-          y: 300,
-        },
-        { width, height: Floor.spriteSpec.height },
-      ),
+        Floor.spriteSpec.frames
+      )
     );
 
     this.addComponent(new TopCollidable());
diff --git a/engine/entities/Player.ts b/engine/entities/Player.ts
index cfe4dd2..947fbd6 100644
--- a/engine/entities/Player.ts
+++ b/engine/entities/Player.ts
@@ -1,5 +1,5 @@
-import { Entity, EntityNames } from ".";
-import { IMAGES, SPRITE_SPECS, Sprites, type SpriteSpec } from "../config";
+import { Entity, EntityNames } from '.';
+import { IMAGES, SPRITE_SPECS, Sprites, type SpriteSpec } from '../config';
 import {
   Jump,
   FacingDirection,
@@ -12,16 +12,16 @@ import {
   Collide,
   Control,
   Mass,
-  Moment,
-} from "../components";
-import { Direction } from "../interfaces";
+  Moment
+} from '../components';
+import { Direction } from '../interfaces';
 
 export class Player extends Entity {
   private static MASS: number = 10;
   private static MOI: number = 100;
 
   private static spriteSpec: SpriteSpec = SPRITE_SPECS.get(
-    Sprites.COFFEE,
+    Sprites.COFFEE
   ) as SpriteSpec;
 
   constructor(playerId: string) {
@@ -31,15 +31,15 @@ export class Player extends Entity {
       new BoundingBox(
         {
           x: 300,
-          y: 100,
+          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));
@@ -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 dd3dba9..8aee83c 100644
--- a/engine/entities/index.ts
+++ b/engine/entities/index.ts
@@ -1,4 +1,4 @@
-export * from "./Entity";
-export * from "./Floor";
-export * from "./Player";
-export * from "./names";
+export * from './Entity';
+export * from './Floor';
+export * from './Player';
+export * from './names';
diff --git a/engine/entities/names.ts b/engine/entities/names.ts
index 21594c8..cf65f9f 100644
--- a/engine/entities/names.ts
+++ b/engine/entities/names.ts
@@ -1,4 +1,4 @@
 export namespace EntityNames {
-  export const Player = "Player";
-  export const Floor = "Floor";
+  export const Player = 'Player';
+  export const Floor = 'Floor';
 }
diff --git a/engine/interfaces/Action.ts b/engine/interfaces/Action.ts
index 61c89e1..f0e6a66 100644
--- a/engine/interfaces/Action.ts
+++ b/engine/interfaces/Action.ts
@@ -1,5 +1,5 @@
 export enum Action {
   MOVE_LEFT,
   MOVE_RIGHT,
-  JUMP,
+  JUMP
 }
diff --git a/engine/interfaces/Direction.ts b/engine/interfaces/Direction.ts
index 0bc6ef3..af1c7ac 100644
--- a/engine/interfaces/Direction.ts
+++ b/engine/interfaces/Direction.ts
@@ -1,6 +1,6 @@
 export enum Direction {
-  UP = "UP",
-  DOWN = "DOWN",
-  LEFT = "LEFT",
-  RIGHT = "RIGHT",
+  UP = 'UP',
+  DOWN = 'DOWN',
+  LEFT = 'LEFT',
+  RIGHT = 'RIGHT'
 }
diff --git a/engine/interfaces/Draw.ts b/engine/interfaces/Draw.ts
index 6561a01..8479fe4 100644
--- a/engine/interfaces/Draw.ts
+++ b/engine/interfaces/Draw.ts
@@ -1,4 +1,4 @@
-import type { Coord2D, Dimension2D } from "./";
+import type { Coord2D, Dimension2D } from './';
 
 export interface DrawArgs {
   center: Coord2D;
diff --git a/engine/interfaces/index.ts b/engine/interfaces/index.ts
index 8cdf4d8..c2f6896 100644
--- a/engine/interfaces/index.ts
+++ b/engine/interfaces/index.ts
@@ -1,4 +1,4 @@
-export * from "./Vec2";
-export * from "./Draw";
-export * from "./Direction";
-export * from "./Action";
+export * from './Vec2';
+export * from './Draw';
+export * from './Direction';
+export * from './Action';
diff --git a/engine/network/index.ts b/engine/network/index.ts
index 1726ffc..1bf95fb 100644
--- a/engine/network/index.ts
+++ b/engine/network/index.ts
@@ -1,7 +1,7 @@
 export enum MessageType {
-  NEW_ENTITY = "NEW_ENTITY",
-  REMOVE_ENTITY = "REMOVE_ENTITY",
-  UPDATE_ENTITY = "UPDATE_ENTITY",
+  NEW_ENTITIES = 'NEW_ENTITIES',
+  REMOVE_ENTITIES = 'REMOVE_ENTITIES',
+  UPDATE_ENTITY = 'UPDATE_ENTITY'
 }
 
 export type EntityAddBody = {
diff --git a/engine/structures/Grid.ts b/engine/structures/Grid.ts
index 6e8c0cb..5f0e053 100644
--- a/engine/structures/Grid.ts
+++ b/engine/structures/Grid.ts
@@ -1,6 +1,6 @@
-import type { Coord2D, Dimension2D } from "../interfaces";
-import type { BoxedEntry, RefreshingCollisionFinderBehavior } from ".";
-import { Miscellaneous } from "../config/constants";
+import type { Coord2D, Dimension2D } from '../interfaces';
+import type { BoxedEntry, RefreshingCollisionFinderBehavior } from '.';
+import { Miscellaneous } from '../config/constants';
 
 export class Grid implements RefreshingCollisionFinderBehavior {
   private cellEntities: Map<number, string[]>;
@@ -12,11 +12,11 @@ export class Grid implements RefreshingCollisionFinderBehavior {
   constructor(
     gridDimension: Dimension2D = {
       width: Miscellaneous.WIDTH,
-      height: Miscellaneous.HEIGHT,
+      height: Miscellaneous.HEIGHT
     },
     cellDimension: Dimension2D = {
       width: Miscellaneous.DEFAULT_GRID_WIDTH,
-      height: Miscellaneous.DEFAULT_GRID_HEIGHT,
+      height: Miscellaneous.DEFAULT_GRID_HEIGHT
     },
     topLeft = { x: 0, y: 0 }
   ) {
@@ -73,7 +73,7 @@ export class Grid implements RefreshingCollisionFinderBehavior {
 
     const translated: Coord2D = {
       y: center.y - this.topLeft.y,
-      x: center.x - this.topLeft.x,
+      x: center.x - this.topLeft.x
     };
 
     const topLeftBox = {
@@ -82,7 +82,7 @@ export class Grid implements RefreshingCollisionFinderBehavior {
       ),
       y: Math.floor(
         (translated.y - dimension.height / 2) / this.cellDimension.height
-      ),
+      )
     };
     const bottomRightBox = {
       x: Math.floor(
@@ -90,7 +90,7 @@ export class Grid implements RefreshingCollisionFinderBehavior {
       ),
       y: Math.floor(
         (translated.y + dimension.height / 2) / this.cellDimension.height
-      ),
+      )
     };
 
     const cells: number[] = [];
diff --git a/engine/structures/QuadTree.ts b/engine/structures/QuadTree.ts
index 1ab2d1d..93702d0 100644
--- a/engine/structures/QuadTree.ts
+++ b/engine/structures/QuadTree.ts
@@ -1,11 +1,11 @@
-import type { Coord2D, Dimension2D } from "../interfaces";
-import type { BoxedEntry, RefreshingCollisionFinderBehavior } from ".";
+import type { Coord2D, Dimension2D } from '../interfaces';
+import type { BoxedEntry, RefreshingCollisionFinderBehavior } from '.';
 
 enum Quadrant {
   I,
   II,
   III,
-  IV,
+  IV
 }
 
 /*
@@ -102,8 +102,8 @@ export class QuadTree implements RefreshingCollisionFinderBehavior {
         [Quadrant.III, { x: this.topLeft.x, y: this.topLeft.y + halfHeight }],
         [
           Quadrant.IV,
-          { x: this.topLeft.x + halfWidth, y: this.topLeft.y + halfHeight },
-        ],
+          { x: this.topLeft.x + halfWidth, y: this.topLeft.y + halfHeight }
+        ]
       ] as [Quadrant, Coord2D][]
     ).forEach(([quadrant, pos]) => {
       this.children.set(
@@ -122,27 +122,27 @@ export class QuadTree implements RefreshingCollisionFinderBehavior {
   private getQuadrants(boxedEntry: BoxedEntry): Quadrant[] {
     const treeCenter: Coord2D = {
       x: this.topLeft.x + this.dimension.width / 2,
-      y: this.topLeft.y + this.dimension.height / 2,
+      y: this.topLeft.y + this.dimension.height / 2
     };
 
     return (
       [
         [
           Quadrant.I,
-          (x: number, y: number) => x >= treeCenter.x && y < treeCenter.y,
+          (x: number, y: number) => x >= treeCenter.x && y < treeCenter.y
         ],
         [
           Quadrant.II,
-          (x: number, y: number) => x < treeCenter.x && y < treeCenter.y,
+          (x: number, y: number) => x < treeCenter.x && y < treeCenter.y
         ],
         [
           Quadrant.III,
-          (x: number, y: number) => x < treeCenter.x && y >= treeCenter.y,
+          (x: number, y: number) => x < treeCenter.x && y >= treeCenter.y
         ],
         [
           Quadrant.IV,
-          (x: number, y: number) => x >= treeCenter.x && y >= treeCenter.y,
-        ],
+          (x: number, y: number) => x >= treeCenter.x && y >= treeCenter.y
+        ]
       ] as [Quadrant, (x: number, y: number) => boolean][]
     )
       .filter(
diff --git a/engine/structures/RefreshingCollisionFinderBehavior.ts b/engine/structures/RefreshingCollisionFinderBehavior.ts
index 21d690d..573ddd8 100644
--- a/engine/structures/RefreshingCollisionFinderBehavior.ts
+++ b/engine/structures/RefreshingCollisionFinderBehavior.ts
@@ -1,4 +1,4 @@
-import type { Coord2D, Dimension2D } from "../interfaces";
+import type { Coord2D, Dimension2D } from '../interfaces';
 
 export interface BoxedEntry {
   id: string;
@@ -7,8 +7,8 @@ export interface BoxedEntry {
 }
 
 export interface RefreshingCollisionFinderBehavior {
-  public clear(): void;
-  public insert(boxedEntry: BoxedEntry): void;
-  public getNeighborIds(boxedEntry: BoxedEntry): Set<string>;
-  public setTopLeft(topLeft: Coord2d): void;
+  clear(): void;
+  insert(boxedEntry: BoxedEntry): void;
+  getNeighborIds(boxedEntry: BoxedEntry): Set<string>;
+  setTopLeft(topLeft: Coord2D): void;
 }
diff --git a/engine/structures/index.ts b/engine/structures/index.ts
index 49a84af..679dbd4 100644
--- a/engine/structures/index.ts
+++ b/engine/structures/index.ts
@@ -1,3 +1,3 @@
-export * from "./RefreshingCollisionFinderBehavior";
-export * from "./QuadTree";
-export * from "./Grid";
+export * from './RefreshingCollisionFinderBehavior';
+export * from './QuadTree';
+export * from './Grid';
diff --git a/engine/systems/Collision.ts b/engine/systems/Collision.ts
index 2dd920e..4a838dd 100644
--- a/engine/systems/Collision.ts
+++ b/engine/systems/Collision.ts
@@ -1,22 +1,22 @@
-import { SystemNames, System } from ".";
+import { SystemNames, System } from '.';
 import {
   Mass,
   BoundingBox,
   ComponentNames,
   Jump,
   Velocity,
-  Forces,
-} from "../components";
-import { Game } from "../Game";
-import { Miscellaneous, PhysicsConstants } from "../config";
-import { Entity } from "../entities";
-import type { Coord2D, Dimension2D, Velocity2D } from "../interfaces";
-import { BoxedEntry, RefreshingCollisionFinderBehavior } from "../structures";
+  Forces
+} from '../components';
+import { Game } from '../Game';
+import { Miscellaneous, PhysicsConstants } from '../config';
+import { Entity } from '../entities';
+import type { Coord2D, Dimension2D, Velocity2D } from '../interfaces';
+import { BoxedEntry, RefreshingCollisionFinderBehavior } from '../structures';
 
 export class Collision extends System {
   private static readonly COLLIDABLE_COMPONENT_NAMES = [
     ComponentNames.Collide,
-    ComponentNames.TopCollidable,
+    ComponentNames.TopCollidable
   ];
 
   private collisionFinder: RefreshingCollisionFinderBehavior;
@@ -38,7 +38,7 @@ export class Collision extends System {
           return;
         }
         entitiesToAddToCollisionFinder.push(entity);
-      }),
+      })
     );
 
     this.insertEntitiesAndUpdateBounds(entitiesToAddToCollisionFinder);
@@ -53,7 +53,7 @@ export class Collision extends System {
 
     entities.forEach((entity) => {
       const boundingBox = entity.getComponent<BoundingBox>(
-        ComponentNames.BoundingBox,
+        ComponentNames.BoundingBox
       );
 
       let dimension = { ...boundingBox.dimension };
@@ -73,7 +73,7 @@ export class Collision extends System {
       collisionFinderInsertions.push({
         id: entity.id,
         dimension,
-        center,
+        center
       });
     });
 
@@ -82,13 +82,13 @@ export class Collision extends System {
       this.collisionFinder.setTopLeft(topLeft);
       this.collisionFinder.setDimension({
         width: bottomRight.x - topLeft.x,
-        height: bottomRight.y - topLeft.y,
+        height: bottomRight.y - topLeft.y
       });
     }
 
     // then, begin insertions
     collisionFinderInsertions.forEach((boxedEntry: BoxedEntry) =>
-      this.collisionFinder.insert(boxedEntry),
+      this.collisionFinder.insert(boxedEntry)
     );
   }
 
@@ -97,7 +97,7 @@ export class Collision extends System {
 
     collidingEntities.forEach(([entityAId, entityBId]) => {
       const [entityA, entityB] = [entityAId, entityBId].map((id) =>
-        game.entities.get(id),
+        game.entities.get(id)
       );
       if (entityA && entityB) {
         this.performCollision(entityA, entityB);
@@ -107,13 +107,13 @@ export class Collision extends System {
 
   private performCollision(entityA: Entity, entityB: Entity) {
     const [entityABoundingBox, entityBBoundingBox] = [entityA, entityB].map(
-      (entity) => entity.getComponent<BoundingBox>(ComponentNames.BoundingBox),
+      (entity) => entity.getComponent<BoundingBox>(ComponentNames.BoundingBox)
     );
 
     let velocity: Velocity2D = { dCartesian: { dx: 0, dy: 0 }, dTheta: 0 };
     if (entityA.hasComponent(ComponentNames.Velocity)) {
       velocity = entityA.getComponent<Velocity>(
-        ComponentNames.Velocity,
+        ComponentNames.Velocity
       ).velocity;
     }
 
@@ -125,7 +125,7 @@ export class Collision extends System {
     ) {
       if (entityBBoundingBox.rotation != 0) {
         throw new Error(
-          `entity with id ${entityB.id} has TopCollidable component and a non-zero rotation. that is not (yet) supported.`,
+          `entity with id ${entityB.id} has TopCollidable component and a non-zero rotation. that is not (yet) supported.`
         );
       }
 
@@ -139,7 +139,7 @@ export class Collision extends System {
 
         entityA.getComponent<Forces>(ComponentNames.Forces).forces.push({
           fCartesian: { fy: F_n, fx: 0 },
-          torque: 0,
+          torque: 0
         });
       }
 
@@ -157,19 +157,19 @@ export class Collision extends System {
 
   private getCollidingEntities(
     collidableEntities: Entity[],
-    game: Game,
+    game: Game
   ): [string, string][] {
     const collidingEntityIds: [string, string][] = [];
 
     for (const entity of collidableEntities) {
       const boundingBox = entity.getComponent<BoundingBox>(
-        ComponentNames.BoundingBox,
+        ComponentNames.BoundingBox
       );
 
       const neighborIds = this.collisionFinder.getNeighborIds({
         id: entity.id,
         dimension: boundingBox.dimension,
-        center: boundingBox.center,
+        center: boundingBox.center
       });
 
       for (const neighborId of neighborIds) {
@@ -177,7 +177,7 @@ export class Collision extends System {
         if (!neighbor) return;
 
         const neighborBoundingBox = neighbor.getComponent<BoundingBox>(
-          ComponentNames.BoundingBox,
+          ComponentNames.BoundingBox
         );
 
         if (boundingBox.isCollidingWith(neighborBoundingBox)) {
@@ -192,11 +192,11 @@ export class Collision extends System {
   // ramblings: https://excalidraw.com/#json=z-xD86Za4a3duZuV2Oky0,KaGe-5iHJu1Si8inEo4GLQ
   private getDyToPushOutOfFloor(
     entityBoundingBox: BoundingBox,
-    floorBoundingBox: BoundingBox,
+    floorBoundingBox: BoundingBox
   ): number {
     const {
       dimension: { width, height },
-      center: { x },
+      center: { x }
     } = entityBoundingBox;
 
     const outScribedRectangle = entityBoundingBox.getOutscribedBoxDims();
@@ -215,7 +215,7 @@ export class Collision extends System {
     if (x >= floorBoundingBox.center.x) {
       boundedCollisionX = Math.min(
         floorBoundingBox.center.x + floorBoundingBox.dimension.width / 2,
-        clippedX,
+        clippedX
       );
       return (
         outScribedRectangle.height / 2 -
@@ -225,7 +225,7 @@ export class Collision extends System {
 
     boundedCollisionX = Math.max(
       floorBoundingBox.center.x - floorBoundingBox.dimension.width / 2,
-      clippedX,
+      clippedX
     );
 
     return (
diff --git a/engine/systems/FacingDirection.ts b/engine/systems/FacingDirection.ts
index daf639f..01f32cf 100644
--- a/engine/systems/FacingDirection.ts
+++ b/engine/systems/FacingDirection.ts
@@ -2,10 +2,10 @@ import {
   ComponentNames,
   Velocity,
   FacingDirection as FacingDirectionComponent,
-  Control,
-} from "../components";
-import { Game } from "../Game";
-import { System, SystemNames } from "./";
+  Control
+} from '../components';
+import { Game } from '../Game';
+import { System, SystemNames } from './';
 
 export class FacingDirection extends System {
   constructor() {
@@ -23,7 +23,7 @@ export class FacingDirection extends System {
         const totalVelocityComponent = new Velocity();
         const control = entity.getComponent<Control>(ComponentNames.Control);
         const velocity = entity.getComponent<Velocity>(
-          ComponentNames.Velocity,
+          ComponentNames.Velocity
         ).velocity;
 
         totalVelocityComponent.add(velocity);
@@ -32,7 +32,7 @@ export class FacingDirection extends System {
         }
 
         const facingDirection = entity.getComponent<FacingDirectionComponent>(
-          ComponentNames.FacingDirection,
+          ComponentNames.FacingDirection
         );
 
         if (totalVelocityComponent.velocity.dCartesian.dx > 0) {
@@ -40,7 +40,7 @@ export class FacingDirection extends System {
         } else if (totalVelocityComponent.velocity.dCartesian.dx < 0) {
           entity.addComponent(facingDirection.facingLeftSprite);
         }
-      },
+      }
     );
   }
 }
diff --git a/engine/systems/Input.ts b/engine/systems/Input.ts
index a32ba9a..4a5a3c3 100644
--- a/engine/systems/Input.ts
+++ b/engine/systems/Input.ts
@@ -4,12 +4,12 @@ import {
   ComponentNames,
   Velocity,
   Mass,
-  Control,
-} from "../components";
-import { Game } from "../Game";
-import { KeyConstants, PhysicsConstants } from "../config";
-import { Action } from "../interfaces";
-import { System, SystemNames } from ".";
+  Control
+} from '../components';
+import { Game } from '../Game';
+import { KeyConstants, PhysicsConstants } from '../config';
+import { Action } from '../interfaces';
+import { System, SystemNames } from '.';
 
 export class Input extends System {
   public clientId: string;
@@ -42,7 +42,7 @@ export class Input extends System {
   public update(_dt: number, game: Game) {
     game.forEachEntityWithComponent(ComponentNames.Control, (entity) => {
       const controlComponent = entity.getComponent<Control>(
-        ComponentNames.Control,
+        ComponentNames.Control
       );
       if (controlComponent.controllableBy != this.clientId) return;
 
@@ -58,7 +58,7 @@ export class Input extends System {
 
       if (entity.hasComponent(ComponentNames.Jump)) {
         const velocity = entity.getComponent<Velocity>(
-          ComponentNames.Velocity,
+          ComponentNames.Velocity
         ).velocity;
         const jump = entity.getComponent<Jump>(ComponentNames.Jump);
 
@@ -78,9 +78,9 @@ export class Input extends System {
             entity.getComponent<Forces>(ComponentNames.Forces)?.forces.push({
               fCartesian: {
                 fy: mass * PhysicsConstants.PLAYER_JUMP_ACC,
-                fx: 0,
+                fx: 0
               },
-              torque: 0,
+              torque: 0
             });
           }
         }
diff --git a/engine/systems/NetworkUpdate.ts b/engine/systems/NetworkUpdate.ts
index 6c1d3e4..bcfb71e 100644
--- a/engine/systems/NetworkUpdate.ts
+++ b/engine/systems/NetworkUpdate.ts
@@ -1,11 +1,11 @@
-import { System, SystemNames } from ".";
-import { Game } from "../Game";
-import { ComponentNames, NetworkUpdateable } from "../components";
+import { System, SystemNames } from '.';
+import { Game } from '../Game';
+import { ComponentNames, NetworkUpdateable } from '../components';
 import {
   type MessageQueueProvider,
   type MessagePublisher,
-  type MessageProcessor,
-} from "../network";
+  type MessageProcessor
+} from '../network';
 
 export class NetworkUpdate extends System {
   private queueProvider: MessageQueueProvider;
@@ -15,7 +15,7 @@ export class NetworkUpdate extends System {
   constructor(
     queueProvider: MessageQueueProvider,
     publisher: MessagePublisher,
-    messageProcessor: MessageProcessor,
+    messageProcessor: MessageProcessor
   ) {
     super(SystemNames.NetworkUpdate);
 
@@ -34,9 +34,9 @@ export class NetworkUpdate extends System {
       ComponentNames.NetworkUpdateable,
       (entity) => {
         const networkUpdateComponent = entity.getComponent<NetworkUpdateable>(
-          ComponentNames.NetworkUpdateable,
+          ComponentNames.NetworkUpdateable
         );
-      },
+      }
     );
 
     this.publisher.publish();
diff --git a/engine/systems/Physics.ts b/engine/systems/Physics.ts
index e324c97..35afb3f 100644
--- a/engine/systems/Physics.ts
+++ b/engine/systems/Physics.ts
@@ -1,4 +1,4 @@
-import { System, SystemNames } from ".";
+import { System, SystemNames } from '.';
 import {
   BoundingBox,
   ComponentNames,
@@ -8,11 +8,11 @@ import {
   Mass,
   Jump,
   Moment,
-  Control,
-} from "../components";
-import { PhysicsConstants } from "../config";
-import type { Force2D, Velocity2D } from "../interfaces";
-import { Game } from "../Game";
+  Control
+} from '../components';
+import { PhysicsConstants } from '../config';
+import type { Force2D, Velocity2D } from '../interfaces';
+import { Game } from '../Game';
 
 export class Physics extends System {
   constructor() {
@@ -24,10 +24,10 @@ export class Physics extends System {
       const mass = entity.getComponent<Mass>(ComponentNames.Mass).mass;
       const forces = entity.getComponent<Forces>(ComponentNames.Forces).forces;
       const velocity = entity.getComponent<Velocity>(
-        ComponentNames.Velocity,
+        ComponentNames.Velocity
       ).velocity;
       const inertia = entity.getComponent<Moment>(
-        ComponentNames.Moment,
+        ComponentNames.Moment
       ).inertia;
 
       // F_g = mg, applied only until terminal velocity is reached
@@ -37,9 +37,9 @@ export class Physics extends System {
           forces.push({
             fCartesian: {
               fy: mass * PhysicsConstants.GRAVITY,
-              fx: 0,
+              fx: 0
             },
-            torque: 0,
+            torque: 0
           });
         }
       }
@@ -49,17 +49,17 @@ export class Physics extends System {
         (accum: Force2D, { fCartesian, torque }: Force2D) => ({
           fCartesian: {
             fx: accum.fCartesian.fx + (fCartesian?.fx ?? 0),
-            fy: accum.fCartesian.fy + (fCartesian?.fy ?? 0),
+            fy: accum.fCartesian.fy + (fCartesian?.fy ?? 0)
           },
-          torque: accum.torque + (torque ?? 0),
+          torque: accum.torque + (torque ?? 0)
         }),
-        { fCartesian: { fx: 0, fy: 0 }, torque: 0 },
+        { fCartesian: { fx: 0, fy: 0 }, torque: 0 }
       );
 
       // integrate accelerations
       const [ddy, ddx] = [
         sumOfForces.fCartesian.fy,
-        sumOfForces.fCartesian.fx,
+        sumOfForces.fCartesian.fx
       ].map((x) => x / mass);
       velocity.dCartesian.dx += ddx * dt;
       velocity.dCartesian.dy += ddy * dt;
@@ -79,14 +79,14 @@ export class Physics extends System {
       const control = entity.getComponent<Control>(ComponentNames.Control);
 
       velocityComponent.add(
-        entity.getComponent<Velocity>(ComponentNames.Velocity).velocity,
+        entity.getComponent<Velocity>(ComponentNames.Velocity).velocity
       );
       if (control) {
         velocityComponent.add(control.controlVelocityComponent.velocity);
       }
 
       const boundingBox = entity.getComponent<BoundingBox>(
-        ComponentNames.BoundingBox,
+        ComponentNames.BoundingBox
       );
 
       // integrate velocity
diff --git a/engine/systems/Render.ts b/engine/systems/Render.ts
index 9bb4091..4a4500d 100644
--- a/engine/systems/Render.ts
+++ b/engine/systems/Render.ts
@@ -1,7 +1,7 @@
-import { System, SystemNames } from ".";
-import { BoundingBox, ComponentNames, Sprite } from "../components";
-import { Game } from "../Game";
-import { clamp } from "../utils";
+import { System, SystemNames } from '.';
+import { BoundingBox, ComponentNames, Sprite } from '../components';
+import { Game } from '../Game';
+import { clamp } from '../utils';
 
 export class Render extends System {
   private ctx: CanvasRenderingContext2D;
@@ -19,7 +19,7 @@ export class Render extends System {
       sprite.update(dt);
 
       const boundingBox = entity.getComponent<BoundingBox>(
-        ComponentNames.BoundingBox,
+        ComponentNames.BoundingBox
       );
 
       // don't render if we're outside the screen
@@ -27,12 +27,12 @@ export class Render extends System {
         clamp(
           boundingBox.center.y,
           -boundingBox.dimension.height / 2,
-          this.ctx.canvas.height + boundingBox.dimension.height / 2,
+          this.ctx.canvas.height + boundingBox.dimension.height / 2
         ) != boundingBox.center.y ||
         clamp(
           boundingBox.center.x,
           -boundingBox.dimension.width / 2,
-          this.ctx.canvas.width + boundingBox.dimension.width / 2,
+          this.ctx.canvas.width + boundingBox.dimension.width / 2
         ) != boundingBox.center.x
       ) {
         return;
@@ -41,7 +41,7 @@ export class Render extends System {
       const drawArgs = {
         center: boundingBox.center,
         dimension: boundingBox.dimension,
-        rotation: boundingBox.rotation,
+        rotation: boundingBox.rotation
       };
 
       sprite.draw(this.ctx, drawArgs);
diff --git a/engine/systems/System.ts b/engine/systems/System.ts
index 8b00dc5..de41988 100644
--- a/engine/systems/System.ts
+++ b/engine/systems/System.ts
@@ -1,4 +1,4 @@
-import { Game } from "../Game";
+import { Game } from '../Game';
 
 export abstract class System {
   public readonly name: string;
diff --git a/engine/systems/WallBounds.ts b/engine/systems/WallBounds.ts
index a0d4a9c..7da84e4 100644
--- a/engine/systems/WallBounds.ts
+++ b/engine/systems/WallBounds.ts
@@ -1,28 +1,24 @@
-import { System, SystemNames } from ".";
-import { BoundingBox, ComponentNames } from "../components";
-import { Game } from "../Game";
-import type { Entity } from "../entities";
-import { clamp } from "../utils";
+import { System, SystemNames } from '.';
+import { BoundingBox, ComponentNames } from '../components';
+import { Game } from '../Game';
+import { clamp } from '../utils';
+import { Miscellaneous } from '../config';
 
 export class WallBounds extends System {
-  private screenWidth: number;
-
-  constructor(screenWidth: number) {
+  constructor() {
     super(SystemNames.WallBounds);
-
-    this.screenWidth = screenWidth;
   }
 
   public update(_dt: number, game: Game) {
     game.forEachEntityWithComponent(ComponentNames.WallBounded, (entity) => {
       const boundingBox = entity.getComponent<BoundingBox>(
-        ComponentNames.BoundingBox,
+        ComponentNames.BoundingBox
       );
 
       boundingBox.center.x = clamp(
         boundingBox.center.x,
         boundingBox.dimension.width / 2,
-        this.screenWidth - boundingBox.dimension.width / 2,
+        Miscellaneous.WIDTH - boundingBox.dimension.width / 2
       );
     });
   }
diff --git a/engine/systems/index.ts b/engine/systems/index.ts
index 075fc4e..43181e9 100644
--- a/engine/systems/index.ts
+++ b/engine/systems/index.ts
@@ -1,9 +1,9 @@
-export * from "./names";
-export * from "./System";
-export * from "./Render";
-export * from "./Physics";
-export * from "./Input";
-export * from "./FacingDirection";
-export * from "./Collision";
-export * from "./WallBounds";
-export * from "./NetworkUpdate";
+export * from './names';
+export * from './System';
+export * from './Render';
+export * from './Physics';
+export * from './Input';
+export * from './FacingDirection';
+export * from './Collision';
+export * from './WallBounds';
+export * from './NetworkUpdate';
diff --git a/engine/systems/names.ts b/engine/systems/names.ts
index cf66422..ddf6f19 100644
--- a/engine/systems/names.ts
+++ b/engine/systems/names.ts
@@ -1,9 +1,9 @@
 export namespace SystemNames {
-  export const Render = "Render";
-  export const Physics = "Physics";
-  export const FacingDirection = "FacingDirection";
-  export const Input = "Input";
-  export const Collision = "Collision";
-  export const WallBounds = "WallBounds";
-  export const NetworkUpdate = "NetworkUpdate";
+  export const Render = 'Render';
+  export const Physics = 'Physics';
+  export const FacingDirection = 'FacingDirection';
+  export const Input = 'Input';
+  export const Collision = 'Collision';
+  export const WallBounds = 'WallBounds';
+  export const NetworkUpdate = 'NetworkUpdate';
 }
diff --git a/engine/utils/coding.ts b/engine/utils/coding.ts
index 4c1b17f..3f78889 100644
--- a/engine/utils/coding.ts
+++ b/engine/utils/coding.ts
@@ -1,8 +1,8 @@
 const replacer = (_key: any, value: any) => {
   if (value instanceof Map) {
     return {
-      dataType: "Map",
-      value: Array.from(value.entries()),
+      dataType: 'Map',
+      value: Array.from(value.entries())
     };
   } else {
     return value;
@@ -10,8 +10,8 @@ const replacer = (_key: any, value: any) => {
 };
 
 const reviver = (_key: any, value: any) => {
-  if (typeof value === "object" && value !== null) {
-    if (value.dataType === "Map") {
+  if (typeof value === 'object' && value !== null) {
+    if (value.dataType === 'Map') {
       return new Map(value.value);
     }
   }
diff --git a/engine/utils/dotProduct.ts b/engine/utils/dotProduct.ts
index 59f8857..82bcdea 100644
--- a/engine/utils/dotProduct.ts
+++ b/engine/utils/dotProduct.ts
@@ -1,4 +1,4 @@
-import type { Coord2D } from "../interfaces";
+import type { Coord2D } from '../interfaces';
 
 export const dotProduct = (vector1: Coord2D, vector2: Coord2D): number =>
   vector1.x * vector2.x + vector1.y * vector2.y;
diff --git a/engine/utils/index.ts b/engine/utils/index.ts
index b70734f..65446d1 100644
--- a/engine/utils/index.ts
+++ b/engine/utils/index.ts
@@ -1,4 +1,4 @@
-export * from "./rotateVector";
-export * from "./dotProduct";
-export * from "./clamp";
-export * from "./coding";
+export * from './rotateVector';
+export * from './dotProduct';
+export * from './clamp';
+export * from './coding';
diff --git a/engine/utils/rotateVector.ts b/engine/utils/rotateVector.ts
index 82bb54d..221ffb2 100644
--- a/engine/utils/rotateVector.ts
+++ b/engine/utils/rotateVector.ts
@@ -1,4 +1,4 @@
-import type { Coord2D } from "../interfaces";
+import type { Coord2D } from '../interfaces';
 
 /**
  * ([[cos(θ), -sin(θ),])  ([x,)
@@ -10,6 +10,6 @@ export const rotateVector = (vector: Coord2D, theta: number): Coord2D => {
 
   return {
     x: vector.x * cos - vector.y * sin,
-    y: vector.x * sin + vector.y * cos,
+    y: vector.x * sin + vector.y * cos
   };
 };
diff --git a/server/package.json b/server/package.json
index 17d3c25..388cff2 100644
--- a/server/package.json
+++ b/server/package.json
@@ -8,6 +8,5 @@
   "peerDependencies": {
     "typescript": "^5.0.0"
   },
-  "dependencies": {
-  }
+  "dependencies": {}
 }
diff --git a/server/src/server.ts b/server/src/server.ts
index b3eb1ea..c77bfef 100644
--- a/server/src/server.ts
+++ b/server/src/server.ts
@@ -1,21 +1,22 @@
-import { Game } from "@engine/Game";
-import { EntityNames, Player } from "@engine/entities";
-import { WallBounds, Physics, Collision, NetworkUpdate } from "@engine/systems";
+import { Game } from '@engine/Game';
+import { EntityNames, Player } from '@engine/entities';
+import { WallBounds, Physics, Collision, NetworkUpdate } from '@engine/systems';
 import {
   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";
+  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";
+const SERVER_TICK_RATE = (1 / 60) * 1000;
+const GAME_TOPIC = 'game';
+const MAX_PLAYERS = 8;
 
 type SessionData = { sessionId: string };
 
@@ -70,11 +71,11 @@ class ServerSocketMessagePublisher implements MessagePublisher {
   }
 
   public publish() {
-    this.messages.forEach(
-      (message) => this.server?.publish(GAME_TOPIC, stringify(message)),
-    );
+    if (this.messages.length) {
+      this.server?.publish(GAME_TOPIC, stringify(this.messages));
 
-    this.messages = [];
+      this.messages = [];
+    }
   }
 }
 
@@ -85,81 +86,102 @@ const messagePublisher = new ServerSocketMessagePublisher();
 const messageProcessor = new ServerMessageProcessor();
 const sessionControllableEntities: Map<string, Set<string>> = new Map();
 
+const sessions = new Set<string>();
+
 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", "*");
+    headers.set('Access-Control-Allow-Origin', '*');
+
+    if (url.pathname == '/assign') {
+      if (sessions.size > MAX_PLAYERS)
+        return new Response('too many players', { headers, status: 400 });
 
-    if (url.pathname == "/assign") {
       const sessionId = crypto.randomUUID();
-      headers.set("Set-Cookie", `SessionId=${sessionId};`);
+      headers.set('Set-Cookie', `SessionId=${sessionId};`);
+
+      sessions.add(sessionId);
 
       return new Response(sessionId, { headers });
     }
 
-    const cookie = req.headers.get("cookie");
+    const cookie = req.headers.get('cookie');
     if (!cookie) {
-      return new Response("No session", { headers, status: 401 });
+      return new Response('No session', { headers, status: 401 });
     }
 
-    const sessionId = cookie.split(";").at(0)!.split("SessionId=").at(1);
+    const sessionId = cookie.split(';').at(0)!.split('SessionId=').at(1);
 
-    if (url.pathname == "/game") {
+    if (url.pathname == '/game') {
       headers.set(
-        "Set-Cookie",
-        `SessionId=${sessionId}; HttpOnly; SameSite=Strict;`,
+        'Set-Cookie',
+        `SessionId=${sessionId}; HttpOnly; SameSite=Strict;`
       );
       server.upgrade(req, {
         headers,
         data: {
-          sessionId,
-        },
+          sessionId
+        }
       });
 
-      return new Response("upgraded", { headers });
+      return new Response('upgraded', { headers });
     }
-    if (url.pathname == "/me") {
+
+    if (url.pathname == '/me') {
       return new Response(sessionId, { headers });
     }
 
-    return new Response("Not found", { headers, status: 404 });
+    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(sessionId);
       game.addEntity(player);
-      sessionControllableEntities.set(sessionId, new Set(player.id));
+      sessionControllableEntities.set(sessionId, new Set([player.id]));
 
       messagePublisher.addMessage({
-        type: MessageType.NEW_ENTITY,
-        body: {
-          entityName: EntityNames.Player,
-          args: { playerId: sessionId },
-        },
+        type: MessageType.NEW_ENTITIES,
+        body: [
+          {
+            entityName: EntityNames.Player,
+            args: { playerId: sessionId, id: player.id }
+          }
+        ]
       });
 
       ws.subscribe(GAME_TOPIC);
     },
     message(ws, message) {
-      if (typeof message == "string") {
+      if (typeof message == 'string') {
         const receivedMessage = parse<ServerMessage>(message);
         receivedMessage.sessionData = ws.data;
 
         messageReceiver.addMessage(receivedMessage);
       }
     },
-    close(_ws) {},
-  },
+    close(ws) {
+      const { sessionId } = ws.data;
+
+      sessions.delete(sessionId);
+
+      const sessionEntities = sessionControllableEntities.get(sessionId);
+      if (!sessionEntities) return;
+
+      messagePublisher.addMessage({
+        type: MessageType.REMOVE_ENTITIES,
+        body: Array.from(sessionEntities)
+      });
+    }
+  }
 });
 
 messagePublisher.setServer(server);
@@ -167,8 +189,8 @@ messagePublisher.setServer(server);
 [
   new Physics(),
   new Collision(new Grid()),
-  new WallBounds(Miscellaneous.WIDTH),
-  new NetworkUpdate(messageReceiver, messagePublisher, messageProcessor),
+  new WallBounds(),
+  new NetworkUpdate(messageReceiver, messagePublisher, messageProcessor)
 ].forEach((system) => game.addSystem(system));
 
 game.start();
-- 
cgit v1.2.3-70-g09d2

