- Fix Day display: server sends phase in datetime_str, index.html uses state
directly instead of fragile regex parse that defaulted to Day 1
- Fix DB growth: snapshots DELETE-then-INSERT by name, prune old events/convos
- Fix console errors: pointer-lock→pointerlock, demo mode stops WS reconnect
and REST polling, mat() guards against undefined color
- FPV NPC chat: E key starts conversation, NPC freezes and faces player,
chat dialog with text input and Web Speech API microphone, contextual
NPC responses (name, age, occupation, mood), ESC to end chat
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix FP/VR visibility in iframe, speed control, pointer lock
- Add FP and JOIN buttons to index.html controls bar
- Forward toggle-fp and show-join messages to 3d iframe
- Add pointer-lock, xr-spatial-tracking, fullscreen to iframe allow
- Click overlay for pointer lock (user gesture required)
- Fix speed control: set simSpeed immediately before async API call
- Prevent speed flickering at 10x/50x
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix street lamps (glow sprites + few PointLights), speed controls in demo mode
- Street lamps: use emissive glow sprites instead of 100+ PointLights
(only 11 actual PointLights at key intersections for night illumination)
- Fix celestialTex definition order (moved before street lamp code)
- Demo speed: setSpeed works locally when no server, forwards to 3d iframe
- Demo tick uses dynamic setTimeout interval based on speed multiplier
- Pause/resume works in demo mode
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Street lamps, moon/stars fix, 100 agents with lifecycle, resizable panel
3D Visual:
- Street lamps along roads with PointLights that glow at night
- Solid 3D moon with glow halo, 500 brighter stars
- Clouds hidden when sunny weather
- Night scene brighter (ambient 0.35, hemi 0.45)
- Furniture placed inside buildings (not in front)
- Agents positioned inside buildings, visible only on interior click
- Cemetery location with gravestones
Agent Lifecycle (demo mode):
- 100 agents with age, gender, occupation, life phase
- Marriage system (18+), pregnancy (9 ticks), births increase population
- Divorce (rare random), aging with career progression
- Illness at 70+, hospitalization, death, burial at cemetery
- Age-based daily routines: kindergarten/school/university/work/retired
- Long-term memory recording life events
- Life plan displayed in info panel
UI:
- Resizable right sidebar panel (drag handle)
- Life plan and long-term memory sections in agent info
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Weather system, day/night cycle, agent behaviors, city expansion
- Sun movement east→zenith→west with dynamic shadows
- Weather effects: rain (4000 particles), snow (2000 particles), thunderstorms (lightning flashes), fog, cloudy skies
- Sun brightness/size adjusts per weather (bright sunny → dim stormy)
- Storm clouds layer (18 dark clouds) for bad weather
- Night: residential buildings become transparent, agents sleep in beds
- Furniture inside buildings: tables at restaurants/bars, desks in offices/schools, seats in cinema/church
- Agent poses: walking, sitting (at tables/desks), sleeping (in beds)
- Bad weather: 70% agents stay indoors; night: all go home to sleep
- Demo mode cycles through full day/night + weather types automatically
- Moon enlarged (10), stars visible from 19:00, brighter after 21:00
- Trees halved in size for better proportion with buildings
- City expanded: WORLD_SIZE 100→130, shadow camera enlarged
- 10 new public buildings (bank, court, gallery, daycare, vet, yoga, pub, etc.)
- 4 new streets for expanded area
- Ollama defa…
Integrate 3D city into main UI: iframe viewport 7/8 + data panel 1/8 right
- index.html: replace 2D canvas with 3D iframe (7/8 width), keep sidebar
right (1/8) with agents/chat/events tabs
- 3d.html: hide status bar and controls when embedded, postMessage bridge
for agent selection and camera controls
- Auto-detect file:// protocol for local demo mode (no server needed)
- Added collision avoidance, smooth mountains, 75 agents, new buildings
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Major simulation features:
- Age progression (1 year per 365 sim days) with lifecycle stages
- Death system for 80+ with exponential probability curve
- Divorce mechanic for unhappy marriages (low trust/sentiment/mood)
- Married couples move in together (cohabitation)
- Church wedding ceremonies, hospital births after 9 sim-day pregnancy
- Baby agents born as real citizens, living with parents, autonomous at age 4
- Annual mayor elections with weighted voting (18+ citizens)
- Short-term (weekly) and long-term goals with auto-refresh
- Memory query API: ask any agent about their memories via LLM
- Community score tracking for election candidacy
- UI: lifecycle badges, deceased agents, mayor display, split goals,
memory query input, parent info, new event icons
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add StockEx trading integration for player agents
- New API endpoints: /stockex/market, /stockex/leaderboard,
/stockex/portfolio/{id}, /stockex/order
- Player agents can browse market data, view portfolios, and place
buy/sell orders on StockEx clearing house
- Orders recorded as life events and memories for the agent
- Web UI: StockEx button in player panel opens trading modal with
live market data, portfolio view, and order form
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add life events, goals, pregnancy system; fix profile editor bugs
- Life events: append-only timeline seeded from persona, extended by
LLM reflections and romance milestones (dating/engaged/married/birth)
- Goals: personal aspirations with progress tracking, managed by LLM
reflections (add/complete/progress)
- Pregnancy: married couples can conceive, birth after ~7 sim-days,
baby names, both parents get memories and life events
- Agent context: LLM now sees life story, goals, children, pregnancy
- Fix profile editor: fetch full agent detail instead of WS summary
(occupation, background, personality sliders now load correctly)
- Fix Go dropdown: only rebuild when empty, preserves user selection
- Fix WS state summary: include age, occupation, daily_plan, is_player
- NN self-improve: track accuracy in training_stats.json, compare with
previous model on push
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
LLM popup: show live usage stats as probability slider moves
Slider now shows real-time estimates that update on drag:
- "X% of decisions via LLM" (how many agent actions use LLM vs routine)
- "~Y calls/hour" (accounting for RPM cap, budget per tick, agent count)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix LLM switcher panel: prevent popup close on slider interaction, fix defaults
- Stop click/mousedown events inside quota panel from propagating to
document handler that closes the popup
- Default probability slider to 10% for rate-limited providers instead
of inheriting NN's 100%
- Show daily limit and max runtime instead of unreliable remaining count
(in-memory counter resets on server restart)
- Badge shows "1500/day · ~6.3h" instead of fake "1500 left"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Detect actual quota exhaustion via llm_status (429 errors), not just
in-memory counter which resets on server restart
- NN auto-sets probability to 100% when selected
- Remove "local" from NN label
- Popup probability slider initializes from current probability, not hardcoded 20%
- Fix pqForCalc to include rpm field for accurate runtime estimates
- Quota badge shows "exhausted" when API is actually rate-limited
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix quota runtime estimates: use RPM as bottleneck, sync top probability slider
- Runtime estimate now based on RPM (Gemini 4 RPM = 240 calls/h, ~6.25h for 1500 RPD)
not probability, which barely affects duration with 50 agents
- Remove misleading per-probability runtime table from popup
- Show RPM and single accurate runtime estimate instead
- Fix ID collision between top slider and popup slider (use class selectors)
- Sync top probability slider when switching provider via popup
- Expose RPM and max_calls_per_hour in /api/llm/quota per-provider data
- Update nn_selfimprove budget calculations to use RPM-based math
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix quota endpoint: per-provider tick rates for accurate runtime estimates
- Add GET /api/llm/quota endpoint exposing per-provider daily quota (Gemini 1500 RPD, Groq 14400 RPD)
- Add personality/home/work fields to agent detail API for NN training data collection
- Fix nn_selfimprove: /api/agents returns dict not list, correct probability endpoint path
- Fix Gemini scheduled reset to 10:00 AM Athens instead of midnight
- Add 'budget' CLI mode to calculate and apply optimal probability for target duration
- Scheduled mode now auto-calculates probability from remaining quota
- Frontend: rate-limited providers (Gemini/Groq) show quota badge and expand a panel
with runtime estimates table, probability slider, and confirm button before switching
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add NN provider as default, remove HF inference (7B/0.5B)
- New NNClient: downloads ONNX model from RayMelius/soci-agent-nn on
first use, runs inference via onnxruntime on CPU (~1ms for 50 agents).
Zero API calls, zero cost, works offline.
- NN is now the default provider — always available, no API key needed.
LLM probability defaults to 100% for NN (no rate limiting).
- Removed HFInferenceClient and all 7B/0.5B model references — these
required HF Pro credits and never worked on free tier.
- Updated provider list in UI, fallback order, and provider icons.
- Added training notebook (notebooks/soci_agent_nn.ipynb).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Matches the server-side default to avoid misleading users into thinking
100% is active when the backend is already throttled to 10%.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add LLM probability slider: controls AI usage per call site
Adds a 0-100% slider (brain emoji, in the toolbar between speed and
zoom controls) that gates every LLM call in the simulation:
- Action decisions, conversation turns, reflections, social starts,
daily plan generation — each rolls random() < llm_call_probability.
Provider defaults (tuned for free-tier daily quotas):
Gemini → 45% (4 RPM + budget=1 → ~150 calls/h → ~10h at 1500 RPD)
Groq → 70% (conserves daily token budget)
HF → 45%
Ollama/Claude → 100% (no quota)
Also reduces Gemini's _max_llm_calls_this_tick from 4 → 1 so the
rate limiter (15s/call) naturally paces the simulation without
needing to burn all 4 budget slots every tick.
Override default via SOCI_LLM_PROB env var (0.0–1.0).
API: GET /api/controls → llm_call_probability field
POST /api/controls/llm_probability?value=0.45
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Show actual HTTP error in LLM test toast instead of 'empty response'
Track _last_error on every HF failure path (non-auth errors).
Test endpoint returns error field combining auth_error and last_error.
Toast now shows model name + real error e.g. 'HTTP 404: Model not found'
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Show all HF models individually in SWITCH LLM popup
- providers list now has 4 separate HF entries (Zephyr, Qwen, Llama, Mistral)
- SwitchProviderRequest accepts optional model field
- switch_llm_provider() forwards model to create_llm_client()
- /llm/providers returns current_model so UI can checkmark the right row
- active checkmark matches on both provider id + model
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add LLM call counter, test button, and better HF error handling
- LLM pill now shows ×N call count each tick in green when active
- LLM popup has a 🔬 Test button — makes a real call and shows raw response
- GET /api/llm/test endpoint for diagnosing provider issues
- HF 401/403 triggers circuit breaker + nokey status (gated model / bad token)
- HF 503 reads estimated_time from response body and waits accordingly
- auth_error field exposed on /llm/test for actionable diagnostics
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Distinguish 'no token' from 'rate limited' in LLM status indicator
HFInferenceClient returns 'nokey' status when HF_TOKEN is absent.
UI shows orange dot with tooltip 'no API token — set HF_TOKEN env var'
instead of red 'rate limit hit', making the cause immediately clear.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Hugging Face Serverless Inference as free LLM provider
- HFInferenceClient uses OpenAI-compatible endpoint at api-inference.huggingface.co
- Default model: Qwen2.5-7B-Instruct (also supports Llama-3.2-3B, Mistral-7B)
- HF_TOKEN auto-injected in HF Spaces — zero config needed on Spaces deployment
- Circuit breaker on quota exhaustion (same pattern as Groq/Gemini)
- Auto-detected in create_llm_client() when HF_TOKEN is set (after Gemini, before Ollama)
- Provider switcher UI shows 🤗 icon for hf provider
- routes.py and server.py updated to accept "hf" as a valid provider
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Click model pill to switch LLM provider at runtime
Backend:
- server.py: get_llm_provider() getter + switch_llm_provider() hot-swaps
sim.llm without restarting the simulation
- routes.py: GET /llm/providers returns available providers (those with
env keys set) + current; POST /llm/provider switches immediately
Frontend:
- #llm-model pill is now clickable (pointer cursor, hover highlight)
- Click opens a dark popup listing available providers with icons;
current provider shows a checkmark
- Selecting a different provider POSTs to the API and shows a toast;
clicking outside or re-clicking the pill closes the popup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix back view: show whenever movingUp, not just during walk anim
Remove scripted conversation fallbacks — LLM-only conversations
- drawPerson: change `if (walkAnim && movingUp)` to `if (movingUp)` so
the back view persists as the agent's facing direction, matching how
horizontal facing is maintained when standing still
- conversation.py: revert scripted starters/replies; if LLM is
unavailable initiate_conversation returns None and continue_conversation
ends the exchange — no canned dialogue
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Show live LLM status in header (active/limited/skipped/idle)
Each LLM client now exposes an llm_status property:
- ClaudeClient: tracks _rate_limited_until on RateLimitError
- GroqClient / GeminiClient: reports circuit-breaker state
- OllamaClient: flags recent connection failures
get_state_summary() now includes llm_status, llm_calls_last_tick, and
llm_skipped so the WebSocket state carries everything the UI needs.
Header model pill gains a coloured dot:
green — calls are happening this tick
yellow — idle (no LLM calls needed)
orange/red — quota or rate limit hit
grey — LLM skipped (fast / 50x mode)
Tooltip shows provider, full model name, and a short status reason.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add render.yaml, fix gemini provider routing, show LLM model in header
- render.yaml: declares LLM_PROVIDER=gemini as versioned config; secrets
(GEMINI_API_KEY, GROQ_API_KEY, etc.) listed as sync:false so they persist
from the Render dashboard without being stored in the repo
- server.py: _choose_provider() now accepts "gemini" from LLM_PROVIDER env var
- simulation.py: get_state_summary() includes llm_provider + llm_model fields
- index.html: header shows active model (e.g. ✦ 2.0-flash) with full name
as tooltip; icon varies by provider (✦ gemini, ⚡ groq, ◆ claude, 🦙 ollama)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add GeminiClient using OpenAI-compatible AI Studio endpoint (free tier:
15 RPM / 1M tokens/day on gemini-2.0-flash, set GEMINI_API_KEY to use)
- Auto-detect provider order: Claude → Groq → Gemini → Ollama
- Fix agent back-view: move direction tracking from drawPerson() to animate()
using pixel delta — reliable for all path angles, no waypoint guessing
- Add scripted fallback dialogue so conversations animate in the UI even
when no LLM is configured
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix apartment assignment, player sleep, gender profile, and NPC conversations
- Player now gets assigned to an available apartment block instead of town_square
- Players auto-sleep at home during sleeping hours (23:00-06:00) and auto-wake
- Added gender field (male/female/nonbinary) to player profile modal and API
- Gender-based attraction: only opposite genders (or nonbinary/unknown) develop romance
- Players now included in romance system (_tick_romance no longer skips is_player)
- Fixed NPC conversations: replaced is_busy check with conversable-state check
so agents eating/relaxing/working can still initiate conversations
- Doubled conversation base chance (extraversion/20 instead of /40)
- Raised max simultaneous conversations cap from 2 to 3
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix WebSocket: use wss:// on HTTPS, ws:// on HTTP
- Sleeping agents now displayed horizontally on a bed with pillow,
blanket, closed eyes and floating ZZZ bubbles
- Agents walking upward show back view (no face, hair covers back of head)
- Road network expanded: north/south access roads + far west/east avenues
give full coverage to every building on the map
- Movement uses L-shaped 2-waypoint queue routing via road grid instead
of a single midpoint snap (agents walk along streets)
- _add_evening_block now fills the full period until sleep — eliminates
the 18:30–22:00 unscheduled gap that flooded Ollama with LLM requests
- Ollama/Claude now capped at 10 LLM calls + 3 conversations per tick
(was unlimited), keeping tick speed consistent at normal simulation speed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Switch large crowds to grid layout + proportional agent shrink
- 1-10 agents at a location: keep natural semicircle arc (unchanged)
- 11+ agents: switch to rectangular grid (cols=sqrt(count*1.3)) with
small deterministic per-agent jitter for organic look.
Grid area: 210x160px (normal) / 290x210px (park/square/sports).
For 66 agents: 10 cols x 7 rows, cellW=21px, cellH=23px.
- drawPerson: scale *= sqrt(12/crowdN), min 0.48.
At 66 agents: scale = 0.82 * sqrt(12/66) = 0.82*0.426 = 0.35
→ agents are ~43% of normal size, fitting their grid cell cleanly.
- New locCrowdCount{} global populated during computeAgentTarget loop.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix agent clustering: valid house slots, even street routing, wider crowd spread
Root causes of 66-agent pile-up:
1. GEN_HOUSE_SLOTS had top row at y=0.06 and interior at y=0.13 (sky/mountain).
All 55 slots now in valid ground area (y≥0.20), spread across full map width.
2. Corner apartments apt_northeast/northwest were at y=0.10 (sky); moved to y=0.22.
apt_southeast/southwest moved from y=0.86 to y=0.78.
3. generate_houses() used random.choice(all_public_zones) — most houses ended up
connecting only through street_north, creating a commute bottleneck. Now cycles
deterministically through the 4 named streets (N/S/E/W) so traffic is evenly split.
4. generate_personas() was cycling through ALL residential (named + generated),
leaving house_gen_64..80 empty. Now uses only house_gen_XX homes for generated
agents, so every generated house gets exactly 1 occupant.
5. computeAgentTarget crowd spread: maxPerRow 8→13, base radius 24→38, row step
14→24px — 66 agents spread ~3× wider than before.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Distribute agents across full map, add children, add corner buildings
- web/index.html: GEN_HOUSE_SLOTS (52 positions across whole map) replaces
old hash-to-bottom-strip logic; 4 corner apartments + diner/pharmacy added
to LOCATION_POSITIONS
- config/city.yaml: 4 corner apartment blocks (apt_northeast/northwest/
southeast/southwest) and Blue Moon Diner + SociMed Pharmacy added
- generator.py: 20% of generated agents are children (age 8-17) with
elementary/middle/high school student occupations and child backstories
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Profile view when walking, fix mouth convention, smaller mouth
Profile view:
- Agents switch to a side-on profile silhouette while in 'moving' state
or visually animating toward their target
- Facing direction tracked in agentFacingRight[]; ctx.scale(-1,1) used
for left-facing agents so all profile code assumes facing right
- Back elements (leg, arm, torso-back) drawn dimmer/first; front
elements drawn on top for natural 2.5D layering
- Profile head: full circle (back=dim) + front-face hemisphere +
ear on back, one eye, nose bump, one eyebrow, mouth
- Female gets hair flowing back; male gets short-back hair patch
Mouth fix:
- Convention was REVERSED: + control point was bowing curve DOWN (∪)
which looks like a frown, not a smile
- Fixed: `quadraticCurveTo(hx, mouthY - mCurve, ...)` so positive mood
pulls control point UP → ∩ shape = corners-up smile ✓
- Mouth half-width 3.2 → 1.9 (proportional to head radius 6.5)
- mCurve multiplier 14 → 9, clamped ±5 (visible depth at mood 0.3 ≈ 1.3px)
- Removed the corner dots that made it look unna…
Fix mouth expression: increase curve depth so smile/frown is visible
The quadratic bezier control-point only deflects half its distance at
the midpoint. With moodVal*3.8 a mood of 0.3 produced <1 screen pixel
of visible curve — imperceptible. Changes:
- Multiplier 3.8 → 14, clamped to ±10, giving ~2px visible curve at
mood ±0.3 (clearly distinguishable smile vs frown)
- Mouth half-width 2.2 → 3.2 (wider mouth reads better at small scale)
- lineWidth 1.0 → 1.4 for visibility
- Lip-corner dots anchor the ends of the curve visually
- Colour range: warm rosy-red (happy) → dark blue-grey (sad)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replaced flat 3-face cube torso with smooth rounded trapezoid shape:
rounded shoulder curves via quadratic bezier, horizontal gradient
(lit left → shadow right) simulating cylindrical form, chest radial
highlight, subtle right-edge depth line
- Eyebrows now react to mood: raised when happy, inner corners angled
up (worried/sad tilt) when mood is negative
- Mouth replaced with quadratic bezier curve: bows down for smile,
straight at neutral, bows up for frown; colour shifts rosy→dark
- Reduced armSwing 16→10, tighter hand position multipliers (0.6→0.4),
consistent arm lineWidth 1.8, hand circle radius 1.5→1.1 — fixes
hands appearing large during walk animation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Enhance web UI: 2.5D agents, road-waypoint movement, weekend badge
- Rewrote drawPerson() for realistic 2.5D look: larger head with shine/mood
mouth, two-segment arms with elbow bend, two-segment legs with knee, shoes
via roundRect, 3-face isometric torso (front/side/top), belt, female skirt
- Moving agents now smoothly traverse road waypoints instead of teleporting;
lerp rate 0.022 for moving state, 0.07 for stationary
- Added agentPrevLocations + agentWaypoints; computeAgentTarget() inserts a
mid-road waypoint on location change during 'moving' state
- Weekend badge (gold pulsing pill) shown in top bar on days 6 & 7 of each week
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add zoom controls, walk animation, and zone background colors
- City fits on one screen by default (WORLD_W/H = 1.0, zoom via ctx.scale)
- Scroll wheel zoom centered on cursor; +/- buttons; Fit button
- Rectangle zoom: draw a selection box to zoom into any area
- Walking agents now animate arms (+/-18px) and legs (+/-13px) only when moving
- 11 colored zone overlays (park green, commercial terracotta, office blue, etc.)
- Richer ground gradient with 3-stop depth variation
- Zoom indicator in canvas corner; pan corrected for zoom level
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add mountain horizon, 2.5D perspective buildings and smaller agent figures
- Mountains with snow caps, near/far layers, dawn/night color adaptation
- All buildings now 2.5D with right-side face and top face perspective
- Agent figures 30% smaller with isometric body, varied skin tones, eyes
- Town square fountain with 3D column and water spray
- Park with walking paths, raised edges, water shimmer
- Factory chimney, church steeple all with perspective depth
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Expand city to 34 locations with new buildings, pan controls, and 2.5D web UI
- Add school, office tower, factory, hospital, 3 apartment blocks, bakery,
cinema, church, town square, sports field, east/west avenues
- New building sprites: factory with chimney smoke, hospital with red cross,
church with steeple, cinema with marquee lights, sports field with track
- Pan system: drag canvas or use sliders to scroll larger world (1.6x1.4)
- Sidebar narrowed 380->260px, agent clustering improved for large crowds
- Occupation-aware work locations (lawyer->tower, mechanic->factory, etc.)
- Routines use new locations for lunch, leisure, and evening entertainment
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Scale to 100 agents: procedural personas, daily routines, speed controls
- Add procedural persona generator with diverse names, Big Five traits,
weighted values/quirks, and occupation-aware home/work assignments
- Add daily routine system: deterministic schedules (work day, weekend,
evening shift, retired) with personality-driven timing and motivation
overrides for critical needs or bad mood
- Generate houses dynamically and scale city capacities proportionally
- Routine-based action dispatch replaces LLM for ~90% of idle decisions
- Default agents raised from 20 to 100, --generate flag for procedural gen
- Per-agent sleep awareness in scheduler via routine wake/sleep times
- Add x5, x10, x50 speed controls to web UI and API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Redesign city: individual houses, real streets, async Ollama client
- Replace 2 apartment blocks with 10 individual houses (1-3 agents each)
- Pair agents by relationships: siblings, couples, roommates, families
- Redesign web UI canvas: road grid with asphalt/lane markings/sidewalks,
varied house colors, trees, street lamps, park with pond and benches
- Convert OllamaClient from sync httpx.Client to async httpx.AsyncClient
to prevent blocking the event loop during LLM inference
- Enable Ollama native JSON mode (format:"json") in complete_json
- Update tests for new 20-location city layout
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add notification toasts and location hover tooltips to web UI
- Floating toast notifications for notable events: romance milestones,
world events, gossip, and new conversations
- Toasts auto-fade after 5 seconds, max 5 stacked from bottom-left
- Color-coded borders: pink for romance, red for events, purple for gossip,
yellow for conversations
- Location hover tooltips showing name, zone, description, occupant list,
and active conversation indicator
- Toasts triggered from both WebSocket events and polling updates
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Connect to /ws/stream for live tick updates instead of polling
- Process state updates from WebSocket messages in real-time
- Automatic reconnection on WebSocket disconnect (3s retry)
- Polling fallback only activates when WebSocket is disconnected
- Status indicator shows "Live (WS)" when WebSocket connected
- Refactored data processing into reusable processStateData()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add simulation speed controls: pause/resume and speed adjustment
- Add pause/resume and speed control (0.25x to 5x) to API server
- New endpoints: GET/POST /api/controls, /controls/pause, /controls/resume, /controls/speed
- Web UI header now has play/pause button, fast/normal/slow speed buttons
- Speed label shows current state (PAUSED, 4x, 2x, 1x, 0.3x)
- Controls state persisted across page refreshes via API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Upgrade web UI with tabbed sidebar and conversation history
- Add tabbed sidebar: Agents list, Chat (conversations), Events log
- Conversations panel shows live and recent dialogues with full turns
- Agent list with sorting (in-conversation first), state icons, partner info
- Enhanced agent detail: relationship bars (familiarity/trust/sentiment/romance),
back navigation, clickable relationships to navigate between agents
- Canvas conversation bubbles showing last spoken message above agents
- Add /api/relationships endpoint for full relationship graph data
- Enhanced /api/conversations: returns full dialogue history (active + recent)
- Enhanced /api/agents/{id}: includes romance, trust, familiarity, interaction count
- Add conversation_history to simulation for preserving finished conversations
- Color-coded event log: moves, reflections, romance, conversations, events
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add gender, romance system, web UI, and API event log
- Add gender field to all 20 personas (male/female/nonbinary)
- Implement romance system: romantic_interest tracking with relationship
progression (crushing -> dating -> engaged -> married)
- Add partner_id to agents for tracking romantic partners
- Create web UI (web/index.html): canvas-based city visualization with
buildings, animated agents with gender-specific sprites, weather effects,
day/night cycle, couple hearts/lines, event log, and agent detail panel
- Add /api/events endpoint and persistent event history in simulation
- Serve web UI from FastAPI with static file mounting
- Update default Ollama model to llama3.2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>