The Entity Factory System provides a unified approach to creating and managing game entities with consistent APIs across all entity types. This system handles both local (client-only) and networked (server-synchronized) entity creation.
Each entity type defines its own factory using the createFactory utility, which generates three standardized methods:
createLocal- Creates local entities (no server synchronization)createNetworked- Creates networked entities (synchronized with server via API)createNetworkedFromLocal- Converts existing local entities to networked
Each entity defines its factory in its corresponding factory file:
// src/objects/spruceTree/factory.tsx
import { createFactory } from "../../utilities/createFactory";
import type { NetworkSyncConfig } from "../../objects/traits/network";
const SpruceTreeNetworkConfig: NetworkSyncConfig = {
syncTraits: ['position', 'placeable'],
syncFrequency: 'batched',
priority: 'normal',
persistent: true
};
export const spruceTreeFactory = createFactory({
factoryFn: createStandardSpruceTree,
network: SpruceTreeNetworkConfig
});All factories are exposed through the WorldObjects registry:
// src/worldObjects.ts
import { assemblerFactory } from "./objects/assembler";
import { spruceTreeFactory } from "./objects/spruceTree/factory";
export const WorldObjects = {
assembler: assemblerFactory,
spruceTree: spruceTreeFactory,
} as const;import { WorldObjects } from "../worldObjects";
// Create local entities (no server sync)
const localSpruce = WorldObjects.spruceTree.createLocal(game, { x: 100, y: 200 });
const localAssembler = WorldObjects.assembler.createLocal(game, { x: 300, y: 400 });
// Create networked entities (server sync with API requests)
const networkedSpruce = await WorldObjects.spruceTree.createNetworked(game, { x: 100, y: 200 });
const networkedAssembler = await WorldObjects.assembler.createNetworked(game, { x: 300, y: 400 });
// Convert local entities to networked
const converted = await WorldObjects.spruceTree.createNetworkedFromLocal(localSpruce, game);- Created instantly on the client
- No server communication
- Useful for previews, temporary objects, and UI elements
- Can be converted to networked entities later
- Make API requests to the server for creation
- Server validates and responds with
entity_placedwebsocket event - Automatically synchronized with other clients
- Include NetworkTrait for ongoing state synchronization
- Extract position and properties from local entity
- Remove local entity from the game world
- Request networked entity creation from server
- Server creates and broadcasts to all clients
Each entity type defines its synchronization behavior:
const NetworkConfig: NetworkSyncConfig = {
syncTraits: ['position', 'placeable'], // Which traits sync to server
syncFrequency: 'batched', // How often to sync ('immediate' | 'batched')
priority: 'normal', // Sync priority ('high' | 'normal' | 'low')
persistent: true // Whether entity persists on server
};- Consistency: All entities use the same factory API
- Type Safety: Full TypeScript support with proper typing
- Server-First: Networked entities always validated by server
- Flexibility: Easy conversion between local and networked entities
- Maintainability: Centralized factory logic with minimal boilerplate
-
Create the base factory function:
export function createStandardMyEntity(game: Game, opts: { position: Position }): MyEntity { // Entity creation logic return entity; }
-
Define network configuration:
const MyEntityNetworkConfig: NetworkSyncConfig = { syncTraits: ['position', 'placeable'], syncFrequency: 'batched', priority: 'normal', persistent: true };
-
Create and export the factory:
export const myEntityFactory = createFactory({ factoryFn: createStandardMyEntity, network: MyEntityNetworkConfig });
-
Add to WorldObjects registry:
export const WorldObjects = { myEntity: myEntityFactory, // ... other entities } as const;
try {
const entity = await WorldObjects.spruceTree.createNetworked(game, { x, y });
} catch (error) {
console.error("Failed to create networked entity:", error);
// Fallback to local entity if needed
const localEntity = WorldObjects.spruceTree.createLocal(game, { x, y });
}The factory system provides a robust, scalable foundation for entity management that supports both single-player and multiplayer gameplay scenarios.