# Concordia Island Concordia Island is an open-ended sandbox world built on Concordia in which 100+ generative agents live in neighborhoods stratified by social class, commute to work, socialize in shared public spaces, and adapt to life events such as job loss or a mugging. Agents are instrumented with repeated psychometric surveys (ESM affect, BFI-2, SWLS, GHQ-12, MEMS) and daily journal reflections to evaluate how different agent decision logics and base LLMs hold up over multi-day simulations. --- ## 0. Quickstart: quick test β†’ 20-agent Brecksville run β†’ view in Studio Run these commands from the root of the Concordia repository. You can also generate and copy-paste them from the **πŸš€ Launch** tab in Simulation Studio. ```bash pip install -e ".[google]" pyyaml scipy # 1. Quick test (mock LLM, no API key, ~1 min): 4 agents, 12 ticks # (one full day, one night of X + marketplace, and the next morning) python -m examples.concordia_island.run \ --personas_date=brecksville_ohio \ --agents=4 --ticks=12 --agent_prefab=esa --engine_type=async \ --event_config=job_loss --layoff_fraction=0.5 --first_dates \ --enable_x=True --x_rounds=1 \ --enable_nighttime_marketplace=True --marketplace_rounds=1 \ --use_mock=True --poll=False --output_dir=./local_runs/quick_test # 2. Full run: 20 agents x 112 ticks (14 simulated days) with a real LLM export GOOGLE_API_KEY= python -m examples.concordia_island.run \ --personas_date=brecksville_ohio \ --agents=20 --ticks=112 --agent_prefab=esa --engine_type=async \ --event_config=job_loss --first_dates \ --api_type=google_aistudio --model_name=gemini-2.5-flash \ --poll=False --output_dir=./local_runs/brecksville_20x112 # Check progress while a run is going (current tick, sim time, agent locations): watch -n 15 cat ./local_runs/brecksville_20x112/progress.json # 3. Open Simulation Studio to inspect agent memories (🧠 Memory Visualizer tab) # and watch the replay on the Brecksville map (πŸ—ΊοΈ Map tab; zoom to block # level to see building names and agent labels). python -m examples.concordia_island.ui.simulation_studio \ --run_dir=./local_runs/brecksville_20x112 --geography=brecksville --port=9090 # Then open http://localhost:9090 in your browser. Without --run_dir, Studio # opens the bundled Gemini 2.5 Flash ESA job-loss run from the paper (see 2.2). ``` --- ## 1. Repository Layout ``` examples/concordia_island/ β”œβ”€β”€ README.md β”œβ”€β”€ run.py # CLI entry point: run a simulation and write a run folder β”œβ”€β”€ island_simulation.py # IslandConcordiaSimulation (Python API) β”œβ”€β”€ mock_language_model.py # Deterministic offline model (--use_mock=True) β”œβ”€β”€ concordia_island_e2e_test.py # End-to-end tests (using the mock model) β”œβ”€β”€ configs/ # Event and shock schedules (job loss, mugging) β”œβ”€β”€ prefabs/ # Agent decision logics and Game Masters β”œβ”€β”€ sim/ # Clock, locations, conversations, marketplace, psychometric surveys β”œβ”€β”€ personas/ # Persona pipeline, census names, and the Brecksville population (see 2.1 and personas/README.md) β”œβ”€β”€ data/ β”‚ β”œβ”€β”€ paper_runs/ # Complete memory logs from the paper's Job Loss and Mugging runs (see 2.2) β”‚ β”œβ”€β”€ atlas/ # Map geometry for Brecksville, Concordia Island, and Kerala β”‚ └── island_100.yaml # Residential, workplace, and public venue definitions └── ui/ # Simulation Studio + Map Dashboard (section 5) ``` --- ## 2. Pregenerated Data (Personas & Memories) All bundled persona and run files are plain JSON and can be inspected directly in Python without starting a model or the UI. Paths below are relative to the repository root. ### 2.1 Pregenerated Personas: `personas/populations/brecksville_ohio/` This subdirectory contains 1,000 pregenerated residents for the Brecksville, Ohio settingβ€”one JSON file per person (`__persona.json`, e.g. `aaron_chen_persona.json`) plus `metadata.json`. Personas are generated in four stages: 1. **Trait sampling**: Quasi-Monte Carlo (Sobol) sampling across 10 axes (`openness`, `conscientiousness`, `extraversion`, `agreeableness`, `neuroticism`, `locus_of_control`, `social_trust`, `religiosity`, `technology_attitude`, `community_orientation`). 2. **Worldview synthesis**: Expanding the trait coordinates into a personal backstory, belief system, and habitual reaction style (`personality`, `original_backstory`). 3. **Formative memory seeding**: A chronological list of childhood and adult developmental memories (`formative_memories`, each prefixed with `[formative]`) loaded into the agent's memory bank before Tick 1. 4. **Demographic grounding**: Name, age, gender, ethnicity, relationship status, economic class, housing tier (`home_place`), workplace (`work_place`), and hobbies. To inspect a persona file directly in Python: ```python import glob import json pop_dir = "examples/concordia_island/personas/populations/brecksville_ohio" with open(f"{pop_dir}/aaron_chen_persona.json") as f: persona = json.load(f) print(persona["name"], persona["age"], persona["economic_class"]) print("Traits:", persona["traits"]) print("First 2 formative memories:") for mem in persona["formative_memories"][:2]: print(" ", mem) print("Total persona files:", len(glob.glob(f"{pop_dir}/*_persona.json"))) ``` Or load the population as `PersonaData` objects using `personas/generator.py`: ```python from examples.concordia_island.personas import generator personas = generator.load_personas( date_label="brecksville_ohio" ) print(len(personas), "loaded") print(personas["Aaron Chen"].formative_memories[:2]) ``` When `run.py` runs with `--personas_date=brecksville_ohio`, it sorts the personas by name, shuffles them with seed 42, and takes `--agents=N` starting at `--population_offset` (default `0`), so the same flags always select the same subset of residents. `run.py` reads the `setting_preset` in the persona set's `metadata.json` (or infers it from the label: Brecksville and Ohio labels use `brecksville_1000`) to choose the `sim/locations.py` homes and public places, so the game master knows the same places as the personas. Override it with `--setting`. **Building a new population.** Only the Brecksville set ships. To generate another one, at any size or for another setting, run the two-step pipeline described in [`personas/README.md`](personas/README.md): 1. `personas/populations/generate_population.py` writes a roster: demographics, census names, and a one-line personality and backstory for each resident. 2. `personas/generate_personas.py` runs trait sampling, worldview synthesis and formative memories for each resident, and saves a persona set that `run.py --personas_date=