Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/salesforce/ai-economist/llms.txt

Use this file to discover all available pages before exploring further.

A Scenario is a concrete subclass of BaseEnvironment (base/base_env.py). It defines the setting of the simulation: which resources exist, how the world map is laid out, what passive dynamics run each step, what observations agents receive, and how rewards are calculated. Scenarios are registered in scenario_registry with a @scenario_registry.add decorator and identified by a name string (e.g. "uniform/simple_wood_and_stone").

Class-level declarations

Every scenario class must declare three class attributes before __init__:
@scenario_registry.add
class Uniform(BaseEnvironment):
    name = "uniform/simple_wood_and_stone"          # unique registry key
    agent_subclasses = ["BasicMobileAgent", "BasicPlanner"]  # expected agent types
    required_entities = ["Wood", "Stone"]           # entities the scenario needs
Entities declared in required_entities are registered with the World and added to every agent’s inventory (for resources) or endogenous state (for endogenous variables).

Abstract methods

Every scenario must implement five abstract methods:

reset_starting_layout()

Part 1 of the episode reset. Initialises the spatial state of the world: where resource source blocks are, where water/other landmarks are, etc.
def reset_starting_layout(self):
    # Place stone source blocks in the bottom half of the map,
    # wood source blocks in the top half.
    ...
    self.world.maps.set("StoneSourceBlock", stone_layout)
    self.world.maps.set("WoodSourceBlock",  wood_layout)

reset_agent_states()

Part 2 of the episode reset. Initialises per-agent state: starting locations, starting inventory, skills, etc.
def reset_agent_states(self):
    for agent in self.world.agents:
        agent.state["loc"] = self.world.get_random_vacant_loc()
        agent.state["inventory"]["Coin"] = self.starting_agent_coin
        agent.state["inventory"]["Wood"] = 0
        agent.state["inventory"]["Stone"] = 0

scenario_step()

Called once per timestep after all component_step() calls. Implements passive world dynamics such as resource regeneration, environmental effects, or any update that is not driven by agent actions.
def scenario_step(self):
    # Regenerate wood on empty source tiles
    for r, c in wood_source_locations:
        if self.world.maps.get("Wood")[r, c] == 0:
            if np.random.rand() < self.wood_regen_weight:
                self.world.maps.set_point("Wood", r, c, 1)

generate_observations()

Returns a {agent.idx: obs_dict} dictionary of scenario-level observations for each agent. The environment prefixes each key with "world-" and merges these with component observations.
def generate_observations(self):
    obs = {str(agent.idx): {} for agent in self.world.agents}
    obs[self.world.planner.idx] = {}
    # Each mobile agent receives the local resource map
    for agent in self.world.agents:
        obs[str(agent.idx)]["map"] = self._get_agent_view(agent)
    return obs

compute_reward()

Returns a {agent.idx: scalar} dictionary of rewards for the current timestep. This is the only place in Foundation where rewards are defined.
def compute_reward(self):
    rew = {str(agent.idx): agent_utility(agent) for agent in self.world.agents}
    rew[self.world.planner.idx] = social_welfare(self.world.agents)
    return rew

Optional methods

  • additional_reset_steps() — extra logic to run at the end of reset (after components reset).
  • scenario_metrics() — returns a {"key": scalar} dict of scenario-level metrics logged at episode end.

Built-in scenarios

Class: Uniform (scenarios/simple_wood_and_stone/dynamic_layout.py)Wood and stone are generated procedurally at the start of each episode using spatial coverage targets and clumpiness parameters. Resources regenerate stochastically each step via a configurable regen kernel.
  • Agents: BasicMobileAgent × n, BasicPlanner × 1
  • Entities: Wood, Stone (+ auto-included Coin, Labor)
  • Key args: starting_wood_coverage, wood_regen_weight, wood_clumpiness, stone_* equivalents, gradient_steepness, isoelastic_eta, energy_cost, planner_reward_type
Class: LayoutFromFile (scenarios/simple_wood_and_stone/layout_from_file.py)Same as uniform/simple_wood_and_stone but reads the initial resource and water layout from a text file (env_layout_file), giving reproducible world maps. Supports a fixed_four_skill_and_loc option that pins agent skills and starting positions to a fixed quartile arrangement.
  • Agents: BasicMobileAgent × n, BasicPlanner × 1
  • Entities: Wood, Stone, Water
  • Key args: env_layout_file, resource_regen_prob, fixed_four_skill_and_loc
Class: OneStepEconomy (scenarios/one_step_economy/one_step_economy.py)A minimal two-step environment (episode length = 2): on step 1 the planner sets tax brackets via PeriodicBracketTax, and on step 2 mobile agents choose how many hours to work via SimpleLabor. Intended for studying tax policy in isolation.
  • Agents: BasicMobileAgent × n, BasicPlanner × 1
  • Entities: Coin
  • Intended components: PeriodicBracketTax, SimpleLabor
  • Key args: agent_reward_type, isoelastic_eta, labor_cost, planner_reward_type
Class: CovidAndEconomyEnvironment (scenarios/covid19/covid19_env.py)Models health and economic dynamics during a pandemic across 51 US-state agents and a federal-government planner. State agents choose pandemic-policy stringency levels; the planner sets federal subsidy payments. Supports replay of real-world data or simulation with fitted epidemiological and economic models.
  • Agents: BasicMobileAgent × 51 (US states + DC), BasicPlanner × 1
  • Intended components: ControlUSStateOpenCloseStatus, FederalGovernmentSubsidy
  • Key args: use_real_world_data, use_real_world_policies, start_date, risk_free_interest_rate, health_priority_scaling_agents, health_priority_scaling_planner

Build docs developers (and LLMs) love