Skip to content

Development — Architecture Overview

This page maps the BDPD codebase for contributors. It explains what lives where and why.


Technology Stack

Layer Technology Purpose
Platform Node.js (ESM), Express Multi-agent simulation server
Agents (platform) Node.js (built-in, sandboxed JS) In-process heuristic and user-code agents
Agents (LLM) Python (Flask, openai) LLM middleman bridge
Card Game Python Simulation engine and LLM integration
Experiments Node.js (runner) + Python (sweeps, stats, plots) Sweep orchestration, statistical inference, visualisation
Tools Python (lxml, cairosvg, PIL) Card generator pipeline
Shared Python Logging, environment checks, versioning, run manifests
Docs MkDocs Material Documentation site

Repository Structure

BDPD/
├── main.js             # Entry point — Express server
├── platform/           # Node.js — Arena server (Express)
│   ├── arena.js        #   Arena instance (state, lifecycle, ticks)
│   ├── world.js        #   Polycentric federation (≥ v1.0)
│   ├── registry.js     #   In-memory index + on-disk persistence
│   ├── scheduler.js    #   Pluggable turn order (simultaneous, sequential_random, wealth_weighted)
│   ├── observability.js#   Noise, visibility, resolution (bucket / exact)
│   ├── perturbation.js #   12 perturbation types (regen/commons/capital/wealth shocks, sanctions, exclusion, …)
│   ├── pacts.js        #   Declared agreements (≥ v0.9 governance)
│   ├── messages.js     #   Cheap-talk channel + broadcast tools (≥ v0.9 governance)
│   ├── reputation.js   #   Per-player behaviour score (≥ v0.9 governance)
│   ├── sandbox.js      #   Code agent sandbox (VM)
│   ├── streamer.js     #   SSE broadcasting
│   └── reporter.js     #   Automated report generation
├── agents/             # Agent implementations
│   ├── base-agent.js   #   Base class
│   ├── built-in.js     #   5 heuristic strategies (Aggressive, Conservative, Adaptive, RCP, Random)
│   ├── api-agent.js    #   HTTP agent dispatcher
│   ├── governance.js   #   Meta-role agents (≥ v0.9): PollutionRegulator, etc.
│   ├── bdpd_agent.py   #   LLM middleman (Flask)
│   ├── cards_ai_play.py#   Card game LLM tournament runner
│   └── bdpd_sdk/       #   Python SDK for LLM agents (BDPDAgent, PlayerMemory, tools)
├── engine/             # Platform resource dynamics (engine-agnostic platform/)
│   ├── base-engine.js  #   Engine interface
│   ├── engine-registry.js #   `logistic` ↔ `seneca` registry, opens to plugins
│   ├── logistic.js     #   Single-stock logistic + Forest Die + hidden reserve
│   ├── seneca.js       #   Bardi (2011) 3-variable ODE (R, C, P)
│   ├── commons.js      #   Shared math primitives + SENECA_DEFAULTS
│   └── metrics.js      #   Gini, welfare, Gate+Rank victory
├── config/
│   └── game-defaults.js#   Central parameter store
├── experiments/
│   ├── experiment.js   #   Node.js experiment framework
│   ├── sweep.py        #   Python sweep coordinator
│   ├── sweep_supplement.py # B1–B5 sweeps
│   ├── sweep_card_tournaments.py # Card tournament runner
│   ├── statistical_inference.py  # Bootstrap, regression, permutation
│   ├── plot_theme.py   #   Matplotlib theming
│   ├── generate_experiment_summaries.py
│   └── definitions/    #   17 JSON sweep definitions
├── cards/
│   └── cards_v03.json  #   Card game data (1308 lines)
├── tools/
│   ├── card_generator/ #   SVG → PNG pipeline
│   │   ├── generate_cards.py
│   │   ├── svg_builder.py
│   │   ├── rasterizer.py
│   │   └── templates/
│   └── panel/          #   Multi-LLM brainstorming workspace (see dev/panel.md)
│       ├── panel       #     Bash CLI (start / say / read / deliver / …)
│       ├── server.py   #     FastAPI read-only WebUI on 127.0.0.1:4848
│       └── static/     #     SSE-driven single-page viewer
├── shared/             # Python utilities
│   ├── bdpd_version.py #   Git-based versioning
│   ├── bdpd_manifest.py#   Run directory creation
│   ├── bdpd_logging.py #   Logging + LLM trace
│   └── bdpd_check_env.py#  Venv guard
├── scripts/            # Shell orchestration
│   ├── setup.sh        #   Environment setup
│   ├── check_env.sh    #   Prerequisite validation
│   ├── run_arena.sh    #   Full arena launcher (local/API/none)
│   └── my_arena.sh     #   Quick arena launcher
├── docs/               # MkDocs documentation
├── site/               # Built HTML (gitignored)
├── mkdocs.yml
├── package.json
├── requirements.txt
├── CITATION.cff
├── README.md
├── CONTRIBUTING.md
├── CHANGELOG.md
├── LICENSE
└── LICENSE-CC

Key Design Decisions

  1. Node.js for the platform server. Express provides mature HTTP routing, SSE streaming, and middleware. The single-threaded async model is appropriate for sequential turn-based games.
  2. ES modules. The platform uses "type": "module" in package.json. All Node.js code uses import/export.
  3. Python for agents and experiments. The scientific Python ecosystem (numpy, matplotlib, scipy) handles statistical inference, plotting, and LLM integration. The Node.js ↔ Python boundary is the HTTP callback interface.
  4. JSON for experiment definitions. Each sweep is a declarative JSON file specifying population, parameter ranges, run counts, and output. No sweep logic is hardcoded — the framework reads definitions generically.
  5. Git-based versioning. No version numbers are hardcoded. bdpd_version.py reads git describe --tags at runtime.
  6. Shared utilities are Python-only. The shared/ module is imported by all Python entry points. There is no equivalent Node.js shared module — the platform is self-contained.

Entry Points

Command What It Does
node main.js Start the Arena server
python3 experiments/sweep.py Run a platform sweep
python3 experiments/sweep_card_tournaments.py Run a card tournament
python3 agents/cards_ai_play.py Single card game (heuristic or LLM)
python3 agents/bdpd_agent.py Start the LLM middleman server
python3 tools/card_generator/generate_cards.py Generate card images
tools/panel/panel start "<topic>" Open a multi-LLM brainstorming session (see Panel)

All Python entry points call bdpd_check_env.require_venv() to enforce the correct virtual environment.