Multiplayer Game Server Architecture: Authoritative vs Peer-to-Peer
Cum alegi intre server authoritative si peer-to-peer pentru jocul tau. Arhitecturi, stackuri, costuri, capcane in productie si cand are sens un model hibrid.

Daca alegi modelul de retea gresit, vei plati dublu: costuri de hosting care explodeaza sau luni de anti-cheat pompate intr-o arhitectura imposibil de aparat. Decizia authoritative vs peer-to-peer nu e filosofie — e una care se vede in ping, in churn si in buget.
Pe scurt: jocurile competitive, cu economie server-side si risc de cheat, merg pe server authoritative. Jocurile co-op casual, fightere cu 2–4 jucatori sau RTS determinist merg bine pe P2P cu rollback/lockstep. In continuare intram in arhitecturi concrete, trade-off-uri reale, costuri si pitfall-uri de productie.
Modelele principale: authoritative si peer-to-peer
Exista trei familii practice de modele:
- Server authoritative: clientii trimit input, serverul simuleaza adevarul, trimite snapshot-uri, aplica anti-cheat si persistenta. Folosit in shootere, battle royale, MMO, survival cu economie.
- Peer-to-peer (P2P) determinist: toti clientii ruleaza aceeasi simulare determinista (RTS-uri clasice). Comunica doar inputuri in lockstep. Sensibil la desync si la comenzi deterministe stricte.
- P2P cu rollback netcode: folosit in fightere/arcade 1v1–1v4. Clientii prezic local, sincronizeaza inputurile pe cadre si re-executa un buffer de stari cand sosesc inputuri intarziate. Latenta perceputa scade mult.
Mai exista si hibridul host-authoritative (un jucator e „serverul”), bun pentru co-op mic, dar cu riscuri de cheat si stabilitate la host migration.
Cand alegi ce: situatii tipice
- FPS/TPS competitiv (ranked, esports): server authoritative cu tick 30–60 Hz, lag compensation pe lovituri, anti-cheat, matchmaking regional. P2P aici e aproape intotdeauna o idee proasta.
- Fighter 1v1: P2P cu rollback (GGPO-like), target 120 Hz sim intern, frame delay configurabil. Autoritative doar pentru rating/economie.
- RTS determinist: P2P lockstep cu input-delay mic si verificare de desync (hash al starii). Server optional pentru lobby si replays.
- Co-op casual (4–8 jucatori), survival PVE: host-authoritative sau P2P cu migrare de host; daca ai economie/persistenta serioasa (tranzactii, monetizare), muta-le server-side.
- Jocuri browser/Telegram Mini Apps cu minigame realtime: WebRTC datachannels P2P cu un relay fallback; authoritative doar pentru anti-cheat minim si scoruri.
Regula pragmatica: daca integritatea competitiva si marketplace-ul conteaza, authoritative. Daca ritmul e local, mic grup si vrei cost zero la servere, P2P/host.
Arhitectura server authoritative, pe concret
Flux de date si componente
- Client trimite
input(comenzi cu secventa si timestamp) prin UDP/QUIC sau WebSocket. - Serverul ruleaza simularea pe tick fix (de ex. 60 Hz), aplica input-urile in ordinea corecta, simuleaza fizica, lovituri si gameplay authoritative.
- Serverul emite
state deltas/snapshotscatre clienti, cu compresie si relevanta per jucator (area-of-interest). - Clientul face
client-side predictionsireconciliationpe bazalastAckInputprimit de la server; interpoleaza alte entitati pentru net-smoothing. - Persistenta: serverul scrie in Postgres (inventar, progres), foloseste Redis pentru matchmaking/session dir si coada de mesaje. Telemetrie in Prometheus + Grafana. Rate limiting si DDoS scrubbing la edge (Cloudflare Magic Transit/Spectrum pentru UDP, sau un ELB/NLB cu GameLift/Agones pentru TCP/QUIC).
Stackuri tipice:
- Unreal Engine 5 Dedicated Server + Epic Online Services (matchmaking, lobbies), sau AWS GameLift/Agones pentru orchestrare.
- Unity headless + Netcode for GameObjects/Netcode for Entities (ECS) cu Photon/Fish-Networking sau Relay propriu.
- Node.js/TypeScript cu Colyseus pentru jocuri 2D/party; Go/C++ custom pentru performanta maxima; Nakama (Go + Postgres + Redis) pentru backend social/persistenta.
- Transport: ENet/RakNet (UDP cu fiabilitate optionala), QUIC (HTTP/3), Steam Networking Sockets pentru ecosistem Steam, WebRTC pentru browser/mobile cu NAT traversal (STUN/TURN).
Ciclu de server si reconciliere
Un server authoritative minimalist in TypeScript cu WebSocket (demonstrativ pentru prototipuri):
import WebSocket, { WebSocketServer } from 'ws';
type Input = { seq: number; dt: number; ax: number; ay: number; fire: boolean; ts: number };
type Player = { id: string; x: number; y: number; vx: number; vy: number; lastAck: number };
const TICK = 1000 / 60; // 60 Hz
const players = new Map<string, Player>();
const inputQueue = new Map<string, Input[]>();
const wss = new WebSocketServer({ port: 8080 });
wss.on('connection', (ws) => {
const id = crypto.randomUUID();
players.set(id, { id, x: 0, y: 0, vx: 0, vy: 0, lastAck: 0 });
inputQueue.set(id, []);
ws.on('message', (buf) => {
const msg = JSON.parse(buf.toString());
if (msg.t === 'inp') {
// sanitize input
const i: Input = {
seq: Math.min(msg.seq ?? 0, 1e9),
dt: Math.min(Math.max(msg.dt ?? 16, 1), 50),
ax: Math.max(Math.min(msg.ax ?? 0, 1), -1),
ay: Math.max(Math.min(msg.ay ?? 0, 1), -1),
fire: !!msg.fire,
ts: Date.now()
};
inputQueue.get(id)!.push(i);
}
});
ws.on('close', () => {
players.delete(id);
inputQueue.delete(id);
});
});
function simPlayer(p: Player, inp: Input) {
const accel = 20; // units/s^2
p.vx += inp.ax * accel * (inp.dt / 1000);
p.vy += inp.ay * accel * (inp.dt / 1000);
// clamp speed
const maxV = 6;
const sp = Math.hypot(p.vx, p.vy);
if (sp > maxV) { p.vx *= maxV / sp; p.vy *= maxV / sp; }
p.x += p.vx * (inp.dt / 1000);
p.y += p.vy * (inp.dt / 1000);
}
setInterval(() => {
// apply inputs per player, in order
for (const [id, p] of players) {
const q = inputQueue.get(id)!;
q.sort((a, b) => a.seq - b.seq);
for (const inp of q.splice(0, q.length)) {
// anti-cheat minimal: drop old/too-fast inputs
if (Date.now() - inp.ts > 500) continue;
simPlayer(p, inp);
p.lastAck = inp.seq;
}
}
// broadcast snapshot deltas
const state = [] as any[];
for (const p of players.values()) state.push({ id: p.id, x: p.x, y: p.y, vx: p.vx, vy: p.vy });
const msg = JSON.stringify({ t: 'snap', tsv: Date.now(), state });
for (const client of wss.clients) {
if (client.readyState === WebSocket.OPEN) client.send(msg);
}
}, TICK);
Acesta este un schelet pentru prototip, nu productie. In productie adaugi: delta-compression (zstd), relevanta per jucator, lag compensation (reconstruiesti scenele la ts - RTT pentru hit-scan), limitari pe input rate si verificari de fisica anti-cheat pe server.
Lag compensation si anti-cheat
- Lag compensation: stochezi un istoric de pozitii pe ~200 ms; cand primesti un
firecu timestamp client, faci raycast in starea istorica. Eviti „leading” nedrept pe ping mare. - Anti-cheat: semnatura client secure boot (EAC/BattleEye pentru PC), sanity checks pe server (viteze maxime, rate fire), verificari ale proiectilelor pe server, server nu accepta stari impuse de client. Pentru economie/inventory, scrierea e numai de pe server in DB.
Orchestrare si observabilitate
- Orchestrare: Agones pe Kubernetes pentru alocare dinamica de game servers; sau GameLift pentru AWS-first; scaling pe
Ready/Allocatedsi pe p95 CPU si memorie. - Observabilitate: Prometheus (tick time, p50/p95 latenta end-to-end, packet loss), Grafana dashboards, logs structurate in Loki/ELK, sampling la profiluri CPU. Alarme pe crestere packet loss > 5% intr-o regiune.
Arhitectura P2P moderna: lockstep si rollback
P2P determinist (RTS)
- Toata simularea e determinista (fara floating nondeterminist, fara RNG necontrolat). Input-urile tuturor jucatorilor pentru „frame N” se colecteaza, apoi se avanseaza „in lockstep”.
- Daca un input lipseste, se asteapta un mic delay (input delay) sau se dropeaza jucatorul.
- Detectia desync: fiecare peer calculeaza un hash al starii la frame-uri cheie si le compara. Daca diverge, se opreste si se face resync/replay.
Instrumente: Steam Networking Sockets pentru transport P2P, EOS P2P, WebRTC datachannels (STUN/TURN). Pentru hashing: xxHash/CityHash pe bufere deterministe.
P2P cu rollback (fightere)
- Fiecare peer prezice inputurile lipsa pe cateva cadre, randeaza imediat, iar cand inputul real soseste, re-executa dintr-un buffer de stari (rollback window 6–10 frame-uri tipic).
- Cheia e performanta simularii per frame si memorie pentru state snapshot-uri. Eviti obiecte alocate masiv (GC spikes). ECS sau data-oriented ajuta.
- Host election si NAT traversal: STUN pentru descoperire, TURN/relays numai cand nu exista direct path (costa egress). Steam/EOS ofera relays proprietare.
Avantaje P2P: cost aproape zero pe server (in afara de relays/matchmaking), latenta „simtita” mai mica la rollback, uptime independent de cloud. Dezavantaje: risc de cheat (man-in-the-middle, mem-edit), complexitate pentru determinism si desync handling, NAT si firewall.
Tabel comparativ al compromisurilor
| Criteriu | Server authoritative | P2P (lockstep/rollback) |
|---|---|---|
| Integritate anti-cheat | Foarte buna (server decide) | Slaba-medie (host/peers pot trișa) |
| Complexitate implementare | Medie-ridicata (server + client) | Ridicata (determinism/rollback) |
| Cost OPEX | Mediu-ridicat (compute + egress) | Redus (doar relays si servicii auxiliare) |
| Latenta perceputa | Buna cu prediction/compensation | Excelenta la rollback, proasta la lockstep |
| Scalare la mii de CCU | Liniara cu orchestrare | Aproape gratuita la transport, greu la NAT |
| Persistenta/economie | Naturala pe server | Necesita un server auxiliar |
| Cross-play si mobile | Simplu cu server relay | Posibile probleme NAT/OS |
| Rezilienta DDoS | Mai buna cu edge scrubbing | Peer IP expus, dificil |
Nimic nu e „magie”: daca vrei cost mic, vei plati in complexitate sau in risc de cheat. Daca vrei integritate, platesti servere si operare. Ingineria e, uneori, despre care factura preferi sa o platesti.
Ce se strica in productie
- Tick drift si GC: la Node/Java/C# poti avea stop-the-world care rupe tick-ul de 60 Hz. Rezolvi cu profiling, pool-uri de obiecte, ECS/data-oriented, sau limbaje cu GC predictibil/arena alloc (C++/Rust/Go cu grija).
- Packet loss si reorder (UDP): implementeaza sequence numbers, ack/NAK, si retransmisie selectiva pe canale fiabile. Pentru lovituri: trimite doar evenimente, nu stari masive.
- NAT traversal: simetrice NAT blocheaza P2P; pregateste TURN/relays si rate-limiting. Pe mobile, comutarea Wi-Fi/5G pierde conexiunea — reconectare la sesiune si resync rapid.
- DDoS si scraping IP: ascunde IP-urile serverelor in authoritative (proxies/anycast). In P2P, IP-urile peerilor pot fi expuse; foloseste relays in regiuni sensibile.
- Migrare de host: in host-authoritative, cand host-ul iese, migrezi statul la alt peer. Testeaza intens — pierderi de pachete in timpul migrarii = desync si rage quit.
- Clock drift: pentru lag compensation si anti-cheat, sincronizeaza ceasurile (NTP, Steam clock). Nu te baza pe
Date.now()din client pentru adevar absolut. - Persistenta lenesa: scrieri mari la final de meci pot bloca DB; fa write-through incremental si batch-uri. Optimizarea ordonarii in DB conteaza; vezi bune practici de indecsi si sortari in evolutia ORDER BY.
- Edge si patching: update-uri gresite la proxy pot rupe WebSocket/UDP (reguli MTU, Path MTU Discovery). Monitorizeaza erorile 4xx/5xx la edge; cand folosesti Nginx/Envoy, ramane valabil principiul „nu atinge in vineri seara” — a fost scris cu sange de SRE.
Cost si ROI: cum bugetezi corect
Nu exista pret unic, dar poti face o planificare „ordine de marime”.
Compute si densitate de sesiuni
- Un server authoritative CPU-bound de shooter la 60 Hz poate sustine 60–100 jucatori pe 4 vCPU daca sim-ul e eficient. Un match 10v10 pe 2 vCPU este realist pentru jocuri 3D moderate. Jocurile 2D/party pot atinge 200–500 jucatori/4 vCPU.
- Densitate creste daca faci area-of-interest si trunchiere de fizica. Scade daca ai proiectile balistice si destructibilitate.
Exemplu aproximativ: o instanta 8 vCPU (cloud general-purpose) la ~0.30 USD/ora poate rula 3–6 meciuri de 20 jucatori. La 1000 CCU medii, ai nevoie de 10–20 astfel de instante, deci ~72–144 USD/zi compute. Egress poate dubla costul.
Latime de banda si egress
- Snapshot/delta eficient: 20–80 kbps per client downlink in jocuri action; uplink 10–30 kbps per client. Egress public cloud costa; pe AWS/GCP poti vedea cateva sute USD/luna doar din traficul jocului la cateva mii CCU.
- P2P reduce egress server, dar relays TURN au cost mare cand intra in joc (transferul trece prin serverul tau oricum).
Servicii gestionate vs self-host
- GameLift/Multiplay/Photon Fusion reduc time-to-market, dar vei plati un premium per ora/conn. Bun pentru lansare/alpha; apoi poti trece la Agones self-host daca ai volum si echipa de SRE.
- Nakama (self-host) ofera matchmaking, prieteni, leaderboards; economisesti timp pe backend social.
Costul anti-cheat si QA
- Anti-cheat comercial (EAC/Battleye) are licentiere si integrare; dar te scuteste de luni de munca si reputatie stricata. In authoritative, tot ai nevoie de server-side sanity checks.
- QA netcode: setup lab cu retea emulata (tc/netem, Clumsy), scenarii cu 1–20% packet loss, jitter 10–100 ms, 3–5 dispozitive mobile reale per platforma. E mai ieftin sa simulezi acum decat sa-ti invete jucatorii termenii „teleport” si „desync”.
ROI pragmatic: authoritative creste retentia cand conteaza corectitudinea; P2P creste retentia cand conteaza latenta scazuta si zero friction. Alege dupa bucla ta de joc si modelul de monetizare.
Modele hibride si exceptii utile
- Hibrid „server pentru economie, P2P pentru moment-to-moment”: serverul valideaza tranzactii, progres, crafting; combat-ul local e P2P/rollback. Bun la co-op survival.
- Host-authoritative cu validare server-side pe evenimente critice (loot, boss kill). Daca pica host-ul, faci upload incremental de state pe un relay, pentru migrari rapide.
- Determinist P2P cu „arbiter server”: in caz de conflict/cheat detection, serverul arbitreaza si poate penaliza. Ajuta la ranked si leaderboarduri curate.
Stackuri recomandate pe tipuri de joc
- Shooter/BR competitiv: UE5 Dedicated Server + EOS (lobbies, auth) + Agones sau GameLift; transport ENet/Steam Sockets; Redis pentru matchmaking, Postgres pentru economie; Cloudflare Spectrum pentru UDP; Prometheus/Grafana/Loki pentru observabilitate.
- Co-op Unity 3D: Unity headless + Netcode for GameObjects, Relay (Photon/Crossplay Relay) + Host migration; economie pe server mic Node/Go + Postgres.
- Party 2D/Web: Colyseus (Node/TS) + WebSocket/WebRTC DataChannels; autoscaling pe Kubernetes; persista scoruri in Postgres; foloseste rate limiting la edge. Pentru optimizari de JS runtime, evaluarile despre ecosisteme ca Bun rescris in Rust pot inspira decizii de toolchain, dar nu inlocuiesc profilarea.
- RTS determinist: motor custom/Unity DOTS cu fixed-point math, P2P lockstep peste Steam/EOS; server subtire pentru lobby, replays, anti-abuz minimal.
- Fighter 1v1: GGPO-like rollback, P2P peste Steam/EOS/WebRTC; relay fallback; ranking si matchmaking pe backend Nakama/Go, verificari anti-boosting.
Pipeline de livrare
- Teste determinism: rulare dubla a aceluiasi demo, verificare hash state.
- Teste retea: scripturi
tcpentru latency/loss/jitter; canale CI care ruleaza smoke pe 30/60/120 Hz. - Canary rollout pe o singura regiune; daca p95 tick time trece pragul, opreste rollout-ul.
Ce trebuie masurat constant
- p50/p95/p99 RTT per regiune; packet loss; jitter; p95 tick time; rata de resync/rollback; disconnect rate per platforma; cost egress/CCU; densitate medie jucatori per instanta. Daca nu masori, optimizarile sunt doar opinii ambalate frumos.
Exemple de flux end-to-end (authoritative)
- Client trimite
Move{seq,ax,ay}la 60 Hz; serverul proceseaza pe tick; tinehistory[200ms]pentru lag compensation; la fiecare 100 ms trimiteDelta{entities in AOI}. Clientul reconciliaza pe bazalastAcksi interpoleaza alti jucatori pe 100 ms buffer. - Pentru lovituri: client trimite
Fire{seq,shootTS,dir}; server cauta in istoric pozitia tintei lashootTS - interpOffset, face raycast, decide hit, aplica damage si emite evenimentul.
Ce sa NU faci
- Sa trimiti de la client pozitii absolute drept „adevar”. Deschizi poarta la speedhack si teleport.
- Sa legi sim-ul de framerate. Foloseste fixed timestep si integrari corecte (ex.: semi-implicit Euler pentru fizica simpla).
- Sa depinzi de
Date.now()pentru sincronizare. Foloseste tick counters si offset server-time. - Sa pui toata logica in RPC-uri synchronous. Foloseste mesaje idempotente si stateless unde se poate.
FAQ
Q: De ce un server authoritative pare „mai laggy” desi e corect? A: Pentru ca serverul valideaza si trunchiaza update-urile; adauga prediction si reconciliation corect pe client. Tuning-ul bufferelor de interpolare si al lag compensation reduce perceputul.
Q: Pot face P2P fara riscuri de cheat? A: Nu complet. Poti reduce cu verificari la host, hash de stare, server arbitru pentru rank, dar cine controleaza clientul controleaza memoria. Pentru competitiv, mergi pe authoritative.
Q: Ce tick rate sa aleg? A: 30 Hz e suficient pentru multe jocuri; 60 Hz pentru shootere rapide; peste 60 Hz are diminishing returns si costa CPU/banda. Mai important e stabilitatea tick-ului si net smoothing.
Q: WebRTC e suficient pentru browser multiplayer? A: Da, pentru 2D/party/co-op si P2P; pentru authoritative in browser, WebSocket e mai simplu si suficient. Daca ai nevoie de UDP-like, WebRTC DataChannels sunt opțiunea.
Q: Cum fac matchmaking corect pe regiuni? A: Harta de regiuni cu latency buckets (0–50, 50–100, 100–150 ms), preferi regiunea comuna minima. Poti permite cross-region ca fallback, dar semnaleaza ping-ul jucatorului.
Q: Pot muta de la P2P la authoritative dupa lansare? A: Este greu. Protocolul, sim-ul si economiile trebuie refactorizate. Daca anticipezi crestere, proiecteaza transportul si serializarea compatibile de la inceput.
Concluzii tactice
- Alege authoritative pentru competitiv, economie server-side si anti-cheat; P2P/rollback pentru 1v1 si co-op mic cu cost minim.
- Construieste pe un transport fiabil (ENet/QUIC/Steam Sockets) si separa clar inputurile de stari.
- Masoara p95 tick si p95 RTT, nu te ghida dupa „merge la mine”.
- Planifica egress si compresie; delta + AOI reduc factura cloud.
- Testeaza determinismul/rollback cu tool-uri de retea emulata in CI, nu doar la QA manual.
- Accepta ca nu exista solutie perfecta — dar exista o solutie potrivita pentru bucla ta de joc si buget.
Daca construiesti un joc multiplayer si ai nevoie de arhitectura, prototip sau audit de retea, scrie-ne: /contact. In calitate de studio care livreaza jocuri si backend-uri, putem proiecta, implementa si opera modelul corect pentru cazul tau.
Key takeaways
- Authoritative pentru competitiv si economie; P2P/rollback pentru 1v1/co-op.
- Transportul conteaza: ENet/QUIC/Steam Sockets reduc jitter si pierderi.
- Lag compensation corect si prediction reduc perceptia de latency.
- Planifica costurile compute + egress; delta si AOI scad factura.
- Testele de retea (loss/jitter) in CI previn surprize in productie.
URMATORUL PAS
Ti-a placut abordarea?
Aplicam aceleasi principii in proiectele clientilor: AI, automatizari, produse care nu se sting dupa lansare.