
Simpy
Implement discrete-event simulations in Python with SimPy events, timeouts, and process flows.
Overview
simpy is an agent skill for the Build phase that teaches SimPy’s event-driven discrete-event simulation primitives in Python.
Install
npx skills add https://github.com/k-dense-ai/scientific-agent-skills --skill simpyWhat is this skill?
- Documents the three-state event lifecycle: not triggered, triggered, and processed
- Shows env.timeout for time progression and returning values from yielded events
- Explains how processes yield events and resume when callbacks run
- Includes runnable snippets for env.event(), succeed(), and env.run() patterns
- Foundation for discrete-event simulation before adding resources and queues
- Covers a 3-state event lifecycle for SimPy events
Adoption & trust: 528 installs on skills.sh; 27.6k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You need timed, event-driven simulation code but are unsure how SimPy events, timeouts, and process yields actually advance state.
Who is it for?
Solo builders adding queuing, capacity, or workflow timing models inside a Python backend or research prototype.
Skip if: Teams that only need one-off scripts with sleep() or datetime loops and do not want a simulation framework.
When should I use this skill?
You are writing or reviewing SimPy simulation code and need correct event, timeout, and process yield patterns.
What do I get? / Deliverables
After using it, your agent produces correct SimPy process patterns with explicit event lifecycle handling and timeout-based time steps.
- SimPy process definitions using events and timeouts
- Runnable simulation snippets aligned with SimPy idioms
Recommended Skills
Journey fit
How it compares
Use instead of guessing SimPy APIs from generic Python snippets when you need discrete-event semantics.
Common Questions / FAQ
Who is simpy for?
Python developers and indie builders modeling systems with SimPy who want accurate event and timeout usage in agent-generated code.
When should I use simpy?
During Build backend work when designing simulations; also when validating throughput assumptions in Validate prototype models that use timed processes.
Is simpy safe to install?
Review the Security Audits panel on this Prism page before installing; the skill is documentation-style guidance without declaring elevated permissions.
SKILL.md
READMESKILL.md - Simpy
# SimPy Events System This guide covers the event system in SimPy, which forms the foundation of discrete-event simulation. ## Event Basics Events are the core mechanism for controlling simulation flow. Processes yield events and resume when those events are triggered. ### Event Lifecycle Events progress through three states: 1. **Not triggered** - Initial state as memory objects 2. **Triggered** - Scheduled in event queue; `triggered` property is `True` 3. **Processed** - Removed from queue with callbacks executed; `processed` property is `True` ```python import simpy env = simpy.Environment() # Create an event event = env.event() print(f'Triggered: {event.triggered}, Processed: {event.processed}') # Both False # Trigger the event event.succeed(value='Event result') print(f'Triggered: {event.triggered}, Processed: {event.processed}') # True, False # Run to process the event env.run() print(f'Triggered: {event.triggered}, Processed: {event.processed}') # True, True print(f'Value: {event.value}') # 'Event result' ``` ## Core Event Types ### Timeout Controls time progression in simulations. Most common event type. ```python import simpy def process(env): print(f'Starting at {env.now}') yield env.timeout(5) print(f'Resumed at {env.now}') # Timeout with value result = yield env.timeout(3, value='Done') print(f'Result: {result} at {env.now}') env = simpy.Environment() env.process(process(env)) env.run() ``` **Usage:** - `env.timeout(delay)` - Wait for specified time - `env.timeout(delay, value=val)` - Wait and return value ### Process Events Processes themselves are events, allowing processes to wait for other processes to complete. ```python import simpy def worker(env, name, duration): print(f'{name} starting at {env.now}') yield env.timeout(duration) print(f'{name} finished at {env.now}') return f'{name} result' def coordinator(env): # Start worker processes worker1 = env.process(worker(env, 'Worker 1', 5)) worker2 = env.process(worker(env, 'Worker 2', 3)) # Wait for worker1 to complete result = yield worker1 print(f'Coordinator received: {result}') # Wait for worker2 result = yield worker2 print(f'Coordinator received: {result}') env = simpy.Environment() env.process(coordinator(env)) env.run() ``` ### Event Generic event that can be manually triggered. ```python import simpy def waiter(env, event): print(f'Waiting for event at {env.now}') value = yield event print(f'Event received with value: {value} at {env.now}') def triggerer(env, event): yield env.timeout(5) print(f'Triggering event at {env.now}') event.succeed(value='Hello!') env = simpy.Environment() event = env.event() env.process(waiter(env, event)) env.process(triggerer(env, event)) env.run() ``` ## Composite Events ### AllOf - Wait for Multiple Events Triggers when all specified events have occurred. ```python import simpy def process(env): # Start multiple tasks task1 = env.timeout(3, value='Task 1 done') task2 = env.timeout(5, value='Task 2 done') task3 = env.timeout(4, value='Task 3 done') # Wait for all to complete results = yield simpy.AllOf(env, [task1, task2, task3]) print(f'All tasks completed at {env.now}') print(f'Results: {results}') # Alternative syntax using & operator task4 = env.timeout(2) task5 = env.timeout(3) yield task4 & task5 print(f'Tasks 4 and 5 completed at {env.now}') env = simpy.Environment() env.process(process(env)) env.run() ``` **Returns:** Dictionary mapping events to their values **Use cases:** - Parallel task completion - Barrier synchronization - Waiting for multiple resources ### AnyOf - Wait for Any Event Triggers when at least one specified event has occurred. ```python import simpy def process(env): # Start multiple tasks with different durations fast_task = env.timeout(2, value='Fast') slow_task = env.timeout(10, valu