Skip to content

Repository files navigation

DEAL

A data-driven Unity framework for stacking-score card games.

DEAL is the engine under Aurayale, a Balatro-inspired collectible card game. It exists because we wanted the core of that genre — play a hand, watch bonuses trigger one by one, see Base × Multiplier explode — to be something designers assemble from data, not something engineers re-code for every card.

  • Game flow is a state machine you can see. Draw, select, score, resolve — each step is a ScriptableObject state with data-defined transitions. Changing "3 discards per round" to 2 is a field edit, not a code change.
  • A card is a data asset. Effects are composed from Condition[] + Effect[] traits pointing at status objects. Adding a card means creating a .asset — zero code, no recompile.
  • Scoring is one pipeline: Base × Multiplier. Every bonus — card traits, statuses, "joker"-style persistent modifiers — is a step on that pipeline, and each step can drive UI feedback in sequence.
  • The core is deterministic and headless-testable. Seeded RNG, an immutable command log, and a 141-test EditMode suite that runs without a scene — same seed, same result, CI-friendly.

Build the Balatro loop in five steps

The shortest path to "numbers go up":

  1. Define cards. Create card assets (CardSO subclasses) and give them suit/number traits — or your own trait types; the base card has no built-in poker vocabulary.
  2. Lay out the flow. Create a ScriptableStateMachine with states for deal → select → play-or-discard → score. Budget mechanics (hands/discards remaining) are integer player properties checked by transition conditions.
  3. Score the hand. Wire a ScoreCounterSO (the poker evaluator ships as one strategy; write your own by subclassing) and map results to base score and multiplier.
  4. Add modifiers. Build "joker"-style effects as ModifierTraits (condition + effect data) on cards, or as persistent StatusSOs that trigger at scoring phases.
  5. Watch it stack. Score mutations flow through the command processor; hook the events to animate your A × B display per trigger.

The samples (Package Manager → DEAL → Samples) show working scenes for card dealing, suit/number changes, and pattern evaluation, plus in-code samples (Tests/EditMode/Samples/) demonstrating every extension seam: a custom command verb, a custom scoring strategy with no poker, a custom property provider and status phase, and a two-client lockstep match over the in-process loopback transport.

Extending without forking

Every place a game needs its own rules is an open seam:

You want to… Use
Add a game-specific command verb CommandHandlerRegistry.RegisterHandler(string, handler)
Score by your own rules (non-poker included) subclass ScoreCounterSO
Add a status trigger phase beyond the built-ins any string key; StatusPhases is just a preset
Feed FSM actions a custom system value subclass SystemPropertyProviderSO
Add card mechanics ModifierCondition / ModifierEffect / StatusSO subclasses
Swap how player input arrives (human, bot, remote) IPlayerInput behind SeatRegistry
Run deterministic multiplayer logic in-process INetTransport + LoopbackTransport

Module maturity

Be aware of what's battle-tested and what's newer:

Module Status
FSM engine, card/trait system, status system, scoring pipeline, command system Stable — shipping in Aurayale
Poker evaluation (Mustaverse.DEAL.Poker) Stable — slated to move into its own assembly so non-poker games don't reference it
Seats/input seam, determinism seam (IRng, BattleBarrier) Validated — adopted by a second internal title
Net transport (loopback), damage pipeline (IDamageModifier) Preview — proven by tests and samples; not yet exercised by a shipping game. APIs may still move.

What DEAL is (and isn't) good at today

DEAL targets turn-based card games with data-driven effects: score-stacking roguelikes (Balatro-likes), turn-loop battlers, and classic flow games. The engine-free core assembly (Mustaverse.DEAL.Core — no UnityEngine reference) holds the deterministic seams, so game logic is testable headless.

It does not yet provide a priority/reaction-stack primitive (the Yu-Gi-Oh/MTG family of interaction), a remote network driver, or server-side score verification. The command log and seeded RNG are designed so a verifier could replay a match — building that verifier is on the roadmap, not in the box.

Tests

EditMode suite (Mustaverse.DEAL.Tests.EditMode): 141 tests across RNG reproducibility, command-log integrity, scoring/damage math, status behavior, pattern evaluation, and the extension-seam samples. Window → General → Test Runner → EditMode → Run All. No scene required.

Roadmap

  • Score-verification service (replay a match from seed + command log)
  • Remote transport driver + matchmaking companions for the net seam
  • Poker module split into its own assembly (PHEval dependency leaves core)
  • Sample-content slimming: legacy casino-flow content moves fully into samples

License

Apache-2.0 — free for commercial use, patent grant included. See LICENSE.md. Issues and PRs welcome.

About

No description, website, or topics provided.

Resources

Stars

9 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages