Files
zfxaction25/AGENTS.MD
2026-04-19 00:43:27 +02:00

4.5 KiB

AGENTS

Context

  • Game genre: roguelite strategy deckbuilder.
  • Game fantasy: program a robot courier on a hex farmland delivering crate goods to sheds while glitches mutate instructions and patches improve the deck/program.
  • Use this file to keep new work aligned with the existing design/implementation; see code under RobotAndDonkey.Game and tests under RobotAndDonkey.Tests.

Design document

  • Detailed system design exists in the design.md file.
  • UX design for a card row exists in the cardrow.md file.

Tech Design

  • Deterministic core: GameState.GameState.CreateNew seeds Utils.SRandom; CoreLoop owns Board.Generate, glitch deck, robot, decks, and metrics (energy wasted, overspill, path length, visits). Balancing tunables live in Data/Balancing.cs.
  • Deterministic finite automaton: CoreLoop.RunPhase (ERunPhase) feeds Requests (Execution/Requests/) and Commands (Execution/Commands/) via GameRuntime; EnterPreview seeds the first tape/hand; loop is DrawGlitch -> Improve -> (Gamble/BufferOverflow) -> ExecuteProgram/Scoring -> back to DrawGlitch.
  • Entities/modifiers: cards/robots/cells derive from Modifiers.Entity holding modifiers. Modifier (Kind/Id/Duration) exposes OnAdded/Before/After/OnRemoved; DebuffSources disables effects. ModifierStack pushes robot -> cell -> card layers before each card; immunity/debuff rules are honored when executing intents.
  • Intent pipeline: cards override Card.CreateIntents to enqueue intents (Intents/*). ModifierStack.Execute runs modifier Before hooks, validates Intent.IsValid (energy + debuffs), runs intents (mutate board/currency/add intents), then After hooks. Results records mirror deltas for UI sync.
  • Board model: Board.Board stores ImmutableArray and TargetDeliveryAmount; Board.Generate builds axial hex maps sized by difficulty, sprinkling terrain/POIs with Balancing probabilities while preserving connectivity and POI reachability. Towers seed permanent Unreliable to neighbors; corrupt cells added by spread. FindCellIndex is currently O(n).
  • Robots: Robots.* records define starting deck/program count; base Robot exposes Currency (energy/max carry/preview/tape length/hand size) derived from difficulty. Derived robots add modifiers (e.g., AnalystModifier) and deck tweaks.
  • Cards/modifiers: Cards/Patches and Cards/Glitches are records; PatchCard/GlitchCard derive from Card with tooltip/modifier metadata. ModifyCardBase handles temporary modifier application; OccupiedSpace respects Efficient. Corruption-aware indexing uses Utils.CardExtensions.NextIndexConsideringCorruption.
  • Frontend: HexBoard3D builds a 3D board with HexMeshBuilder multimeshes per cell type, billboarded POI sprites cached in dictionaries, highlight/selection meshes, camera-facing pivoted textures, optional debuff VFX from cell modifiers. Exported textures/materials/pivots enable art hookup.

Code Style & Patterns

  • Indentation is done with 4 spaces per level.
  • C# records and expression-bodied members; prefer immutability (ImmutableArray, init props) and explicit DeepClone including modifiers/debuff state.
  • No modifier duplicates; always use AddModifier/InsertModifier/RemoveModifier so hooks fire. Respect DebuffSources when checking if effects apply.
  • Intents/results are the only way to mutate state for UI; emit CurrencyResult/HandResult/TapeResult/PoiResult/etc. with a cloned state whenever state changes.
  • Thread deterministic RNG through CoreLoop.Random (ref SRandom) instead of creating new Random instances; avoid hidden randomness.
  • Balancing.Instance is the source of truth for costs/probabilities; avoid magic numbers in cards/intents/board generation.
  • Tests live in RobotAndDonkey.Tests with builders (BoardBuilder, CoreLoopBuilder, TestRuntime, CardTestBase) and card-specific suites; mirror patterns for new content to keep coverage and determinism.
  • Hex math uses axial coords (Utils.Hex) and EDirection; derive relative directions via helpers instead of manual math to respect corruption/orientation rules. Rendering caches meshes/sprites and small helper methods over monoliths.
  • Variable names are full words and are not abbreviated (e.g. exception instead of ex, image instead of img). Structs have an S prefix, enums have an E prefix, fields have a m_ prefix, statics have a s_ prefix, members use UpperCamelCase, locals and arguments use lowerCamelCase.
  • Inside of a class: statics appear first, then methods, then properties, and finally all other members.
  • Always include method visibility modifiers, especially private.
  • Don't use regions.
  • Curly braces each belong in their own line.