Broken Reality 2000 - UI Programming

Broken Reality 2000 - UI Programming

A modular UI system for a surreal Y2K exploration game, designed to scale across devices and support dynamic in-game dialogue.

A modular UI system for a surreal Y2K exploration game, designed to scale across devices and support dynamic in-game dialogue.

Category

Category

Unity · C# · UI Systems

Unity · C# · UI Systems

Role

Role

UI Programmer

UI Programmer

Studio

Studio

Dynamic Media Triad

Dynamic Media Triad

Duration

Duration

1 Year

1 Year

The Challenge

Create an adaptable UI system that fits the game’s Y2K aesthetic while remaining responsive and usable across screen sizes. Dialogue, HUD, and menus needed to be modular and easily reusable by designers and writers.

What I Built

I built a fully modular, data-driven UI system in Unity using ScriptableObjects, reusable components, and clean architecture. The system supports dialogue, HUD, prompts, lists, tabs, and contextual interactions while remaining responsive across resolutions. All features were designed to match the game’s Y2K aesthetic and provide a flexible, efficient workflow for designers and writers.

Watch it in action

Technical Contributions

1. Universal Dynamic List Management System

Problem:

Build a reusable UI list system capable of powering multiple categories (NPCs, interactables, collectibles) without duplicated logic.

Solution:

Created a fully dynamic list generator that filters data, builds UI elements, and binds callbacks at runtime, allowing any category to plug into the same system.

private void UpdateList 
  ( List<ScannableData> items,
    List<ScannableData> scannedItems,
    List<GameObject> uiButtons,
    GameObject window,
    UnityAction<int> onClick )
{
    scannedItems.Clear();
    uiButtons.ForEach(Destroy);
    uiButtons.Clear();

    foreach (var i in items)
        if (i.Scanned) scannedItems.Add(i);

    buttonTemplate.SetActive(true);

    for (int i = 0; i < scannedItems.Count; i++)
    {
        var btn = Instantiate(buttonTemplate, window.transform);
        btn.transform.GetChild(0).GetComponent<Image>().sprite = scannedItems[i].Sprite;
        btn.GetComponent<Button>().AddEventListener(i, onClick);
        uiButtons.Add(btn);
    }

    buttonTemplate.SetActive(false

Result:

One system powers 4+ major UI categories, cutting code duplication by ~80% and supporting unlimited scalable content.

2. Dynamic Home Menu System

Problem:

The home menu needed to always reflect real-time progress: badges, likes, credits, and unlocks.

Solution:

Developed a real-time menu updater that calculates badge tiers, updates progress bars, and syncs all runtime data every time the pause menu opens.

public void ShowPauseMenu()
{
    foreach (var b in badges)
    {
        if (playerLikes.Value <= b.MaxLikes)
        {
            currentBadge = b;
            b.BadgeIsUnlocked = playerLikes.Value >= b.MaxLikes;
            break;
        }
    }

    likesBar.minValue = currentBadge.MinLikes;
    likesBar.maxValue = currentBadge.MaxLikes;
    currentCreditsText.text = playerCredits.Value.ToString();

    pauseMenu.SetActive(true

Result:

Instantly accurate home menu with correct badge logic, progress tracking, and full UI synchronization every time the menu is accessed.

3. Performance Optimized Quest Tracking

Problem:

Display active quests without constant runtime processing to avoid performance overhead.

Solution:

Implemented lazy-loaded UI updates that only run when the quest screen is opened, filtering relevant quests and generating UI on demand.

private void UpdateActiveTaskList()
{
    activeQuests.Clear();
    activeQuestsButtons.ForEach(Destroy);
    activeQuestsButtons.Clear();

    foreach (var q in questLoader.quests)
        if (q.IsActive) activeQuests.Add(q);

    buttonTemplate.SetActive(true);

    for (int i = 0; i < activeQuests.Count; i++)
    {
        var btn = Instantiate(buttonTemplate, activeQuestsWindow.transform);
        btn.transform.GetChild(0).GetComponent<TextMeshProUGUI>().text = activeQuests[i].QuestName;
        btn.GetComponent<Button>().AddEventListener(i, TaskClicked);
        activeQuestsButtons.Add(btn);
    }

    buttonTemplate.SetActive(false

Solution:

On-demand quest UI with zero unnecessary per-frame cost, improving overall UI performance.

4. Scalable ScriptableObject Architecture

Problem:

Needed a badge progression system that designers could expand without touching code.

Solution:

Built a clean ScriptableObject-based badge asset containing all progression logic and properties.

[CreateAssetMenu]
public class Badge : ScriptableObject
{
    public string BadgeName;
    public int BadgeNumber;
    public int MinLikes;
    public int MaxLikes;
    public bool BadgeIsUnlocked

Result:

Fully designer-driven badge system where new badges require zero engineering time and integrate instantly with UI.

Results & Impact

  • UI scaled cleanly across 4+ resolutions with no layout issues

  • Zero UI bugs reported during internal testing

  • Cut content-creation iteration time by about 40%

  • Reduced overall UI memory usage through modular components and streamlined asset structure

  • Designers added dialogue/content independently

Create a free website with Framer, the website builder loved by startups, designers and agencies.