feat(server): wire StockpileLog into GameLoop and SocketServer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-03-09 02:48:23 +00:00
parent 9194a56848
commit 188a915732
2 changed files with 66 additions and 1 deletions
+26
View File
@@ -9,6 +9,8 @@ import { serializeWorldState, serializeStateUpdate } from './stateSerializer.js'
import { computeSuperlatives } from '../systems/superlativesComputer.js';
import type { BondRegistry } from '../systems/bondRegistry.js';
import type { InventionTimeline } from '../industry/inventionTimeline.js';
import type { StockpileLog } from '../industry/stockpileLog.js';
import type { StructureData } from '../systems/buildingSystem.js';
export class SocketServer {
private io: Server<ClientEvents, ServerEvents>;
@@ -51,6 +53,11 @@ export class SocketServer {
this.io.emit('invention-event', summary);
};
this.gameLoop.onStockpileEvent = (entry) => {
this.io.emit('stockpile-event', entry);
this.io.emit('stockpile-summary', this.computeStockpileSummary());
};
this.gameLoop.eventMemoryService.onEventRecorded = (entityId, event) => {
// Only send to clients following this NPC
for (const [socketId, followedId] of this.followedEntities) {
@@ -94,6 +101,13 @@ export class SocketServer {
socket.emit('invention-history', inventionTimeline.getSummaries());
}
// Send stockpile history and summary
const stockpileLog = this.gameLoop.world.getSingleton<StockpileLog>('stockpileLog');
if (stockpileLog) {
socket.emit('stockpile-history', stockpileLog.getRecent());
}
socket.emit('stockpile-summary', this.computeStockpileSummary());
// Notify others
socket.broadcast.emit('player-joined', { playerId, entityId: entity });
@@ -163,6 +177,18 @@ export class SocketServer {
});
}
private computeStockpileSummary(): Record<string, number> {
const summary: Record<string, number> = {};
for (const entity of this.gameLoop.world.query('structure')) {
const s = this.gameLoop.world.getComponent<StructureData>(entity, 'structure')!;
if (s.type !== 'stockpile' || s.buildProgress !== undefined) continue;
for (const [itemId, qty] of s.inventory) {
summary[itemId] = (summary[itemId] ?? 0) + qty;
}
}
return summary;
}
private broadcastSuperlatives(): void {
if (this.superlativesSubscribers.size === 0) return;
const registry = this.gameLoop.world.getSingleton<BondRegistry>('bondRegistry');