This file is the agent-focused onboarding and execution guide for this repository. It complements README.MD with practical context for coding agents.
FGEngine is a 2D fighting game engine written in Go, using Ebitengine for rendering and input. The project currently has two primary surfaces:
- Game runtime (main executable)
- Utility/test binary (cmd/test)
Current status from README.MD: major rewrites are in progress.
- Go 1.25.0 (go.mod)
- github.com/hajimehoshi/ebiten/v2 (game loop, rendering, input, gamepads)
- github.com/ebitengine/debugui (runtime debug UI tooling)
- gopkg.in/yaml.v3 (serialization for characters, language data)
- Desktop native target via regular Go build/test
- Character definitions: YAML under assets/characters
- Localized text: YAML under assets/text
- Sprites and stage art: assets/common, assets/stages, etc.
- main.go -> config.InitGameConfig() -> ebiten.RunGame(scene.NewSceneManager())
- cmd/test/main.go -> language YAML loading smoke program
- scene.Scene interface:
- Update([2]input.GameInput) SceneStatus
- Draw(*ebiten.Image)
- scene.SceneManager owns current scene and routes transitions with SceneStatus.
- Scene transitions:
- Controller selection
- Main menu
- Gameplay
- scene/gameplay.go creates:
- 2 characters via character.LoadCharacter("PlaceHolder", side)
- camera
- stage
- gameplay.GameState
- gameplay.GameState.Update delegates to each character state machine.
- character.Character has:
- Name
- StateMachine *animation.StateMachine
- animation.StateMachine contains runtime-only combat state and an ActiveAnim player.
- animation.AnimationPlayer handles:
- Active animation
- Frame timing
- Loop/non-loop behavior
- Sprite selection via frame data
- input.GameInput is a bitmask byte.
- Directional and button states are merged and polled every frame.
- SOCD cleaning exists (Left+Right and Up+Down neutralization).
- Global input ownership supports P1/P2 grouping.
- Camera abstraction in graphics/camera.go:
- WorldToScreen and CameraTransform
- optional world bounds locking
- Stage rendering supports:
- solid color
- grid
- image-based stages
- Image cache in graphics/imageCache.go uses mutex-protected map and fallback sprite.
- animation/: animation playback, frame data, state machine
- character/: character loading (YAML), drawing, box rendering
- collision/: hit/hurt/collision box types and detection
- config/: runtime window/layout/lang settings
- constants/: world size, camera size, scene constants
- gameplay/: game state update
- graphics/: camera, cache, render queue abstractions
- input/: keyboard/gamepad mapping, poll/update helpers, special input
- language/: i18n YAML import model
- rollback/: rollback/netcode experiments (currently empty placeholder)
- scene/: scene manager and scene implementations
- stage/: stage visuals and background generation
- types/: shared types (vectors, rects)
Loader expects:
- name
- stateMachine.activeAnim.animations map
Minimal animation expectations:
- each animation has sprites and framedata
- frame data supports duration, spriteIndex, optional velocity deltas and metadata
Example source of truth:
- assets/characters/PlaceHolder.yaml
Path behavior:
- character loader resolves sprite relative paths against the character YAML path.
- language.Language:
- lang
- game_text map
Files:
- assets/text/EN.yaml
- assets/text/BR.yaml
- Validate core packages:
- go test ./animation ./character ./collision ./config ./constants ./gameplay ./graphics ./input ./language ./scene ./stage ./types . ./cmd/test
- Validate full repository:
- go test ./...
- No stable automated test suite yet
- Most packages return "[no test files]"; current validation is mostly compile-level.
- Refactor in progress
- README indicates active rewrites.
- Prefer minimal, localized changes; avoid broad architectural rewrites unless requested.
- Scope is desktop-first for now
- Prioritize Linux/Windows desktop behavior in runtime and tooling.
- Defer non-desktop targets unless explicitly requested.
- Rollback package is not wired in runtime flow yet
- rollback/ exists but is currently empty in the workspace snapshot.
- Treat rollback integration as future work unless explicitly requested.
- Keep data/runtime split through struct tags
- Runtime-only state uses yaml:"-" where needed.
- Preserve serialization boundaries when changing structs.
- Favor package-local ownership of responsibilities
- input handles polling and normalization.
- scene handles state transitions.
- gameplay coordinates entities.
- character/animation handle per-entity behavior.
- Prefer explicit nil checks and graceful fallback
- Existing code frequently checks nil before access.
- image cache fallback to default image is an established pattern.
- Keep camera-space transforms centralized
- Use graphics.CameraTransform and WorldToScreen instead of custom per-call math.
- Use bitmask-safe input logic
- Use GameInput helpers (IsPressed, JustPressed, JustReleased).
- Preserve SOCD cleanup behavior when extending input systems.
When implementing a change:
- Identify surface: runtime game, shared systems, or utility binaries.
- Make smallest viable change and keep package boundaries.
- Run targeted go test commands for changed packages.
- If change is runtime-wide, run the validated core package command from section 6.
- Document any command failure and exact error in your final report.
When adding features:
- Add/update YAML schema with backward compatibility in mind.
- Update loaders and default/fallback behavior together.
- Keep scene transitions and input semantics deterministic frame-to-frame.
- Define rollback package integration points with scene/gameplay flow.
- Introduce at least smoke tests for YAML load paths and animation playback.
- Add a repo-native cross-platform build script for Linux/macOS/Windows desktop workflows.
- Document one canonical run command for desktop game and one for utility/smoke binaries.
This structure follows practical guidance from widely adopted agent-doc patterns:
- Keep a single predictable root file with execution-critical information.
- Prioritize build/test/run commands that are actually validated.
- Include architecture map so agents search less and edit the right package first.
- Explicitly list known breakages and constraints to reduce failed attempts.
- Keep guidance concise, actionable, and maintenance-friendly.
External references consulted while preparing this file:
- https://agents.md/
- https://docs.github.com/en/copilot/how-tos/configure-custom-instructions/add-repository-instructions
- https://llmstxt.org/
- https://developers.openai.com/api/docs/guides/prompt-engineering
Treat this file as living documentation. Whenever build commands, architecture, or known breakages change, update AGENTS.md in the same PR.