// Node. import msgpack from 'msgpack-lite'; import {performance} from 'perf_hooks'; // 3rd party. // 2nd party. import {Synchronizer} from '@avocado/state'; import {Ticker} from '@avocado/timing'; // 1st party. import {InputPacket} from '../common/packet'; import {WorldTime} from '../common/world-time'; import {createEntityForConnection} from './create-entity-for-connection'; import {createRoom} from './create-server-room'; // Create game. export default function() { setInterval(createMainLoop(), 1000 / 80); return createConnectionListener(); } // Create room. const room = createRoom(); // Time :) const worldTime = new WorldTime(); worldTime.hour = 10; // Entity tracking. const informables = []; const synchronizer = new Synchronizer({ room, worldTime, }); // Connection listener. function createConnectionListener() { return (socket) => { // Create and track a new entity for the connection. const entity = createEntityForConnection(socket); // Track informables. informables.push(entity); entity.on('destroyed', () => { const index = informables.indexOf(entity); if (-1 !== index) { informables.splice(index, 1); } }); // Add entity to room. room.addEntityToLayer(entity, 'everything'); // Initial information. entity.inform(synchronizer.state); // Listen for events. socket.on('packet', createPacketListener(socket)); socket.on('disconnect', createDisconnectionListener(socket)); } } // Handle incoming messages. function createPacketListener(socket) { const {entity} = socket; return (packet) => { if (packet instanceof InputPacket) { entity.inputState = packet.toState(); } }; } // Handle disconnection. function createDisconnectionListener(socket) { const {entity} = socket; return () => { entity.destroy(); }; } // Main loop. let lastTime = performance.now(); const informTicker = new Ticker(1 / 40); informTicker.on('tick', () => { // Inform entities of the new state. for (const entity of informables) { entity.inform(synchronizer.state); } }); function createMainLoop() { return () => { const now = performance.now(); const elapsed = (now - lastTime) / 1000; lastTime = now; // Tick synchronized. synchronizer.tick(elapsed); // Tick informer. informTicker.tick(elapsed); } }