mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-11 23:23:43 +00:00
45 lines
4.5 KiB
Markdown
45 lines
4.5 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
Important rule: never create co-authored commits. Never mention Claude in commits.
|
|
|
|
## Project overview
|
|
|
|
Cosmic Clash is an open-source, physics-based "vehicle soccer" game (a spiritual successor to Rocket League) built in Godot 4.4, using space ships instead of cars. The project is GDScript/Godot only right now — the "C# backend" mentioned in README.md is planned but not yet started. There is no server-side code; the MVP is local-only play against bots.
|
|
|
|
Because the gameplay concept (vehicle soccer) can't be copyrighted but specific expression can, all code/art/assets must be original — this is why the project uses Godot instead of Unreal/Unity and ships instead of cars. Keep this in mind when writing code or pulling in assets: don't port or closely mirror Rocket League's actual implementation.
|
|
|
|
## Godot MCP server
|
|
|
|
This repo vendors [godot-mcp](https://github.com/tugcantopaloglu/godot-mcp) as a git submodule at `mcp/godot-mcp` and registers it in `.mcp.json`. **Prefer the godot-mcp tools over manual file edits or shell commands** when the task involves inspecting or modifying the Godot project — reading/editing scenes, nodes, scripts, running the project, or interacting with a live Godot editor/runtime instance. It understands Godot's scene tree and `.tscn`/`.gd` structures directly, which is more reliable than hand-parsing them.
|
|
|
|
Setup after cloning (submodules aren't checked out by default):
|
|
|
|
```bash
|
|
git submodule update --init --recursive
|
|
cd mcp/godot-mcp
|
|
npm install
|
|
npm run build
|
|
```
|
|
|
|
`GODOT_PATH` (env var in `.mcp.json`) is left blank to auto-detect the Godot executable; set it explicitly if auto-detection fails on your machine.
|
|
|
|
## Commands
|
|
|
|
There is no build step, linter, or automated test suite for the GDScript project itself — Godot projects run directly from source.
|
|
|
|
- **Open the project**: open `Game/` as a project in the Godot 4.4 editor, or run `godot --path Game` from the repo root.
|
|
- **Run the game**: press Play in the editor, or `godot --path Game Game/scenes/main_menu.tscn`.
|
|
- The `mcp/godot-mcp` submodule is a separate Node/TypeScript project with its own `npm install` / `npm run build` (see above) — it is tooling, not part of the game itself.
|
|
|
|
## Architecture
|
|
|
|
- **Scene flow**: `main_menu.tscn` → (Play button, `main_menu_play_button.gd`) → `scenes/Game.tscn` → on match timer expiry, back to `main_menu.tscn`. The match is a fixed 150-second timer (`game.gd`).
|
|
- **Game.tscn** instances `objects/ship.tscn` (player-controlled ship), `objects/ball.tscn`, and `objects/goal.tscn` over a static terrain body.
|
|
- **Ship physics** (`scripts/ship.gd`, class `Ship`, extends `RigidBody3D`): all movement is force/torque-based (`_integrate_forces`), not kinematic — thrust and rotation inputs are converted to world-space forces/torques relative to the ship's orientation, with manual drag and speed/angular-speed clamping applied each physics tick. Physics formulas are commented inline; see `FLIGHT_MANUAL.md` for the player-facing explanation of controls and flight model.
|
|
- **Vehicle.gd** (`scripts/Vehicle.gd`) is a separate, simpler `RigidBody3D` base class used by `objects/vehicle.tscn`. It is *not* currently the base class for `Ship` — `ship.gd` reimplements similar logic directly. Treat these as two independent, currently-diverging implementations rather than a class hierarchy.
|
|
- **HUD / telemetry pattern**: `Ship` computes flight data (speed, altitude, attitude, heading, thrust, angular velocity, camera mode) once per physics tick and emits it via signals, only when the value changes past a threshold (see the `_last_*` fields and `*_THRESHOLD` constants in `ship.gd`). `HUDController` (`scripts/HUDController.gd`, on `scenes/HUD.tscn`, instanced inside `ship.tscn`) discovers the ship and game manager via Godot groups (`"ship"`, `"game"`) rather than direct node paths, connects to their signals, and only updates label text in response — it does no polling. Follow this discovery-by-group + signal-push pattern when adding new instruments or cross-node communication, rather than `get_node` with hardcoded paths or per-frame polling.
|
|
- **Input actions** are defined in `Game/project.godot` under `[input]` (`move_forward`, `turn_left`, `turbo`, etc.) and read via `Input.is_action_pressed(...)` — add new controls there rather than hardcoding key/button checks.
|
|
- Physics engine is Jolt (`Game/project.godot`, `[physics] 3d/physics_engine="Jolt Physics"`).
|