Open card lab prototype

Triunfi

An open card game system where the rules are data, so you can measure what makes a card game fun before you print anything.

How it works See the numbers

  • Hawk1
    Art slot

    Swift. Can attack the turn it enters.

    1 / 1Unit · Beast
  • Bolt1
    Art slot

    Deal 2 damage to a chosen enemy character.

    Action
  • War Banner3
    Art slot

    Your units get +1 power.

    Relic

What it is

Triunfi is two things at once: a small open format for trading card games, and a lab for testing how a game plays. Its starting question is Magic's resource problem. When your resources are cards in your deck, you get mana screw and flood, and Triunfi tries other answers and counts what happens.

The name comes from trionfi, the first tarot decks, which were a shared structure that many printers reinterpreted. The vision document says theme and genre are deliberately not decided yet.

Card dataSets and decks are JSON files with namespaced ids (publisher:set:card) and a JSON Schema. Anyone can write one. Effects are a vocabulary such as damage, draw, buff and summon, not code.
Rules modulesThe engine never mentions lands or ink. It asks the active resource system what you can afford and how to pay. The same cards play under any module, which is what makes comparison fair.
Core engineTypeScript: turns, zones, targeting, effects and a seeded random generator, so a game with the same seed replays the same way. The web game and the headless simulation run the same engine.

Source: docs/VISION.md; README.md; docs/RULES.md

Seven resource modules

  • ramp
  • lands
  • inkwell
  • pitch
  • bank
  • tide
  • surge

Ramp is Hearthstone-style automatic growth, lands is Magic's, inkwell and pitch are in the spirit of Lorcana and Flesh and Blood, and bank follows Runeterra. Tide and surge are the project's own: tide makes you choose each turn between growing your energy and drawing a card, and surge lets you borrow up to 2 energy against next turn. The mechanics notebook credits the inspirations by name; this page only uses those names to describe the rules, with no affiliation.

Real cards from the JSON

The prototype core set has 77 cards under a CC-BY-4.0 licence, with generic names and no art. These six are rebuilt as HTML from sets/proto-core.json. The rules text is my plain-language reading of each card's data; the app generates its own text from the same data.

  • Spark Wisp1
    No art in set

    When this dies, deal 1 damage to a random enemy character.

    1 / 2Unit · Spirit
    triunfi:proto:spark-wisp
  • Bulwark Drone1
    No art in set

    Guard. Enemies must attack this unit first.

    0 / 3Unit · Construct
    triunfi:proto:bulwark-drone
  • Raider2
    No art in set

    No abilities. A plain, fast attacker.

    3 / 2Unit · Soldier
    triunfi:proto:raider
  • Forge3
    No art in set

    Pay 2: summon a Recruit token.

    Relic
    triunfi:proto:forge
  • Last Stand2
    No art in set

    Heal 3. If your life is 10 or less, heal 3 more and draw a card.

    Action
    triunfi:proto:last-stand
  • Sweep4
    No art in set

    Deal 2 damage to every enemy unit.

    Action
    triunfi:proto:sweep

Card names and stats checked against sets/proto-core.json. Hawk, Bolt and War Banner above come from the same file. The set has no art fields; the hatched panels are placeholders I added.

What the simulations say

Source: reports/latest.md, generated 2026-09-30. Midrange deck against midrange deck, 1,000 games per resource system, a simple greedy AI on both sides, seed 1, no second-player bonus. These are lab numbers for a prototype card pool, not a balance claim.

P1 win: first player's win rate (50% is fair). Stuck: share of turns with cards in hand but nothing playable. Empty hand: share of turns starting with almost no cards.
SystemAvg turnsP1 winStuckEmpty handEnergy / turn
Ramp7.3173.7%6.8%1.7%4.08
Lands7.8044.2%26.3%16.5%2.12
Inkwell7.9239.8%14.5%29.6%2.65
Pitch4.2672.9%3.2%0.0%6.23
Bank7.3474.8%7.2%1.8%4.14
Tide7.4870.7%6.8%0.0%3.87
Surge7.0274.9%4.4%2.0%4.25
  • Lands really does screw

    One turn in four, a player holds cards and can play none (26.3% stuck), the highest of the seven.

    Source: reports/latest.md; docs/MECHANICS.md

  • Going first is strong

    The first player wins 71 to 75 percent under five of the seven systems. Only lands and inkwell, where every card is also a resource, flip it below 50 percent.

    Source: reports/latest.md; docs/FIRST-PLAYER.md

  • Pitch breaks the cost curve

    Players spend over 6 energy a turn from turn one and games last about 4 turns, against 7 to 8 for the rest. A cost of 5 does not mean the same thing under every module.

    Source: reports/latest.md; docs/MECHANICS.md

Second-player fixes, tested

With the stronger Planner AI (500-game runs in the reports), the first player wins 81.0% under ramp with no compensation. Giving the second player one extra card and a Coin moves that to 51.3%, close to fair. The same fix pushes inkwell down to 12.3%, so one fix does not suit every module.

Source: reports/first-player.md (300 games per cell, AI planner)

What is in the repository

  • in code present and described in the README
  • prototype works as a lab, not a finished game
  • unverified not tested by us
  • Deterministic engine in code

    Seeded random numbers and one engine for play and simulation. Engine tests live in tests/engine.test.ts and run with npm test.

    Source: README; src/engine/

  • Ability grammar in code

    Triggers, conditions, effects, targets, auras, activated abilities and keywords such as swift, guard, barrier and deadly. Rules text is generated from the data.

    Source: docs/RULES.md

  • Two AIs prototype

    A fast greedy player, and a Planner that searches whole turns and simulates the opponent's reply. The docs say the Planner beats the greedy AI about 67 percent overall.

    Source: docs/MECHANICS.md (round 3); src/ai/

  • Headless simulation in code

    npm run sim plays AI against AI and writes Markdown and JSON reports. Options pick systems, decks, seed, games, bonus cards and a deck matrix.

    Source: README; src/sim/

  • Playable web app prototype

    React and Vite. Three tabs: Play against the AI, a Sim Lab, and a card gallery. We did not launch it for this page.

    Source: README; src/web/ (PlayView, SimLab, CardGallery)

  • Open licensing unverified

    The card sets say CC-BY-4.0. The package file says UNLICENSED for the code, and no licence file was found at the top level, so the code's terms are unclear.

    Source: sets/proto-core.json; package.json

Status

  • Run, per the repository in code

    Reports dated 2026-09-30 exist, so the simulator was run on its author's machine. Two commits are in the history.

  • Not run by us unverified

    We read the code, docs and reports and did not run the tests, the simulator or the web app. The numbers above are quoted, not reproduced.

  • Open questions planned

    The vision lists balancing independent sets, colour or faction identity, the minimal stable core, and who versions the format. The theme is also undecided.

  • Simple AI caveat prototype

    The notebook says synergy decks under-perform with a simple AI, so balance numbers for them should not be trusted yet.