Replaces the fixed centred arena with per-world tile geometry, which is the foundation the remaining features sit on. - MapGrid: tile grid with three independent flags -- blocks movement, bullets, sight -- so a pit stops feet but not bullets or eyes, and a barricade stops feet and bullets but not eyes. Circle collision with per-axis sliding, and Bresenham line of sight shared by fog and aggro. - MapGen: rooms and corridors generated from (seed, depth), with hand-authored boss arenas from Rooms stamped in first so a corridor can never carve through a designed fight. Reachability from spawn to boss is asserted over 40 seeds -- "usually connected" is the failure mode that ruins one run in twenty. - Dungeons are populated at creation, per room, instead of gating on waves. You explore and choose your fights; the run ends when the boss dies, not when the map is swept. Boss rooms have no lock, so walking out is always available. - Aggro: enemies need range AND line of sight, so a dungeon stays quiet until engaged and cover actually protects. - Hard fog, scrolling camera, and terrain rendering. Maps are streamed per peer in chunks around that peer's player, and the seed is deliberately NOT sent -- a client holding it could regenerate the whole dungeon, which is a map hack for free. Stream radius (900u) is wider than view radius (460u) because the client predicts movement against walls and simulates bullets that die on them; the accepted cost is a cheater seeing a little further than the fog, never the floor plan. Partial map knowledge means wall deaths must be announced rather than derived. A test caught the subtle half of that: out-of-bounds tiles read as WALL by design, so checking geometry before bounds reported every bullet leaving the map as a wall kill. 128 tests (was 103); check.sh, test.sh and smoke.sh pass. 0.26 ms/tick with 4 players and a boss, ~65x headroom.
This commit is contained in:
1 parent
e1f9fa8096
commit
7af439341d
34 files changed
+1522
-196
No files matched your search
+23
-5
@@ -160,12 +160,24 @@ func send_welcome(peer_id: int) -> void:
|
||||
s_welcome.rpc_id(peer_id, peer_id, Protocol.VERSION)
|
||||
|
||||
|
||||
## Deliberately carries the map's SIZE and not its seed. Handing over the seed
|
||||
## would let any client regenerate the whole dungeon locally, which is a map
|
||||
## hack with no work required; tiles are streamed instead (send_map_chunks).
|
||||
func send_enter_instance(peer_id: int, id: int, kind: int, server_tick: int,
|
||||
boss_id: String, spawn: Vector2) -> void:
|
||||
boss_id: String, spawn: Vector2, map_w: int, map_h: int,
|
||||
portal: Vector2) -> void:
|
||||
if _is_local(peer_id):
|
||||
client.on_enter_instance(id, kind, server_tick, boss_id, spawn)
|
||||
client.on_enter_instance(id, kind, server_tick, boss_id, spawn, map_w, map_h, portal)
|
||||
else:
|
||||
s_enter_instance.rpc_id(peer_id, id, kind, server_tick, boss_id, spawn)
|
||||
s_enter_instance.rpc_id(peer_id, id, kind, server_tick, boss_id, spawn,
|
||||
map_w, map_h, portal)
|
||||
|
||||
|
||||
func send_map_chunks(peer_id: int, instance_id: int, data: PackedByteArray) -> void:
|
||||
if _is_local(peer_id):
|
||||
client.on_map_chunks(instance_id, data)
|
||||
else:
|
||||
s_map_chunks.rpc_id(peer_id, instance_id, data)
|
||||
|
||||
|
||||
func send_snapshot(peer_id: int, data: PackedByteArray) -> void:
|
||||
@@ -231,10 +243,16 @@ func s_welcome(peer_id: int, _version: int) -> void:
|
||||
|
||||
@rpc("authority", "call_remote", "reliable", 1)
|
||||
func s_enter_instance(id: int, kind: int, server_tick: int, boss_id: String,
|
||||
spawn: Vector2) -> void:
|
||||
spawn: Vector2, map_w: int, map_h: int, portal: Vector2) -> void:
|
||||
if client == null:
|
||||
return
|
||||
client.on_enter_instance(id, kind, server_tick, boss_id, spawn)
|
||||
client.on_enter_instance(id, kind, server_tick, boss_id, spawn, map_w, map_h, portal)
|
||||
|
||||
|
||||
@rpc("authority", "call_remote", "reliable", 1)
|
||||
func s_map_chunks(instance_id: int, data: PackedByteArray) -> void:
|
||||
if client != null:
|
||||
client.on_map_chunks(instance_id, data)
|
||||
|
||||
|
||||
@rpc("authority", "call_remote", "reliable", 1)
|
||||
|
||||
Reference in new issue
Block a user