Logging: add informative console logs for startup, ports, connections, JOIN/deny, input, and periodic events
- Configure logging via LOG_LEVEL env (default INFO) - Log when servers start listening (WT/QUIC/InMemory/HTTPS static) - Log WT CONNECT accept, QUIC peer connect, datagram traffic at DEBUG - Log GameServer creation, tick loop start, JOIN accept/deny, config_update broadcasts, and input reception
This commit is contained in:
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from dataclasses import dataclass
|
||||
import logging
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
from collections import deque
|
||||
|
||||
@@ -53,6 +54,7 @@ class GameServer:
|
||||
self.runtime = ServerRuntime(config=config, state=GameState(config.width, config.height))
|
||||
self.sessions: Dict[int, PlayerSession] = {}
|
||||
self._config_update_interval_ticks = 50 # periodic resend
|
||||
logging.info("GameServer created: field=%dx%d, tick_rate=%d TPS, wrap=%s", config.width, config.height, config.tick_rate, config.wrap_edges)
|
||||
|
||||
async def on_datagram(self, data: bytes, peer: TransportPeer) -> None:
|
||||
# Minimal header parse
|
||||
@@ -85,6 +87,7 @@ class GameServer:
|
||||
# Broadcast to all sessions (requires real peer handles)
|
||||
for session in list(self.sessions.values()):
|
||||
await self.transport.send(payload, TransportPeer(session.peer))
|
||||
logging.debug("Broadcasted config_update to %d sessions", len(self.sessions))
|
||||
|
||||
async def relay_input_broadcast(
|
||||
self,
|
||||
@@ -115,6 +118,7 @@ class GameServer:
|
||||
r = self.runtime
|
||||
tick_duration = 1.0 / max(1, r.config.tick_rate)
|
||||
next_cfg_resend = self._config_update_interval_ticks
|
||||
logging.info("Tick loop started at %.2f TPS", 1.0 / tick_duration)
|
||||
while True:
|
||||
start = asyncio.get_event_loop().time()
|
||||
# process inputs, update snakes, collisions, apples, deltas
|
||||
@@ -388,12 +392,14 @@ class GameServer:
|
||||
if pid is None:
|
||||
payload = build_join_deny(version=self.runtime.version, seq=self.runtime.next_seq(), reason="Server full")
|
||||
await self.transport.send(payload, peer)
|
||||
logging.warning("JOIN denied: server full (name=%s)", name)
|
||||
return
|
||||
# Spawn snake
|
||||
snake = self._find_spawn()
|
||||
if snake is None:
|
||||
payload = build_join_deny(version=self.runtime.version, seq=self.runtime.next_seq(), reason="No free cell, please wait")
|
||||
await self.transport.send(payload, peer)
|
||||
logging.warning("JOIN denied: no free cell (name=%s)", name)
|
||||
return
|
||||
# Register session and snake
|
||||
color_id = preferred if (preferred is not None) else self._choose_color_id()
|
||||
@@ -403,6 +409,7 @@ class GameServer:
|
||||
self.runtime.state.snakes[pid] = snake
|
||||
self.runtime.state.occupy_snake(snake)
|
||||
self._ensure_apples()
|
||||
logging.info("JOIN accepted: player_id=%d name=%s color=%d len=%d at=%s", pid, name, color_id, snake.length, snake.body[0])
|
||||
# Send join_ack
|
||||
cfg = self.runtime.config
|
||||
ack = build_join_ack(
|
||||
@@ -445,7 +452,7 @@ class GameServer:
|
||||
full = pack_header(
|
||||
self.runtime.version, PacketType.STATE_FULL, 0, self.runtime.next_seq(), self.runtime.state.tick & 0xFFFF
|
||||
) + body
|
||||
await self.transport.send(full, peer)
|
||||
await self.transport.send(full, peer)
|
||||
else:
|
||||
# Partition by packing whole snakes first, apples only in first part; chunk a single oversized snake using 2-bit chunks
|
||||
update_id = self.runtime.next_update_id()
|
||||
@@ -563,6 +570,7 @@ class GameServer:
|
||||
break
|
||||
if player_id is None:
|
||||
return
|
||||
logging.debug("INPUT from player_id=%d: %d events (base_tick=%d)", player_id, len(events), base_tick)
|
||||
# Relay to others immediately for prediction
|
||||
await self.relay_input_broadcast(
|
||||
from_player_id=player_id,
|
||||
|
||||
Reference in New Issue
Block a user