Challenge: Card Trick · CTF: DalCTF 2026 · Category: Miscellaneous · Difficulty: Medium

The Challenge

There is an invite only, unreleased game made by valve. In this game, there is a character who is a gambler who has her first ability based on cards. The flag format is the order of the suits as they appear on the tooltip, with each suit followed by the stat modifier for that suit, finished with the number of cards she can hold at one time. Assume the ability is at max level.

Example: dalctf{ruby15_emerald-25_sapphire50_amethyst-100_25} (negative numbers included)

No file, no netcat, no encoded blob. Just prose. This is a pure trivia/OSINT challenge dressed up as “misc,” and the entire difficulty is in precisely pinning down a handful of in-game numbers. The example flag is deliberately misleading — it uses gemstone names (ruby, emerald, …) that have nothing to do with the answer. All it’s actually telling you is the shape of the flag:

1
dalctf{ <suit><value> _ <suit><value> _ <suit><value> _ <suit><value> _ <count> }
  • Four suit/value pairs, underscore-separated
  • A trailing integer
  • Values can be negative (negatives keep their -, positives have no +)

So the work breaks down into four questions:

  1. Which game?
  2. Which character and ability?
  3. What are the four suits, in tooltip order, and their stat modifiers at max level?
  4. How many cards can she hold at once?

Let’s take them one at a time.


Step 1 — Identify the game

“an invite only, unreleased game made by valve”

This is almost a giveaway if you follow gaming news. Valve has exactly one famous title that spent a long stretch in an invite-only, unreleased closed beta: Deadlock, their 6v6 hero-shooter/MOBA hybrid. It was the worst-kept secret in gaming for months — playable only if a friend invited you, and never “officially” released during that period.

That single clue (“invite only, unreleased, Valve”) maps cleanly to Deadlock.

Step 2 — Identify the character and ability

“a character who is a gambler who has her first ability based on cards”

Now we need a female Deadlock hero themed around gambling / cards, whose first ability (Ability 1 / signature 1) is card-based.

A quick search for “Deadlock gambler hero card ability” lands on Wraith. Wraith is a fast-talking, fast-firing gunslinger whose kit got reworked to lean hard into the gambler fantasy. Her Ability 1 is named Card Trick:

Deal weapon damage to summon cards of a random suit. Each card can be thrown, dealing damage and applying a different effect depending on its suit.

That’s our ability. The challenge name — “Card Trick” — is literally the ability name, confirming we’re on the right track.

Step 3 — Get the numbers (and why secondary sources fail)

This is where the challenge actually bites. Card Trick has been reworked and re-balanced repeatedly, so the internet is full of contradictory values:

SourceSpadeDiamondHeartClub
Reveal tweet (Deadlock Intel)+70%-8%75 HP30%
One wiki summary+60%-8%75 HP-30%
An “improved totals” blurb2.5x-13%15050%

If you just grab the first number you see, you’ll get the flag wrong — which is exactly what happened on my first submission attempt. The tweet and the wiki give base values; the challenge explicitly says “Assume the ability is at max level.” In Deadlock every ability has a base form plus three upgrade tiers (T1/T2/T3), bought with ability points. “Max level” = all three upgrades purchased.

So I needed the authoritative, current, per-tier data — not a journalist’s snapshot from launch day. The cleanest way to get that is to skip the prose entirely and read the shipped game data directly via the community-maintained Deadlock API, which mirrors Valve’s ability definitions.

Finding the ability’s internal class name

First, pull Wraith’s hero object and look at which ability fills signature1:

1
curl -sL "https://api.deadlock-api.com/v1/assets/heroes/by-name/wraith" -o wraith.json
1
2
3
import json
d = json.load(open("wraith.json"))
print(d["items"]["signature1"])   # -> citadel_ability_card_toss

Card Trick’s internal class name is citadel_ability_card_toss (the “throw cards” mechanic).

Pulling the raw ability definition

1
curl -sL "https://api.deadlock-api.com/v1/assets/items/citadel_ability_card_toss" -o cardtrick.json

Dumping the properties block gives the base values, with their exact units:

1
2
3
4
5
SpadeDamageBonus   = 60     (postfix %, label "Bonus Damage")
DiamondResistShred = -8.0   (postfix %, label "Bullet and Spirit Resist Reduction")
ClubSlowPercent    = -30    (postfix %, label "Movement Slow")
HeartHeal          = 75     (label "Heal")
AbilityCharges     = 2      (label "Charges")

Note the signs baked into the data: Diamond and Club are stored negative (-8, -30), Spade and Heart are positive. That directly matches the example flag’s “negative numbers included” hint.

Confirming the tooltip ORDER

