humus-old/server/game.js

87 lines
2.3 KiB
JavaScript
Raw Normal View History

2019-03-20 15:28:18 -05:00
// Node.
2019-04-13 18:42:53 -05:00
import msgpack from 'msgpack-lite';
2019-03-20 15:28:18 -05:00
import {performance} from 'perf_hooks';
// 3rd party.
// 2nd party.
2019-04-07 20:04:34 -05:00
import {Synchronizer} from '@avocado/state';
2019-04-09 09:55:25 -05:00
import {Ticker} from '@avocado/timing';
2019-03-27 15:51:58 -05:00
// 1st party.
2019-04-11 15:27:39 -05:00
import {InputPacket} from '../common/packet';
2019-04-04 07:31:21 -05:00
import {WorldTime} from '../common/world-time';
2019-03-27 15:51:58 -05:00
import {createEntityForConnection} from './create-entity-for-connection';
import {createRoom} from './create-server-room';
2019-03-20 15:28:18 -05:00
// Create game.
2019-04-03 17:34:15 -05:00
export default function() {
setInterval(createMainLoop(), 1000 / 80);
return createConnectionListener();
2019-03-20 15:28:18 -05:00
}
2019-03-27 15:51:58 -05:00
// Create room.
const room = createRoom();
2019-04-04 07:31:21 -05:00
// Time :)
2019-04-04 17:18:55 -05:00
const worldTime = new WorldTime();
2019-04-07 14:14:05 -05:00
worldTime.hour = 10;
2019-03-27 01:52:55 -05:00
// Entity tracking.
const informables = [];
2019-04-07 20:04:34 -05:00
const synchronizer = new Synchronizer({
2019-03-27 01:52:55 -05:00
room,
2019-04-04 17:18:55 -05:00
worldTime,
2019-03-27 01:52:55 -05:00
});
2019-03-20 15:28:18 -05:00
// Connection listener.
2019-04-03 17:34:15 -05:00
function createConnectionListener() {
2019-03-20 15:28:18 -05:00
return (socket) => {
// Create and track a new entity for the connection.
const entity = createEntityForConnection(socket);
2019-03-27 15:51:58 -05:00
// Track informables.
informables.push(entity);
entity.on('destroyed', () => {
const index = informables.indexOf(entity);
if (-1 !== index) {
informables.splice(index, 1);
}
});
// Add entity to room.
2019-03-27 17:16:09 -05:00
room.addEntityToLayer(entity, 'everything');
2019-04-08 08:01:17 -05:00
// Initial information.
entity.inform(synchronizer.state);
2019-03-20 15:28:18 -05:00
// Listen for events.
2019-04-11 15:27:39 -05:00
socket.on('packet', createPacketListener(socket));
2019-04-03 17:34:15 -05:00
socket.on('disconnect', createDisconnectionListener(socket));
2019-03-20 15:28:18 -05:00
}
}
// Handle incoming messages.
2019-04-11 15:27:39 -05:00
function createPacketListener(socket) {
2019-03-20 15:28:18 -05:00
const {entity} = socket;
2019-04-11 15:27:39 -05:00
return (packet) => {
if (packet instanceof InputPacket) {
2019-04-13 19:16:42 -05:00
entity.inputState = packet.toState();
2019-03-20 15:28:18 -05:00
}
};
}
// Handle disconnection.
2019-04-03 17:34:15 -05:00
function createDisconnectionListener(socket) {
2019-03-20 15:28:18 -05:00
const {entity} = socket;
return () => {
entity.destroy();
2019-03-20 15:28:18 -05:00
};
}
// Main loop.
let lastTime = performance.now();
const informTicker = new Ticker(1 / 40);
2019-04-09 09:55:25 -05:00
informTicker.on('tick', () => {
// Inform entities of the new state.
for (const entity of informables) {
entity.inform(synchronizer.state);
}
});
2019-04-03 17:34:15 -05:00
function createMainLoop() {
2019-03-20 15:28:18 -05:00
return () => {
const now = performance.now();
const elapsed = (now - lastTime) / 1000;
lastTime = now;
2019-04-07 15:16:12 -05:00
// Tick synchronized.
2019-04-07 20:04:34 -05:00
synchronizer.tick(elapsed);
2019-04-09 09:55:25 -05:00
// Tick informer.
informTicker.tick(elapsed);
2019-03-20 15:28:18 -05:00
}
}