INDEPENDENT PRODUCT / ENGINEERING CASE STUDY
Building goScribble.
From a shared canvas to a worldwide game in 36 languages. I’m the sole creator of goScribble — a browser-based drawing game where people and AI play together.
- Sole creator
- Thousands of players worldwide
- 36 languages

01 /
A product I own, end to end
goScribble is a social drawing game for friends, teams and groups. A player is given a secret word and draws it while the others try to guess. Rounds, a timer and a leaderboard give the session a shared rhythm. AI participates by interpreting the drawing, proposing guesses and adding commentary. The result is a familiar group activity with an additional, unpredictable participant.
As the sole creator, I conceived and built the product and take responsibility for its engineering and operation. That connects the visible experience to the systems underneath: how someone joins a room, how a stroke reaches the other players, and what happens when a connection drops. goScribble has thousands of players worldwide and supports 36 languages.
02 /
A shared link. A shared canvas.
The public browser experience starts with creating or joining a room. Players can share a room link instead of organising accounts or downloads before they play. This keeps the path from an invitation to a shared activity short. Room settings let a group choose how to play, while the drawing, guesses and round progress stay together in one experience.
Cross-device play changes the engineering requirements of a canvas. A drawing made on a phone must make sense to someone viewing it on a desktop. Stroke coordinates are normalised rather than tied to a particular screen size, so the shared drawing can be rendered at different dimensions. The interface supports mouse, touch and stylus input. Language also reaches beyond translated buttons: the game’s word choices and AI responses need to fit the selected locale.


Light-mode public-site previews captured on 26 September 2026. Gameplay screenshots supplied by Arisson.
03 /
One room. One source of truth.
The browser frontend uses React and TypeScript; a Bun WebSocket server coordinates live play. The server owns the room’s phases, timers, roster and scoring. Clients send actions and receive updates instead of independently deciding which phase the room is in. That gives the game one place to resolve transitions between choosing a word, drawing, revealing an answer and ending the game.
The room implementation separates responsibilities behind that shared state. A canvas buffer handles stroke starts, appended points, clearing, undo and snapshots. A transport layer manages socket delivery and broadcasts. Keeping these concerns distinct makes it possible to reason about drawing history without mixing it with connection management. A snapshot gives a joining or returning player a representation of the canvas, rather than depending entirely on events that arrived before they connected.
Reconnection is part of the game lifecycle. Connection controllers track disconnects and grace periods, with drawing pauses and reconnect budgets handled explicitly. Timers have a defined owner, so different parts of the room do not independently advance the same turn. These boundaries address a practical source of complexity in multiplayer software: a player’s connection can change while a round and its scheduled work are still in progress.

- 01
Browser clients
Drawing, guesses and a responsive canvas
- WebSocket actions ↔ room updates
- 02
Room server
Authoritative state, timers and canvas snapshots
- Asynchronous requests → current-turn results
- 03
AI adapter
Bounded stroke data, locale and answer-length clues
The secret answer stays outside AI requests. Late results are discarded; AI failures do not stop a round.
04 /
Interpreting drawings without the secret answer
AI guessing uses a compact representation of drawing strokes, rather than a screenshot of the canvas. The adapter simplifies paths and limits the amount of point data sent in a request, retaining information such as colour and stroke width. This makes the input bounded and directly connected to the drawing data the game already owns. It also makes clear what the model is being asked to interpret: a set of marks, with incomplete and sometimes ambiguous geometry.
The secret word is deliberately absent from the AI guessing API. Requests contain the stroke representation, the selected locale, the word lengths and earlier guesses. The model must propose an answer from those clues, in the game’s language. Commentary is a separate interaction: it reacts to the drawing with a selected personality, without receiving the secret answer. Withholding the answer is an implementation boundary, rather than relying only on a prompt to keep it hidden.
AI requests are asynchronous and may finish after the room has moved on. The guessing controller tracks the turn and request generation, permits one request in flight and discards stale results. Reconnection can pause scheduled attempts. Commentary has its own cancellation and generation checks. Failures return no result instead of stopping the game, so an unavailable or late AI response does not need to become a failed round for the human players.

05 /
Boundaries that keep the game understandable
The architecture keeps live room coordination separate from slower AI work. Drawing and game-state messages travel through the room server; AI responses re-enter that flow only when they still belong to the active turn. This separation is useful for correctness as well as responsiveness: a delayed external service should not be allowed to rewrite what the room currently considers to be happening.
Active rooms are currently held in memory, keeping their state and lifecycle close to the process coordinating the game. That also means room state is tied to that process: durable recovery after a restart would need a persistence design. Distributing rooms across servers would introduce decisions about room routing, state ownership and recovery. The current separation of room state, transport and scheduled work makes those responsibilities explicit when considering how the system could evolve.
06 /
Small interactions. Broad responsibility.
Building goScribble connects product design, frontend interaction, real-time backend behaviour, multilingual delivery and AI integration in one working product. Supporting 36 languages and thousands of players worldwide gives that work an audience beyond a demonstration. Sole ownership also means that the boundaries between those disciplines are mine to handle: a simple invitation flow and a dependable turn transition are both parts of the same experience.
The project is a concrete way to explore how I approach engineering: make the interaction understandable, keep state ownership explicit, and account for late work and unreliable connections. If those are challenges your team works on, I’d be happy to discuss the implementation and its tradeoffs.