The challenge wants the suits “in the order they appear on the tooltip.” Don’t guess — the JSON literally encodes the tooltip layout under tooltip_details.info_sections. Reading the properties_block entries in order:

1
2
3
4
Spade   -> SpadeDamageBonus
Diamond -> DiamondResistShred
Club    -> ClubSlowPercent
Heart   -> HeartHeal

So the tooltip order is Spade → Diamond → Club → Heart. (This matters! The reveal tweet listed them Spade/Diamond/Heart/Club — a different order. Trusting the tweet would have swapped the last two.)

Applying the max-level (T3) upgrades

The upgrades array in the same JSON spells out exactly what each tier changes:

1
2
3
4
5
6
7
Tier 1: AbilityCharges      +2
Tier 2: Damage              +40   (and +0.4 spirit scaling)
Tier 3: SpadeDamageBonus    +40
        DiamondResistShred  -5
        ClubSlowPercent     -20
        HeartHeal           +75   (and +0.5 spirit scaling)
        ImprovedJokerChance +1

Tier 3 is the “all suits are improved” upgrade. These are additive bonuses on top of the base values. I sanity-checked the additive convention against Damage: base 45 + T2 +40 = 85, which is the well-documented max-level damage — so the same base+bonus arithmetic applies to every property.

Working out each suit at max level:

SuitBaseT3 bonusMax level
Spade (Bonus Damage)60%+40100%
Diamond (Resist Reduction)-8%-5-13%
Club (Movement Slow)-30%-20-50%
Heart (Heal)75+75150

So the four pairs are: spade100, diamond-13, club-50, heart150.

Step 4 — How many cards can she hold?

This is the sneaky final integer, and it’s the one I got wrong on my first try.

The obvious-but-wrong answer is 8. Lots of write-ups and the wiki say Card Trick “generates a random card out of an 8-card stack (2 of each suit).” But re-read the question carefully: it asks how many cards she can hold at one time — not how big the draw deck is. The 8-card stack is just the bag of possibilities the RNG draws from to decide which suit you get; it is not your hand size.

The number of cards Wraith actually holds ready to throw is AbilityCharges. From the data:

1
2
AbilityCharges base value = 2
Tier 1 upgrade            = +2   ->  4 at max level

And remember — “assume the ability is at max level.” Tier 1 (“increases her maximum card count,” as the build guides describe it) bumps her from 2 charges to 4. So at max level she holds 4 cards.

That’s the trap the challenge was built around: the well-publicized “8” is a deck-composition factoid, while the real “cards held” value is a leveled charge count of 4.

Step 5 — Assemble the flag

Plug everything into the example’s format:

1
2
3
order:   Spade, Diamond, Club, Heart
values:  100,   -13,     -50,  150
held:    4
1
dalctf{spade100_diamond-13_club-50_heart150_4}

Correct.


Lessons Learned

  • A “Cards”-category challenge that’s really OSINT. No tooling solves this — only knowing (or quickly identifying) Valve’s Deadlock and the hero Wraith.
  • Read the question, not the meme. The most-quoted numbers (the +70% reveal tweet, the “8-card stack” trivia) are exactly the wrong ones. The challenge specifically says max level and cards held, and both of those steer you off the popular answers.
  • Go to the source data. Game journalism and wikis lag behind balance patches and mix up base vs. upgraded values. The Deadlock API exposes Valve’s actual ability definitions — including per-tier upgrade deltas and the literal tooltip ordering — which removed every ambiguity:
    • base properties → starting values + correct signs
    • tooltip_details.info_sections → suit order
    • upgrades[] → the T3 deltas to add for “max level”
  • Mind the distinction between a draw pool and a hand size. 8 (the stack) vs 4 (charges held) is the whole challenge in miniature.

Appendix — One-shot data pull

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 1. find the ability class name on Wraith
curl -sL "https://api.deadlock-api.com/v1/assets/heroes/by-name/wraith" \
  | python3 -c "import sys,json;print(json.load(sys.stdin)['items']['signature1'])"
# -> citadel_ability_card_toss

# 2. dump the ability's suit values, tooltip order, and upgrade tiers
curl -sL "https://api.deadlock-api.com/v1/assets/items/citadel_ability_card_toss" \
  -o cardtrick.json
python3 - <<'PY'
import json
d = json.load(open("cardtrick.json"))
base = {k: d["properties"][k]["value"] for k in
        ["SpadeDamageBonus","DiamondResistShred","ClubSlowPercent","HeartHeal","AbilityCharges"]}
print("base:", base)
for i,u in enumerate(d["upgrades"],1):
    print(f"T{i}:", [(p['name'], p.get('bonus')) for p in u["property_upgrades"]])
PY