Clouds: lower opacity, depthWrite off, softer puffs.
Moon shadow color now matches sky phase instead of fixed black.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix day display, DB growth, console errors; add FPV NPC chat with speech input
- 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>
Enhanced building architecture: chimneys, porches, bay windows on houses; balconies and cornices on apartments; glass curtain-wall office; sawtooth roof factory with loading dock; rose window church with buttresses; clock tower school; cinema with ticket booth; hospital with helipad; museum with columns and dome; park with gazebo and flower beds; ornate town square fountain
- 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>
First-person VR mode, calendar system, agent fixes, player character
- First-person mode (WASD+mouse) with PointerLockControls
- WebXR VR support for headsets
- Player can join city as playable character with HUD
- NPCs face the player when nearby in FP mode
- Calendar system starting 1 April 2026 with seasons
- Weather: 75% sunny, snow only in winter, rain other seasons
- Aging tied to calendar (1 year = 365 days, not tick-based)
- Moon phases (full/half/quarter/new, 28-day cycle)
- Agents always visible (no indoor hiding)
- Windows semi-transparent in interior view
- Dead agents show death date/age, no needs bars
- Agent movement speed 4x faster
- Sleeping agents lie along beds (not perpendicular)
- Furniture marked isFurniture for interior view
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>
Brighter night scene, building interior view on click
- Night lighting 3x brighter: hemi 0.35, ambient 0.25, lighter sky gradient, less fog
- Window glow increased to 0.8 emissive intensity
- Click building to enter interior: walls become transparent, camera zooms in
- See agents inside on beds, tables, desks
- Exit interior on empty click, Escape, or close panel
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>
Add 3D city visualization: buildings, humanoid agents, sky environment
- Three.js isometric 3D city with 70 locations: houses, apartments, shops,
offices, factories, public buildings (police, fire, museum, mall, townhall,
market), parks, and entertainment venues
- Detailed humanoid figures with arms, legs, clothing, walking animation
- Sky system: sun/moon, stars, clouds, mountains, day/night lighting
- 75 demo agents with collision avoidance around buildings
- Grid of streets connecting all city blocks
- /3d route added to FastAPI server
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>