Initial commit

This commit is contained in:
2026-08-24 22:20:36 +02:00
commit 62f7b1278a
251 changed files with 16670 additions and 0 deletions
+191
View File
@@ -0,0 +1,191 @@
const GAME_TICKRATE = 1000 / 30;
const INACTIVITY_THRESHOLD_MS = 5 * 60000;
let looseAccumulator = 0;
let accumulator = 0;
let difference = 0;
let n = performance.now();
let nn = Date.now();
let batch = {};
let isLooseIteration = false;
const packet = require("./Packets/packet");
const Game = require("./Game/Game");
const getFixedDate = require("./Utility/getFixedDate");
const packetRelevancies = require("./Data/packetRelevancies");
const constants = require("./Data/constants");
const { TIMING_EVENTS_BY_ID } = constants;
function gameLoop() {
difference = performance.now() - n;
accumulator += difference;
n = performance.now();
nn = Date.now();
if (accumulator > GAME_TICKRATE) {
Game.maps.forEach(map => {
map.eventAuthors.forEach(id => {
const currentFlush = map.eventBuffer[id];
const entity = map.getEntityFromSubgroup(currentFlush.target);
if (entity) entity.emit("attacking", currentFlush.data, currentFlush.author);
});
if (looseAccumulator === 15) {
looseAccumulator = 0;
isLooseIteration = true;
};
map.players.forEach(player => {
if (isLooseIteration) {
player.isInactive = player.lastInteractionTimestamp + INACTIVITY_THRESHOLD_MS < n;
player.refreshVisibilities(false);
if (player.isInactive) player.setIndependentEvent(4, 0);
};
if (player.hasUnexpectedlyLeft) return;
player.flush(1);
batch.packet = null;
batch.offset = 0;
const localPacketsLength = map.networkPacketsLocal.length;
const individual = map.networkPacketsInvidiual[player.id];
if (!localPacketsLength && individual)
for (let i = 0, length = individual.length; i < length; i++) batch = packet(individual[i].packet, batch, player.id, individual[i].metadata);
if (localPacketsLength)
for (let i = 0, j = 0; i < localPacketsLength; i++) {
const p = map.networkPacketsLocal[i];
const relevancyRequirement = packetRelevancies[p.header];
if (relevancyRequirement(player, p)) batch = packet(p.packet, batch, player.id, p.metadata);
if (individual)
while (j < individual.length && (i === individual[j].index || i === localPacketsLength - 1)) {
batch = packet(individual[j].packet, batch, player.id, individual[j].metadata);
j++;
};
};
for (let i = 0, length = map.testPackets.length; i < length; i++) {
const p = map.testPackets[i];
const relevancyRequirement = packetRelevancies[p.header];
if (relevancyRequirement(player, p)) batch = packet(p.packet, batch, player.id, p.metadata);
};
for (let i = 0, length = map.networkPacketsGlobal.length; i < length; i++) {
const p = map.networkPacketsGlobal[i];
batch = packet(p.packet, batch, player.id, p.metadata);
};
if (player.topics) {
player.topics.each((key, value) => {
for (let i = 0, length = value.length; i < length; i++) {
const p = value[i];
batch = packet(p, batch, player.id);
};
});
};
if (batch.offset) {
const packet = batch.packet.slice(0, batch.offset);
const session = socket.sockets[player.sessionID];
session.send(packet, true, true);
};
if (individual) individual.length = 0;
});
map.testPackets.length = 0;
map.networkPacketsGlobal.length = 0;
map.eventAuthors.length = 0;
map.eventBuffer = {};
map.packetCount = map.networkPacketsLocal.length;
map.networkPacketsLocal.length = 0;
if (isLooseIteration) {
map.towers.forEach(tower => {
if (!tower.searchedTarget) return;
tower.initializeAttackWithCannon(tower.searchedTarget);
tower.searchedTarget = null;
});
map.lookingForTarget.forEach(e => e.initializeAttackWithCannon(e.searchedTarget));
map.lookingForTarget.length = 0;
map.dirtyChunks.forEach(c => {
c.map.clear();
c.head = null;
c.tail = null;
});
};
});
Game.packets.each((_, value) => {
if (value.length > 0) console.info("Topic length", value.length, "All topics length", Game.packets.map.size)
value.length = 0
});
const closest = Game.events.peek();
if (closest && n >= closest.value)
Game.events.forEach(entry => {
if (n < entry.value) return false;
const event = Game.events.poll();
const { id, entity, index, getLocalization, data, isSingle } = event.obj;
const mapID = getLocalization();
const map = Game.maps[mapID - 1];
const entityInstance = map.getEntityFromSubgroup(entity.id);
const eventExists = entityInstance && entityInstance.events[id] && entityInstance.events[id][index];
const isCancelled = eventExists && entityInstance.events[id][index].isCancelled;
if (isSingle && eventExists) entityInstance.events[id][index].isOver = true;
if (!isCancelled && eventExists) {
const methodName = TIMING_EVENTS_BY_ID[id];
entityInstance[methodName](data);
};
return true;
});
const closestFixed = Game.eventsFixed.peek();
if (closestFixed && nn >= closestFixed.value)
Game.eventsFixed.forEach(entry => {
if (nn < entry.value) return false;
const event = Game.eventsFixed.poll();
const { fn, arguments, next } = event.obj;
fn(...arguments);
if (next) {
const nextRunDate = getFixedDate(30);
next(nextRunDate, event.obj);
};
return true;
});
isLooseIteration = false;
looseAccumulator++;
accumulator -= GAME_TICKRATE;
};
if (difference < GAME_TICKRATE - 32) setTimeout(() => gameLoop());
else setImmediate(() => gameLoop());
};
module.exports = gameLoop;