Polaroid Awards
The engineering behind an indie photo contest πΈ
15 minutes π
We found out that's the average time a player spends with our game during a festival. So, how do you turn 15 minutes of gameplay into something lasting?
I was asking myself this a few days before FΓ³rum EaΓ Jogos, which took place in late April. Asumi: Little Ones is a photography game, so it was obvious to me: The photos are lasting.
Players always want to show off their best shots, right? But when you're at an in-person event, how do you let a player share their photos with friends? You can't ask everyone to bring a USB drive!
The answer came in an unprecedented and complex format β a photography competition integrated into the game.

The flow
- Player plays the demo at the festival booth
- During the session, they take photos with the in-game camera
- Photos automatically go to a dedicated website and the community Discord
- Other people vote on the best photos
- We announce winners weeks later, creating prolonged engagement
Requirements β
We knew a few things were necessary:
- Zero friction for the player: photos upload by themselves, no login required
- Anonymity: each player gets a 5-letter code (
BAKOM,TIRUP) instead of a real name - Offline resilience: the system must work even if the event's internet is unstable or nonexistent (This was super important!)
- Public voting: people who didn't attend the event can vote on photos via the website
β The architecture β
The stack: Unity Engine (our game lives there lol), Supabase (database), Next.js + Vercel, a Discord bot, Brevo for personalized emails, and, of course, players to take photos.

Database
We created an online database with three tables.
contest_sessionsβ one row per player, indexed by the 5-letter codecontest_picturesβ one row per photo, with photo metadata (visible animal species, time of day, camera mode)contest_votesβ anonymous votes linked to a fingerprint
Offline queue
The most critical component on the Unity side is the ContestUploader β a persistent on-disk queue inspired by message brokers. When the player takes a photo, it's saved locally and enqueued in a JSON file. An async loop attempts to send in 4 sequential stages (PNG upload, DB insert, Discord post, done). Each stage is idempotent β if the game crashes between stage 1 and 2, on relaunch it resumes exactly where it left off.
Confused? π« TL;DR: If the internet fails, the system retries. After 5 consecutive failures, the item goes to a dead letter queue, which is a technical name for a queue of failed items. This means the machine can be offline for hours β or entire days β without losing a single photo. On reconnection, everything uploads automatically.
In practice, this allowed us to operate at events completely without internet (I'm looking at you, Gamescom Latam π).
The website π
Photos go through two pages:
Player page
The player enters their 5-letter code and sees all session photos in polaroid format. They can choose a favorite photo to officially enter the competition.
Public voting
Shows all the best photos in a grid. Anyone can vote without logging in β identification via anonymous fingerprint π€.

Discord and emails π©
On Discord, a simple bot counts all β votes on player photos. It serves as a voting channel parallel to the website.
For player communication, we use Brevo to send personalized emails with a direct link to each person's page. When the booth operates offline, the email-to-code matching is done by temporal correlation β the Forms timestamp matches the session's created_at within 1-2 minutes in the natural flow.
It's Not All Sunshine and Rainbows + What We Learned πΉ
Events are hostile environments for network-dependent software. Internet drops, hotspots die, firewalls block. Even working offline, one of the Gamescom booths unfortunately couldn't participate in the competition π’
Still, we're very happy with everyone who managed to participate π
165 photos were taken, from more than 15 players. We never expected this level of participation from a game so new on the market.
There's so much more I could talk about here, like the anti-spam and anti-bot tools, the voting grid randomization system, and the unique password generator, but this is the heart of the system.
The Polaroid Awards lives on in our community (and in the polaroids we mailed out).
π’ Want to participate? There's still time to vote until May 31st! Vote here
If you're thinking about doing something similarly wild for your game, I hope this post serves as both a map and a warning about the bumps in the road.
