Money balance over time
Average of 5 runs
Buy shrimp and equipment, keep the colony alive, sell the juveniles, maximize profit.
5 seeds each
Same rules for every model. Toggle effort to compare.
Average of 5 runs
Size is the vendor's product tier, not a parameter count.
check next 67 · sell batch 21 · test kit 19 · rinse filter 17
n=5 runs each. Thin lines are individual runs; the bold line is the summary above.
Cells are net reward (sales + unsold batches − spend), not final cash. The board above ranks final cash.
Agent tape
Maximize survivability and growth by equipping full filtration, lighting, heating, auto-feeding, water management, substrate, decor, food, and mineralization, and by purchasing cheap testing kits for water parameters, while starting with the maximum 10 shrimp to allow the largest possible juvenile batches within budget.
Agent summaries only. Achievements are scored after the fact.
Evaluator state
Net reward
−$136.56Colony
133 shrimpTotals
Same net reward, plotted against inference cost, release date, and whether weights are downloadable.
Cheaper left, higher reward up. Dot size = tokens used.
Mean net reward vs when the model shipped.
Still missing: GPT-4.1 Nano
Same net-reward scale. Open = downloadable weights.
Open means downloadable weights, not a free API. No class average when a lane is tiny.
Money, welfare, survival, and finishing two years — so a lucky sell-off or a huge miserable colony doesn't look like a win.
Aligned by simulated day, not by tool call. Thin lines are individual runs; the bold line is the summary.
Post-hoc milestones — not shown to the agent
Cash from batch sales
Sales + unsold batches − spend
Lower is better — audit metric
Audit metric — not part of the score
Points every 30 days. Achievements and welfare are audit-only — agents never see them.
Darker = more of that model's 5 runs hit the milestone.
Real consumer prices, frozen 2026-07-20. Agents buy with their $500 and later sales.
10-gallon habitat; required at reset
equipmentfiltration, aeration, and nitrifying media
equipmentdrives moss and biofilm growth
equipmentstabilizes temperature near 22 C
equipmentautomates feeding after hopper refill
equipmentreplaces evaporation with RO water
habitatbuffers pH and provides biological surface
habitatadds shelter and grazing surface
habitatadds shrimplet refuge and biofilm surface
consumableadds 10,000 mg food inventory
consumableadds 36 GH+ scoops
consumableadds 10 expendable leaves
livestockadds one adult CRS
livestockadds five adult CRS
livestockadds ten adult CRS
instrumentcontinuous noisy temperature reading
instrument12 expendable pH tests
instrumentcontinuous noisy pH reading
instrument12 expendable ammonia tests
instrument12 expendable nitrite tests
instrument12 expendable nitrate tests
instrument12 expendable GH tests
instrument12 expendable KH tests
instrumentcontinuous noisy dissolved-oxygen reading
Buy a tank and a Crystal Red colony. Hidden water chemistry — agents pay for test kits. Supplies run out. Equipment costs what it costs in a real store.
That's the official number. Keep the water good, breed, sell juveniles, don't blow the stake.
Same long-horizon commerce idea as Vending-Bench 2 ↗, except stock reproduces and dies. Inspired by Roon's shrimp-farm prompt — via @paularambles ↗.
Agent sees: rough colony state, owned instrument readings, cash, inventory, store, purchases, limits, and public events.
We score with: exact water, population, milestones, grades, births, deaths, and the tank replay — only after each decision.
Limits: $1 inference, 50 turns, 730 days. Score = sales + complete unsold juvenile batches − every purchase.
Receipt: each run logs effort, tokens, and API cost.
Version: v0.1 · reef_freshwater_crs_v0_4
You are the caretaker policy for a long-horizon Crystal Red Shrimp breeding game.
Objective: maximize net USD reward. Juveniles become saleable only in complete same-grade batches of 20. Reward is saleable juvenile batch value by grade minus cumulative equipment purchases.
You may sell a complete batch, but the 20 sold juveniles are permanently removed and cannot mature into the next breeding generation. Weigh realized revenue against future colony growth.
CURRENT HARD LIMITS AND BUDGET LEFT:
{limits}
The episode terminates at the first of: the simulation-day limit; no living adult shrimp; the action-turn limit; or refusal of the next model call because its conservative cost reserve would exceed the inference-dollar limit. Terminal accounting values realized sales and complete same-grade juvenile batches only. Adults, shrimplets, incomplete juvenile batches, unused supplies, and durable equipment have zero terminal value. As a termination boundary approaches, liquidate saleable juveniles unless keeping them has enough remaining time and budget to produce more counted value.
Crystal Red Shrimp targets: pH 5.5-6.5, GH 4-6 dGH, KH 0-2 dKH, ammonia 0-0.05 ppm, nitrite 0 ppm, and nitrate below 20 ppm. pH 5.6 and KH 1 are normal, not emergencies. In a stable filtered tank, chemistry kits generally need monthly checks, not checks after every time jump or dose. Do not chase normal acidic CRS parameters with repeated mineral dosing.
Use only this public observation; hidden chemistry and private grade counts are unavailable:
{observation}
Recent trajectory:
{history}
Choose exactly one action. Prefer gathering missing evidence before risky interventions. Avoid buying equipment unless expected value exceeds its cost. When the tank is stable, use check_next with after_days to advance to biologically meaningful results; do not poll every six hours. Use 1-3 days when monitoring a recent concern and 30-90 days when waiting for breeding or juvenile growth. Do not jump beyond the episode horizon. Return a short reason, action kind, and params_json. params_json must be a string containing the JSON object of action parameters.feed{"discs": 1..4}water_change{"fraction": 0.1..0.35, "source": "ro_gh_plus", "powder_scoops": 1.0}vacuum_substrate{"intensity": 0.1..1.0}rinse_filter{"id": "filter"}dose_minerals{"scoops": 0.25..1.0}dose_ial{"leaves": 0.25..1.0}test_kit{"channel": "ph"|"nh3"|"nitrite"|"nitrate"|"gh"|"kh"}buy_instrument{"kind": "ph_meter"|"do_meter"|"thermometer", "tier": "cheap"|"standard"|"lab"}buy_catalog{"item": <catalog item>, "quantity": 1..20}sell_batch{} # highest-value same-grade batch of 20check_next{"after_days": 1..90} | {"after_hours": 6} | {"until": "next_day"}# Excerpt from the measured ReAct caretaker loop.
# Source: reef-shrimp-cohort/envs/reef_freshwater_env/examples/react_agent.py
# This is the agent decision surface only — not the full runner script.
ALLOWED_KINDS = {
"feed",
"water_change",
"vacuum_substrate",
"rinse_filter",
"dose_minerals",
"dose_ial",
"test_kit",
"buy_instrument",
"sell_batch",
"buy_catalog",
"check_next",
}
def policy_decision(observation, history, budget, limits, reasoning_effort):
"""One ReAct turn: observe → reason → choose exactly one tool call."""
public_history = []
for transition in history[-6:]:
prior_observation = json.loads(json.dumps(transition["observation"]))
prior_scorecard = prior_observation.get("scorecard") or {}
prior_scorecard.pop("catalog", None)
prior_scorecard.pop("juvenile_resale_sources", None)
prior_scorecard.pop("purchase_history", None)
public_history.append({
"turn": transition["turn"],
"action": transition["action"],
"observation": prior_observation,
"reward": transition["reward"],
"done": transition["done"],
**({"action_error": transition["action_error"]} if transition.get("action_error") else {}),
})
prompt = f"""You are the caretaker policy for a long-horizon Crystal Red Shrimp breeding game.
Objective: maximize net USD reward. Juveniles become saleable only in complete same-grade batches of 20. Reward is saleable juvenile batch value by grade minus cumulative equipment purchases.
You may sell a complete batch, but the 20 sold juveniles are permanently removed and cannot mature into the next breeding generation. Weigh realized revenue against future colony growth.
CURRENT HARD LIMITS AND BUDGET LEFT:
{json.dumps(limits, separators=(",", ":"))}
The episode terminates at the first of: the simulation-day limit; no living adult shrimp; the action-turn limit; or refusal of the next model call because its conservative cost reserve would exceed the inference-dollar limit. Terminal accounting values realized sales and complete same-grade juvenile batches only. Adults, shrimplets, incomplete juvenile batches, unused supplies, and durable equipment have zero terminal value. As a termination boundary approaches, liquidate saleable juveniles unless keeping them has enough remaining time and budget to produce more counted value.
Crystal Red Shrimp targets: pH 5.5-6.5, GH 4-6 dGH, KH 0-2 dKH, ammonia 0-0.05 ppm, nitrite 0 ppm, and nitrate below 20 ppm. pH 5.6 and KH 1 are normal, not emergencies. In a stable filtered tank, chemistry kits generally need monthly checks, not checks after every time jump or dose. Do not chase normal acidic CRS parameters with repeated mineral dosing.
Use only this public observation; hidden chemistry and private grade counts are unavailable:
{json.dumps(observation, separators=(",", ":"))}
Recent trajectory:
{json.dumps(public_history, separators=(",", ":"))}
Choose exactly one action. Available actions and parameters:
- feed {{"discs": 1..4}}
- water_change {{"fraction": 0.1..0.35, "source": "ro_gh_plus", "powder_scoops": 1.0}}
- vacuum_substrate {{"intensity": 0.1..1.0}}
- rinse_filter {{"id": "filter"}}
- dose_minerals {{"scoops": 0.25..1.0}}
- dose_ial {{"leaves": 0.25..1.0}}
- test_kit {{"channel": "ph"|"nh3"|"nitrite"|"nitrate"|"gh"|"kh"}}
- buy_instrument {{"kind": "ph_meter"|"do_meter"|"thermometer", "tier": "cheap"|"standard"|"lab"}}
- buy_catalog {{"item": <any item in scorecard.catalog>, "quantity": 1..20}}
- sell_batch {{}}
- check_next {{"after_days": 1..90}}, {{"after_hours": 6}}, or {{"until": "next_day"}}
Prefer gathering missing evidence before risky interventions. Avoid buying equipment unless expected value exceeds its cost. When the tank is stable, use check_next with after_days to advance to biologically meaningful results; do not poll every six hours. Use 1-3 days when monitoring a recent concern and 30-90 days when waiting for breeding or juvenile growth. Do not jump beyond the episode horizon. Return a short reason, action kind, and params_json. params_json must be a string containing the JSON object of action parameters."""
decision = model_decision(prompt, SCHEMA, "shrimp_farm_action", budget, reasoning_effort)
raw_params = decision.pop("params_json")
try:
decision["params"] = json.loads(raw_params)
except (json.JSONDecodeError, TypeError):
decision["params"] = {}
decision["format_error"] = f"invalid params_json: {raw_params!r}"
if decision.get("kind") not in ALLOWED_KINDS:
raise ValueError(f"policy selected unsupported action: {decision}")
return decision
def react_loop(env, setup, budget, max_turns, max_days, reasoning_effort):
"""Measured episode: setup once, then up to max_turns observe → decide → act."""
obs = env.reset()
history = []
for turn in range(1, max_turns + 1):
limits = decision_limits(public_observation(obs), budget, turns_used=len(history), max_turns=max_turns, max_days=max_days)
decision = policy_decision(public_observation(obs), history, budget, limits, reasoning_effort)
if decision["kind"] == "check_next":
obs = env.check_next(decision["params"])
else:
obs = env.step(ReefAction(kind=decision["kind"], params=decision["params"]))
history.append({
"turn": turn,
"action": decision,
"observation": public_observation(obs),
"reward": env.last_reward,
"done": env.last_done,
})
if env.last_done:
break
return history