Inspiration
It all started when me, and my friend decided to learn Japanese. Flash cards such as Anki works, but we eventually found out that we could not write any Japanese characters at all. So, it seems obvious that an app specifically made for this is the right answer. Expanding on this idea is the tug of war aspect. We loved tug of war as kids, and fun. Combining these two ideas became much more than a language learning app, but rather a fun past time for all people.
What it does
Tsunahiki is a mobile educational game where you learn kana by playing tug of war against an opponent.
kana appears on screen. You draw it with your finger.
- Correct stroke → you pull the rope toward your side.
- Wrong stroke or miss → the opponent pulls, and you lose ground.
Rounds are short. Matches are tense. You win by pulling the rope past the threshold. The core loop is: see the kana → draw it → feel the result immediately. No menus, no score screens between reps. Just draw, pull, repeat.
Currently playable: hiragana tug of war with real-time stroke recognition, a working opponent AI, and win/lose states.
How we built it
The game itself is UI heavy, thus, a game engine such as Godot does not suit our needs. Thus, we came across Kotlin Multiplatform. Thus, the entire client is built with Kotlin, with a compose UI.
The stroke recognition is namely the hard part. We first tried to use a machine learning approach, but we are worried about its performance on non-powerful devices. We first opted for Dynamic Time Warping (DTW), a time series model that matches points to another points, and gets the similarity cost. However, upon testing, it proves to be bad on handwriting tasks. Then, came the paper from Moussa et al.. It is called DTW_seg, and so, after a few testing, we found that it is better than regular DTW.
Challenges we ran into
- Stroke recognition is hard. Kana have specific stroke orders and shapes, and fingers are imprecise. We had to balance forgiving-enough-to-be-fun against strict-enough-to-actually-teach.
- Making losing feel fair. If the opponent pulls too hard, the game feels punishing. Too soft, and there are no stakes. Tuning that was more design work than code.
- Scope. We had a fixed deadline and school on top of it. We cut features aggressively and focused on making one loop feel good instead of five loops feel mediocre.
Accomplishments that we're proud of
- A working vertical slice: the core loop is playable and actually fun.
- Real-time stroke recognition running on-device with no noticeable lag.
- A modular architecture that makes future expansion a data problem, not a rewrite.
- Shipping something playable under a tight deadline with competing schoolwork.
What we learned
- Constraints force clarity. Not having time to build everything made us decide what Tsunahiki actually is.
- Game feel is not a nice-to-have. The difference between "educational tool" and "game" is entirely in the feedback — sound, timing, screen shake, rope tension.
- Designing for extensibility early pays off, even when it feels like overengineering at the start.
What's next for Tsunahiki
Tsunahiki was built on a modular core, and that's the whole point. The whole application can be easily extendable to other languages/scripts. However, we are going to focus on the future our native ancient roots. As a Filipino, we want people to learn the Baybayin script, the original script of the Filipino language.
Additionally, we want to develop the multiplayer in Rust. This was our initial plan, however, due to time constraints, and competing schoolworks, we simply opted for offline enemy AI.
Built With
- dtw
- kmp
- koin
- kotlin
- multiplatform
Log in or sign up for Devpost to join the conversation.