DEV Community

Elodie Hao Liu
Elodie Hao Liu

Posted on Fully Autonomous

How I used parallel Claude Code agents to write hundreds of Chinese working lives

My side project is a game I'm building. This is the side project of that side project.

One Job, One Life is a free browser game. You draw a random job card (a specific job, city, employer and seniority in China) and live it year by year until retirement. You might get a county-hospital surgeon, a deep-sea sailor, or a jianbing street vendor outside a Tianjin metro station.

The game: your status on the left, your working life unfolding year by year on the right

I built it over a weekend with Claude Code. The interesting part wasn't the app. It was getting a group of agents to write hundreds of careers without the whole thing quietly falling apart. Here is what worked and what broke.

Bar chart of commits per hour: 1 to 13 an hour on Saturday evening, then 5 and 7 on Sunday morning after moving to its own repo

The one decision that shaped everything: no LLM at runtime

Every story is written ahead of time and stored as JSON. While you play, a small seeded rules engine decides what happens: promotions, events, job offers, and when AI starts moving into your tasks.

That means there's no per-play AI cost and no latency, and the same card still plays out differently each run. All the model work moves to authoring time, where I can check it before anyone sees it.

The design idea: the same job title is a different life

A job title tells you surprisingly little. I wanted the game to show that by making you live the difference, so two things are built into the rules.

Place and employer change the whole curve. Each card has a multiplier for its city and employer. Smaller employers also get a lower ceiling: promotions are harder and pay is squeezed further up the ladder. In the simulation, a mid-career neurosurgeon at a top Beijing hospital peaks at about nine times the pay of a new surgeon at a county hospital. Those are modeled estimates, not claims about real people. Place also shows up in the small decisions, like a Beijing renovation manager whose child goes to primary school across the border in Yanjiao.

AI arrives as tasks, not as a robot that takes your job. Each occupation's typical tasks are marked as something AI can do, something shared, or something that stays human. From your third year, AI starts moving in on them one at a time. Most of the time it just changes the work: a film editor's AI rough cut removes a pause, and the editor puts it back. A reporter checks an AI transcript that heard an old woman's Cantonese "don't have" as "have". A tunnel engineer taps the rock with a hammer after a model rated it too highly. When you leave, the review lists what AI still couldn't take.

The game doesn't tell you what to think about any of this. You just live it.

The pipeline

Flow diagram: occupation data, agent writes draft, build script, Monte Carlo, English overlay, validators

Each career starts from an occupation dataset I've been building: career ladders, pay by years of experience, and a task-by-task assessment of what AI can take.

An agent gets a small batch of jobs and a written brief, then for each one it:

  1. Queries the dataset for that occupation
  2. Writes a draft: a typical day, what each career level is actually like (the daily work, the people, the tools), events, decisions, the backstory and later life
  3. Runs a build script that merges the draft with the real numbers. Agents never type salaries onto the card
  4. Runs a Monte Carlo simulation of hundreds of lives
  5. Writes an English overlay that matches the Chinese card item by item, with numbers inherited rather than retyped

Then validators check it: every level has its story, nothing is missing from the English, no Chinese characters are left over, and the simulated career distribution looks plausible. If nearly everyone reaches the top, the card fails.

Several agents ran at once, each told to touch only its own files.

What went wrong

One agent's mistake became everyone's bug. I added a small feature to the shared build script and put a // comment in the middle of a very long one-line object literal. Everything after it on that line (role, headline, unit, city...) became part of the comment. Every card built in that window silently lost those fields.

An agent noticed, moved the comment and kept going. Afterwards I told agents to report problems with shared scripts instead of editing them, but I was glad this one hadn't waited.

Background agents raced my release. Agents were still building cards while I shipped the finished ones. My release script copied a curated card index into the working tree, then ran git add. Between those two steps an agent's build rewrote the file, so unfinished cards got committed and two deploys failed. The failed builds never went live.

The fix was to stop using the working tree at all and write the file straight into the git index:

git update-index --cacheinfo 100644,$(git hash-object -w "$T/index.ts"),src/lib/game/cards/index.ts
Enter fullscreen mode Exit fullscreen mode

Salary text is hostile. Parsing free-text pay data gave me some great bugs. "3-5 years" became ¥3,000. The 3 in "Unity3D" became a salary. An annual figure read as monthly pay produced someone earning ¥600,000 a month. Each one was found by looking at a simulated result that felt wrong.

The source data was wrong in ways only a careful reader catches. One occupation's AI-exposure tasks described casting turbine blades, but it was a chemical engineer. A sports coach had a physical therapist's career ladder. Agents caught these because they had to write a coherent life on top of the data. They'd write a correction on the card and flag the problem for me.

That became the rule: if you're unsure, skip it, ship what you can confirm, and add it to a doubts list. It kept the work moving, and I reviewed everything in one pass at the end.

My gender checker was confidently wrong. Some stories imply the player's gender, so a script looks for gendered words. It kept flagging 老公房 (an older style of public housing) because it contains 老公, "husband". It also read 陪产假, paternity leave, as a woman's maternity leave. Cheap checks are worth having, but a person or agent still has to read what they flag.

Simulation showed problems no card could fix. On 92% of cards, at least 40% of simulated lives stopped exactly one level below the top, and agents reported that tuning a card barely moved it. On 96% of cards, not one simulated life burned out. Those are engine problems, not writing problems, and they only showed up because every card was simulated.

Histogram: on most cards, 40 to 60 percent of simulated lives ended one level below the top

What I actually did

I set the direction and played the lives. Most of my input was taste: "this is too dark," "this button text is too long," "a foreign player can't read that icon."

To be clear about the AI involved: the code and the stories were written by Claude, and the illustrations came from an image model. The career data is what keeps it grounded, and each event shows where it comes from. This post was drafted with Claude too, from what actually happened during the build, and reviewed by me.

At the end of a life you get a review and a poster:

A share poster: I spent 31 years as a Nurse in Shanghai, with peak pay, the hardest year and how it ended

If you've run content-writing agents at scale, I'd love to hear how you handled shared tooling. And if you try the game, tell me which job you drew and how far you got.

Top comments (0)