David Cacorovski

David Cacorovski





Types:







Language:







Year:














Notice: All games are only available on PC.

2026

2026


Occupational Hazards

Occupational Hazards





RandomGen
Type: Backend
Occupational Hazards, Ostinato, Stupid Simulator 2

Purpose: A centralized, seed-based utility designed to provide deterministic, pseudo-random number generation across modular game systems.


using System;
using System.Collections.Generic;

public static class RandomGen
{
    public static int Seed { get; private set; }
    private const string DEFAULT = "default";
    private static Dictionary<string, System.Random> randomGenerators = new();

    private struct RandomInfo
    {
        public int StartingSeed;

        public RandomInfo(int startingSeed)
        {
            StartingSeed = startingSeed;
        }
    }

    public static void Initialize()
    {
        Seed = (int)(DateTime.Now.Ticks & 0xFFFFFFF);
        randomGenerators.Clear();
    }

    public static void Initialize(int seed)
    {
        Seed = seed;
        randomGenerators.Clear();
    }

    // key would be for example battle or roomGeneration
    public static int Get(string key)
    {
        if(!randomGenerators.ContainsKey(key))
        {
            int keySeed = Seed + key.GetHashCode();
            randomGenerators[key] = new System.Random(keySeed);
        }

        return randomGenerators[key].Next();
    }

    public static int Get() => Get(DEFAULT);
}
					


Base Monster AI
Type: Backend, Gameplay
Occupational Hazards

Purpose: A customizable state machine script that transitions monsters between specific scriptable object logics. It allows unique AI behaviors (e.g., different vent interactions) to be seamlessly integrated into a unified logic field.


// Adjustable Variables
[Header("AI Settings")]
public Monsters _monster;
public int _navAgentTypeID;
public IdleLogic _idleLogic;
public DoorLogic _doorLogic;
public InteractionsLogic _interactionsLogic;
public PatrolLogic _patrolLogic;
public ChaseLogic _chaseLogic;
[ShowIf(nameof(CheckForMolerat))] [AllowNesting] public VentLogic _ventLogic;
[ShowIf(nameof(CheckForFunnyGuy))] [AllowNesting] public StalkLogic _stalkLogic;
				
[Header("Interaction Scripts")]
public MonsterComebackTrigger _comebackTrigger;
public ThrowableLogic _throwableLogic;
public DialogueBank _afterFirstEncounter;
[ShowIf(nameof(CheckForFunnyGuy))] public TeleportThrowable _teleportThrowableLogic;
				
[Header("Kill Logics")]
public FunnyGuyKillLogic _funnyGuyKillLogic;
				
[Header("General Settings")]
public float _baseSpeed = 12f;
public GameObject _model;
public Animator animator;
public Transform _fallbackTransform;
[ShowIf(nameof(CheckForFunnyGuy))] [AllowNesting] public float _pissOffCap = 100f;

void Awake()
{
    monsterPathing = GetComponent<NavMeshAgent>();
    _iIdleLogic = SelectIdle.Idle(_idleLogic, this);
    _iVentLogic = SelectVent.Vent(_ventLogic, this);
    _iPatrolLogic = SelectPatrol.Patrol(_patrolLogic, this);
    _iStalkLogic = SelectStalk.Stalk(_stalkLogic, this);
    _iChaseLogic = SelectChase.Chase(_chaseLogic, this);
    _iDoorLogic = SelectDoor.Door(_doorLogic, this);
    _iInteractionsLogic = SelectInteractions.Interactions(_interactionsLogic, this);
    col = GetComponent<BoxCollider>();
}

