Pumpets: Multiplayer Pet Simulation

Pumpets: Multiplayer Pet Simulation

A multiplayer pet ecosystem built in Unity, featuring autonomous AI, Firebase-backed real-time synchronization, client driven spawning, and a fully dynamic world where 20+ pets interact through breeding, hunting, and pack behavior.

A multiplayer pet ecosystem built in Unity, featuring autonomous AI, Firebase-backed real-time synchronization, client driven spawning, and a fully dynamic world where 20+ pets interact through breeding, hunting, and pack behavior.

Category

Category

Unity · C# · AI Systems · Firebase · WebGL

Unity · C# · AI Systems · Firebase · WebGL

Role

Role

Game Programmer

Game Programmer

Studio

Studio

Client Project (Upwork)

Client Project (Upwork)

Duration

Duration

2 Months

2 Months

The Challenge

Build a fully autonomous pet ecosystem where multiple online users can spawn pets through a WebGL interface while all animals interact through complex AI states such as breeding, hunting, feeding, and social behavior. The system needed to synchronize real-time data across players without the official Firebase SDK (not WebGL-compatible) and support 20+ AI-driven entities at 144 FPS.

What I Built

Engineered the full backend–gameplay pipeline: a WebGL safe Firebase REST integration, a real-time viewer queue, a modular animal architecture, a centralized spawner manager, and autonomous AI systems powering a persistent multi-user pet ecosystem.

Technical Contributions

1. WebGL-Compatible Firebase Integration via Custom REST API

Problem:
Firebase’s official Unity SDK does not work on WebGL, making database reads/writes impossible for browser users.

Solution:
Created a custom REST wrapper supporting GET, SET, PUSH, and DELETE with async coroutines, enabling full CRUD operations for real-time simulation.

private IEnumerator GetDataCoroutine(string path, Action<string> callback)
{
    string url = $"{databaseURL}/{path}.json";
    using (UnityWebRequest req = UnityWebRequest.Get(url))
    {
        yield return req.SendWebRequest();
        if (req.result == UnityWebRequest.Result.Success)
            callback?.Invoke(req.downloadHandler.text

Result:
Delivered a fully functional data pipeline for WebGL that handled spawning, queues, world sync, and multi-user interactions without external plugins.

2. Hierarchical AI State Machine Architecture

Problem:
Pets needed reactive behavior: hunting, breeding and idle transitions. Hard-coded logic made the AI unmaintainable and difficult to extend.

Solution:
Designed an extensible State Machine framework with a base State class and specialized implementations. Each state cleanly handled enter/tick/exit lifecycle and transitions.

public abstract class State 
{
    public virtual void OnStateEnter() { }
    public abstract void Tick();
    public virtual void OnStateExit

public class State_Hunt : StateTypeHostilePet
{
    BaseAnimal prey;
    public override void Tick()
    {
        if (prey == null || prey.isDead) 
        { 
          pet.Behavior.SetState(new State_IDLE(pet)); 
            return; 
        }
        pet.Behavior.Walk(prey.transform.position);
        if (pet.Physics.IsTouchingAgent) 
          pet.Behavior.SetState(new State_Attack(pet, prey

Result:
Created flexible AI that supports multiple emergent behaviors without rewriting core logic. Reduced bugs, simplified debugging, and allowed rapid expansion of enemy/pet features.

3. Real-Time Viewer Queue

Problem:
When the ecosystem is full, new viewers needed a fair way to join without interrupting current players or exceeding the pet limit.

Solution:
Implemented a polling-based queue system tied to Firebase. When a space opens, the system popped the next viewer, assigned a random pet, and transitioned them to the naming & spawn screen.

private IEnumerator PollSpawnRequests() 
{
    while (true) 
    {
        FirebaseREST.Instance.GetData("ecosystem/spawnRequests", json => {...}
        yield return new WaitForSeconds(2f

Result:
Viewers could join the world smoothly with zero conflicts. Ensured fairness, prevented overpopulation bugs, and created a clean onboarding flow for new players.

4. Animal Architecture

Problem:
The project required multiple animal types (peaceful pets and hostile predators) with shared logic but different behaviors. Duplicated code made updates slow.

Solution:
Designed an inheritance model:

  • BaseAnimal (Abstract): Movement, physics, health, happiness, timers

  • Pet: Breeding, needs, passive interactions

  • HostilePet: Hunting logic, aggression, combat

This allowed states, behavior trees, and physics to operate consistently across all animals.

public abstract class BaseAnimal : MonoBehaviour
{
    public BaseBehavior Behavior { get; protected set; }
    public BasePhysics Physics { get; protected set; }
    public BaseAnimator Animator { get; protected set; }

    protected virtual void Awake()
    {
        Behavior = GetComponent<BaseBehavior>();
        Physics = GetComponent<BasePhysics>();
        Animator = GetComponent<BaseAnimator

public class Pet : BaseAnimal
{
    protected override void Awake()
    {
        base.Awake();
        Behavior = GetComponent<PetBehavior>();
        Physics = GetComponent<PetPhysics>();
        Animator = GetComponent<PetAnimator>();
        Friendliness = Friendliness.Passive

public class HostilePet : Pet
{
    protected override void Awake()
    {
        base.Awake();
        Behavior = GetComponent<HostilePetBehavior>();
        Physics = GetComponent<HostilePetPhysics>();
        Animator = GetComponent<HostilePetAnimator

Result:
Enabled rapid creation of new animal types, reduced maintenance overhead, and kept all AI and physics unified.

5. Firebase Driven Spawner Manager

Problem:
When a viewer finished naming a pet, the host world needed to spawn that pet in the live ecosystem instantly and without duplication or race conditions.

Solution:
Created a centralized spawner that polls Firebase for spawn requests, parses data safely, spawns the corresponding prefab, and clears the request atomically.

var dict = Json.Deserialize(json) as Dictionary<string, object>;
foreach (var kvp in dict)
{
    string petName = value["name"] as string;
    string petType = value["type"] as string;
    SpawnPet(petName, petType);
    FirebaseREST.Instance.DeleteData($"ecosystem/spawnRequests/{key}"

Result:

Delivered reliable multi-user spawning with consistent world state, even under rapid bursts of activity. Prevented duplicate spawns and kept the simulation synchronized.

Results & Impact

  • Achieved full WebGL compatibility through a custom Firebase REST pipeline

  • Sustained 144 FPS with 20+ live AI-driven entities in the ecosystem

  • Delivered multi-layer AI with emergent behaviors (breeding, hunting, socializing)

  • Ensured fair multi-user access via a real-time viewer queue system

  • Maintained low overhead with an optimized 2-second polling cycle

  • Guaranteed consistent world state through automatic cleanup and data persistence

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