greghouse - come grow something. 🌱

A live, multiplayer virtual garden where your real plant grows alongside digital ones.

  • React - built the web app UI
  • Node.js - ran the server and database
  • WebSockets - real-time multiplayer
  • Canvas + pixel art - drew the garden world
  • C++ / Arduino - programmed the physical device
  • ESP32 - the microcontroller running the hardware
  • AWS - received and stored sensor readings in the cloud
  • Cloudflare Tunnel - made the local server accessible publicly

Inspiration

Most people keep houseplants alive through a mix of guilt and occasionally remembering. We wanted to make plant care feel social, alive, and a little playful, a cozy world you can actually walk around in with friends, while keeping it grounded in the real thing sitting on your desk.

So we built greghouse: a multiplayer virtual garden full of chatty, expressive pixel-art plants, each with its own species and personality. The twist is that greghouse isn't purely a game. One of the plants, Greg, is a real physical plant fitted with a diagnostic device, an ESP32 with a soil-moisture sensor in its pot. Greg's condition in the virtual garden is driven by real hardware readings, in real time. Dry out the actual soil and Greg gets thirsty everywhere at once.

The important part is that Greg isn't a one-off gimmick. The whole system is designed so that any plant in the garden can be paired with its own device and go live. For the hackathon we built one device and simulated the rest, so you can see exactly what a fully instrumented garden would feel like with the real one and the simulated ones side by side.

What it does

greghouse is a shared, walk-around virtual garden that mirrors real plants into a digital world.

