How madavidcoder/circle-seige works
1. Overall shape
Circle Siege is a two-part game: a Godot frontend for rendering, input, UI, and gameplay, and a Rust backend for audio analysis. The architectural boundary is between the real-time game client and the audio/event-generation layer.
2. Frontend runtime
The frontend/ directory is the main shipped game. It contains a Godot project (project.godot), scenes (main.tscn, ChordTelegraph.tscn, Projectile.tscn, RadialTelegraph.tscn), and many GDScript components that implement the menu, game loop, HUD, and effects.
3. Frontend composition
The game client is organized as scene-based modules:
- main.gd / main.tscn for top-level app flow
- menu.gd for start/settings/input selection
- director.gd for orchestrating gameplay events
- player.gd for cursor-following player behavior
- projectile.gd, chord_telegraph.gd, radial_telegraph.gd for hazards and warning visuals
- lives_display.gd, near_miss_fx.gd, shockwave.gd, beat_particles.gd, spectrum.gd for feedback and HUD
4. Gameplay data flow
The primary in-game flow is: audio source selection → beat/energy analysis → spawning of telegraphs/projectiles → player dodges with mouse input → HUD/visual feedback updates. The director appears to be the central gameplay coordinator that turns audio timing into attack patterns.
5. Audio source modes
The README and assets show three input modes:
- Demo tracks bundled as demo_*.jsonl and demo.wav
- Local file input chosen by the player
- System audio loopback for live music from apps like Spotify
This is a major architectural boundary because the backend must handle multiple audio sources, while the frontend presents them as game modes.
6. Rust backend role
The backend/ crate is a separate Rust executable with main.rs, processor.rs, and record.rs. Based on the README tech stack, it handles audio analysis, FFT/tempo/beat detection, and record generation. It is not the game itself; it is the analysis engine that produces timing/intensity data for the frontend to consume.
7. Backend responsibilities
The backend likely has three concerns:
- command-line startup and configuration (clap in the README)
- asynchronous processing / streaming (tokio)
- beat and tempo analysis (aubio, plus any FFT/feature extraction logic in processor.rs)
record.rs likely defines the event/trace format used for playback or exporting analysis results.
8. Trace-based playback
The presence of demo_chill.jsonl, demo_normal.jsonl, and demo_hard.jsonl suggests the game can play back precomputed event traces rather than analyzing audio every time. That makes the frontend capable of deterministic demo playback, while the backend likely generates or records these traces for live or offline use.
9. Visual and accessibility layer
The frontend includes custom shaders and theme resources (flow_gradient.gdshader, *.tres, gradient_bg.gd, audiowide.tres, syne*.tres) plus settings for movement reduction and high-contrast modes. This is a distinct UI/visual subsystem layered on top of gameplay, not part of the audio analysis pipeline.
10. Input and control model
Player control is intentionally minimal: the mouse position drives the player avatar, and keyboard input is mostly reserved for menu navigation. That means the core runtime loop is: cursor input + audio-derived hazards + collision/life management.
11. External dependency boundary
The project depends on Godot Engine for the client runtime and Rust for analysis tooling. The README also calls out a Windows-only limitation due to audio loopback compatibility, which affects deployment architecture because system-audio capture is part of the core feature set.
12. How to draw the architecture
A useful diagram would show:
- a Godot game client containing menu, gameplay director, entities, HUD, and effects
- a Rust audio analysis service/tool producing beat/event records
- audio inputs feeding the Rust side
- JSONL/demo traces or live analysis output feeding the game director
- mouse/keyboard input feeding the player/menu
- rendered visuals and collision feedback as the client’s output
The central integration point is the event stream that converts music into obstacle patterns.
Main entry points: director.gd Director · main.gd Main app · arena.gd Arena · menu.gd Menu
Components 18
Godot Client
Real-time game client built in Godot.
- Main app · Top-level game state and scene entry point.
frontend/main.gd - Menu · Start, settings, and input mode selection.
frontend/menu.gd - Director · Converts timing data into attacks and gameplay events.
frontend/director.gd - Player · Mouse-driven player movement and dodge behavior.
frontend/player.gd - Arena · Core playfield and collision space.
frontend/arena.gd - Projectile · Primary moving obstacle spawned during play.
frontend/projectile.gd - Chord tel. · Telegraphed hazard indicating upcoming patterns.
frontend/chord_telegraph.gd - Radial tel. · Area-style warning visualization for attacks.
frontend/radial_telegraph.gd - HUD · Lives and spectrum feedback shown during play.
frontend/lives_display.gd - Effects · Near-miss, shockwave, and beat-reactive visuals.
frontend/near_miss_fx.gd - Camera · Scene camera behavior for gameplay framing.
frontend/camera_2d.gd - Config · Runtime configuration and accessibility options.
frontend/config.gd
Rust Analysis
Audio analysis and trace generation tooling.
- Backend CLI · Command-line startup and orchestration for analysis.
backend/src/main.rs - Processor · Streaming audio processing, FFT, tempo, and beat detection.
backend/src/processor.rs - Record format · Event/trace representation for demo playback or export.
backend/src/record.rs
Assets & Traces
Bundled audio, traces, and visual resources.
- Audio input · Demo tracks, local files, and system loopback audio.
frontend/demo.wav - Demo traces · Precomputed challenge traces for deterministic playback.
frontend/demo_normal.jsonl - Visual assets · Fonts, shaders, and theme resources for presentation.
frontend/flow_gradient.gdshader
Connections 22
- Main app → Menu: routes to · Starts in menus and setup flows.
- Main app → Director: loads gameplay · Enters the active game loop.
- Main app → Config: applies settings · Reads runtime and accessibility options.
- Menu → Audio input: selects mode · Chooses demo, local file, or system audio.
- Menu → Backend CLI: launches analysis · Starts analysis path for live or local audio.
- Director → Player: drives encounters · Coordinates hazards against player movement.
- Director → Projectile: spawns · Creates moving hazards from beat events.
- Director → Chord tel.: spawns · Creates advance warnings for patterns.
- Director → Radial tel.: spawns · Creates area warning visuals.
- Director → HUD: updates · Feeds lives, timing, and spectrum state.
- Director → Effects: triggers · Emits hit and beat feedback effects.
- Player → Arena: moves in · Player stays constrained to the playfield.
- Projectile → Arena: collides in · Hazards interact with the playfield.
- Chord tel. → Arena: warns in · Telegraph visuals appear in the arena.
- Radial tel. → Arena: warns in · Telegraph visuals appear in the arena.
- Backend CLI → Processor: orchestrates · Configures and runs analysis stages.
- Processor → Record format: emits · Produces trace data and analysis results.
- Audio input → Processor: feeds · Raw audio is analyzed into events.
- Record format → Demo traces: serializes as · Trace output can be stored and replayed.
- Demo traces → Director: replays into · Demo playback feeds the gameplay coordinator.
- Visual assets → Main app: skins · Themes, shaders, and fonts shape presentation.
- Visual assets → Effects: supports · Effects use shared visual resources.