Klea Merkuri

Klea Merkuri

Sep 24, 2026 · 17 min read

This Is What I Built For My First Hackathon

I was in the back of an Uber in San Francisco, visiting a friend, when she pulled out her phone mid-conversation and did her Duolingo for the day. She wasn’t learning anything in that moment. She was keeping a number from resetting to zero.

I used to be her.

Duolingo was the first language app I tried, years before Rosetta Stone, and the streak worked on me the same way until I missed one 😬

The whole thing fell apart immediately. The number had been the reason to open the app, and once it was gone, so was the reason.

Rosetta Stone had the opposite problem. It wanted a dedicated block of time to sit down, focus, and commit to a lesson.

I don’t reliably have that.

I spent two and a half years switching between an app that demanded a session and an app that rewarded just showing up, and neither ever asked me to actually use the language.

They asked me to recognize it, or to open the app. Those aren’t the same thing.

I wanted to build something different, so I made Mandarin Rescue, a mobile-first puzzle game where you read a Mandarin clue and draw a path through a maze to guide a Beagle home. It’s an MVP and an idea I’m testing that I believe holds potential.

So when the Nerdy AI Hackathon put out a language-learning prompt, I already knew what I wanted to build: a game where understanding Mandarin is the only way to win.

Why Mandarin Reading Comprehension Became the Main Game Mechanic

Mandarin Rescue makes the language clue part of the puzzle itself. You don’t answer a vocabulary question and then get to play.

Understanding the clue determines what you do in the maze.

The Beagle is based on my own dog, Eve (who also inspired my portfolio agent). I care a lot about getting Beagles out of research labs, and it just so happens that this personal value translates into a really solid rescue framing for the game.

Your understanding of the Mandarin clue determines whether the path you draw is correct. There’s no separate quiz before the game. If the clue says 先喝水,再回家 (first drink water, then go home) and you draw straight to the house icon, you fail because you skipped a step the sentence told you not to skip.

If you route to 肉 (meat) instead of 水 (water) because you weren’t sure which character was which, you fail there too.

Same maze. Different mistake. Both are language mistakes.

Tip 👀
When you’re designing an educational game, look at the thing the player has to do to win. You can consider a game mechanic as probably not doing enough work if the player can win without using the skill you’re trying to teach.

Why Mandarin Recognition Isn’t the Same as Comprehension

Mandarin Rescue is built around a distinction I kept running into while testing my own levels: recognizing a character isn’t the same as understanding a sentence well enough to act on it.

This isn’t language sitting on top of a game, and it isn’t a game with vocabulary sprinkled on top to make it feel educational.

Rosetta Stone gives you a structured language lesson.

Duolingo gives you short exercises and a streak system.

Both can ask you to recognize a character and connect it to a meaning in isolation.

I wanted to test something closer to what happens when you actually need the language for something. Can you read this, understand what it’s asking, and act on it correctly?

I found out how much that distinction mattered while building my own levels. The later ones turn off pinyin and English translation by default.

Pinyin is the Romanized spelling system used to represent Mandarin pronunciation, so removing it takes away one of the supports I was relying on early in the game.

The first time I played through one of those levels without the scaffolding, I had a few uncomfortable seconds where I wasn’t sure I remembered 水 correctly.

Then I did, and the Beagle went home.

That felt different from getting a flashcard right because instead of recognizing a word and moving on, I needed the word to make the next move.

How Puzzle Games Shaped the Mandarin Rescue Design

When I saw the hackathon’s language-learning prompt, my first thought leaned more towards skepticism about my own idea than excitement.

Another gamified language app? What’s actually going to make this different from the fifty that already exist?

Before I wrote any code, I spent time looking at how puzzle games teach mechanics without stopping the player for a lecture.

Portal doesn’t sit you down and explain the portal gun before letting you play. You learn what it does by trying it and watching what happens.

The Witness takes a similar approach with its puzzle rules. You discover how the system works by interacting with it.

That was much closer to what I wanted for Mandarin 💁‍♀️

I didn’t want to teach a word and then immediately ask you to prove you remembered it.

I wanted you to understand the clue because understanding it was the thing that let you progress.

Why Gamification Alone Doesn’t Solve Language Learning

Gamification itself isn’t exactly a new concept in learning. Language apps have been using points, levels, streaks, rewards, and other game elements for years.

The problem I kept seeing was that the game loop could become the goal.

You chase coins or levels or cosmetic unlocks, while the vocabulary underneath could be swapped for almost anything without changing how the game feels.

The other option is a game that stays mostly decorative. There’s a badge here, a progress bar there, but underneath it you’re still completing a lesson.

Neither approach answered the question I cared about: What happens when the language and the game mechanic are the same thing?

Once I had that question, the design became much clearer.

  1. The clue tells you what has to happen.
  2. The maze is how you make it happen.
  3. There’s no menu where you separately prove you know the vocabulary. The maze itself is the proof.

Hey! I am not a game developer, nor do I even have that much experience gaming. So there are definitely many aspects and parts that should probably be refined. I’m also not a language learning expert to set up a solid curriculum. This MVP is almost like a proof of concept of an idea of exploring what learning can look like in a world that tries to put the two concepts of gaming and learning together while still keeping them apart.

