make next update interval a property on network update component instead of inheritable attribute on entities
This commit is contained in:
parent
c551f519ca
commit
29ba1c29d7
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user