top of page

Salary Theft Simulator

A critical VR simulation game where rest becomes a risk and productivity produces harm. (Personal Project)

Salary Theft Simulator - A critical VR simulation game where rest becomes a risk and productivity produces harm. Built with Unity + XR Interaction Toolkit, featuring: VR interaction system Boss surveillance AI Stealth mechanics Immersive, humorous office environment Explores interaction design, game feel, and VR player experience.


Link to Github:

https://github.com/Swaiky666/SalaryTheftRepo



🎬 Gameplay Video



🌌 Background


Salary Theft Simulator presents a workplace where labor directly produces psychological pressure.The player assumes the role of an employee whose stress level increases whenever they work.If stress exceeds a critical threshold, the employee suffers a health breakdown.

At the same time, the employee must complete a minimum amount of daily work to avoid termination.This creates a constant conflict between survival within the system and self-preservation.

The game frames stress not as a personal weakness, but as a structural outcome of contemporary labor conditions Rest, distraction, and idleness become necessary counter-actions rather than moral failures.


⚙️ Core Gameplay Mechanics


  • Stress Accumulation System: Performing work tasks or just staying at office increases the player’s stress level. Excessive stress leads to illness or failure states.


  • Mandatory Productivity Quota: Each day requires a minimum amount of completed work to prevent being fired, enforcing constant pressure.


  • Stress Relief Through “Unproductive” Actions: Activities such as eating, using a phone, or resting reduce stress but do not contribute to productivity.


  • Surveillance and Avoidance: Company leaders and cameras monitor the workplace.Stress-relief actions must be performed discreetly to avoid penalties.


  • Risk Management Loop: Gameplay centers on balancing productivity, stress, and visibility under surveillance rather than optimizing efficiency.


🔁 Game Flow


ree


Game Tutorial
VR interactive buttons
Print document
Submit documents
Cleaning
Sneaking food

Sneaking food can reduce stress, and some foods even have buffs, such as a temporary increase in movement speed.


Play mobile games

Control your mobile game character by holding and shaking your phone.

Monitor

A white light indicates no player is within range, yellow indicates a player is present, and red indicates the current player is slacking off.

ree
NPC patrol system

ree
Was caught slacking off

ree

Workspace UI Information

ree
Daily task board

ree


⚙️Technical Showcase


1. NPC Behavior Tree Architecture

Clean, extensible AI with composable nodes(csharp)
public class NPCBehaviorTree
{
    private void BuildBehaviorTree()
    {
        rootNode = new SelectorNode(
            // Priority 1: Avoid obstacles
            new SequenceNode(
                new ConditionNode(() => npc.HasObstacleAhead),
                new ActionNode(AvoidObstacle)
            ),
            // Priority 2: Special points
            new SequenceNode(
                new ConditionNode(() => npc.EnableSpecialPoints),
                new ActionNode(CheckForSpecialPoints)
            ),
            // Priority 3: Path following
            new ActionNode(FollowPath)
        );
    }
}

2. Advanced Vision System


ree
NPCs track players with realistic head rotation and line-of-sight(csharp)

private void ScanForPlayer() {     Vector3 detectionDirection = GetHeadLookDirection(); // Head follows rotation          foreach (Collider collider in Physics.OverlapSphere(transform.position, _playerDetectionDistance))     {         if (collider.CompareTag(_playerTag))         {             // Check angle and raycast for occlusion             RaycastHit hit;             if (Physics.Raycast(eyePosition, rayDirection, out hit, distance))             {                 if (hit.collider.CompareTag(_playerTag))                 {                     _hasPlayerInSight = true;                     LockOntoPlayer(collider.transform);                 }                 else if (IsBlockingObject(hit.collider))                 {                     _isPlayerBlocked = true; // Player hidden                 }             }         }     } }

3. Dynamic Special Points System

NPCs interrupt patrols to visit points of interest with probability-based activation(csharp)
public Transform GetNearbySpecialPoint()
{
    foreach (Transform specialPoint in _specialPoints)
    {
        float distance = Vector3.Distance(transform.position, specialPoint.position);
        if (distance <= _specialPointDetectionRange)
        {
            // Cooldown prevents spam
            _specialPointCooldownRemaining = _specialPointCooldownTime;
            
            // Chance roll for natural behavior
            if (Random.Range(0f, 1f) <= _specialPointActivationChance)
            {
                return specialPoint;
            }
        }
    }
    return null;
}

4. VR "Phone Shake" Mini-Game: Technical

Eliminates dependency on absolute world orientation by computing rotations relative to player's starting pose:

Calibrated Relative Rotation System(csharp)
// PhoneShakeDetector.cs
public void Calibrate()
{
    neutralRotation = transform.rotation; // Store "neutral" as reference
    smoothedTiltInput = 0f;
}

private void Update()
{
    // Compute rotation in neutral coordinate space
    Quaternion delta = Quaternion.Inverse(neutralRotation) * transform.rotation;
    
    // Extract roll angle (screen-normal rotation)
    float roll = delta.eulerAngles.z;
    if (roll > 180f) roll -= 360f; // Convert [0,360) to (-180,180]
    
    currentRollAngle = roll;
}
ree

Math insight:

  • Quaternion inverse gives the "opposite" rotation

  • Composition Inverse(neutral) * current yields the delta rotation

  • This is the same principle used in IMU sensors for drift correction


VR Interaction Hook via XR Toolkit(csharp)
// VRGameStarter.cs
private void Start()
{
    interactable = GetComponent<XRBaseInteractable>();
    interactable.selectEntered.AddListener(OnGrabStart);
    interactable.selectExited.AddListener(OnGrabEnd);
}

private void OnGrabStart(SelectEnterEventArgs args)
{
    isBeingGrabbed = true;
    climbingGameUI.StartGame();
}

private void OnGrabEnd(SelectExitEventArgs args)
{
    isBeingGrabbed = false;
    climbingGameUI.StopGame();
}

No button presses required—the act of picking up the phone is the start button. This follows affordance theory from Don Norman's Design of Everyday Things: the phone's graspability naturally suggests its function.


🚀 Future Plans


  1. Add more work-related items and idle / distraction items.

  2. Develop multiplayer gameplay, introducing a new party-style competitive mode where one player takes the role of the manager, and multiple players act as employees.

  3. Implement an in-game shop system where players can spend their earned salary to buy special items, such as

    • specific foods that provide temporary buff effects,

    • special equipment that increases movement speed,

    • or tools that help stay hidden and avoid detection.


Project Gallery

bottom of page