Update server.js
Browse files
server.js
CHANGED
|
@@ -4,28 +4,34 @@ const { Server } = require('socket.io');
|
|
| 4 |
|
| 5 |
const app = express();
|
| 6 |
const server = http.createServer(app);
|
| 7 |
-
const io = new Server(server, {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
app.use(express.static('public'));
|
| 10 |
|
| 11 |
// GLOBAL STATE
|
| 12 |
const players = {};
|
|
|
|
| 13 |
const GLOBAL_SEED = Math.floor(Math.random() * 1000000);
|
| 14 |
|
| 15 |
io.on('connection', (socket) => {
|
| 16 |
-
// 1. Send configuration
|
| 17 |
socket.emit('config', { seed: GLOBAL_SEED });
|
| 18 |
|
| 19 |
// 2. Player joins
|
| 20 |
socket.on('join', (data) => {
|
| 21 |
players[socket.id] = {
|
| 22 |
id: socket.id,
|
| 23 |
-
name: data.name.substring(0, 12)
|
| 24 |
skin: data.skin || "square",
|
| 25 |
x: 0,
|
| 26 |
y: 0,
|
| 27 |
score: 0,
|
| 28 |
-
isDead: false
|
|
|
|
| 29 |
};
|
| 30 |
});
|
| 31 |
|
|
@@ -33,39 +39,49 @@ io.on('connection', (socket) => {
|
|
| 33 |
socket.on('update', (data) => {
|
| 34 |
const p = players[socket.id];
|
| 35 |
if (p) {
|
| 36 |
-
|
| 37 |
-
p.
|
| 38 |
-
p.
|
| 39 |
-
p.
|
| 40 |
-
p.
|
| 41 |
-
p.score = data
|
| 42 |
-
p.isDead = data
|
|
|
|
| 43 |
}
|
| 44 |
});
|
| 45 |
|
| 46 |
-
// 4. Handle Disconnect
|
| 47 |
socket.on('disconnect', () => {
|
| 48 |
delete players[socket.id];
|
| 49 |
});
|
| 50 |
});
|
| 51 |
|
| 52 |
-
// BROADCAST LOOP (
|
|
|
|
|
|
|
| 53 |
setInterval(() => {
|
| 54 |
const pack = [];
|
| 55 |
const leaderboard = [];
|
|
|
|
| 56 |
|
| 57 |
for (const id in players) {
|
| 58 |
const p = players[id];
|
| 59 |
|
| 60 |
-
//
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
|
| 70 |
if (!p.isDead) {
|
| 71 |
leaderboard.push({ name: p.name, score: p.score });
|
|
@@ -76,11 +92,12 @@ setInterval(() => {
|
|
| 76 |
leaderboard.sort((a, b) => b.score - a.score);
|
| 77 |
const top3 = leaderboard.slice(0, 3);
|
| 78 |
|
| 79 |
-
|
|
|
|
| 80 |
|
| 81 |
-
},
|
| 82 |
|
| 83 |
const PORT = process.env.PORT || 3000;
|
| 84 |
server.listen(PORT, () => {
|
| 85 |
-
console.log(`Server running on port ${PORT}`);
|
| 86 |
});
|
|
|
|
| 4 |
|
| 5 |
const app = express();
|
| 6 |
const server = http.createServer(app);
|
| 7 |
+
const io = new Server(server, {
|
| 8 |
+
cors: { origin: "*" },
|
| 9 |
+
pingInterval: 2000,
|
| 10 |
+
pingTimeout: 5000
|
| 11 |
+
});
|
| 12 |
|
| 13 |
app.use(express.static('public'));
|
| 14 |
|
| 15 |
// GLOBAL STATE
|
| 16 |
const players = {};
|
| 17 |
+
// A static seed ensuring everyone gets the exact same map logic
|
| 18 |
const GLOBAL_SEED = Math.floor(Math.random() * 1000000);
|
| 19 |
|
| 20 |
io.on('connection', (socket) => {
|
| 21 |
+
// 1. Send configuration immediately
|
| 22 |
socket.emit('config', { seed: GLOBAL_SEED });
|
| 23 |
|
| 24 |
// 2. Player joins
|
| 25 |
socket.on('join', (data) => {
|
| 26 |
players[socket.id] = {
|
| 27 |
id: socket.id,
|
| 28 |
+
name: (data.name || "Guest").substring(0, 12),
|
| 29 |
skin: data.skin || "square",
|
| 30 |
x: 0,
|
| 31 |
y: 0,
|
| 32 |
score: 0,
|
| 33 |
+
isDead: false,
|
| 34 |
+
lastSeen: Date.now()
|
| 35 |
};
|
| 36 |
});
|
| 37 |
|
|
|
|
| 39 |
socket.on('update', (data) => {
|
| 40 |
const p = players[socket.id];
|
| 41 |
if (p) {
|
| 42 |
+
// Data comes in array: [x, y, vx, vy, score, isDead]
|
| 43 |
+
p.x = data[0];
|
| 44 |
+
p.y = data[1];
|
| 45 |
+
p.vx = data[2];
|
| 46 |
+
p.vy = data[3];
|
| 47 |
+
p.score = data[4];
|
| 48 |
+
p.isDead = data[5];
|
| 49 |
+
p.lastSeen = Date.now();
|
| 50 |
}
|
| 51 |
});
|
| 52 |
|
|
|
|
| 53 |
socket.on('disconnect', () => {
|
| 54 |
delete players[socket.id];
|
| 55 |
});
|
| 56 |
});
|
| 57 |
|
| 58 |
+
// BROADCAST LOOP (30 TPS)
|
| 59 |
+
// 30 times a second is the sweet spot for browser games.
|
| 60 |
+
// 60 TPS over internet often causes packet choking (the 0.1fps issue).
|
| 61 |
setInterval(() => {
|
| 62 |
const pack = [];
|
| 63 |
const leaderboard = [];
|
| 64 |
+
const now = Date.now();
|
| 65 |
|
| 66 |
for (const id in players) {
|
| 67 |
const p = players[id];
|
| 68 |
|
| 69 |
+
// Timeout check (remove stale players)
|
| 70 |
+
if (now - p.lastSeen > 10000) {
|
| 71 |
+
delete players[id];
|
| 72 |
+
continue;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
// COMPRESSION: Send Array instead of Object
|
| 76 |
+
// [id, x, y, skin, isDead, name]
|
| 77 |
+
pack.push([
|
| 78 |
+
p.id,
|
| 79 |
+
Math.round(p.x),
|
| 80 |
+
Math.round(p.y),
|
| 81 |
+
p.skin,
|
| 82 |
+
p.isDead ? 1 : 0,
|
| 83 |
+
p.name
|
| 84 |
+
]);
|
| 85 |
|
| 86 |
if (!p.isDead) {
|
| 87 |
leaderboard.push({ name: p.name, score: p.score });
|
|
|
|
| 92 |
leaderboard.sort((a, b) => b.score - a.score);
|
| 93 |
const top3 = leaderboard.slice(0, 3);
|
| 94 |
|
| 95 |
+
// Send world state
|
| 96 |
+
io.emit('w', { p: pack, l: top3 });
|
| 97 |
|
| 98 |
+
}, 33);
|
| 99 |
|
| 100 |
const PORT = process.env.PORT || 3000;
|
| 101 |
server.listen(PORT, () => {
|
| 102 |
+
console.log(`Server running on port ${PORT} | Seed: ${GLOBAL_SEED}`);
|
| 103 |
});
|