01Why does this project exist?
I have a lovely family of four. It was a nice day - the first day of the Lunar New Year in Vietnam, which we call Tết. We decided to play a board game called Tiến Lên, a popular card game in Vietnam. We had a lot of fun playing together.
We kept score on paper, which is very traditional, but by the end of the game we realized we had lost track of some points and it was difficult to figure out where the mistakes were. At that moment, I realized that keeping score can be quite cumbersome and distracting from the enjoyment of the game.
That's when I thought about creating an app to help us and other players easily manage and track scores. Fortunately, I had free time during the Tết holiday and decided to learn Next.js by building this idea. This project was born out of a desire to enhance our gaming experience and make it more enjoyable for everyone involved.
02Key Features
03Screenshots
Designed for phones. Tap any screenshot to enlarge.




04Tech Stack
Each technology was chosen deliberately. This was my first real Next.js project - the goal was to learn the framework while shipping something genuinely useful.
05Under the Hood
The core of the app is a score reducer that handles all game state - adding players, submitting round scores, and computing the running totals with penalty logic.
TypeScript
// Score reducer - handles round submissions
function scoreReducer(state, action) {
switch (action.type) {
case 'SUBMIT_ROUND': {
const { scores, penalty } = action.payload
return {
...state,
rounds: [...state.rounds, scores],
totals: state.players.map((p, i) => ({
...p,
score: p.score + scores[i] - (penalty[i] ?? 0)
}))
}
}
case 'ADD_PLAYER':
return { ...state, players: [...state.players, action.payload] }
default:
return state
}
}06Project Stats
07Future Work

Pomodoro Timer
A Pomodoro timer living inside Neovim - written in pure Lua, zero dependencies, synced across sessions via IPC.

Toggle Terminal
A dependency-free Neovim plugin for a floating terminal with multi-session support - centered on screen, winbar tab bar, persistent buffers, auto-resizing on UI changes.

iBridge - IPC messaging & RPC framework
An IPC/RPC framework that bridges processes across language boundaries - a C++ server and a JavaScript client talking to each other over Unix domain sockets and Protocol Buffers, with no shared memory and no native bindings.

Understanding MachO Binary Format
High level architecture of a Mach-O binary. Learned through implementing application support parsing iOS binary.
