Hackathon

Junction 2025: Survive the Feissari

Our Junction 2025 game, where Google Gemini plays street salespeople, won the best use of Gemini award and an honorable mention in Supercell's challenge.

Juho Torkkeli

· 5 min read

Event
Junction 2025
Dates
Nov 14–16, 2025
Location
Hype Arena, Espoo
Challenge
Supercell
Result
Honorable mention; best use of Gemini award
Start screen of Survive the Feissari: an orange pixel-font title on a dark card, a quoted definition of a feissari, a player name field and a Start Playing button.

Junction 2025 ran November 14–16 at Hype Arena in Espoo, under the theme “Utopia & Dystopia”. I’ve been at Junction every year since 2022. This time our team entered Supercell’s challenge with a browser game called Survive the Feissari. You start with €100 and three minutes, and you try to get past as many street salespeople as you can before they empty your wallet. The salespeople are played by Google Gemini.

What is a feissari?

If you’ve walked through a Finnish city center, you’ve met one. A feissari (from the English “face-to-face”) is a street fundraiser or salesperson who stops you to sign you up for a monthly donation or a subscription. The game explains the word before you play. The start screen quotes this definition:

A feissari (Finnish, from English “face-to-face”) is a slightly annoying person who engages in face-to-face sales or fundraising, often for commercial companies or charities.

How the game works

Each feissari is a character with their own role prompt and a set of emotes, the character images the game shows with each line. You talk to them in free text, or tap one of three quick actions the model suggests after every reply. The prompt asks for one violent, one neutral and one positive action every time, things like “Punch”, “Run away” or “Bow”.

A conversation ends in one of two ways: the feissari sells you something and the money leaves your balance, or they give up. Either way, the next one walks up. You play until the three minutes run out or your money does.

You can also get violent. The prompt tells a feissari to give up right away if the customer gets violent, unless their character says otherwise. But the model can raise your threat level for it, shown as five stars like a GTA wanted level. Five stars ends the game on the spot.

The score is:

score = feissari defeated × money left × (5 − threat level)

So the best runs get past a lot of salespeople with the wallet intact and without punching anyone. Scores go to a global leaderboard.

How we built it

The frontend is Next.js 16 and React 19 with Tailwind CSS and shadcn/ui. The backend is Express and TypeScript, and it keeps games, conversations and the leaderboard in Firestore. The model is Gemini 2.5 Flash. It all ran on Google Cloud, with a GitHub Actions workflow deploying the frontend.

We started on Friday evening by writing the first features as GitHub issues and assigning them to the GitHub Copilot coding agent. It opened pull requests for the start screen, a basic backend and the connection between the two, and we reviewed and merged them before midnight. The leaderboard came the same way on Saturday. On top of that came the game logic, the chat UI, the threat level, voice clips and sound effects, and the deployment.

Let the model talk, let the code count

The game’s rules are all numbers, but a language model decides when those numbers change. The main thing I learned from this project: an LLM is bad at arithmetic. So we stopped asking it for numbers wherever we could.

Every reply from Gemini is a JSON object with the character’s message, an emote, the player’s balance, whether the conversation is over, the three quick actions, and whether the threat level should go up. The decisions come back as true or false, and the backend does the counting: it raises the threat level, counts the feissari you’ve got past and calculates the score.

The one number the model still returns is your balance after a sale, and the backend checks it. The balance can’t go below zero, and it can’t go up, so no feissari will ever hand you money. The rest of the reply is checked too. An emote the character doesn’t have falls back to a default, missing quick actions get default ones, and if the reply doesn’t parse at all, the conversation ends with a fallback line instead of crashing the game.

My part: making it look like a game

My part was the visual pass, late on Saturday night and into the small hours of Sunday. I added the feissari definition quoted above to the start screen and switched the UI to the BoldPixels pixel font. I reworked the color scheme across the start, game and leaderboard screens and redid the leaderboard layout, with the stats moved to the bottom. It all went in as one pull request just before 3 am. The start screen in the cover image is the result.

Result

We didn’t win the Supercell challenge, but we got an honorable mention. We did win the best use of Gemini award, which earned us a place at Legends Day, a networking and celebration event Junction organized with Google right after the hackathon.

It was an amazing weekend, and one I won’t forget.

The hosted version ran on credits, so it won’t stay online. The code is public on GitHub.

More from this series