async function sendChunk() { const ticksToSend = currentTick - lastSentTick; if (ticksToSend <= 0) return; const snapshotobstacles = JSON.parse(JSON.stringify(obstacles)); const payload = { sessionId: sessionID, inputs: [...inputLog], totalTicks: ticksToSend }; inputLog = []; lastSentTick = currentTick; try { const res = await fetch('/api/validate', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(payload) }); const data = await res.json(); // Update für visuelles Debugging if (data.serverObs) { serverObstacles = data.serverObs; // --- NEU: DEBUG MODUS VERGLEICH --- if (typeof DEBUG_SYNC !== 'undefined' && DEBUG_SYNC) { compareState(snapshotobstacles, data.serverObs); } // ---------------------------------- } if (data.status === "dead") { console.error("💀 SERVER KILL", data); gameOver("Vom Server gestoppt"); } else { const sScore = data.verifiedScore; // Score Korrektur if (Math.abs(score - sScore) > 200) { console.warn(`⚠️ SCORE DRIFT: Client=${score} Server=${sScore}`); score = sScore; } } } catch (e) { console.error("Netzwerkfehler:", e); } } window.submitScore = async function() { const nameInput = document.getElementById('playerNameInput'); const name = nameInput.value; const btn = document.getElementById('submitBtn'); if (!name) return alert("Namen eingeben!"); btn.disabled = true; try { const res = await fetch('/api/submit-name', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ sessionId: sessionID, name: name }) }); const data = await res.json(); let myClaims = JSON.parse(localStorage.getItem('escape_claims') || '[]'); myClaims.push({ name: name, score: Math.floor(score / 10), code: data.claimCode, date: new Date().toLocaleString('de-DE'), sessionId: sessionID }); localStorage.setItem('escape_claims', JSON.stringify(myClaims)); document.getElementById('inputSection').style.display = 'none'; loadLeaderboard(); } catch (e) {} }; async function loadLeaderboard() { const res = await fetch(`/api/leaderboard?sessionId=${sessionID}`); const entries = await res.json(); let html = "

BESTENLISTE

"; entries.forEach(e => { const color = e.isMe ? "yellow" : "white"; html += `
#${e.rank} ${e.name}${Math.floor(e.score/10)}
`; }); document.getElementById('leaderboard').innerHTML = html; } async function loadStartScreenLeaderboard() { try { const listEl = document.getElementById('startLeaderboardList'); if (!listEl) return; const res = await fetch('/api/leaderboard'); const entries = await res.json(); if (entries.length === 0) { listEl.innerHTML = "
Noch keine Scores.
"; return; } let html = ""; entries.forEach(e => { let icon = "#" + e.rank; if (e.rank === 1) icon = "🥇"; if (e.rank === 2) icon = "🥈"; if (e.rank === 3) icon = "🥉"; html += `
${icon} ${e.name}${Math.floor(e.score / 10)}
`; }); listEl.innerHTML = html; } catch (e) {} } function compareState(clientObs, serverObs) { // 1. Anzahl prüfen if (clientObs.length !== serverObs.length) { console.error(`🚨 ANZAHL MISMATCH! Client: ${clientObs.length}, Server: ${serverObs.length}`); } const report = []; const maxLen = Math.max(clientObs.length, serverObs.length); let hasMajorDrift = false; for (let i = 0; i < maxLen; i++) { const cli = clientObs[i]; const srv = serverObs[i]; let drift = 0; let status = "✅ OK"; // Client Objekt vorbereiten let cID = "---"; let cX = 0; if (cli) { cID = cli.def.id; // Struktur beachten: cli.def.id cX = cli.x; } // Server Objekt vorbereiten let sID = "---"; let sX = 0; if (srv) { sID = srv.id; // Struktur vom Server: srv.id sX = srv.x; } // Vergleich if (cli && srv) { // IDs unterschiedlich? (z.B. Tisch vs Lehrer) if (cID !== sID) { status = "❌ ID ERROR"; hasMajorDrift = true; } else { drift = cX - sX; if (Math.abs(drift) > SYNC_TOLERANCE) { status = "⚠️ DRIFT"; hasMajorDrift = true; } } } else { status = "❌ MISSING"; hasMajorDrift = true; } // In Tabelle eintragen report.push({ Index: i, Status: status, "C-ID": cID, "S-ID": sID, "C-Pos": cX.toFixed(1), "S-Pos": sX.toFixed(1), "Drift (px)": drift.toFixed(2) }); } // Nur loggen, wenn Fehler da sind oder alle 5 Sekunden (Tick 300) if (hasMajorDrift || currentTick % 300 === 0) { if (hasMajorDrift) console.warn("--- SYNC PROBLEME GEFUNDEN ---"); else console.log("--- Sync Check (Routine) ---"); console.table(report); // Das erstellt eine super lesbare Tabelle im Browser } }