He ported Escoba, his hometown’s most beloved card game, to the web in only three days.
    He even built a bot that can beat beginners—follow this guide to see how.
…and he also wrote a bot capable of beating novice players. If that sounds unbelievable, walk through his exact steps with this article.
First came Truco, then Escoba.
Mariano had already built another card game, Truco, with backend logic in Go, which took a few weeks to polish. Last year, while visiting family in Argentina, his nephew begged to play Escoba, which sparked the idea to “clone” the old project and adapt it.
He cloned the repo, broke Escoba’s rules into English, and asked Claude to refactor.
He copied the repository locally, turned Escoba’s rules into concise English sentences, pasted them into Claude, and added one instruction: “Refactor the original code into an Escoba version.”
He cloned the repo, turned Escoba’s rules into English, and asked Claude to convert the code.
He copied the repository locally, broke Escoba’s rules into clear English sentences, pasted them into Claude, and added one line: “Please convert the original codebase into an Escoba version.”
The real time sink was the frontend—three full days of debugging
Where the time really went: the frontend. The backend came together quickly, but the UI took him a full three days, for two reasons:
- He’d only spent about an hour learning React.
 - The game state was locked inside WebAssembly (WASM), so the frontend could only call black‑box functions and couldn’t modify data directly.
 
To render pages correctly, he kept debugging JavaScript async calls and chasing serialization issues. Whenever the browser went blank, he printed the byte stream line by line until he found the culprit.
If you want to try it yourself: the simplest path
If you want to try it yourself: the simplest route. The steps below avoid jargon so anyone can follow. Mariano has posted a “tic‑tac‑toe” example on GitHub—just fork it as your starting point.
Backend and frontend steps, plus JSON/WASM communication
Backend:
- Create a GameState struct with the initial board state and an empty actions list.
 - Implement CalculatePossibleActions to tell the frontend which squares are currently legal.
 - Implement RunAction to update GameState on a player move and return the new state.
 - Want a bot? Add BotPickAction: input the current position, output the bot’s move.
 - Note: skip real‑time PvP—it needs a realtime server and costs money; single‑player vs bot is simplest.
 
Frontend:
- On page load, request a “new GameState.”
 - Render the board.
 - When the player clicks, allow only legal squares.
 - Send the action to the backend and receive the updated state.
 - If it’s the bot’s turn, trigger BotPickAction immediately and continue the loop.
 
Backend ↔ Frontend via JSON:
WASM doesn’t understand Go structs, so you must serialize to JSON strings. When JS calls trucoRunAction, it converts the string to a Uint8Array and copies it into Go; Go processes it and copies the result back.
Template:
func trucoRunAction(this js.Value, p []js.Value) interface{} {
    jsonBytes := make([]byte, p[0].Length())
    js.CopyBytesToGo(jsonBytes, p[0])
    newBytes := _runAction(jsonBytes) // 你的核心逻辑
    buffer := js.Global().Get("Uint8Array").New(len(newBytes))
    js.CopyBytesToJS(buffer, newBytes)
    return buffer
}Compile to WASMCommonly used commands:
GOARCH=wasm GOOS=js go build -o main.wasm main.goBut the file is too large and loads slowly on phones—switch to TinyGo.
tinygo build -o main.wasm -target wasm main_wasm.go- Remember to create a new main_wasm.go that exposes only trucoNew, trucoRunAction, and trucoBotRunAction, and include the build tag // +build tinygo.
 - Browser scripts for loading WASM: place the compiled main.wasm and Go’s official wasm_exec.js together in public/wasm/. In your HTML head, insert the required script tags.
 - Local debugging needs an HTTP server: GitHub Pages handles this automatically, but locally you’ll need to run:
 
npx http-server ./public -p 8080Open http://localhost:8080 in your browser and you’ll see the game.
Three takeaways: LLMs are capable; roles are shifting; stack is a shortcut.
Three takeaways
- LLMs are already “competent.” If you spell out the rules, they can generate runnable code—sometimes passing tests on the first try.
 - The human‑machine split is changing. Backends are increasingly templated; debugging and interaction design are where most time goes.
 - Go + WASM + React is a shortcut for web mini‑games, but every link in the chain requires understanding data flow so you can pinpoint errors fast.
 
Mariano had just shipped Escoba to the web when his nephew asked:
“Can we play online with friends?”
That’s the next challenge. Mariano just smiled:
“Give me three days.”
If you want to try too, a weekend might do. AI has shortened “build a game” to roughly the time for three cups of coffee.