void Update()
{
    if(_doNothing || _comeback) return;

    if (IsPlayerLookingAtMonster() && !_playerSeenMonster)
    {
        seenTimer += Time.deltaTime;
	
        if (seenTimer >= 0.5f)
        {
            _playerSeenMonster = true;
        }
    }

    switch(monsterMode)
    {
        case MonsterMode.Idle:
            _iIdleLogic?.HandleIdleMode();
            break;
        case MonsterMode.Vent:
            _iVentLogic?.HandleVentMode();
            if(_iVentLogic == null) goto default;
            break;
        case MonsterMode.Door:
            _iDoorLogic?.HandleDoorMode();
            if(_iDoorLogic == null) goto default;
            break;
        case MonsterMode.Patrol:
            _iPatrolLogic?.HandlePatrolMode();
            if(_iPatrolLogic == null) goto default;
            break;
        case MonsterMode.Chase:
            _iChaseLogic?.HandleChaseMode();
            if(_iChaseLogic == null) goto default;
            break;
        case MonsterMode.Stalk:
            _iStalkLogic?.HandleStalkMode();
            if(_iStalkLogic == null) goto default;
            break;
        case MonsterMode.Interactions:
            _iInteractionsLogic?.HandleInteractionsMode();
            if(_iInteractionsLogic == null) goto default;
            break;
        case MonsterMode.Nothing:
            break;
        default:
            Debug.LogError($"Unknown monster mode, got switched to {monsterMode.ToString()}, going to Idle");
            ChangeMonsterState(MonsterMode.Idle);
            break;
    }
}

					


VR Programming
Type: VR, Backend
Occupational Hazards

Purpose: A custom-built VR interaction system for grabbing, holding, and interacting with objects, featuring bespoke hand-tracking for improved reliability over standard templates.


void Update()
{
    if(pickupCooldown > 0f) pickupCooldown -= Time.deltaTime;

    // Manual hand velocity tracking for reliable VR throws
    velocity = ((transform.position - lastPosition) / Time.fixedDeltaTime) * 1f;

    Quaternion deltaRotation = transform.rotation * Quaternion.Inverse(lastRotation);
    deltaRotation.ToAngleAxis(out float angle, out Vector3 axis);
    if (angle > 180f) angle -= 360f;
    angularVelocity = (axis * angle * Mathf.Deg2Rad / Time.fixedDeltaTime) * 1f;

    lastPosition = transform.position;
    lastRotation = transform.rotation;
}

public void HoldObject(GameObject item)
{
    pickupCooldown = 0.15f;
    _pickup = item.GetComponent<Pickup>();
    _item = _pickup._item;
    heldObject = item;

    if(item.TryGetComponent<Rigidbody>(out Rigidbody rb))
    {
        heldRB = rb;
        rb.isKinematic = true;
        rb.useGravity = false;
        rb.linearVelocity = Vector3.zero;
        rb.angularVelocity = Vector3.zero;
    }

    ChildColliders(item, false);
    item.transform.SetParent(transform.parent, true);
    item.transform.localPosition = Vector3.zero;
    item.transform.localRotation = Quaternion.identity;
}

public void DropObject(bool pocket)
{
    if (heldObject == null) return;

    Transform obj = heldObject.transform;
    Rigidbody rb = heldRB;

    obj.SetParent(null, true);
    ChildColliders(heldObject, true);

    if (rb != null)
    {
        rb.isKinematic = false;
        rb.useGravity = true;

        // Clamp to prevent insane physics launch on release
        rb.linearVelocity = Vector3.ClampMagnitude(velocity, 24f);
        rb.angularVelocity = Vector3.ClampMagnitude(angularVelocity, 45f);
        rb.linearVelocity += transform.forward * 0.5f;
        rb.WakeUp();
    }

    if(pocket) _pickup.PocketInInventory();
    Reset();
}
					


Sound and Music Manager
Type: Audio, Backend
Occupational Hazards, Stupid Simulator, Stupid Simulator 2

Purpose: A versatile string-based audio manager capable of handling all sound events, including starting, pausing, stopping, and fading music. Supports standard audio as well as spatial audio and FMOD integration.


