import { ObjectType, v } from 'convex/values'; import { Conversation, serializedConversation } from './conversation'; import { Player, serializedPlayer } from './player'; import { Agent, serializedAgent } from './agent'; import { GameId, parseGameId, playerId } from './ids'; import { parseMap } from '../util/object'; import { DayNightCycle, SerializedDayNightCycle, dayNightCycleSchema } from './dayNightCycle'; export const historicalLocations = v.array( v.object({ playerId, location: v.bytes(), }), ); export const serializedWorld = { nextId: v.number(), conversations: v.array(v.object(serializedConversation)), players: v.array(v.object(serializedPlayer)), agents: v.array(v.object(serializedAgent)), historicalLocations: v.optional(historicalLocations), dayNightCycle: v.object(dayNightCycleSchema), }; export type SerializedWorld = ObjectType; export class World { nextId: number; conversations: Map, Conversation>; players: Map, Player>; agents: Map, Agent>; historicalLocations?: Map, ArrayBuffer>; dayNightCycle: DayNightCycle; constructor(serialized: SerializedWorld) { const { nextId, historicalLocations } = serialized; this.nextId = nextId; this.conversations = parseMap(serialized.conversations, Conversation, (c) => c.id); this.players = parseMap(serialized.players, Player, (p) => p.id); this.agents = parseMap(serialized.agents, Agent, (a) => a.id); this.dayNightCycle = new DayNightCycle(serialized.dayNightCycle); if (historicalLocations) { this.historicalLocations = new Map(); for (const { playerId, location } of historicalLocations) { this.historicalLocations.set(parseGameId('players', playerId), location); } } } playerConversation(player: Player): Conversation | undefined { return [...this.conversations.values()].find((c) => c.participants.has(player.id)); } serialize(): SerializedWorld { return { nextId: this.nextId, conversations: [...this.conversations.values()].map((c) => c.serialize()), players: [...this.players.values()].map((p) => p.serialize()), agents: [...this.agents.values()].map((a) => a.serialize()), historicalLocations: this.historicalLocations && [...this.historicalLocations.entries()].map(([playerId, location]) => ({ playerId, location, })), dayNightCycle: this.dayNightCycle.serialize(), }; } }