Technical UI Case Study

Debt Deadline

Three UI systems in action. See how I turn game UI concepts into clear, rewarding interactions in Unity.

Role
Unity Developer
UI/UX · Sound Design
Tools
Timeline
2022 – present
Team
Two-person team

About the Game

A psychological-thriller RPG with a retro-cinematic style, where every playthrough is unique and every decision matters.

Escape a procedurally generated nightmare while managing your sanity—or your own mind will turn against you.

How to keep a complex game readable as its protagonist loses his mind?

Debt Deadline is a roguelike combining sanity, combat, and intrigue. Its UI had to read at a glance and make each interaction feel rewarding. I planned and coded the three systems below, connected them to game data, and created their transitions and sound design.

Selected UI Work

  • Concept
  • Design
  • Code
  • Animation
  • Audio

David's sanity ranges from −100 to 100 with each decision.
The HUD shows four distinct mental states.
Players can see how their choices affect his sanity.

The challenge

Sanity needed a visual identity of its own. A bar could be mistaken for HP; a number beside an icon felt dull and lacked visual weight. Every change had to be felt, and all four mental states had to read without a tutorial.

The approach
  • Four portraits show the mental states. Each covers part of the −100 to 100 range and has its own idle pulse.
  • The star flips below zero, turning from white to black.
  • The value counts to its new total with a flicker.
  • State changes trigger a visual and audio burst: a star explosion, hit overlay, and sound.
  • At −100, the display turns critical. The star trembles and the overlay signals danger.
HudView_Sanity.cs
// Runs every frame while the number counts, so one big drop
// can cross two states and play both bursts in order.
bool enteredStrained = isMovingDown
    && previousValue >  SanityThreshold_Strained_Max
    && currentValue  <= SanityThreshold_Strained_Max;

if (enteredStrained)
    OnEnterStrained();   // star flip + hit overlay + FMOD burst
Code example

Retune the states without changing the HUD. As the displayed value eases toward its target, HudView_Sanity checks the four thresholds every frame. Those thresholds live in the game's balance constants.

  • Code
  • Animation
  • Audio

You owe the Boss money. Pay in five days or he'll kill you.
That makes the money counter a constant focus.
Motion and sound make each payout feel rewarding.

$ 0 0 0 1 2 5 0 6 4 1 2 3 4 5 Iron housing Drum Mask Digit on Digit off
1
The housing shakes with each change.The iron frame and dollar plate give the counter its weight.
2
One scrolling strip per digit.Each drum moves its strip behind a fixed window.
3
The mask reveals one digit.The rest of the strip stays hidden behind the frame.
4
Lit digits show the amount.Active digits use #ABABFF.
5
Leading zeros stay dim.Unused digits fade to #14172E.
The challenge

Money needed to feel like a tangible reward. The counter had to capture a slot machine's motion and sound while keeping the total easy to read. We needed simple, low-cost solutions that preserved that mechanical feel without rebuilding the full mechanism or sacrificing responsiveness.

The approach
  • Each digit rolls the full change in value. From 1,250 to 1,480, the units move 230 steps, the tens 23, and the hundreds 2.
  • Fast digits swap to a pre-blurred strip. A texture change supplies the motion blur.
  • Flat strips look like spinning drums. Each scrolls behind a mask.
  • Small payouts play six times faster. Changes of 100 or less stay responsive.
  • Staggered starts create a slot machine's rhythm. Each drum begins slightly after its neighbor.
HudView_MoneyCounter.cs
// How far one drum spins, carry-overs included.
// digitIdx: 0 = units, 1 = tens, 2 = hundreds...
private static DigitSpinData GetDigitSpinData(int fromVal, int toVal, int digitIdx)
{
    // Cut off every digit to the right of this drum.
    // For 1,250 → 1,480, the tens drum sees 125 → 148.
    int place = (int)Mathf.Pow(10, digitIdx);
    int fromB = fromVal / place;
    int toB = toVal / place;

    // Each unit of difference is one step of this drum:
    // units 230, tens 23, hundreds 2, thousands 0.
    int dir = toVal > fromVal ? 1 : toVal < fromVal ? -1 : 0;
    int steps = Mathf.Abs(toB - fromB);

    // The drum starts and stops on the last digit of what it sees.
    return new DigitSpinData
    {
        fromDigit = fromB % 10,   // 125 → 5
        toDigit = toB % 10,       // 148 → 8  (5 + 23 steps lands on 8)
        steps = steps,
        direction = dir
    };
}
Code example

Each digit's timing is tunable in play mode. HudView_MoneyCounter calculates the spin distance per digit. Each CounterDigit scrolls its strip along an easing curve with its own delay; all timings live in the Inspector.

  • Concept
  • Design
  • Code
  • Animation
  • Audio

Buy from the merchant's cabinet; sell from your briefcase.
The shop reflects the game's noir, retrofuturistic world.
Separate displays make it clear who owns each item.

The challenge

The shop needed to express the game's world. A grid of items alone couldn't give browsing the sense of handling real goods. Buying and selling had to feel grounded in that world, with clear transactions and predictable navigation across mouse, keyboard, and controller.

The approach
  • A cabinet for buying; a briefcase for selling. Glass and lighting frame the NPC's goods, while price tags turn the player's inventory into a selling display.
  • Recessed slots and oversized art add depth. Masks, outlines, and dithered textures create the illusion and break the grid's flat silhouette.
  • One navigation model serves all three contexts. Buying, selling, and the player's briefcase share the same behavior under different visual skins.
  • Unavailable items give clear feedback. Grayscale, a wiggle, and a refusal sound play without reaching the transaction logic.