public Sound PlaySoundHandle(string eventName, GameObject pos, Dictionary<string, float> parameters = null)
{
    string fullPath = "event:/Sounds/" + eventName;
    FMOD.Studio.EventInstance instance = RuntimeManager.CreateInstance(fullPath);

    Globals.SpatialSounds(instance, pos);

    if(parameters != null)
    {
        foreach(var param in parameters)
        {
            instance.setParameterByName(param.Key, param.Value);
        }
    }
    instance.start();
    instance.release();
    return new Sound(instance);
}

public void StopAll()
{
    SFXBus.stopAllEvents(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
    VoicesBus.stopAllEvents(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
    MusicBus.stopAllEvents(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
}

public void Mute()
{
    isMuted = true;
    SFXBus.setMute(true);
    VoicesBus.setMute(true);
    MusicBus.setMute(true);
}

public void Unmute()
{
    isMuted = false;
    SFXBus.setMute(false);
    VoicesBus.setMute(false);
    MusicBus.setMute(false);
}
					


Difficulty Settings
Type: Backend
Occupational Hazards

Purpose: A modular system that automatically adjusts numerical values across various gameplay scripts based on the selected difficulty level.


// Oxygen.cs — scales tank capacity and depletion rate
switch(Globals.DifficultyMode)
{
    case Difficulty.Easy:
        actualOxygenCap = _oxygenCap * Globals.Plus50Percent;
        _depletionMultiplier = Globals.Minus50Percent;
        _capacityDepletion = Globals.Minus50Percent;
        break;
    case Difficulty.Normal:
        actualOxygenCap = _oxygenCap * 1.0f;
        _depletionMultiplier = 1.0f;
        _capacityDepletion = 1.0f;
        break;
    case Difficulty.Hard:
        actualOxygenCap = _oxygenCap * Globals.Minus50Percent;
        _depletionMultiplier = Globals.Plus50Percent;
        _capacityDepletion = Globals.Plus50Percent;
        break;
    case Difficulty.Permadeath:
        actualOxygenCap = _oxygenCap * Globals.Minus75Percent;
        _depletionMultiplier = Globals.Plus100Percent;
        _capacityDepletion = Globals.Plus50Percent;
        break;
}

// GainOxygen.cs — scales how fast oxygen refills at stations
switch(Globals.DifficultyMode)
{
    case Difficulty.Easy:
        oxygenGainSpeedMultiplier *= Globals.Minus50Percent;
        break;
    case Difficulty.Normal:
        oxygenGainSpeedMultiplier = 1f;
        break;
    case Difficulty.Hard:
        oxygenGainSpeedMultiplier *= Globals.Plus50Percent;
        break;
    case Difficulty.Permadeath:
        oxygenGainSpeedMultiplier *= Globals.Plus75Percent;
        break;
}
					


Seeded Shop
Type: Backend, Gameplay
Occupational Hazards

Purpose: Utilizes the RandomGen utility to ensure a specific seed consistently offers the exact same four items in the shop per run.


void OnEnable()
{
    if(GameManager.Instance == null) return;

    if(!GameManager.Instance.ShopGenerated)
    {
        GameManager.Instance.ShopGenerated = true;
        _items = new GameObject[4];
        List<int> usedIndices = new List<int>();
        int random;
        System.Random seededRandom = new System.Random(RandomGen.Seed);

        for(int i = 0; i < _items.Length; i++)
        {
            do
            {
                random = seededRandom.Next(0, _availableItems.Length);
            }
            while (usedIndices.Contains(random));

            GameObject newItem = Instantiate(_itemUIPrefab, _buttonContainer);
            _items[i] = newItem;
            Buy buyObject = _items[i].GetComponent<Buy>();
            buyObject._item = _availableItems[random];

            TMP_Text itemText = _items[i].GetComponentInChildren<TMP_Text>();
            itemText.text = $"{_availableItems[random].itemName}\n\n\n\n\n\n\n\n${_availableItems[random].price}";
            usedIndices.Add(random);
        }
    }
}
					


PA System
Type: Audio, Backend
Occupational Hazards

Purpose: Integrates with the dialogue manager to play a jingle and apply FMOD audio effects, accurately simulating a realistic PA system broadcast.


private void PlayJingle(bool PAMode)
{
    (paJinglePath, paJingleEndPath) = RandomManager.Instance.RandomJingle();

    EventReference jinglePath = PAMode ? paJinglePath : walkieJinglePath;
    jingleInstance = CreateAndStartInstance(jinglePath, PAMode ? paObjects : new[] { GameManager.Instance.PlayerScript.gameObject }, PAMode);
}

public void TogglePAMode(bool PAMode)
{
    isPAMode = PAMode;
    if(PAMode)
    {
        for(int i = 0; i < paInstances.Length; i++)
        {
            ToggleMute(paInstances[i], false);
        }
        ToggleMute(walkieInstance, true);
    }
    else
    {
        for(int i = 0; i < paInstances.Length; i++)
        {
            ToggleMute(paInstances[i], true);
        }
        ToggleMute(walkieInstance, false);
    }
}

private EventInstance CreateAndStartInstance(EventReference path, GameObject[] targets, bool mute)
{
    EventInstance instance = RuntimeManager.CreateInstance(path);
    foreach (var target in targets)
    {
        Globals.SpatialSounds(instance, target);
    }
    ToggleMute(instance, mute);
    instance.setParameterByName(WalkieTalkieParam, mute ? 0 : 1);
    instance.start();
    return instance;
}
					


Sound Perception
Type: Audio, Backend, Gameplay
Occupational Hazards

Purpose: An auditory perception script that allows monsters to detect and react to player movements and interactions. Features dynamic hearing ranges affected by the volume of different emitted noises.


public void ActionPerformed(Transform transform, float value)
{
    distance = Vector3.Distance(gameObject.transform.position, transform.position);
    combined = distance / value;

    if(PlayerRegistry.ActivePlayers.Contains(transform))
    {
        int index = PlayerRegistry.ActivePlayers.IndexOf(transform);
        monster._lockedOn = PlayerRegistry.ActivePlayers[index];
    }
    else
    {
        return;
    }

    if(_threshold / 2.2f > combined && monster.monsterMode == MonsterMode.Idle ||
       _threshold / 2.2f > combined && monster.monsterMode == MonsterMode.Patrol)
    {
        monster.ChangeMonsterState(MonsterMode.Chase);
    }
    else if(_threshold > combined && monster.monsterMode == MonsterMode.Idle)
    {
        monster.ChangeMonsterState(MonsterMode.Patrol);
    }

    if(_threshold > combined)
    {
        lastSoundTime = Time.time;
        _lastSoundSource = transform;
        _lastSoundPosition = _lastSoundSource.position;
    }
}

private void Update()
{
    if (!isMolerat) return;

    if(monster.monsterMode != MonsterMode.Idle && Time.time - lastSoundTime > moleratForgetTime
        && Vector3.Distance(transform.position, _playerTransform.position) > soundDistance)
    {
        monster.ChangeMonsterState(MonsterMode.Idle);
    }

    if(monster.monsterMode != MonsterMode.Chase && Vector3.Distance(transform.position, _playerTransform.position) < 5f)
    {
        monster.ChangeMonsterState(MonsterMode.Chase);
    }
}
					


Animation Functions
Type: Animation, Backend
Occupational Hazards

Purpose: A utility for triggering specific events, such as localized audio playback, at precise frames within an animation timeline.


public void PlayFMODEvent(int value)
{
    eventInstance = FMODUnity.RuntimeManager.CreateInstance(events[value]);
    Globals.SpatialSounds(eventInstance, gameObject);
    eventInstance.start();
}

public void ReleaseFMODEvent()
{
    eventInstance.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
    eventInstance.release();
}

public void MarkLoopPoint()
{
    Animator animator = GetComponent<Animator>();
    if (animator == null) return;

    AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
    _loopStateName = stateInfo.IsName("") ? null : stateInfo.shortNameHash.ToString();
    _loopNormalizedTime = stateInfo.normalizedTime % 1f;
}

public void ReturnToLoopPoint()
{
    Animator animator = GetComponent<Animator>();
    if (animator == null || string.IsNullOrEmpty(_loopStateName)) return;

    animator.Play(int.Parse(_loopStateName), 0, _loopNormalizedTime);
}
					


VR Settings Presets
Type: UI, Backend
Occupational Hazards

Purpose: A preset system for VR comfort settings that batch-applies grouped configurations (Normal, Motion Sick) across several dropdowns, while automatically detecting manual overrides and reverting the selection to Custom.


void OnDropdownChanged(int index)
{
    Globals.Presets = (VRPresets)index;
    if(index != 2) GiveSpecificSettings(index);
}

void OnSettingChanged(int index)
{
    if(applyingPreset || index == 2 || index == 3) return;
    _dropdown.SetValueWithoutNotify(2);
    Globals.Presets = (VRPresets)2;
    _dropdown.RefreshShownValue();
}

void GiveSpecificSettings(int index)
{
    applyingPreset = true;

    if(index == 0)
    {
        // Normal preset
        dropdowns[0].value = 0;
        dropdowns[1].value = 2;
        dropdowns[3].value = 0;
        dropdowns[4].value = 0;
        dropdowns[5].value = 1;
    }
    else if(index == 1)
    {
        // Motion Sick preset
        dropdowns[0].value = 1;
        dropdowns[1].value = 1;
        dropdowns[3].value = 0;
        dropdowns[4].value = 2;
        dropdowns[5].value = 0;
    }

    foreach(var dropdown in dropdowns)
    {
        dropdown.RefreshShownValue();
    }

    applyingPreset = false;
}
						


Stupid Simulator 2

Stupid Simulator 2




DialogueManager - Core Flow
Type: Backend, UI
Stupid Simulator 2

Purpose: Acts as the entry and exit point for all dialogue sequences, handling the instantiation of the UI canvas, input map switching, and bootstrapping the first dialogue element.


public class DialogueManager : Singleton<DialogueManager>
{
    public void StartDialogue(Dialogue dialogue)
    {
        if(dialogue == null) return;
        
        textbox = Instantiate(DialogueContainerPrefab, UIManager.Instance.CanvasTransform);
        textbox.GetComponent<InfoGrab>().GrabInfo();
        CurrentDialogue = dialogue;
        CurrentIndex = 0;
        InputManager.Instance.SwitchInputMaps("Player");
        CurrentElement = CurrentDialogue.elements[CurrentIndex];
        dynamicElement = null;
        originalDialogue = true;
        ShowNextDialogue();
    }

    public void EndDialogue()
    {
        StopAllCoroutines();
        isTyping = false;
        dialogueText.text = "";
        speakerNameText.text = "";
        Destroy(textbox);
    }
}
        


DialogueManager - Text Animator
Type: UI
Stupid Simulator 2

Purpose: A coroutine that creates a dynamic typewriter effect. It parses custom inline characters (^, |, ~) to inject precise pauses and pacing into the dialogue while syncing audio cues per letter.


private IEnumerator TypeText(string text, float speed, string name)
{
    textbox.SetActive(true);
    isTyping = true;
    dialogueText.text = "";
    
    foreach (char letter in text.ToCharArray())
    {
        if(!isTyping)
        {
            dialogueText.text = text.Replace("^", "").Replace("|", "").Replace("~", "");
            break;
        }

        if(letter == '^')
        {
            InputManager.Instance.DisableInput();
            if(!fastForward) yield return new WaitForSeconds(speed * 5);
            InputManager.Instance.SwitchInputMaps("Player");
            continue;
        }
        else if(letter == '|')
        {
            InputManager.Instance.DisableInput();
            if(!fastForward) yield return new WaitForSeconds(speed * 10);
            InputManager.Instance.SwitchInputMaps("Player");
            continue;
        }
        else
        {
            dialogueText.text += letter;
        }

        if(!fastForward)
        {
            SoundManager.Instance.PlaySound(name);
            yield return new WaitForSeconds(speed);
        }
        else
        {
            yield return null;
        }
    }
    
    isTyping = false;
    isWaiting = true;
}
        


DialogueManager - Prompt Validation
Type: Backend / Logic
Stupid Simulator 2

Purpose: Evaluates complex game states to determine if specific dialogue choices should be revealed. It checks global flags, inventory contents, and calculates dynamic stat thresholds (like comparing IQ to Goofy stats) before validating a prompt.


private bool IsPromptValid(DynamicSettings[] requirements)
{
    foreach(DynamicSettings requirement in requirements)
    {
        if(requirement.flag.flagName != "_None")
        {
            bool isFlagSet = FlagManager.Instance.CheckFlag(requirement.flag.flagName);
            if(isFlagSet != requirement.isNotValid) return true;
            continue;
        }

        if(requirement.item != null)
        {
            foreach(Item item in GameManager.Instance.Inventory)
            {
                if(item == requirement.item) return true;
            }
            continue;
        }

        Character targetCharacter = GameManager.Instance.GetCharacter(requirement.characterName);
        if(targetCharacter == null) continue;

        if(requirement.IntStat())
        {
            int currentStatValue = targetCharacter.GetStat(requirement.statType);
            int currentStatValue2 = currentStatValue;

            switch(requirement.statType)
            {
                case StatType.Aura:
                    currentStatValue *= targetCharacter.GetStat(StatType.WR);
                    break;
                case StatType.IQ:
                    if(targetCharacter.GetStat(StatType.Goofy) <= currentStatValue)
                        currentStatValue2 -= targetCharacter.GetStat(StatType.Goofy);
                    else
                        currentStatValue2 = targetCharacter.GetStat(StatType.Goofy) - currentStatValue2;
                    break;
            }

            if(currentStatValue >= requirement.minThreshold && currentStatValue <= requirement.maxThreshold ||
               currentStatValue2 >= requirement.minThreshold && currentStatValue2 <= requirement.maxThreshold)
            {
                return true;
            }
        }
    }
    return false;
}
        


Flags
Type: Backend
Stupid Simulator 2

Purpose: A persistent flag system that records player choices to a save file, actively altering future dialogue branches and game events.


public class FlagManager : Singleton<FlagManager>
{
    private Dictionary<string, bool> activeFlags = new Dictionary<string, bool>();

    // Call this to turn a flag on or off
    public void SetFlag(string flagName, bool state)
    {
        activeFlags[flagName] = state;
        UpdateDebugInspector();
    }

    // Call this to check if a flag is true. If it hasn't been set yet, it returns false.
    public bool CheckFlag(string flagName)
    {
        if (activeFlags.TryGetValue(flagName, out bool state))
        {
            return state;
        }
        return false;
    }

    // Pulled by the save system to write every flag to the save file
    public Dictionary<string, bool> GetAllFlags()
    {
        return activeFlags;
    }

    // Called on load to restore flags from that save file
    public void RestoreSavedFlags(Dictionary<string, bool> savedFlags)
    {
        activeFlags = savedFlags ?? new Dictionary<string, bool>();
        UpdateDebugInspector();
    }
}
					


Stats
Type: Backend, Gameplay
Stupid Simulator 2

Purpose: A dialogue-driven stat distribution system where specific stat thresholds influence conversation paths and alternate game endings.


if(CurrentElement.modifyStats)
{
    if(PlayerStats.IntStats.Contains(CurrentElement.statType))
    {
        ActiveCharacter.ModifyStat(CurrentElement.statType, CurrentElement.amount);
        ActiveStatType = CurrentElement.statType;

        if(CurrentElement.amount < 0)
        {
            GameManager.Instance.LevelDown(CurrentElement.statType, CurrentElement.amount, CurrentElement.bonusPoints);
        }
        else
        {
            GameManager.Instance.LevelUp(CurrentElement.statType, CurrentElement.amount, CurrentElement.bonusPoints);
        }
        CurrentIndex++;
        return;
    }
    else if(PlayerStats.BoolStats.Contains(CurrentElement.statType))
    {
        ActiveCharacter.ModifyStat(CurrentElement.statType, CurrentElement.yayOrNay);
        ActiveStatType = CurrentElement.statType;
    }
}
else if(CurrentElement.dynamicCheck)
{
    // Branches the conversation based on how one character's stat compares to another's
    if(CurrentElement.characterTwoName != null && CurrentElement.characterTwoName != "")
    {
        Character charName = GameManager.Instance.GetCharacter(CurrentElement.characterTwoName);

        if(ActiveCharacter.GetStat(CurrentElement.statType) > charName.GetStat(CurrentElement.statType) && !CurrentElement.lesserOrFalse ||
           ActiveCharacter.GetStat(CurrentElement.statType) < charName.GetStat(CurrentElement.statType) && CurrentElement.lesserOrFalse)
        {
            DialogueOrDynamicElement(CurrentElement.dialogue);
            return;
        }
    }
}
					


Diverge Plus Converge
Type: Backend
Stupid Simulator 2

Purpose: A seed-based branching dialogue framework that uses RandomGen to provide pseudo-random outcomes that remain deterministic across identical seeds.


if(CurrentElement.branchingPaths != null && CurrentElement.branchingPaths.Length > 0)
{
    // Deterministic pick across one of several possible dialogue branches
    int seed = RandomGen.Get("Branch") % CurrentElement.branchingPaths.Length;
    EndDialogue();
    StartDialogue(CurrentElement.branchingPaths[seed]);
    return;
}
else if(CurrentElement.converge != null)
{
    // Regardless of which branch played, converge back into one shared dialogue
    EndDialogue();
    StartDialogue(CurrentElement.converge);
    return;
}
					


Prompt System
Type: UI, Backend
Stupid Simulator 2

Purpose: A dialogue-integrated prompt system that conditionally displays choices based entirely on the player's current stats and inventory items.


if(CurrentElement.prompts != null && CurrentElement.prompts.Length > 0)
{
    InputManager.Instance.SwitchInputMaps("UI");
    EndDialogue();
    InPrompt = true;
    GameObject choicesPrompt = UIManager.Instance.ActualInstantiate(UIManager.Instance.ChoicesPrefab, UIManager.Instance.CanvasTransform);
    UIController controller = choicesPrompt.GetComponent<UIController>();
    Transform layoutTransform = choicesPrompt.transform.Find("Layout");

    int first = 0;

    foreach(PromptSettings prompt in CurrentElement.prompts)
    {
        // Skip any choice whose stat/inventory requirements aren't met
        if(prompt.requirements != null && prompt.requirements.Length > 0 && !IsPromptValid(prompt.requirements))
        {
            continue;
        }

        GameObject buttonObject = UIManager.Instance.ActualInstantiate(UIManager.Instance.BasicButtonPrefab, layoutTransform);
        Button button = buttonObject.GetComponent<Button>();
        TMP_Text buttonText = buttonObject.GetComponentInChildren<TMP_Text>();
        if(first == 0)
        {
            controller._defaultButton = buttonObject;
            EventSystem.current.SetSelectedGameObject(buttonObject);
            first++;
        }

        buttonText.text = prompt.name;

        button.onClick.AddListener(() =>
        {
            Destroy(choicesPrompt);
            StartDialogue(prompt.dialogue);
        });
    }

    return;
}
					


CreateManagers
Type: Backend
Stupid Simulator 2

Purpose: A global bootstrapper that automatically initializes all core game managers, allowing seamless playtesting directly from any scene.


using UnityEngine;

public class CreateManagers : MonoBehaviour
{
    public GameObject[] managerPrefabs;

    void Awake()
    {
        foreach(var prefab in managerPrefabs)
        {
            if(prefab != null)
            {
                string managerName = prefab.name;
                if(FindObjectOfType(prefab.GetComponent<MonoBehaviour>().GetType()) == null)
                {
                    GameObject obj = Instantiate(prefab);
                    obj.name = managerName;
                    DontDestroyOnLoad(obj);
                }
            }
        }
    }
}
			        


Robo Smashers

Robo Smashers





2025

2025


Ostinato

Ostinato




Dialogue Manager
Type: UI, Backend
Ostinato

Purpose: A dialogue system supporting both typewriter effects and instant text display, featuring dynamic character screen transitions during conversations.


public void ShowNextDialogueLine()
{
    if(currentElementIndex < currentDialogue.elements.Length)
    {
        currentElement = currentDialogue.elements[currentElementIndex];

        if(currentDialogue.dialogueType == DialogueType.Instant)
        {
            if(currentDialogue.audioClip != null && currentDialogue.audioClip != "")
            {
                vaInstance = FMODUnity.RuntimeManager.CreateInstance(currentDialogue.audioClip);
                PlayAudio(vaInstance);
            }
            StartCoroutine(InstantDialogue());
        }
        else
        {
            if(!string.IsNullOrEmpty(currentElement.textBlipSound))
            {
                textBlipSoundInstance = FMODUnity.RuntimeManager.CreateInstance(currentElement.textBlipSound);
            }
            StartCoroutine(TypewriterDialogue(currentElement));
            currentElementIndex++;
        }
    }
    else StartCoroutine(UIDissapear());
}

public void ApplyImage(DialogueElement element, VisualElement image)
{
    // Slides the speaker's sprite in from whichever side they're set to talk from
    if(!element.rightSide)
    {
        image.AddToClassList("showUpLeft");
    }
    else
    {
        image.AddToClassList("showUpRight");
    }

    if(element.applySprite)
    {
        image.style.backgroundImage = new StyleBackground(element.sprite.texture);
    }
    else
    {
        image.style.backgroundImage = null;
    }
}
					


Room Generation
Type: Backend, Gameplay
Ostinato

Purpose: A seeded procedural generator utilizing RandomGen to construct rooms based on predefined architectural design patterns.


public class ClassicalGenerationStrategy : IEraGenerationStrategy
{
    private IRoomLogic[] roomLogics;
    private int roomCap = 10;
    private int[] specialClassicalRooms = { };

    public ClassicalGenerationStrategy()
    {
        // Which room types are allowed to appear during this era
        roomLogics = new IRoomLogic[]
        {
            new EnemyRoomLogic(),
        };
    }

    public List<RoomType> GenerateEra()
    {
        List<RoomType> rooms = new List<RoomType>();

        for (int i = 0; i < roomCap; i++)
        {
            int random = RandomGen.Get("RoomGenerator");
            int index = random % roomLogics.Length;

            rooms.Add(roomLogics[index].GetRoomType(random));
            if (!RoomChecker.CheckRoom(rooms[i], roomLogics, specialClassicalRooms, i))
            {
                rooms[i] = RoomType.Enemy;
            }
        }

        RoomChecker.ResetRoomCounts();
        return rooms;
    }
}
					



2024

2024


Crazy Asteroids

Crazy Asteroids





2023

2023


Stupid Simulator

Stupid Simulator




OddsMaker

OddsMaker





2022

2022


Ace Attorney: Cutting Edge

Ace Attorney: Cutting Edge




GTFO My Dungeon

GTFO My Dungeon





2021

2021


Minimons Evolution

Minimons Evolution




The Abyss Below

The Abyss Below





2020

2020


Monster Clicker

Monster Clicker




The Saviour of Dharkon

The Saviour of Dharkon