Highlights
After our most extensive pre-release program ever, we’re proud to release Mesa 3.0 as stable. Mesa 3.0 brings major improvements to agent-based modeling, making it more intuitive and powerful while reducing complexity. This release modernizes core functionalities and introduces new capabilities for both beginners and advanced users.
Streamlined agent management
The centerpiece of Mesa 3.0 is its new agent management system. Agents are now automatically tracked and assigned unique IDs, eliminating common boilerplate code. The new AgentSet functionality provides an elegant and flexible way to work with agents, for example:
# Find agents meeting specific criteria
wealthy_agents = model.agents.select(lambda a: a.wealth > 1000)
# Group and analyze agents
grouped = model.agents.groupby("state")
state_stats = grouped.agg({
"count": len,
"avg_age": ("age", np.mean),
"total_wealth": ("wealth", sum)
})
# Activate agents in different patterns
model.agents.shuffle_do("step") # Random activation
model.agents.select(lambda a: a.energy > 0).do("move") # Conditional activation
The AgentSet provides powerful methods for filtering, grouping, and analyzing agents, making it easier to express complex model logic. Each model automatically maintains an AgentSet containing all agents (model.agents
) and separate AgentSets for each agent type (model.agents_by_type
). See the full AgentSet docs here.
Modern Visualization with SolaraViz
Mesa 3.0's new experimental visualization system, SolaraViz, provides a modern, interactive interface for model exploration:
from mesa.visualization import SolaraViz, make_space_component, make_plot_component
visualization = SolaraViz(
model,
[
make_space_component(agent_portrayal),
make_plot_component(["population", "average_wealth"]),
lambda m: f"Step {m.steps}: {len(m.agents)} agents" # Custom text component
],
model_params=parameter_controls
)
Key visualization features:
- Interactive browser-based interface with real-time updates
- Support for both grid-based and network models
- Visualization of PropertyLayers and hexagonal grids
- Custom components using Matplotlib or text
- Improved performance and responsiveness
Check out the Visualization Tutorial to get started.
Note: SolaraViz is in active development. We might make API breaking changes between Mesa 3.0 and 3.1.
Enhanced data collection
The DataCollector now supports collecting different metrics for different agent types, using agenttype_reporters
:
self.datacollector = DataCollector(
model_reporters={"total_wealth": lambda m: m.agents.agg("wealth", sum)},
agent_reporters={"age": "age", "wealth": "wealth"},
agenttype_reporters={
Predator: {"kills": "kills_count"},
Prey: {"distance_fled": "total_flight_distance"}
}
)
Experimental features
Mesa 3.0 introduces several experimental features for advanced modeling:
- Cell Space with integrated PropertyLayers and improved agent movement capabilities
- Voronoi grid implementation
- Event-scheduling simulation capabilities
These experimental features are in active development and might break API between releases.
Breaking changes
See our Mesa 3.0 migration guide for a full overview.
If you want to move existing models from Mesa 2.x to 3.0, there are a few things you have to change.
- Models must explicitly initialize the Mesa base class:
class MyModel(mesa.Model):
def __init__(self, n_agents, seed=None):
super().__init__(seed=seed) # Required in Mesa 3.0
- Agents are created without manual ID assignment:
# Old
agent = MyAgent(unique_id=1, model=self)
# New
agent = MyAgent(model=self)
- Scheduler replacement with AgentSet operations:
# Old (RandomActivation)
self.schedule = RandomActivation(self)
self.schedule.step()
# New
self.agents.shuffle_do("step")
# Old (SimultaneousActivation)
self.schedule = SimultaneousActivation(self)
self.schedule.step()
# New
self.agents.do("step")
self.agents.do("advance")
Furthermore:
- Steps counter automatically increments
mesa.flat
namespace removed- Python 3.10+ required
- Reserved model variables (
agents
,steps
, etc.) protected - Simplified DataCollector initialization
- Old visualization system replaced by SolaraViz
Getting Started
Install Mesa 3.0:
pip install --upgrade mesa
If building a new model, we recommend checking out the updated Mesa Overview and Introductory Tutorial.
For updating existing models, we recommend upgrading in steps:
- Update to latest Mesa 2.x
- Address deprecation warnings
- Upgrade to Mesa 3.0
- Replace schedulers with AgentSet functionality
A detailed migration guide is available to help moving to Mesa 3.0. For questions or support, join our GitHub Discussions or Matrix Chat.
We would love to hear what you think about Mesa 3.0! Say hello here and leave any feedback on 3.0 here.
What's Changed
⚠️ Breaking changes
- Remove mesa.flat namespace by @rht in #2091
- breaking: Remove visualization_old (mesa-viz-tornado) by @rht in #2133
- viz: Combine code for rendering in browser and Jupyter by @rht in #2180
- breaking: Add dependencies argument to custom space_drawer by @rht in #2209
- Require Mesa models to be initialized with
super().__init__()
by @EwoutH in #2218 - Allow AgentSet.do() to take Callable function by @quaquel in #2219
- Change warning when setting model.agents to error by @EwoutH in #2225
- model: Automatically increase
steps
counter by @EwoutH in #2223 - move solara_viz back to experimental by @Corvince in #2278
- track unique_id automatically by @quaquel in #2260
- update Agent.init to remove deprecation warning by @quaquel in #2328
- replace model with random in AgentSet init by @quaquel in #2350
- remove cookiecutter by @quaquel in #2421
- Viz: Refactor Matplotlib plotting by @quaquel in #2430
- api reorganization by @quaquel in #2447
- Deprecate
initialize_data_collector
by @EwoutH in #2327
🧪 Experimental features
- devs/eventlist: Add repr method to print EventList pretty by @EwoutH in #2195
- Voronoi Tessellation based Discrete Space by @vitorfrois in #2084
- Make cell connections public and named by @Corvince in #2296
- Update to CellCollection.select by @quaquel in #2307
- Have a dedicated neighborhood property and a get_neighborhood method on Cell by @quaquel in #2309
- Encapsulate cell movement in properties by @quaquel in #2333
- experimental: Integrate PropertyLayers into cell space by @EwoutH in #2319
- Generalize CellAgent by @Corvince in #2292
- cell space: Add convenience properties for grid width and height by @quaquel in #2348
- Bugfix for deepcopy / pickling discrete spaces by @quaquel in #2378
- Add support for drawing discrete grids by @quaquel in #2386
- Altair spaces by @quaquel in #2397
- Mark SolaraViz as experimental for Mesa 3.0 by @EwoutH in #2459
🎉 New features added
- Set JupyterViz as stable by @rht in #2090
- Add AgentSet.groupby by @quaquel in #2220
- AgentSet: Add
set
method by @EwoutH in #2254 - AgentSet: Add
agg
method by @EwoutH in #2266 - Implement new SolaraViz API by @Corvince in #2263
- GroupBy: Add
count
andagg
methods by @EwoutH in #2290 - datacollector: Allow collecting data from Agent (sub)classes by @EwoutH in #2300
- Add optimized shuffle_do() method to AgentSet by @EwoutH in #2283
- Visualize PropertyLayers by @EwoutH in #2336
- Move core example models back (v2) by @EwoutH in #2358
- Add Model.rng for SPEC-7 compliant numpy random number generation by @quaquel in #2352
- remove_all_agents method added to model by @quaquel in #2394
- Pass through model.rgn in agent analogous to model.random by @quaquel in #2400
- add agents property to all spaces by @quaquel in #2418
🛠 Enhancements made
- Rename JupyterViz to SolaraViz by @rht in #2187
- refactor: Rename jupyter_viz namespace to solara_viz by @rht in #2188
- Visualisation: Allow specifying Agent shapes in agent_portrayal by @rmhopkins4 in #2214
- Split AgentSet into map and do to seperate return types by @quaquel in #2237
- Performance enhancements for Model.agents by @quaquel in #2251
- AgentSet: Allow selecting a fraction of agents in the AgentSet by @EwoutH in #2253
- Model: Replace
get_agents_of_type
method withagents_by_type
property by @EwoutH in #2267 - add default SolaraViz by @Corvince in #2280
- Simplify ModelController by @Corvince in #2282
- Add default values and missing value handling to
agentset.get
by @quaquel in #2279 - SolaraViz Updates by @Corvince in #2299
- Solara viz: use_task for non-threaded continuous play by @Corvince in #2304
- Reduce core dependencies, split in optional dependencies by @EwoutH in #2265
- use GridDraggable instead of Column in SolaraViz by @wang-boyu in #2344
- update legend, xlabel & format of matplotlib plots by @wang-boyu in #2346
- init.py: Import mesa.experimental by @EwoutH in #2374
- Importable examples by @Corvince in #2381
- update_tutorial environment by @tpike3 in #2411
- expand ax.scatter kwargs that can be used by @quaquel in #2445
🐛 Bugs fixed
- datacollector: store separate snapshots of model data per step by @EwoutH in #2129
- Jupyter_viz: Allow measures to be None by @EwoutH in #2163
- Jupyter Viz: Don't avoid interactive backend by @EwoutH in #2165
- fix: Render agent marker radius correctly by @rht in #2181
- fix: Use model.schedule.steps -> mode._steps for batch_run by @rht in #2183
- SolaraViz: Reset components when params are changed by @rht in #2240
- Fix deterministic behavior in
move_agent_to_one_of
withselection="closest"
by @OrenBochman in #2118 - viz: stop running and disable buttons when model.running is False by @wang-boyu in #2332
- experimental init: Fix Solara import by making it lazy by @EwoutH in #2357
- fix: pass
model.random
to schedulers by @quaquel in #2359 - fix: register agent after creating unique_id and pos attributes by @wang-boyu in #2368
- solara: viz tutorial: fix histogram code by @Corvince in #2379
- Fix for mistaken removal of _draw_grid by @quaquel in #2398
- fixes weakref bug in shuffe_do by @quaquel in #2399
- Fix #2452 - handle solara viz model params better by @Corvince in #2454
- Update MoneyModel.py by @quaquel in #2458
- Bugfix for Solara deepcopy bug by @quaquel in #2460
- solaraviz kwargs related bugfix by @quaquel in #2463
🔍 Examples updated
- Cleanup and restructure basic example models by @EwoutH in #2365
- Ruff basic examples by @EwoutH in #2370
- refactor: Simplify Schelling code by @rht in #2353
- Move examples into mesa by @Corvince in #2387
- Explicitly test basic examples by @quaquel in #2390
- Make example import absolute by @quaquel in #2402
- Cleanup and restructure EpsteinCivilViolence and PdGrid examples by @EwoutH in #2408
- Reorganize advanced examples: wolf_sheep and sugarscape_g1mt by @quaquel in #2410
- reactivate ruff for advanced examples and include them in tests by @quaquel in #2414
- Updates to Epstein example by @quaquel in #2429
- Update examples to use updated space drawing by @quaquel in #2442
📜 Documentation improvements
- Fix image on landing page of docs. by @jackiekazil in #2146
- Replace links in docs - google group to matrix. by @jackiekazil in #2148
- Add experimental features to documentation as per #2122 by @stephenfmann in #2154
- Update visualisation docs by @EwoutH in #2162
- Add original conference paper link to docs by @ENUMERA8OR in #2160
- docs/conf.py: Use modern
intersphinx_mapping
format by @EwoutH in #2206 - docs: Update Readme and tutorials to mention Mesa 3.0 pre-releases by @EwoutH in #2203
- Contribution: Add "I have no idea where to start" section by @EwoutH in #2258
- Write initial Mesa Migration guide by @EwoutH in #2257
- docs: Fix Visualization Tutorial (main branch) by @EwoutH in #2271
- Docs: Fix broken relative links by removing
.html
suffix by @EwoutH in #2274 - Readthedocs: Don't let notebook failures pass silently by @EwoutH in #2276
- Update viz tutorial to the new API by @Corvince in #2289
- Enforce google docstrings by @quaquel in #2294
- Api docs by @quaquel in #2298
- update migration guide to describe solaraviz updates by @Corvince in #2297
- Migration Guide: Add Model initialization requirement and automatic Agent.unique_id assignment by @EwoutH in #2302
- Deprecate Time module and all its Schedulers by @EwoutH in #2306
- intro_tutorial: Don't initialize agents with an unique_id by @EwoutH in #2315
- Migration guide: Intro, upgrade strategy, model.agents, headers by @EwoutH in #2314
- docs: Update overview for Mesa 3.0 by @EwoutH in #2317
- Readthedocs: Add version switch and update URL by @EwoutH in #2324
- Update migration_guide.md by @quaquel in #2347
- Include examples in readthedocs (port) by @EwoutH in #2392
- Update into_tutorial by @tpike3 in #2372
- Update Schelling Readme.md by @quaquel in #2406
- Update Conway example by @quaquel in #2403
- Boltzman readme by @quaquel in #2405
- Update Readme.md of Boid flockers by @quaquel in #2404
- add advanced examples to rtd by @quaquel in #2413
- Tutorial Improvements by @tpike3 in #2415
- space: Add note that Grids are maintenance only by @EwoutH in #2420
- Migration guide: Update automatic unique_id assignment examples by @EwoutH in #2419
- Update docstring of SimEvent by @quaquel in #2417
- best-practices: Update Model Layout section by @EwoutH in #2424
- docs: Clean-up index.md by @EwoutH in #2422
- Update wolf-sheep png and fix typo in file name by @quaquel in #2444
- Include main examples readme in docs by @quaquel in #2448
- remove how-to guide and update docs in places by @quaquel in #2449
- Docs reorganization by @quaquel in #2450
🔧 Maintenance
- CI: Add weekly scheduled run to all CI workflows by @EwoutH in #2130
- Drop support for Python 3.9, require Python >= 3.10 by @EwoutH in #2132
- Add script to list unlabeled PR's since latest release by @rht in #2047
- CI: Let pytest treat warnings as errors for examples by @EwoutH in #2204
- CI: Add test job for Python 3.13 by @EwoutH in #2173
- Add pull request templates by @EwoutH in #2217
- benchmarks: Add BoltzmannWealth model by @EwoutH in #2252
- CI: Add optional dependency for examples by @EwoutH in #2261
- Resolve multiprocessing warning, state Python 3.13 support by @rht in #2246
- make typing behavior of AgentSet.get explicit by @quaquel in #2293
- model: Move random seed and random to init by @rht in #1940
- Remove schedulers from benchmark models. by @quaquel in #2308
- tests: Resolve warnings by removing scheduler and updating arguments by @EwoutH in #2329
- add super call to Model and remove self.schedule by @quaquel in #2334
- Code coverage: ignore experimental and visualization by @Corvince in #2361
- add codecov token, fixes #2363 by @Corvince in #2366
- add test_time back by @quaquel in #2367
- Release notes: Add example category by @EwoutH in #2369
- Add empty
pull_request_template.md
to enable PR template chooser by @EwoutH in #2409 - remove deprecated HexGrid class by @quaquel in #2441
- rename make_plot_measure to make_plot_component and add some kwargs by @quaquel in #2446
New Contributors
- @stephenfmann made their first contribution in #2154
- @ENUMERA8OR made their first contribution in #2160
- @rmhopkins4 made their first contribution in #2214
- @vitorfrois made their first contribution in #2084
- @OrenBochman made their first contribution in #2118
Full Changelog: v2.4.0...v3.0.0