summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElizabeth Hunt <elizabeth.hunt@simponic.xyz>2023-09-02 14:40:46 -0600
committerElizabeth Hunt <elizabeth.hunt@simponic.xyz>2023-09-02 14:40:46 -0600
commit29ba1c29d7ada13a9e6d475ca880d121a85894ea (patch)
tree35a2b36191d197cd44b255cb0dcbc32077a212b4
parentc551f519cadb8628d58114512770c69b01d80a0c (diff)
downloadjumpstorm-29ba1c29d7ada13a9e6d475ca880d121a85894ea.tar.gz
jumpstorm-29ba1c29d7ada13a9e6d475ca880d121a85894ea.zip
make next update interval a property on network update component instead of inheritable attribute on entities
-rw-r--r--engine/components/BoundingBox.ts1
-rw-r--r--engine/components/NetworkUpdateable.ts18
-rw-r--r--engine/entities/Entity.ts5
-rw-r--r--engine/entities/Floor.ts6
-rw-r--r--engine/entities/Player.ts6
-rw-r--r--engine/systems/NetworkUpdate.ts23
-rw-r--r--server/src/server.ts16
7 files changed, 42 insertions, 33 deletions
diff --git a/engine/components/BoundingBox.ts b/engine/components/BoundingBox.ts
index 921feb9..f01ae9b 100644
--- a/engine/components/BoundingBox.ts
+++ b/engine/components/BoundingBox.ts
@@ -16,6 +16,7 @@ export class BoundingBox extends Component {
}
public isCollidingWith(box: BoundingBox): boolean {
+ // optimization; when neither rotates just check if they overlap
if (this.rotation == 0 && box.rotation == 0) {
const thisTopLeft = this.getTopLeft();
const thisBottomRight = this.getBottomRight();
diff --git a/engine/components/NetworkUpdateable.ts b/engine/components/NetworkUpdateable.ts
index 014270c..78d7324 100644
--- a/engine/components/NetworkUpdateable.ts
+++ b/engine/components/NetworkUpdateable.ts
@@ -1,7 +1,23 @@
import { Component, ComponentNames } from '.';
export class NetworkUpdateable extends Component {
- constructor() {
+ static DEFAULT_UPDATE_JITTER_MS = 30;
+ static DEFAULT_THRESHOLD_TIME_MS = 20;
+
+ public updateThreshold: number;
+ public jitter: number;
+
+ constructor(
+ updateThreshold = NetworkUpdateable.DEFAULT_THRESHOLD_TIME_MS,
+ jitter = NetworkUpdateable.DEFAULT_UPDATE_JITTER_MS
+ ) {
super(ComponentNames.NetworkUpdateable);
+
+ this.updateThreshold = updateThreshold;
+ this.jitter = jitter;
+ }
+
+ public getNextUpdateTime() {
+ return Math.random() * this.jitter + this.updateThreshold;
}
}
diff --git a/engine/entities/Entity.ts b/engine/entities/Entity.ts
index 7078f79..a7d561c 100644
--- a/engine/entities/Entity.ts
+++ b/engine/entities/Entity.ts
@@ -1,8 +1,7 @@
import { EntityNames, Floor, Player } from '.';
import { type Component } from '../components';
-const randomId = () =>
- (performance.now() + Math.random() * 10_000_000).toString();
+const randomId = () => (Math.random() * 1_000_000_000).toString();
export abstract class Entity {
public id: string;
@@ -59,6 +58,4 @@ export abstract class Entity {
public abstract setFrom(args: Record<string, any>): void;
public abstract serialize(): Record<string, any>;
-
- public abstract getNextUpdateInterval(): number;
}
diff --git a/engine/entities/Floor.ts b/engine/entities/Floor.ts
index f56c0d3..fb4988d 100644
--- a/engine/entities/Floor.ts
+++ b/engine/entities/Floor.ts
@@ -17,7 +17,7 @@ export class Floor extends Entity {
this.addComponent(
new Sprite(
- IMAGES.get((Floor.spriteSpec?.states?.get(width) as SpriteSpec).sheet),
+ IMAGES.get(Floor.spriteSpec!.states!.get(width)!.sheet!)!,
{ x: 0, y: 0 },
{ width, height: Floor.spriteSpec.height },
Floor.spriteSpec.msPerFrame,
@@ -45,8 +45,4 @@ export class Floor extends Entity {
)
);
}
-
- public getNextUpdateInterval() {
- return Math.random() * 500;
- }
}
diff --git a/engine/entities/Player.ts b/engine/entities/Player.ts
index b42fca4..02dd14e 100644
--- a/engine/entities/Player.ts
+++ b/engine/entities/Player.ts
@@ -60,7 +60,7 @@ export class Player extends Entity {
const [leftSprite, rightSprite] = [Direction.LEFT, Direction.RIGHT].map(
(direction) =>
new Sprite(
- IMAGES.get(Player.spriteSpec.states?.get(direction)?.sheet as string),
+ IMAGES.get(Player.spriteSpec.states!.get(direction)!.sheet!)!,
{ x: 0, y: 0 },
{ width: Player.spriteSpec.width, height: Player.spriteSpec.height },
Player.spriteSpec.msPerFrame,
@@ -102,8 +102,4 @@ export class Player extends Entity {
new BoundingBox(center, boundingBox.dimension, boundingBox.rotation)
].forEach((component) => this.addComponent(component));
}
-
- public getNextUpdateInterval() {
- return Math.random() * 30 + 50;
- }
}
diff --git a/engine/systems/NetworkUpdate.ts b/engine/systems/NetworkUpdate.ts
index f4c8f9c..524ebf4 100644
--- a/engine/systems/NetworkUpdate.ts
+++ b/engine/systems/NetworkUpdate.ts
@@ -1,6 +1,6 @@
import { System, SystemNames } from '.';
import { Game } from '../Game';
-import { ComponentNames } from '../components';
+import { ComponentNames, NetworkUpdateable } from '../components';
import {
type MessageQueueProvider,
type MessagePublisher,
@@ -55,15 +55,20 @@ export class NetworkUpdate extends System {
// 2. send entity updates
const updateMessages: EntityUpdateBody[] = [];
- // todo: figure out if we can use the controllable component to determine if we should publish an update
game.forEachEntityWithComponent(
ComponentNames.NetworkUpdateable,
(entity) => {
+ const networkUpdateableComponent =
+ entity.getComponent<NetworkUpdateable>(
+ ComponentNames.NetworkUpdateable
+ );
+ const nextUpdateTime = networkUpdateableComponent.getNextUpdateTime();
+
const newHash = stringify(entity.serialize());
let updateInfo: EntityUpdateInfo = this.entityUpdateInfo.get(
entity.id
) ?? {
- timer: this.getNextUpdateTimeMs(),
+ timer: nextUpdateTime,
hash: newHash
};
@@ -71,13 +76,11 @@ export class NetworkUpdate extends System {
updateInfo.timer -= dt;
this.entityUpdateInfo.set(entity.id, updateInfo);
if (updateInfo.timer > 0) return;
- updateInfo.timer = entity.getNextUpdateInterval();
+ updateInfo.timer = nextUpdateTime;
this.entityUpdateInfo.set(entity.id, updateInfo);
- // maybe update if hash is not consitent
- if (updateInfo.hash == newHash) {
- return;
- }
+ // maybe update, if hash is not consistent
+ if (updateInfo.hash == newHash) return;
updateInfo.hash = newHash;
this.entityUpdateInfo.set(entity.id, updateInfo);
@@ -102,7 +105,7 @@ export class NetworkUpdate extends System {
}
}
- private getNextUpdateInterval(): number {
- return Math.random() * 30;
+ private getNextUpdateInterval() {
+ return Math.random() * 30 + 20;
}
}
diff --git a/server/src/server.ts b/server/src/server.ts
index 575e916..3beebd5 100644
--- a/server/src/server.ts
+++ b/server/src/server.ts
@@ -42,7 +42,9 @@ export class GameServer {
fetch: (req, srv) => this.fetchHandler(req, srv),
websocket: {
open: (ws) => this.openWebsocket(ws),
- message: (ws, msg) => this.websocketMessage(ws, msg),
+ message: (ws, msg) => {
+ if (typeof msg === 'string') this.websocketMessage(ws, msg);
+ },
close: (ws) => this.closeWebsocket(ws)
}
});
@@ -54,21 +56,19 @@ export class GameServer {
private websocketMessage(
websocket: ServerWebSocket<SessionData>,
- message: string | Uint8Array
+ message: string
) {
- if (typeof message == 'string') {
- const receivedMessage = parse<ServerMessage>(message);
- receivedMessage.sessionData = websocket.data;
+ const receivedMessage = parse<ServerMessage>(message);
+ receivedMessage.sessionData = websocket.data;
- this.messageReceiver.addMessage(receivedMessage);
- }
+ this.messageReceiver.addMessage(receivedMessage);
}
private closeWebsocket(websocket: ServerWebSocket<SessionData>) {
const { sessionId } = websocket.data;
const sessionEntities =
- this.sessionManager.getSession(sessionId)!.controllableEntities;
+ this.sessionManager.getSession(sessionId)?.controllableEntities;
this.sessionManager.removeSession(sessionId);
if (!sessionEntities) return;