Add in-game chat, bot fill for casual, and borderless fullscreen
- In-game chat: T=all, Y=team (race doubles as team), server-relayed and team-filtered via new ChatManager autoload; last 10 messages shown bottom-left (chat/chat_box.gd). - Bot fill for casual (bots/): keeps each of the match's 2 offered races at a minimum of 7 total humans+bots, spawning/despawning reactively as players join/leave. Bots always fly their race's fighter and use negative peer_ids so they ride the existing networked-ship stack (spawning, loadout sync, health/position sync, bullet attribution) with no special-casing. Casual matchmaking now forms with just 1 real player queued instead of waiting for a second (matchmaking-api/). - Borderless fullscreen with stretch scaling disabled instead of scaling the Steam-Deck-matched 1280x800 canvas up to fill PC monitors (which read as zoomed in) — PC monitors now reveal more world/HUD at native size instead. Reworked main_menu/team_select/chat_box to position via anchors relative to the real window instead of hardcoded coordinates. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+55
-2
@@ -17,6 +17,12 @@ spacewar/ ← repo root
|
||||
│ ├── ship.tscn ← player ship scene (formerly node_2d.tscn)
|
||||
│ ├── ship_movement.gd ← player ship logic
|
||||
│ └── bullet.tscn/gd ← projectile
|
||||
├── chat/
|
||||
│ └── chat_box.tscn/gd ← WoW-style chat overlay (T=all, Y=team), added to world.tscn
|
||||
├── bots/
|
||||
│ ├── bot_manager.gd ← autoload; server-only bot fill (join/leave reconciliation)
|
||||
│ ├── bot_ai.gd ← class_name BotAI; seek-nearest-enemy-and-shoot brain
|
||||
│ └── bot_names.gd ← class_name BotNames; procedural callsign pool
|
||||
├── world/
|
||||
│ ├── world.tscn ← game world; world.gd loads the active map into MapContainer
|
||||
│ ├── world.gd ← picks/instances a map scene from world/maps/
|
||||
@@ -49,7 +55,8 @@ World (Node2D) ← world.gd instances MAP_SCENE into MapContainer o
|
||||
├── HUD (CanvasLayer)
|
||||
│ └── HealthLabel
|
||||
├── PauseMenu (CanvasLayer, layer=10) ← menu/pause_menu.tscn
|
||||
└── TeamSelect (CanvasLayer, layer=20) ← menu/team_select.tscn; queue_free()s after selection
|
||||
├── TeamSelect (CanvasLayer, layer=20) ← menu/team_select.tscn; queue_free()s after selection
|
||||
└── ChatBox (CanvasLayer, layer=5) ← chat/chat_box.tscn
|
||||
```
|
||||
|
||||
### `world/maps/map_01.tscn` — hand-painted map
|
||||
@@ -81,6 +88,8 @@ Player (CharacterBody2D) ← ship_movement.gd
|
||||
| `move_down` | S | — |
|
||||
| `shoot` | Space | — |
|
||||
| `toggle_pause` | Esc | Start / Options button (JoyButton 6) |
|
||||
| `chat_all` | T | — |
|
||||
| `chat_team` | Y | — |
|
||||
|
||||
## Game Flow
|
||||
|
||||
@@ -93,7 +102,32 @@ main_menu.tscn
|
||||
└── RANKED → disabled (coming soon)
|
||||
```
|
||||
|
||||
> **Note:** `server_browser.tscn` was built (Task 1) and is functional, but the current flow bypasses it — CASUAL goes directly to the world and TeamSelect handles name/race/ship. The server browser will be re-integrated when real multiplayer server listing is built.
|
||||
> **Note:** `server_browser.tscn` was built (Task 1) and is functional, but the current flow bypasses it — CASUAL goes directly to the world and TeamSelect handles name/race/ship. The server browser will be re-integrated when real multiplayer server listing is built. It still uses the old hardcoded-1280px layout style (see Display below) — not yet updated since it isn't reachable in the live flow.
|
||||
|
||||
## Display
|
||||
|
||||
Launches borderless fullscreen at the real screen resolution (`window/size/mode=3`
|
||||
in `project.godot`) with stretch mode **disabled** — 1 game pixel = 1 screen
|
||||
pixel everywhere, no UI/world scaling. Chosen over Godot's default
|
||||
`canvas_items`+`expand` stretch (which scales the whole 2D canvas to fill the
|
||||
window) because the game's design canvas is deliberately sized to the Steam
|
||||
Deck's native 1280×800; scaling that up to fill a PC monitor made everything
|
||||
look zoomed in. With stretch disabled, PC monitors just reveal more of the
|
||||
world/HUD at native size instead — the actual map (`world/maps/map_01.tscn`)
|
||||
is already a fixed-size 14016×6000 arena, not viewport-sized, so there's more
|
||||
world to reveal.
|
||||
|
||||
This means every menu Control has to position itself relative to the *real*
|
||||
window size, not a fixed 1280×800 design canvas — anchors (0.0=edge,
|
||||
0.5=center, 1.0=opposite edge) plus fixed pixel offsets from that anchor,
|
||||
not raw absolute pixel coordinates. `main_menu.gd` and `team_select.gd` both
|
||||
have a `_place()`/direct-property-assignment helper for this — **always set
|
||||
anchor properties directly (`node.anchor_left = ...`) rather than through
|
||||
sequential `set_anchor_and_offset()` calls**: that method's default
|
||||
`push_opposite_anchor=true` drags the opposite side's anchor/offset along
|
||||
whenever two sequential calls momentarily disagree (e.g. left set to a 0.5
|
||||
anchor while right is still its 0.0 default), corrupting layout — hit this
|
||||
exact bug converting the play-mode buttons to be centered.
|
||||
|
||||
## Key Autoload — `GameConfig`
|
||||
|
||||
@@ -113,3 +147,22 @@ main_menu.tscn
|
||||
| `ship_invincibility_time` | float | Tuning constant |
|
||||
| `bullet_damage` | int | Tuning constant |
|
||||
| `ship_wall_damage` | int | Tuning constant |
|
||||
| `chat_focused` | bool | Set by ChatBox while its input line has keyboard focus; gates ship movement/fire input |
|
||||
| `bot_min_team_size` | int | Tuning constant — min humans+bots per race, see `bots/bot_manager.gd` |
|
||||
| `bot_engage_range` | float | Tuning constant — bot max shoot distance |
|
||||
| `bot_stop_distance` | float | Tuning constant — bot stops closing distance below this |
|
||||
| `bot_aim_tolerance_deg` | float | Tuning constant — how precisely a bot must face a target to fire |
|
||||
|
||||
## Key Autoload — `BotManager`
|
||||
|
||||
Server-authoritative bot fill for casual (`bots/bot_manager.gd`). Keeps each of the
|
||||
match's 2 offered races at `GameConfig.bot_min_team_size` total humans+bots,
|
||||
reacting to `PlayerRegistry.loadout_updated`/`player_removed` and
|
||||
`World.decide_offered_races()`. See `overview/bots.md`.
|
||||
|
||||
## Key Autoload — `ChatManager`
|
||||
|
||||
Server-relayed chat (`autoload/chat_manager.gd`). `send_chat(text, team_only)` sends;
|
||||
`message_received(sender_name, sender_race, team_only, text)` signal delivers
|
||||
incoming messages to `ChatBox`. "Team" messages are filtered server-side to
|
||||
peers sharing the sender's race (race doubles as team — see `PlayerRegistry`).
|
||||
|
||||
Reference in New Issue
Block a user