Explore: How To Make A Fantastic Tic Tac Toe Game With React

How the Mandarin Maze Checks Reading Comprehension

You read the clue at the top of the screen, then draw a continuous path with your finger through the maze below it. Release, and the game checks your route.

That check happens entirely on the client, meaning the code runs in the player’s browser or device, using TypeScript. No AI model decides whether you got it right.

The game checks fixed rules:

  • Did you hit the required stops in the correct order?
  • Did you avoid anything the clue told you to avoid?
  • Did your path stay connected without crossing a wall?

Those rules don’t change depending on what the model thinks you meant.

That’s an important distinction because a player needs to trust the feedback.

If you fail a level and aren’t sure whether you made the mistake or the game made the mistake, the feedback stops being useful.

When you fail, Mandarin Rescue tells you why. You might have the wrong order, the wrong target, or you might have hit something the clue told you to avoid.

That’s much more useful than a generic “try again.” You get information you can use the next time you read the clue.

Note 💬
The AI generates practice content, but it doesn’t grade the player. I kept those two jobs separate so the game rules stay predictable. Separating deterministic logic from AI generated action and response is something I further touched on my HOA Connect portal project.

How Maze Design Can Accidentally Let Players Win Without Reading

My first maze layouts had hazards sitting in short dead-end pockets. They were technically reachable, but nobody had a reason to go there.

Players would glance at the maze, see the dead end, and route around it without ever reading the character telling them to avoid it 😓

The maze was doing the teaching instead of the language, and that was exactly what I didn’t want.

I moved the hazards onto paths that look like real shortcuts, the kind of route someone might draw when they’re rushing toward the house without stopping to read the clue carefully.

Now, if you fail on one of those, the failure is connected to the language. You misread 避开 (avoid) and the game caught it.

The order-based levels had the same problem.

On an early 先喝水,再回家 level (first drink water, then go home) I’d made 水 the only way through the maze. Every route passed through it.

Players were “learning” the checkpoint because the maze forced them through it, not because they understood the sentence.

I redesigned those layouts so there’s a clean, walkable shortcut straight to 家 that skips 水 entirely.

If you take that shortcut, you fail with a wrong-order message.

That only works because the correct route isn’t the only route.

How the 12 Mandarin Rescue Levels Build the Learning Mechanics

The MVP has 12 curated levels. By MVP, I mean the smallest version I could ship while still testing whether the core idea worked.

The first couple of levels teach the mechanic itself. You read 小狗回家 (the puppy goes home) find 家, and avoid the wrong turn.

From there, the levels add order constraints such as 先...再... (first this, then that.)

Then come hazards on paths that look like reasonable routes if you misread the clue, followed by keys, doors, and switches.

By level 12, you’re combining those mechanics in one clue.

Pinyin and English translation are on by default early in the game, and you can turn them off once you don’t need them. The app also keeps track of which characters you’ve gotten right consistently, so the practice system can reduce the scaffolding you’ve already outgrown.

I didn’t want the game to punish you for still learning. I wanted it to give you enough support to understand the mechanic, then gradually get out of your way.

Every level also works fully muted, with audio as an optional feature.

Most of my actual practice happens in places where I can’t or don’t want sound on, like waiting rooms, the car, or wherever I’ve got a few free minutes.

Note: If listening were required, I’d have recreated the same problem I had with Rosetta Stone. The app would be asking me to create the right environment before I could use it.

How Gemini Generates Adaptive Mandarin Practice

After you finish the 12 curated levels, a Supabase Edge Function quietly generates your next practice rescue using Gemini.

An Edge Function is a small piece of backend code that runs on demand rather than living inside the app itself. In this case, it gives the app a place to request a new practice level without putting that logic directly into the player’s browser.

Gemini looks at what’s stored locally on your device:

  • which characters you’ve struggled with
  • which ones you haven’t seen in a while
  • whether you’re consistently handling order constraints or still getting tripped up by them

It uses that information to build a new level around what you need to practice.

If the API call fails, you’re offline, or the response comes back malformed, the app falls back to a pre-built level instead of breaking.

You never see the failure.

You just get a rescue either way.

The model picks which words show up next. It has no say in whether you got the puzzle right. That’s still handled by the same deterministic TypeScript logic checking every level, whether I curated it myself or generated it with Gemini.

Again, I wanted that separation because the game should never leave you wondering whether an AI decided you were right or wrong.

The geometry and language rules decide the outcome while the model decides what to practice.

How I Fixed Duplicate Gemini API Calls in React

The adaptive practice feature also taught me something I wasn’t expecting about API costs.

Early on, the preload was firing more than once per rescue. Every time a player’s local progress updated, a React effect would re-trigger the same request, sometimes three times for the exact same state.

I only noticed because I checked my Gemini usage and it was higher than it should’ve been for how little testing I’d actually done.

Not my brightest moment 🤦‍♀️

The fix was fingerprinting the learner’s state and only calling the API when that fingerprint actually changed.

It’s a small bug, but it’s the kind you don’t catch by reading your own code. You catch it by watching what the application actually does.

