A stateful async agent for ArtifactsMMO that lets you control characters using high-level logic instead of raw API calls.
- 📡 OpenAPI Spec: https://api.artifactsmmo.com/openapi.json
- Set up TOKEN as env. To get this visit https://www.artifactsmmo.com/my
export TOKEN=<your_token>- Go to the main.py and create your hero
hero = await Hero.create_hero("MyHero")
await hero.move(1, 4)
await hero.attack()- Check logs to observe behavior
2026-04-16 17:13:24,171 - INFO - [MyHero] - 🏃 Start move (0, 0) --> (1, 4)
2026-04-16 17:14:51,630 - INFO - [MyHero] - ⏳ Waiting cooldown: 40 sec
2026-04-16 17:15:13,717 - INFO - [MyHero] - ⚔️ Win | HP: 120→125 (+5)
The agent automatically handles cooldowns and keeps state in sync, so you can write high-level logic without worrying about timing or API details.
- 🧠 Stateful hero models (health, inventory, position, tasks)
- ⏳ Automatic cooldown handling (no manual sleeps)
- 🔄 Real-time state synchronization from API responses
- ⚡ Fully async - manage multiple heroes concurrently
- 🎯 Focus on behavior, not HTTP requests
- 📊 Action-level logging for better observability
The Hero class provides simple async methods to interact with the game API.
All methods are async, waiting cooldown and update the hero state automatically.
Core
hero.move(x: int, y: int)- move to the target positionhero.attack()- attack the current enemyhero.gather()- gather resources at current locationhero.craft(code: str, count: int = 1)- craft items by codehero.rest()- restore HP if not full (skips if already full)
Bank
hero.deposit_bank_item_all(exclude_code_set: set[str] | None)- deposit all items to the bank (can exclude specific item codes)hero.withdraw_bank_items(items: dict[str, int])- withdraw items from the bank
Tasks
hero.task_accept()- accept a new taskhero.task_trade(item_code: str, item_count: int)- trade items for task progresshero.task_trade_all()- trade all available items for the current taskhero.task_complete()- complete the current task if possible
# Create hero
hero = Hero.create_hero("MyHero")
# Move
await hero.move(0, 1)
# Fight
await hero.attack()
# Gather
await hero.gather()
# Craft
await hero.craft("iron_sword", count=2)
# Rest
await hero.rest()Using the basic actions above, you can build more complex automation flows. For example, a simple loop to complete monster-killing tasks:
# main.py
async def monsters_task_loop(hero: Hero):
task_type = "monsters"
# Accept task if none active
if not hero.task.code:
await hero.move(*get_task_master_location(task_type))
await hero.task_accept()
# Move to target
await hero.move(*get_kill_target_location(hero.task.code))
# Combat loop
while not hero.task.is_complete:
# take a rest if health is not full
if not hero.health.is_full:
await hero.rest()
# deposit all items if inventory is full
if hero.inventory.is_full:
await hero.move(*BANK_LOCATION)
await hero.deposit_bank_item_all()
await hero.move(*get_kill_target_location(hero.task.code))
await hero.attack()
# Return and complete task
await hero.move(*get_task_master_location(task_type))
await hero.task_complete()To start a hero, pass its name and a task function to run:
# main.py
def main():
run([
("HeroName1", monsters_task_loop),
])To run multiple heroes in one script. If one hero failed, another continue:
# main.py
def main():
run([
("HeroName1", monsters_task_loop),
("HeroName2", monsters_task_loop),
])python3 main.py....
2026-04-15 18:43:15,826 - INFO - [HeroName1] - ⚔️ Attacking... HP: 140/140
2026-04-15 18:43:16,933 - INFO - [HeroName1] - ⏳ Waiting cooldown: 54 sec
2026-04-15 18:44:10,987 - INFO - [HeroName1] - ⚔️ Win → HP: 140→88 (-52)
2026-04-15 18:44:10,988 - INFO - [HeroName1] - 🏃 Start move (0, 1) --> (1, 2)
2026-04-15 18:44:12,308 - INFO - [HeroName1] - ⏳ Waiting cooldown: 10 sec
2026-04-15 18:44:22,318 - INFO - [HeroName1] - 📜 Complete task chicken of type monsters
2026-04-15 18:44:23,636 - INFO - [HeroName1] - ⏳ Waiting cooldown: 3 sec
2026-04-15 18:44:26,640 - INFO - [HeroName1] - 📜 Completed task. Rewards: {'items': [{'code': 'tasks_coin', 'quantity': 3}], 'gold': 200}
Configuration is done via environment variables.
- Copy the example file:
cp .env.example .env- Fill in required values (e.g. TOKEN).
TOKEN=<your_token_from_artifactsmmo>
or set via bash
export TOKEN=<your_token_from_artifactsmmo>The application will not run without a valid TOKEN.
- Optional configuration:
TIMEOUT_CONNECT=5.0
TIMEOUT_READ=15.0
TIMEOUT_WRITE=5.0
TIMEOUT_POOL=5.0
RETRY_COUNT=3
RETRY_DELAY=1.0
BASE_URL=https://api.artifactsmmo.com
LOG_LEVEL=INFO
MIT License © 2026