The garden:

  • The owner signs in (Google or dev login) and gets a procedurally generated pixel-art garden - ponds, winding paths, trees, groves, lily pads - with up to six potted plants.
  • You walk an avatar around the garden (WASD or an on-screen joystick) and water plants by walking up to them: your gardener holds out a watering can, pours, splashes, and the soil ticks up.
  • Each plant has a species and a personality (a melodramatic rubber plant, a stoic cactus, an anxious basil that knows it's technically a salad ingredient...). Plants gradually dry out over time, their mood swings between happy, thirsty, and drowning, and they narrate the whole thing in a live feed.
  • You can record a short voice for any plant. Walk close and it plays back, volume rising as you approach - plants without a recorded voice get a synthesized chirp instead.
  • An ambient weather badge reads your local conditions and comments on how fast the soil is drying.

Multiplayer - the garden is live and shared:

  • Every garden is a live room. The owner opens their garden; visitors join through a share link, pick a name and customize an avatar, and drop straight into the same garden.
  • Everyone sees everyone: avatars walk around in real time, positions and chat stream between all players, and everyone watches the same plants change mood together.
  • Because the world is generated deterministically from a shared seed, every player is standing in a pixel-perfect identical garden - no one's map drifts.
  • Visitors can nag the owner to water a plant that's getting parched, which pops a friendly alert and chime on the owner's screen (and only the owner's).

The real plant - the diagnostic device:

  • A capacitive soil probe sits in Greg's pot, wired to the ESP32 diagnostic device.
  • The device reads moisture every 2 seconds, pushes it to the cloud, and shows Greg as a bobbing pixel-art plant with a live face - happy, thirsty, or drowning - plus a stats screen on touch.
  • The web app pulls that same reading and renders Greg identically for every player. Live plants carry a LIVE SENSOR badge; the simulated ones carry SIMULATED, so it's always clear which is which.
  • If the probe goes quiet for 10 seconds, the app honestly shows "probe offline" and freezes the last value instead of inventing one.
  • Whatever voice the owner records for Greg gets transcoded and played out loud through the device's onboard speaker.

How we built it

greghouse is three connected pieces - a React garden client, a Node social server, and an ESP32 diagnostic device with an AWS pipeline carrying the real soil data.

1. The garden

A pixel art world generated from a single random seed, so every player - owner and visitors - sees an identical map. All state lives in one store and syncs to the server when things change.

2. Multiplayer

One Node server handles the API, a JSON file as the database, and WebSockets for real-time updates. Every garden is its own room. Positions and chat relay between everyone instantly. Garden state syncs in two speeds - frequent small updates for moisture and mood, bigger updates when something structural changes like adding a plant.

3. The soil pipeline

The ESP32 reads the probe and posts the number straight to AWS API Gateway, Lambda, and DynamoDB, which stamps it and saves it. The browser polls a Node proxy every 2 seconds to get the latest reading.

4. One source of truth for mood

The same threshold table and mood logic exist in both JavaScript and C++. Both sides take the same soil number and run the same math - so the screen on the desk and the browser across the world always agree on whether the plant is happy, thirsty, or drowning.

5. Hardware polish

The device pulls the plant's name, species, and pot color from the server every 5 seconds. WiFi credentials can be pushed from the web app without reflashing. The owner's recorded voice gets transcoded by the server into raw audio the ESP32's speaker can play directly, driven by a hardware timer so animation never stutters.

6. Hosting

Local Node server exposed publicly via a Cloudflare Tunnel - the same URL handles visitor share links and ESP32 requests. Has to be local because it needs persistent WebSockets, a file-based database, and ffmpeg on the machine.

Challenges we ran into

  • Voltage issues with setup - We originally planned to have more sensors to show, but due to some constraints having only one port to place, we could only do the Soil Moisture level.
  • A TLS handshake doesn't fit in a 2-second budget. Doing a fresh HTTPS POST every 2s meant a full 1-2s handshake and a heap spike each time. We switched to a persistent keep-alive TLS session so the cadence actually holds.
  • CORS between the browser and AWS. API Gateway didn't return CORS headers, so the browser couldn't read the data directly. Rather than fight the cloud config, we proxied the newest reading through our own server, same-origin, and cached it so we don't hammer the upstream.
  • Never let the audio timer read freed memory. Voice playback runs off a hardware timer on the ESP32. Swapping in a freshly downloaded clip meant carefully stopping the timer, swapping the buffer pointer, restarting, then freeing the old buffer - get the order wrong and the device crashes mid-sentence.
  • Keeping real and simulated plants consistent in a multiplayer world. A stale owner tab could easily overwrite a live probe reading with an old simulated value. We had to make each live plant's soil come exclusively from the telemetry pipeline and strip it out of every owner-authored sync, so a real plant can never be clobbered by a guess - even with several players connected at once.
  • No fake data, ever. It was tempting to interpolate or invent a reading when the network blipped. We drew a hard line: if the probe is stale, the UI says "probe offline" and freezes - a hardware demo that quietly lies about its sensor isn't a hardware demo.
  • Keeping two codebases in perfect agreement. The mood thresholds live in both JS and C++. Every tuning change had to land in both places or the site and the device would visibly disagree in front of a judge.

Accomplishments that we're proud of

  • It's genuinely real-time and genuinely physical. Stick your finger in the actual dirt and, about 2 seconds later, Greg's face changes on the device and in every browser watching the garden. That loop - soil, ESP32, AWS, server, browser - actually closes, live.
  • A true multiplayer world. Multiple people walk the same garden at once, chatting and watering, and the world is provably identical for all of them down to the last mushroom.
  • A design that scales past the demo. One real diagnostic device and a set of simulated plants running the same code path - so the path from "one live plant" to "a whole instrumented garden" is already there.
  • Honest hardware. The "probe offline" state and the no-fake-data rule mean the demo tells the truth even when the Wi-Fi doesn't.
  • The whole plant, end to end: procedural pixel-art world, multiplayer netcode, browser voice recording and playback through a hardware speaker, cloud telemetry, and Wi-Fi provisioning pushed from the web straight to the device.

What we learned

  • Embedded work is a game of budgets - heap, time, and a 2-second cadence you can't blow. Keep-alive sockets, buffer discipline, and picking the right ADC pin mattered more than any single feature.
  • Match the tool to the shape of the problem. WebSockets, a local JSON DB, and a live ffmpeg process meant serverless was the wrong home; a long-running process behind a tunnel was the right one.
  • Determinism is a feature. A seeded world generator turned "sync a whole map across every player" into "sync one number."
  • Design for N, build for 1. Keying everything on plant ID and running simulated plants through the real mood logic meant our single device was a genuine slice of the full system, not a special case.
  • For a hardware demo, honesty is the killer feature. The moment we made the app refuse to invent data, the whole thing felt trustworthy instead of like a prop.

What's next for greghouse

  • Many real plants. The stack already keys on plant ID and flags live plants independently - the next step is simply more diagnostic devices, turning a mostly-simulated garden into a mostly-real one.
  • More sensors, richer moods. Light, temperature, and humidity probes so plants can be "sunburned," "cold," or "leggy," not just thirsty.
  • A friendlier onboarding for the hardware, so anyone can drop a diagnostic device into a pot, scan a code, and mirror their own real plant into the garden.
  • Bigger gardens and events - seasonal weather, visitor counts, and public "open garden" hours where friends can wander in and water your plants for you.
  • WHEELS - So that our amazing friends can remember to be watered.

Why is this called greghouse?

We like Doctor House, and this is a virtual garden acts as a greenhouse for you to grow all your plants together... so we combined it to show our beloved character alive as a flowery friend :)

Share this project:

Updates