DesignGddBlind Effect

Blind Effect

Status: Designed Author: Nathan + game-designer Last Updated: 2026-04-07 System Index: Extension of Status Effect System (#7) and Enemy Data & AI (#6)


1. Overview

Blind is a status effect applied to the player that hides enemy intents for the duration of the effect. While blinded, the intent display for all living enemies is replaced with a concealment overlay — the player cannot see what any enemy will do on their next turn. Blind is a pure information denial mechanic: it does not change the dice, reduce damage, or alter scoring. The only thing it takes away is the player's ability to plan around incoming enemy actions. Blind lasts for exactly 1 turn by default, though specific sources can apply extended durations. The effect expires at the end of the player's scoring phase (before the enemy phase executes), meaning the player plays their hand without the information, and the reveal happens as enemies act — not before.

The system is introduced through the Merchant's POCKET_SAND action (shop combat) and can appear on select interference-type enemies in later floors. It integrates with the existing Status Effect System as a new TIMED debuff with a new modifier_type of INFORMATION_DENY, and hooks into the Dice Combat UI's intent rendering pipeline.


2. Player Fantasy

The terror of playing blind. Most of the game is about reading the battlefield — "the skeleton is attacking for 12, the shaman is about to heal, I should kill the shaman." Blind strips that away. For one turn, the player is flying without instruments.

The fantasy has two moments:

  1. The panic moment — the intent icons go dark. The player has to make a decision with incomplete information. Do they prioritize the enemy most likely to deal damage? Kill the most dangerous target even without confirmation? Use a consumable as insurance? This engages the player's pattern recognition ("I know what this enemy type usually does") and tests their mental model of enemy behaviors.

  2. The resolution moment — the player scores and commits. Then the enemy phase plays out. Finding out what was hidden is a small dramatic beat — relief if enemies did nothing devastating, dread if the hidden action was exactly what the player feared.

Secondary fantasy: counterplay mastery. Veteran players will know which relics counter blind and keep them specifically for floors where blinding enemies appear. Recognizing the Merchant's POCKET_SAND setup and having a Clarity Lens relic ready feels like reading an opponent.

Target MDA aesthetics: Challenge (primary — plays without information), Discovery (secondary — learning enemy behavior by heart to compensate), Fantasy (tertiary — the world pushes back in unexpected ways).

This mechanic does NOT serve Submission (relaxation). Blind is a tension spike, not a comfort mechanic. It should be used sparingly.


3. Detailed Design

3.1 Core Rules

  1. Blind is a status effect ("blind") applied to the player, not enemies.
  2. While blind is active (stacks > 0), all enemy intent displays are hidden.
  3. Blind hides intent only — enemy HP bars, shield values, and status effect icons on enemies remain fully visible. The player can still see how healthy enemies are and what statuses they carry; they just cannot see the action those enemies will take next.
  4. Blind uses DurationType.TIMED. Duration is measured in player turns: the stack count decreases by 1 at the start of the player's phase (before the player rolls dice).
  5. Blind stacks extend duration, they do not intensify effect. Applying Blind 2 to a player already at Blind 1 results in Blind 3 (3 turns hidden).
  6. When Blind expires (stacks reach 0), intent icons are immediately restored. The restore happens before the player rolls, so the player always enters their turn with full information unless they are currently blinded.
  7. Blind is a debuff (is_debuff = true). Future cleanse mechanics (consumables, relics, shrine blessings) can remove it.
  8. Multiple sources of Blind (e.g., Merchant + a Shadow Rogue in the same encounter) stack additively on duration. The player can accumulate multiple blind turns.

3.2 What Is Hidden vs. Visible During Blind

InformationBlinded StateVisible State
Enemy HP barVisibleVisible
Enemy shield / block valueVisibleVisible
Enemy status effect icons (Burn, Freeze, etc.)VisibleVisible
Enemy name labelVisibleVisible
Enemy intent iconHiddenVisible
Enemy intent tooltip (hover)HiddenVisible
Enemy intent value (damage number / heal amount)HiddenVisible
Targeting label ("will attack you for 12")HiddenVisible

The hover tooltip is also suppressed while blind is active. The player cannot work around the visual by hovering — the information is simply unavailable.

3.3 Visual Treatment

Intent display during Blind:

  • The intent icon slot is replaced with a solid "?" icon (or a closed eye icon, per art direction). Use the existing 1-bit art style.
  • A subtle desaturated overlay (greyscale tint, ~30% opacity) appears over each enemy's intent area — not the whole enemy sprite, just the intent badge.
  • The targeting label beneath each enemy reads: "???" instead of the normal action description.
  • A status indicator on the player HUD shows the Blind debuff icon with the remaining stack count (same visual system as existing status icons).

Blind application animation:

  • When Blind is applied, the intent icons "close" with a brief fade-to-grey animation (~0.3 seconds). This is not a screen-wide effect — only the intent badges animate.
  • Optional: brief screen-edge darkening pulse (vignette flash, 1 frame) to communicate "something happened to you."

Blind expiry animation:

  • At the start of the player's turn when stacks hit 0, intent icons "open" with a fast fade-in (~0.2 seconds).
  • No fanfare. The reveal is understated — the icons just come back.

3.4 Enemy Usage — Who Can Blind?

Blind is a rare, high-value interference. It should feel notable when it appears, not routine. Placement follows the principle: blind appears on enemies whose thematic identity centers on deception, misdirection, or information warfare.

Tier 1 — Existing enemy: Merchant (POCKET_SAND)

Already defined in shop-combat-system.md. The Merchant applies Blind 1 with 20% action weight. This is the player's introduction to blind in a controlled context (a chosen fight with a known, special enemy).

Tier 2 — New interference-type enemies (recommended additions)

The following enemies are designed to carry Blind as their primary interference. These are proposals — the enemy database owner should review for balance fit:

EnemyFloor RangeTierBlind MechanicOther Actions
Shadow Rogue8-12EliteSNEAK_ATTACK: Blind 1 + deal 8 damage (combined action)STAB: 12 damage
Smoke Cultist5-8BasicRITUAL_SMOKE: Blind 1CURSE: target one die
Blind Oracle11-15ElitePROPHECY_VEIL: Blind 2WEAKEN: -20% player damage next turn
Arch Demon (Act 3 Boss)Floor 15BossDREAD_AURA: Blind 1 on turn 2 of phase 2Full existing kit

Design constraint: no more than 1 blinding enemy per encounter. The blind effect is disruptive enough that stacking it across multiple enemies in one fight would feel oppressive rather than interesting. If the encounter generator places multiple blinding enemies together, one of them should have its Blind action weighted out (set weight to 0 for that encounter slot).

Tier 3 — Arch Demon passive consideration

The Arch Demon's Phase 2 (boss-specific) can include a DREAD_AURA action that blinds for 1 turn. This is a thematic fit (Act 3 boss creating dread and uncertainty) and a late-game skill test. It should appear at most once per phase.

3.5 Counterplay

Blind is meaningful only if the player has counterplay options. The following counterplay vectors are designed into the system:

Intrinsic counterplay (no items required):

  • Enemy behaviors are learnable. Veteran players who have memorized what Shadow Rogues and Smoke Cultists do can play optimally even without seeing the intent. Pattern AI enemies follow fixed sequences — a player who counts turns knows exactly what's coming.
  • The player can still see enemy HP and statuses, so priority targeting (kill the low-HP enemy, focus the burning one) remains available.
  • If an enemy is the only surviving enemy, the player knows the intent must be one of that enemy's possible actions. Narrowing the possibility space is a skill expression.

Relic counterplay:

Relic NameEffectAvailability
Clarity LensImmune to Blind. Intent always visible.Rare relic, shop or elite reward
Smelling SaltsWhen Blind is applied, immediately reduce stacks by 1 (minimum 0). Blind 1 = no effect; Blind 2 = Blind 1.Uncommon relic
Oracle's MonocleWhile Blind, deal +10% damage (fighting blind makes you reckless and powerful).Uncommon relic

Consumable counterplay:

ConsumableEffectNotes
Eye Drops (new)Remove all stacks of Blind immediately. Single use.Sold in shops, found in rewards
ReforgeDoes not cleanse Blind (wrong tool category)Existing item

Elemental counterplay:

  • Freeze applied to a blinding enemy prevents that enemy from executing their next action. Freezing an enemy before they can apply Blind wastes their turn. This is the primary offensive counterplay — control the enemy, deny the blind.
  • Wind combo (Frost Lance, Tempest) AoE can freeze multiple enemies simultaneously, shutting down coordinated blind setups.

Cleanse mechanic (future-proofing):

The Status Effect System already notes a future cleanse mechanic. When cleanse is implemented, Blind (is_debuff = true) should be cleansable. Any cleanse consumable, relic, or shrine blessing should remove Blind along with other debuffs.

3.6 Interaction with Interference System

Blind is a status effect, not an interference type. Interference types (SNIPE, CHAOS, etc.) are instantaneous effects that happen during the enemy phase. Blind is a persistent debuff that affects the player's information state across a full player turn.

The two systems coexist:

  • POCKET_SAND (Merchant action) applies the Blind status during the enemy phase, taking effect immediately — the player's next turn will be blinded.
  • If a CHAOS interference also fired the same enemy phase, the dice are scrambled AND the player plays next turn without knowing what enemies will do. Stacked pressure is intentional for the Merchant encounter.
  • Blind does not prevent or modify any interference type. If a die is SNIPED while the player is blind, the snipe still happens normally. The player still sees the die being affected.

3.7 Interaction with Per-Enemy Turn Limit

The turn limit is unchanged by Blind. The player has the same number of turns to defeat the enemy whether blinded or not. Blind does not pause or reset the turn counter.


4. Formulas

4.1 Blind Duration

applied_blind_stacks = source_base_stacks

if target already has "blind":
    target.statuses["blind"].stacks += applied_blind_stacks
else:
    target.statuses["blind"] = { stacks: applied_blind_stacks }

Where source_base_stacks is defined per enemy action:

SourceBase StacksNotes
Merchant POCKET_SAND120% action weight
Smoke Cultist RITUAL_SMOKE1100% action weight on that action
Shadow Rogue SNEAK_ATTACK1Combined with 8 damage
Blind Oracle PROPHECY_VEIL2Elite — 2-turn blind
Arch Demon DREAD_AURA1Phase 2 only, once per phase

4.2 Blind Tick (Duration Decrease)

Blind is DurationType.TIMED. Ticking follows the existing tick rule:

# At the START of the player's turn:
if player has "blind":
    player.statuses["blind"].stacks -= 1
    if player.statuses["blind"].stacks <= 0:
        remove_status(player, "blind")
        signal blind_expired  # Triggers intent reveal animation in UI

This means:

  • Blind applied during the enemy phase of Turn N → player is blinded during Turn N+1, expires at the start of Turn N+2.
  • Blind 2 applied → player is blinded during Turns N+1 and N+2, expires at Turn N+3.

4.3 Smelling Salts Relic Interaction

# Called during apply_status, before committing:
if player has relic "smelling_salts":
    applied_blind_stacks = max(0, applied_blind_stacks - 1)
    if applied_blind_stacks == 0:
        return  # Blind fully absorbed, nothing applied

Net result: Smelling Salts converts Blind 1 into no effect, Blind 2 into Blind 1, Blind 3 into Blind 2.

4.4 Oracle's Monocle Relic Interaction

# In damage calculation, after base scoring:
if player has "blind" and player has relic "oracles_monocle":
    final_damage *= 1.10

Applies to hand damage only, not elemental combo bonus damage.

4.5 Eye Drops Consumable

# On use:
if player has "blind":
    remove_status(player, "blind")
    signal blind_expired  # Same intent reveal animation as natural expiry
else:
    # No-op — consumable still consumed (wasted use, player's mistake)

Consumable is wasted if used while not blinded. This is consistent with how other consumables behave on null targets.


5. Edge Cases

SituationResolution
Blind applied when player is already at Blind 3Stacks add normally. No cap. Blind 6 is possible at extreme karma debt (multiple Merchants + bodyguards).
Player uses Eye Drops when not blindedConsumable consumed, no effect. No refund. Warning tooltip on hover: "Only effective while Blinded."
Player kills the blinding enemy before it actsEnemy dies during player phase; its queued intent never executes. Blind is never applied. The player avoided the blind entirely — this is correct and a valid strategic reward.
Blind applied to player on the very last turn (turn limit turn)Blind applies normally but is essentially irrelevant — the player has no more turns. The enemy phase will execute either as the player's last action or after their loss.
Multiple blinding enemies in same encounterStacks accumulate per application. E.g., two Smoke Cultists that both use RITUAL_SMOKE in the same enemy phase = Blind 2. This is acceptable as a rare late-game spike but the encounter generator should be configured to avoid pairing blinding enemies (see Section 3.4).
Blind expires mid-enemy-phase (impossible by design)Blind ticks at the START of the player's turn, not during the enemy phase. The enemy phase never modifies Blind stacks. This edge case cannot occur.
Player freezes the enemy before POCKET_SAND firesFrozen enemy skips their action (including POCKET_SAND). Blind is not applied. Freeze works as a full action denial.
Clarity Lens relic + Blind applied anywayClarity Lens grants immunity. The apply_status call for "blind" is no-opped before any stacks are added. Stacks stay at 0 (or the status is never created). The intent icons remain visible throughout.
Cleanse consumable (future) removes Blind that has already caused a turn of blindnessThe Blind is removed mid-turn if the consumable is used during the player's turn. The intent icons restore immediately. The player can respond to newly visible intents before scoring if the UI updates fast enough — this is intentional (spending a consumable slot to restore info mid-turn is a valid play).
Enemy's CONDITIONAL AI changes action after intent is setIn the existing enemy AI design, intents are set at the start of the player phase and do not change. Blind hiding the intent is accurate to what the enemy will actually do — the hidden information is stable.
Arch Demon DREAD_AURA blind fires in phase 1 (bug)The Phase 2 flag should gate the action. If triggered in Phase 1 by a bug, behavior is identical (Blind 1 applied) but the design intent is violated. This should be caught by acceptance criteria test #11.

6. Dependencies

Upstream (systems this depends on)

SystemTypeInterface
Status Effect SystemHardBlind is registered as a new StatusData resource. Ticking, stacking, and removal follow the existing status lifecycle. Adds INFORMATION_DENY to StatusModifierType enum (or uses NONE if the hook is fully in the UI layer — see note below).
Enemy Data & AIHardBlind-applying actions are defined as EnemyAction resources with action_type = DEBUFF, status_id = "blind", target = PLAYER (new target type needed — see note below).
Dice Combat ManagerHardManages turn phase boundaries where Blind ticks. Emits signal to UI when Blind state changes.

Implementation note — StatusModifierType: The existing StatusModifierType enum covers damage and block math. INFORMATION_DENY is a new type that does not modify combat math — it modifies UI rendering. The cleanest implementation is to add INFORMATION_DENY to the enum and handle it as a special case in the UI layer (the Combat UI queries whether the player has "blind" and hides intents accordingly), rather than having the Status Effect System's query functions handle it.

Implementation note — EnemyTarget: Existing targets are ALL_PLAYERS, RANDOM_PLAYER, SELF, ALL_ENEMIES. The blind action targets the player. In solo, this is equivalent to ALL_PLAYERS or RANDOM_PLAYER (same result). For implementation, use ALL_PLAYERS for DEBUFF actions targeting the player to keep the schema consistent with any future multiplayer consideration.

Downstream (systems that must be aware of this)

SystemTypeInterface
Dice Combat UIHardMust query Blind status before rendering intent displays. When player.has_status("blind"), replace intent icons with "?" and suppress hover tooltips. Listens for blind_expired signal to trigger reveal animation.
Shop Combat SystemSoftMerchant POCKET_SAND action already documented. No new interface needed — it's just an EnemyAction using status_id = "blind".
Relic DatabaseSoftClarity Lens, Smelling Salts, Oracle's Monocle must be added as new relic definitions. They read/modify Blind stacks through the existing status API.
Consumable DatabaseSoftEye Drops must be added as a new consumable. Uses remove_status(player, "blind").
Enemy DatabaseSoftShadow Rogue, Smoke Cultist, Blind Oracle must be defined with Blind-applying actions. Arch Demon's Phase 2 must add DREAD_AURA action.
Audio ManagerSoftPOCKET_SAND sand-throw SFX on blind application, "blind cleared" tone on expiry. Uses existing SFX event system.

7. Tuning Knobs

All values live in assets/data/status_effects/blind.tres and assets/data/relics/ (per relic). None hardcoded.

KnobDefaultSafe RangeCategoryWhat It Affects
BLIND_BASE_DURATION (Merchant POCKET_SAND)11-2GateBlind from the Merchant. 2 turns turns a boss fight level encounter into a punishing info blackout.
BLIND_BASE_DURATION (Smoke Cultist)11-2GateBlind from basic-tier enemies. Should stay at 1 — basic enemies should not inflict 2-turn blindness.
BLIND_BASE_DURATION (Blind Oracle)21-3GateElite enemy, higher baseline acceptable. 3 is maximum before the effect becomes frustrating rather than challenging.
BLIND_BASE_DURATION (Arch Demon DREAD_AURA)11-2GateBoss context. 1 keeps it fair — the boss already has a full multi-phase kit.
SMELLING_SALTS_ABSORB1 stack1-2FeelStacks of Blind the Smelling Salts relic absorbs on application. 2 would make the relic too strong against 1-stack sources.
ORACLES_MONOCLE_BONUS10% damage5-20%CurveDamage bonus while blind. Too high (>20%) encourages intentionally staying blinded, which trivializes the mechanic.
PRICE_EYE_DROPS80g50-120gGateShop purchase price. Should be more expensive than a standard consumable (70g) but not so expensive it's never purchased.
MAX_BLIND_ENCOUNTER_SOURCES1 per encounter1-2GateNumber of enemies in a single encounter allowed to have Blind actions. 1 is the strong recommendation. Increase to 2 only if playtesting shows blind encounters are too easy to avoid.
INTENT_REVEAL_ANIM_DURATION0.2s0.1-0.4sFeelSpeed of the intent-reveal animation when blind expires. Shorter feels snappier; longer is more dramatic.
INTENT_HIDE_ANIM_DURATION0.3s0.2-0.5sFeelSpeed of the intent-hide animation when blind is applied. Slightly slower than reveal for dramatic weight.

8. Acceptance Criteria

All criteria must pass before this feature ships. Each criterion maps to a specific, verifiable behavior.

#CriterionVerification Method
1Blind status applies correctly from POCKET_SANDTrigger Merchant combat, let POCKET_SAND fire. Assert player.statuses["blind"].stacks == 1.
2Intent icons are hidden while Blind is activeFunctional: during a turn where player has blind stacks > 0, assert that intent icon nodes are set to the "?" placeholder and not the enemy's actual intent icon.
3Intent hover tooltips are suppressed while Blind is activeFunctional: hover over enemy intent badge while blinded, assert that no tooltip appears (tooltip node is not shown).
4Enemy HP, shield, and status icons remain visible while Blind is activeVisual verification: enter a blinded turn, confirm HP bars, shield values, and status badges render normally.
5Blind stack decreases by 1 at the start of the player's turnUnit test: apply Blind 2, advance to player turn, assert stacks == 1. Advance again, assert stacks == 0 and status removed.
6Intent icons restore when Blind expiresFunctional: observe intent icons return to normal on the turn after Blind stacks reach 0. Assert reveal animation plays.
7Blind stacks accumulate from multiple sourcesUnit test: apply Blind 1, then Blind 1 again from a different source, assert stacks == 2.
8Clarity Lens relic grants full immunityApply Clarity Lens relic. Trigger POCKET_SAND. Assert player.statuses does not contain "blind" after application. Intent icons never change.
9Smelling Salts relic reduces applied stacks by 1Unit test: equip Smelling Salts, apply Blind 1 → stacks = 0 (not applied). Apply Blind 2 → stacks = 1.
10Eye Drops consumable removes all Blind stacks immediatelyEquip Eye Drops, apply Blind 2, use Eye Drops, assert player.statuses["blind"] is absent and intent icons restore.
11Eye Drops consumed with no effect when player is not blindedUse Eye Drops while not blinded, assert consumable is consumed and no error is thrown.
12Oracle's Monocle deals +10% damage while blindedUnit test: calculate hand damage with and without Blind active while Oracle's Monocle is equipped. Assert 10% increase is applied when blind.
13Freezing a blinding enemy before it acts prevents Blind applicationSet up combat: enemy queued to use POCKET_SAND, trigger Freeze on that enemy before their action fires, assert player never receives Blind.
14Arch Demon DREAD_AURA only fires in Phase 2Boss encounter test: assert DREAD_AURA action does not appear in Phase 1 intent sequence. Assert it appears at most once in Phase 2.
15Encounter generator does not place two blinding enemies in same encounterEncounter generator test: run 1000 procedural encounter generations for floors 5-15, assert 0 encounters contain more than 1 enemy with a Blind-applying action (assuming MAX_BLIND_ENCOUNTER_SOURCES = 1).
16Blind status icon and stack count appear on player HUDExperiential: while blinded, assert the Blind debuff icon with correct stack count is visible on the player status bar (same row as other debuffs).
17Blind application animation plays on POCKET_SAND fireExperiential: trigger POCKET_SAND, observe intent badges animate to "?" within 0.3 seconds. No visual pop/flicker.
18Blind expiry animation plays cleanlyExperiential: observe intent reveal animation at Blind expiry. Assert no frame where both "?" and real icon are simultaneously visible.
19Blind does not affect the per-enemy turn counterFunctional: assert turn counter increments and decrements identically whether or not the player is blinded.
20Playtest validation — "information denial feels fair, not arbitrary"Playtest criterion: run 5 playtests where Blind fires at least once. Players should not describe the effect as "I had no way to respond" — they should describe it as "I didn't know what was coming but I made my best guess." If more than 2 of 5 sessions report arbitrary frustration, reduce default Blind duration or increase counterplay availability.
Built with LogoFlowershow