You host a living colony.
It runs itself.

Drop one script. Detailed pixel humans walk on your page with a real human gait — knees bend, arms swing opposite their legs, pelvis sways, head bobs. Each one is a unique person: Human Architecture profile, religion, life experiences, a Meta-Mystical reading. Pets walk with them — dogs, cats, bunnies, ducks, horses, with their own dispositions. Bump into someone and a compatibility score floats up. Build a house and the builder mutters "framing the roof." An LLM drifts the world's weather, scarcity, and social pressure every minute, and a society engine ticks every five seconds picking each person's next action.

We surprise you. You watch.

auto · the colony right now
loading…
6
Population
3
Couples
0
Buildings
1
Day
Hosts
500
Roster
500
Activities
500
Environments
25
Things

How this works

A society engine runs the colony. You host. We watch with you.

Each person is a real character. When a colonist spawns, an LLM generates their full Human Architecture profile (Mike Jones's 6-layer / 39-trait personality framework), a Periodic Table of Experiences reading across their life history, a religion with a devotion level, and a Meta-Mystical synthesis (sun-moon-rising, Human Design type, Gene Keys, numerology, spirit animal, an archetypal title). All persistent. The colonist keeps the same DNA across reloads.

Behavior is utility-AI driven, every five seconds. Each agent has five needs (energy, hunger, social, fun, ambition) that decay over time, and ten possible actions (sleep, eat, work, socialize, exercise, drink, reflect, wander, dig, plant). A scoring loop picks each person's next action from base needs × HA modifiers × environment effects × god-decree. The highest-scoring action wins. If it requires a different location, they walk there.

The world has weather. Once a minute an LLM drifts food and money scarcity, social pressure, novelty, and the weather itself. Storms slow outdoor action. Famine reshapes the table. A colonist's stress response (Fight / Flight / Freeze / Fawn from their HA profile) fires under high social pressure.

Pets walk with them. Dogs, cats, bunnies, ducks, horses — each with its own disposition. Most are good; a few are naughty. Bump into one and you'll see a heart and a phrase like "good boy!" — or a lightning bolt and "no, drop it!" if you're training a bad one.

The library grows itself. Every night at 3am, an LLM expansion run adds new colonists, activities, environments, and props — and any new activity that needs a new motion ships its own CSS keyframe straight into /css/frontier-anims.css for every host site. The roster you host today isn't the roster you'll host next week.

We'd rather surprise you than give you another thing to configure. If you want control, there are ten thousand other widgets. If you want a tiny world that shows up on your site and does its own thing, stay.

Quickstart

Three ways in. Pick your power level.

1 · Drop it in — easy mode

<!-- canonical source: ./js/addpeople.js -->
<!-- if this ever moves (cdn.addpeople.ai, versioned path), the URL is the only thing you update -->

<div id="village" style="position:relative;height:120px"></div>

<script
  src="./js/addpeople.js"
  data-mount="#village"
  data-count="12"
  data-context="morning"></script>

2 · Grab the catalog — JSON nerd mode

const r = await fetch(
  `${window.__APBASE}/api/scene?people=9&context=morning`
);
const scene = await r.json();

// scene.environment — sky, ground, accent, time
// scene.people[]    — id, archetype, outfit, activity
// render however you want. we're not the boss of you.

3 · Mount it with code — power user mode

const village = AddPeople.mount({
  target: '#village',
  count: 12,
  context: 'night',
  tags: ['dj', 'dancer']
});

// the village reacts to live state
village.setState({ busy: true, mood: 'high' });

API reference

All endpoints are GET, return JSON, send Access-Control-Allow-Origin: *, and cache for 5 minutes. Pass seed=N for deterministic output. Rate-limited because even pixel people have dignity.

GET /api/scene
A ready-made diorama. N people paired with activities plus one environment. This is the one you want 90% of the time.
people number of humans, default 9, max 60 context work · home · outdoor · night · morning · studio · live peopleTags comma-list, e.g. trader,chef,wizard activityTags comma-list filter on activities envTags comma-list filter on environments mood set to live to match today's real-world vibe seed integer for deterministic output
GET /api/people
Get a list of fake humans.
count default 12, max 200 tags comma-list seed integer
GET /api/activities
What they could be doing. "Frying eggs." "Reviewing a term sheet." "Tying a rope for unclear reasons."
count default 12, max 200 tags comma-list seed integer
GET /api/environments
Where they hang out. Sky color, ground color, accent, time of day.
count default 1, max 50 tags comma-list seed integer
GET /api/vibe
Market + weather + internet mood. For when your little people should match the day. Pulls SPY/VIX, LA weather, and Hacker News sentiment. Cached 5 minutes so nobody's DDoSing anybody.
(no params) returns { market, weather, hn, mood }

Try it live

Turn the knobs. Watch the village rebuild. Same API calls you'd make from your own code.

SPY
VIX
LA weather
HN chatter
mood

Meet the cast

A brief, unauthorized lineup.

Trader (shouts at charts).   Chef (on fire).   Wizard (refuses to explain).   DJ (unbearably confident).   Baker (flour-based decisions).   Scientist (it's a phase).   Astronaut (just got back, won't shut up).   Dogwalker (in charge of three kingdoms).   Mike Jones (the only one wearing sunglasses indoors).

Download · self-host

Runs on one of Mike's boxes. The renderer and catalogs are yours to grab — free, CORS-open. Host your own copy on a Raspberry Pi in your closet; go nuts. The source code stays in a vault. We tried open-sourcing it once and the wizards filed an injunction.

Grab everything

# the renderer
curl ./js/addpeople.js > addpeople.js

# catalogs (500 of each, free, unencumbered)
curl ./data/people.json > people.json
curl ./data/activities.json > activities.json
curl ./data/environments.json > environments.json

Routes you'll need

# any static server works; routes are:
#   GET /api/scene?people=9&context=morning
#   GET /api/people?count=12&tags=chef
#   GET /api/activities
#   GET /api/environments
#   GET /api/vibe
#   GET /api/catalog

# Express handlers in dashboard/server.js
# ~100 lines. copy. paste. done.

The boring but important part

☆ Privacy, plainly.

The API is public, rate-limited, and has no tracking cookies. Your IP is hashed before being counted — we literally cannot identify you. No analytics pixel. No third-party scripts. No "anonymized" data sharing that somehow keeps reappearing in breach reports. Just a JSON endpoint and a bunch of tiny people.