Tip 👇
When an API call should happen only when certain data changes, you need to make that dependency explicit. Otherwise, a React Effect can quietly turn one request into several.

What Building a Language Learning MVP Taught Me About Scope

Scoping mattered more than I expected going in. It’s the decision of how much of a game I was actually going to build, and it’s one of the biggest architectural decisions that’s easy to forget.

I could have built more curated levels, started on a second language, added more visual polish, or tried to make the AI generate everything from the beginning.

Instead, I chose one language and 12 curated levels, then put AI-generated practice after those levels.

Partly, that was due to the hackathon deadline. But the bigger reason was that I wanted to know whether the core mechanic actually worked before I multiplied it.

It’s much easier to find a flawed idea in 12 levels than in 40 😌

I also made one architectural decision early that was non-negotiable: the app had to keep working if the AI, the network, or the API failed.

That decision also shaped the scope. The curated levels had to be a complete experience on their own, with the AI acting as an additional layer of practice rather than something the entire game depended on.

If a language-learning tool stops functioning the moment the Wi-Fi drops, it isn’t doing the job I built it to do.

Why Scope Is an Architectural Decision, Not Just a Project Constraint

When I think about architecture, I usually think about the technology choices. Things like what runs on the client, what goes through Supabase, where an API call happens, or which service handles a particular job.

This project reminded me that deciding how big the thing is can be just as important as deciding what technologies build it.

For this project, “one language, 12 curated levels, then adaptive practice” wasn’t just a list of things I happened to have time for. It defined what the application needed to support, what could stay simple, and where I actually needed complexity.

With those constraints, I had a boundary to build inside.

That’s really easy to forget now that AI can generate a surprising amount of an application very quickly.

It’s tempting to describe the big version of what you want, start building, and let the AI fill in the architectural decisions as it goes.

That can work for getting something on the screen, but if I’m not making those decisions myself, I’m handing over part of the product’s direction without really knowing where it’s going.

Though the model can make reasonable choices based on the prompt, the code already in front of it, and patterns it has seen elsewhere, those choices aren’t necessarily the choices I would have made for this project.

That’s where scope becomes part of the architecture.

How Starting With a Small MVP Keeps AI-Assisted Projects on Track

I needed to decide what Mandarin Rescue actually had to do before I asked myself how much infrastructure, content, and AI behavior I wanted to add around it.

This is my first hackathon submission, and the part I didn’t expect was how much of the work would be those decisions rather than code.

What should the MVP include?

What should it leave out?

Twelve levels and one language felt small while I was building it. It doesn’t feel small now that it’s done (and, you know, after I had to fix a number of things 🙄).

Starting with that smaller boundary gave me something much more useful than a bigger app full of unfinished systems, since I could actually test whether the basic requirement worked.

Could a player understand a Mandarin clue and use that understanding to get the dog home?

I need that answered before I start scaling anything else.

And I think that’s the part that’s easiest to lose when you’re building with AI. You can go from an idea to a surprisingly complete-looking app very quickly, but looking complete isn’t the same as knowing that you’ve built the right thing.

Yes, AI can help me build faster. But I still need to decide what I’m building, how much of it I actually need, and what has to work before I add more.

Tip 💯
Before you ask AI to build the next big feature, decide what the smallest version of the product needs to prove. That boundary gives you something concrete to test instead of letting the scope grow with every new idea.

Related: Lessons Learned From Shipping An App For The First Time

What I’d Build Next in Mandarin Rescue

I want to stay inside Mandarin before I touch a second language.

Twelve levels are enough to test the mechanic, but not enough to know what a full learning arc looks like.

I want proficiency stages, a story that actually grows instead of resetting, and a retention system I trust more than simply storing progress locally.

I also want to test the AI-generated levels harder against actual learning data before I rely on them more.

Once that flow feels complete, I’d look at more languages, more visual craft, and deeper narrative.

But I don’t want to lose the original reason I built it.

I started Mandarin Rescue because I kept opening language apps for reasons that had very little to do with using the language.

Sometimes the streak became the reason. Other times, the lesson became the task. I wanted to see what happened when I removed those things and made comprehension responsible for getting the dog home.

The first time a level turned off my translations and I had to just know what 水 meant, I felt the difference. That’s what I want to keep building toward.

For anyone who wants to try it, here’s the repo link. It’s a PWA, so you can save it as a mini app on your phone to pop in whenever you want. The practice rounds are self-improving.

And if you’re learning Mandarin yourself, I’d love to know whether reading a clue and having to act on it feels different from getting a flashcard right.

It’s a Wrap

I built Mandarin Rescue to test one simple idea: what if understanding the language was the thing that made the game work?

It isn’t finished. The learning arc needs more testing, the generated levels need more validation, and there are plenty of places where the game could grow.

But I finally have something I can play instead of another language-learning concept sitting in my notes.

Thanks for joining me, and if you give the rescue a try, I really want to know where you get stuck.

‘Til next time, friends ✌️

😏 Don’t miss these tips!

We don’t spam! Read more in our privacy policy

Related Posts

Leave a Comment

Your email address will not be published. Required fields are marked *