5.2 KiB
5.2 KiB
AGENTS.md
Godot 4.6 GDScript strategy game, early-stage (most gameplay is stubbed).
Commands
- Validate / reimport after edits:
godot --headless --path . --import - Run the test suite:
godot --headless --path . res://tests/test_runner.tscn(prints a summary and exits non-zero on failure) - Parse-check a single script:
godot --headless --path . --check-only --script res://scenes/units/unit.gd - Run a scene directly:
godot --path . res://scenes/ui/menu_screen.tscn - Profile the headless server (prints a report every N seconds):
godot --headless --path . res://scenes/server_main.tscn -- --server --profile-interval 5. A client's--profile-intervalis forwarded to the server it spawns, and F3 on the client prints/clears its own report. F4 prints thePerformanceMonitorreport (FPS-dive diagnostics plus the recent action log) without clearing it; the HUD also prints one automatically when the frame rate dives. - There is no linter, formatter, or CI. Do not invent commands beyond the ones listed here.
godot --path .with no scene fails:project.godotsets noapplication/run/main_scene. Pass a scene path or set the main scene in the editor.--check-onlydoes not load autoloads, so scripts referencingGameClock,GameConfigorNetworkreport false "Identifier not found" errors. Prefer--importplus the test suite for real validation.
Gotchas
- Renderer is
gl_compatibility(not Forward+) and 3D uses Jolt Physics. GL Compatibility omits Forward+ only features. .uidfiles are Godot-maintained; keep them paired with their scripts, never hand-edit or delete..godot/is generated and gitignored.- Indent
.gdfiles with tabs (Godot default)..editorconfigonly enforces UTF-8. scenes/world_map.tscnusesTileMapLayer(scene format=4), not the deprecatedTileMap.- Multiplayer uses
WebSocketMultiplayerPeer(HTTP), not ENet/UDP, so the browser client can reach the same server. The dedicated server listens on--port(default 27015) and binds to--bind(default127.0.0.1, i.e. reverse-proxy only); the client defaults to the page's own origin on the web,ws://127.0.0.1:27015/wsin development (editor or debug builds) andwss://tismo.cfpi-fpsi.eu/wsin release builds. Join accepts a bare hostname or a fullws(s):///http(s)://URL. The join screen opens a lobby connection, asks the server for its game list (Network.request_game_list/GameServer.game_list), then logs in over the same connection withNetwork.join_game_from_lobby. - Export templates must match the engine: use
godot_4_6withgodot_4_6-export-templates-binfrom nixpkgs.
Architecture
- Game logic is server-authoritative.
scripts/server/game_state.gd(GameState) is a scene-free model that owns the world, units, cities, territory, economy, training and visibility.scripts/server/game_server.gd(GameServer) is the root of the headless server (scenes/server_main.tscn); it owns aGameState, validates orders and broadcasts snapshots.Network(autoload) carries orders up and snapshots down.scenes/world_map.gdis a view only: it rebuilds terrain from the shared seed, renders snapshots and sends orders (falling back to a localGameStatewhen run standalone). - Movement is continuous: the server calls
GameState.advance_movement(delta / GameClock.SECONDS_PER_HOUR)every frame andtick_hour()on each hour for training/visibility/economy;advance_hour()bundles both for tests and offline play. The client extrapolates each unit along its snapshot path (seeworld_map.gd:_apply_unit_position) so motion stays smooth between hourly snapshots, and predicts move orders locally (_predict_path, mirroringGameState.find_path) so a click feels instant before the server confirms it. - Data-driven resources:
class_namescripts indata/*.gd(CivDescription,ProtoUnit) define schemas; concrete instances are.tresunderdata/civilisations/anddata/units/. Add content as new.tresfiles, not hardcoded values. - Scenes are grouped by area:
scenes/,scenes/ui/,scenes/units/. Reusable scenes attach aclass_namescript (e.g.Unit). - Reusable logic lives in
class_namescripts underscripts/classes/(MapGenerator,MapTopology,HexPathfinder,TextFormat); keep new algorithms there so they stay testable without a running scene. scenes/map_overlay.gd(MapOverlay) is the shared base for the tile overlaysTerritoryandFogOfWar; put layer/topology/geometry plumbing there, not in the subclasses.- Tests live in
tests/as*_test.gdfiles extending theTestCasebase intests/framework/.tests/test_runner.gd(run viatests/test_runner.tscn) discovers and runs them. Add a newtests/<topic>_test.gdfor each new pure orclass_namebehaviour.
Deployment
flake.nixexposespackages.<system>.serverand.web, plusnixosModules.default.nix/module.nixruns the server as aservices.battle-for-tismosystemd unit and serves the web client through nginx, proxying/wsto the local server. The web client connects to the page's own origin.- Build locally with
nix build .#serverandnix build .#web; both usegodot_4_6and its matching export templates from the flake's pinned nixpkgs.