Beluga Bus gameplay

About

This was a group submission for the November 2025 Three Thing Game jam, an internal game jam hosted by the University of Hull, and came second place. Participants are given three words and must make a game around that theme, with our team being given the words: Underwater, Bus, and Blossom. The player controls a beluga "bus" that drives around picking up passengers and dropping them off at their destination. At the end of each day a player receives a score, and are able to progress to the next day. This repeats until they fail to reach the ever increasing target score. There is an online leaderboard for players to compare and compete for the highest score. The project was made in Unity with C#, and can be played on itch.io on both mobile and desktop or downloaded from the links above.

Core Gameplay Loop

  1. A Fish spawns at a BusStop
  2. It is assigned a random valid destination BusStop
  3. The player must pick it up before its pick-up timer expires
  4. Once picked up, a second delivery timer begins
  5. The fish must be delivered to the correct drop-off BusStop
  6. Failure occurs if either timer expires, success if delivered correctly
Beluga Bus gameplay

Fish Spawning

At its core, Fish objects are state-driven timers between two locations: the pick-up and drop-off stops.

State 1: Waiting at pick-up bus stop

  • Spawned at pick-up BusStop
  • Assigned random drop-off BusStop
  • Waiting timer started
Beluga Bus gameplay Beluga Bus gameplay

Drop-off stop cannot be same as pick-up

do
{
    dropOff = random stop;
}
while (dropOff == pickUp);

State 2: Picked up by bus

  • Fish becomes child of bus
  • UI updates with drop-off location
  • Added to Bus.passengerQueue
  • Removed from BusStop
  • Delivery timer started
  • Pick-up counter increments

Timer resets on pick-up

timer = 15f * difficultyScaling;

State 3: Delivered to drop-off bus stop

  • Fish removed from bus hierarchy
  • UI updates and removes drop-off goal
  • Animation coroutine plays before destruction
  • Drop-off counter increments

Fish must match assigned drop-off bus stop

if (fish.dropOff == busStop)

Drop-off flow

bus.RemovePassenger(f);
CollectionCounter.SuccessfulDropOffs++;
GameController.instance.TotalScoreForRun += 10;
f.MoveAwayFromCenterAndDestroy();

State 4: Failed pickup

  • Missed pick-up counter increments
  • Spawn point freed for new fish

Spawn point freed

pickUp.isFish = false;
Destroy(gameObject);

State 5: Failed drop-off

  • Fish removed from bus hierarchy
  • UI updated
  • Missed drop-off counter increments

Bus Stop Spawning System

The BusStopManager controls global spawning behaviour, managing all active stops and spawn timing.

  • Holds all active BusStop references
  • Spawns fish at random intervals
  • Scales spawn rate with day progression
  • Indirectly controls difficulty

Spawning is managed by a scaling formula

spawnRate -= GameController.instance.dayCounter;
spawnRate = Math.Max(spawnRate, 2);

Difficulty Scaling

Difficulty increases each day via spawn frequency and timer reduction.

Spawn Frequency

Fish spawn rate scaling

spawnRate -= GameController.instance.dayCounter;
spawnRate = Math.Max(spawnRate, 2);

Timer Scaling

Fish timer scaling

timer = baseTimer * Mathf.Pow(dayMultiplier, dayCounter - 1);
timer = Mathf.Max(timer, 0.5f);
Day Spawn Interval Pickup Timer Delivery Timer
1915.0015.00
2814.2514.25
3713.5413.54
4612.8612.86
5512.2212.22
6411.6111.61
7311.0311.03
8210.4810.48
929.969.96
1029.469.46

Score Calculation

Player score is based on pickups, successful deliveries, and missed fish.

Score calculation formula

float raw = pickups * pickupWeight + dropOffs * dropOffWeight - missed * missedPenalty;
float potential = (pickups * (pickupWeight + dropOffWeight)) + (missed * dropOffWeight);
float normalized = potential > 0f ? Mathf.Clamp01(raw / potential) : 1f;
Beluga Bus gameplay Game

Missed fish are heavily penalised, while pickups partially offset losses.

Normalized Score Grade
≥ 0.90S
≥ 0.75A
≥ 0.60B
≥ 0.45C
≥ 0.30D
< 0.30F

A leaderboard tracks the top 10 scores globally. Player names must be 3–20 characters, contain valid symbols only, and pass profanity filtering.

Beluga Bus gameplay