Disclosure: I made 1in8billion.live. It's an independent, unofficial fan-made game inspired by "1 in 8 Billion" and isn't affiliated with 1in8b.life. I built it on top of the MIT-licensed open-source born-somewhere engine, which I didn't write.
This is a write-up of the design ideas behind 1 in 8 Billion – Free Life Simulator, my browser game where you're born in a random country and live one life from birth to death. It covers the general patterns: weighted sampling, data-driven events, local saves and i18n. The code snippets are simplified illustrations of each pattern, not the production source.
1. Weighted random selection
The core mechanic is a draw over 172 countries. A uniform Math.random() pick would be wrong, because Tuvalu shouldn't come up as often as India. The game weights the draw by annual births, and the homepage shows the resulting shares: India around 17.6%, China around 6.7%, Nigeria around 5.7%, and so on.
The standard way to do this is cumulative-weight sampling:
function weightedPick(items) {
// items: [{ id: "IN", weight: 23000000 }, ...]
const total = items.reduce((s, i) => s + i.weight, 0);
let r = Math.random() * total;
for (const item of items) {
r -= item.weight;
if (r < 0) return item;
}
return items[items.length - 1];
}
For 172 entries a linear scan is plenty fast. If you were sampling millions of times, you'd precompute a prefix-sum array and binary search it, or use the alias method for O(1) draws.
I also added a population mode, which swaps birth weights for population weights. That's a nice example of keeping the sampling function generic and passing in a different weight vector.
2. Data-driven life events
Each country carries real indicators: life expectancy, infant mortality, under-5 mortality and GDP per capita (PPP). A simple way to turn these into gameplay is a yearly hazard. Each simulated year, compute a probability of death (and of other events) from the country's stats and the character's age, then roll for it. Infant and under-5 mortality cover the early years, and life expectancy calibrates the curve for the rest of the life.
Choices sit on top of this. At turning points the player picks an action, or auto mode picks one, and the result nudges stats like health, happiness, knowledge and social standing. The game shows these as 0–100 meters along with net assets in PPP dollars.
3. Batch simulation
Once a single life is a pure-ish function of (country, seed, choices), running many is easy. The game's Lab runs lives in bulk and summarizes the results. If you build something similar, keep the simulation step free of DOM access so you can move it to a Web Worker without changing it.
4. No-backend saves with localStorage
There's no signup. Progress and past lives are saved in the browser on the device, and the site tells players plainly that clearing site storage removes them and that there's no cloud sync. The usual pattern:
const KEY = "lives:v1";
const load = () => JSON.parse(localStorage.getItem(KEY) || "[]");
const save = (lives) => localStorage.setItem(KEY, JSON.stringify(lives.slice(-50)));
Version your keys, cap the history, and wrap setItem in try/catch, because storage quotas and private-browsing modes can throw.
5. i18n across six locales
The UI ships in EN, DE, ES, FR, PT-BR and ZH-CN. Some general lessons for a narrative game:
- Keep event text as keyed templates with placeholders, not concatenated strings.
- Use
Intl.NumberFormatfor currency andIntl.PluralRulesfor "1 year / 2 years". - CJK languages often need different line-height and truncation rules on share cards.
6. Shareable output
At the end of a life you can download a life card image, plus a generated family tree. Drawing to a <canvas> and exporting with toBlob() is the usual browser-only way to make an image like this without a server.
Takeaways
Most of the "feel" comes from two choices: weighting the draw by real births, and letting real indicators drive the yearly odds. The rest is UX: pause, two reading speeds, an auto mode, and an education mode for classrooms.
You can try what I built at 1in8billion.live. It's free to play, with an optional US$2.99 one-time Keepsake card. I'd like to hear how you'd approach the hazard model.
Top comments (0)