From 71e3772ee4ff41cae1b12c9de61b710d69c722aa Mon Sep 17 00:00:00 2001 From: JNK234 Date: Wed, 18 Mar 2026 15:15:35 -0500 Subject: [PATCH 1/5] feat: add config and template for baba-is-ai demo Ollama config with qwen2.5:7b defaults and YAML template documenting the prompt context for the llm:choose-based action selection. --- demos/baba-is-ai/action-template.yaml | 20 ++++++++++++++++++++ demos/baba-is-ai/config | 6 ++++++ 2 files changed, 26 insertions(+) create mode 100644 demos/baba-is-ai/action-template.yaml create mode 100644 demos/baba-is-ai/config diff --git a/demos/baba-is-ai/action-template.yaml b/demos/baba-is-ai/action-template.yaml new file mode 100644 index 0000000..ed40e18 --- /dev/null +++ b/demos/baba-is-ai/action-template.yaml @@ -0,0 +1,20 @@ +system: | + You are playing Baba Is AI, a puzzle game where the rules of the world are + physical word-block objects on a grid. Three consecutive word-blocks in a row + or column form a rule: [NOUN] IS [PROPERTY]. For example, "BABA IS YOU" means + you control the baba character, "WALL IS STOP" means walls block movement, + and "FLAG IS WIN" means reaching a flag wins the level. + + CRITICAL INSIGHT: You can PUSH word-blocks to change or break rules. If you + push the STOP block away from "WALL IS STOP", walls become passable. Rules + are not fixed -- they are objects you can physically manipulate. + + Your goal: reach an entity that has the WIN property. + + Respond with exactly one of: up, down, left, right + +template: | + {observation} + + Think about which rules you need to change to reach the goal. + Choose your move. diff --git a/demos/baba-is-ai/config b/demos/baba-is-ai/config new file mode 100644 index 0000000..4fcd404 --- /dev/null +++ b/demos/baba-is-ai/config @@ -0,0 +1,6 @@ +provider=ollama +model=qwen2.5:7b +base_url=http://localhost:11434 +temperature=0.3 +max_tokens=100 +timeout_seconds=45 From 1d37d80d69c0e169a720f4f330d3cbfbe197d093 Mon Sep 17 00:00:00 2001 From: JNK234 Date: Wed, 18 Mar 2026 15:15:43 -0500 Subject: [PATCH 2/5] feat: add baba-is-ai model with rule engine, push system, and LLM integration Complete Baba Is You puzzle demo with 3 levels of increasing difficulty: - Level 1: Navigate (baseline path-finding) - Level 2: Break the Wall (push STOP word-block to disable wall rule) - Level 3: Push and Rearrange (rocks + walls + spatial reasoning) Includes ABM rule engine that scans horizontal/vertical word-block 3-tuples, recursive push chain system, text observation builder for LLM, and win/defeat detection. Uses llm:choose for constrained action selection with accumulating history. --- demos/baba-is-ai/baba-is-ai.nlogox | 740 +++++++++++++++++++++++++++++ 1 file changed, 740 insertions(+) create mode 100644 demos/baba-is-ai/baba-is-ai.nlogox diff --git a/demos/baba-is-ai/baba-is-ai.nlogox b/demos/baba-is-ai/baba-is-ai.nlogox new file mode 100644 index 0000000..a97c0b4 --- /dev/null +++ b/demos/baba-is-ai/baba-is-ai.nlogox @@ -0,0 +1,740 @@ + + + = 0] [ + let p item chain-idx chain-patches + let pushables-here get-pushables-on p + ask pushables-here [ + setxy (xcor + move-dx) (ycor + move-dy) + ] + set chain-idx chain-idx - 1 + ] + + report true +end + +;; ============================================================ +;; LLM INTEGRATION +;; ============================================================ + +to go + if game-state != "playing" [ stop ] + if not llm-config-loaded? [ + output-print "LLM config not loaded. Check config file." + set game-state "error" + stop + ] + + ask babas [ + if has-property? "BABA" "YOU" [ + let obs build-observation + if show-observations? [ output-print obs ] + + set total-llm-calls total-llm-calls + 1 + carefully [ + let action llm:choose obs ["up" "down" "left" "right"] + set last-action action + set total-moves total-moves + 1 + set move-history lput action move-history + try-move action + ] [ + output-print (word "LLM error: " error-message) + ] + ] + ] + + evaluate-rules + check-win-defeat + tick +end + +to step + go +end + +;; ============================================================ +;; OBSERVATION BUILDER +;; ============================================================ + +to-report build-observation + let obs "" + let baba-x [xcor] of one-of babas + let baba-y [ycor] of one-of babas + + set obs (word obs "You are BABA at position (" baba-x ", " baba-y ").\n") + set obs (word obs "Goal: Reach the FLAG to win. You can push word-blocks to change rules.\n\n") + + ;; Active rules + set obs (word obs "Active Rules:\n") + foreach active-rules [ r -> + set obs (word obs "- " r "\n") + ] + set obs (word obs "\n") + + ;; Grid + set obs (word obs "Grid (9x9, @=you, W=wall, F=flag, R=rock, [WORD]=word-block):\n") + let grid-y max-pycor + while [grid-y >= min-pycor] [ + let row "" + let grid-x min-pxcor + while [grid-x <= max-pxcor] [ + let p patch grid-x grid-y + let cell " . " + ;; Check what's on this patch (priority: baba > word-block > wall > rock > flag) + if any? (flags-on p) [ set cell " F " ] + if any? (rocks-on p) [ set cell " R " ] + if any? (walls-on p) [ set cell " W " ] + if any? (word-blocks-on p) [ + let wb one-of (word-blocks-on p) + let txt [word-text] of wb + ;; Pad to 4 chars for alignment + if length txt < 4 [ set txt (word txt " ") ] + set cell (word "[" txt "]") + ] + if any? (babas-on p) [ set cell " @ " ] + set row (word row cell) + set grid-x grid-x + 1 + ] + set obs (word obs row "\n") + set grid-y grid-y - 1 + ] + set obs (word obs "\n") + + ;; Adjacent info + set obs (word obs "Adjacent:\n") + set obs (word obs " up: " (describe-adjacent baba-x (baba-y + 1)) "\n") + set obs (word obs " down: " (describe-adjacent baba-x (baba-y - 1)) "\n") + set obs (word obs " left: " (describe-adjacent (baba-x - 1) baba-y) "\n") + set obs (word obs " right: " (describe-adjacent (baba-x + 1) baba-y) "\n") + set obs (word obs "\n") + + ;; Last action feedback + if [last-action] of one-of babas != "" [ + let b one-of babas + let result ifelse-value [last-action-succeeded?] of b [ "succeeded" ] [ "FAILED - blocked" ] + set obs (word obs "Last action: " [last-action] of b " (" result ")\n\n") + ] + + set obs (word obs "Choose your move: up, down, left, or right.") + report obs +end + +to-report describe-adjacent [ adj-x adj-y ] + let p patch adj-x adj-y + if p = nobody [ report "boundary (impassable)" ] + + let descriptions [] + + if any? (babas-on p) [ set descriptions lput "you" descriptions ] + if any? (word-blocks-on p) [ + let wb one-of (word-blocks-on p) + set descriptions lput (word "word-block [" [word-text] of wb "] (pushable)") descriptions + ] + if any? (walls-on p) [ + ifelse has-property? "WALL" "STOP" + [ set descriptions lput "wall (blocking)" descriptions ] + [ set descriptions lput "wall (passable)" descriptions ] + ] + if any? (rocks-on p) [ + ifelse has-property? "ROCK" "PUSH" + [ set descriptions lput "rock (pushable)" descriptions ] + [ set descriptions lput "rock" descriptions ] + ] + if any? (flags-on p) [ + ifelse has-property? "FLAG" "WIN" + [ set descriptions lput "flag (WIN!)" descriptions ] + [ set descriptions lput "flag" descriptions ] + ] + + ifelse empty? descriptions + [ report "empty" ] + [ report reduce [ [a b] -> (word a ", " b) ] descriptions ] +end + +;; ============================================================ +;; WIN/DEFEAT CHECK +;; ============================================================ + +to check-win-defeat + ;; Check if BABA IS YOU rule is broken + if not has-property? "BABA" "YOU" [ + set game-state "lost - BABA IS YOU rule broken" + output-print "DEFEAT: The BABA IS YOU rule was broken!" + stop + ] + + ;; Check if baba is on a flag with WIN property + ask babas [ + if any? (flags-on patch-here) and has-property? "FLAG" "WIN" [ + set game-state "won" + output-print (word "VICTORY! Solved in " total-moves " moves and " total-llm-calls " LLM calls.") + ] + ] + + ;; Check move limit + if total-moves >= max-moves and game-state = "playing" [ + set game-state "out of moves" + output-print (word "OUT OF MOVES after " total-moves " moves.") + ] +end + +;; ============================================================ +;; REPORTERS FOR MONITORS +;; ============================================================ + +to-report level-report + report (word "Level " (substring level-choice 0 1)) +end + +to-report moves-report + report total-moves +end + +to-report llm-calls-report + report total-llm-calls +end + +to-report status-report + report game-state +end + +to-report rules-report + ifelse empty? active-rules + [ report "none" ] + [ report reduce [ [a b] -> (word a ", " b) ] active-rules ] +end + ]]> + + + + + + + + + + + + + level-report + moves-report + llm-calls-report + status-report + rules-report + + + + + + plot total-moves + + + + + + + + plot total-llm-calls + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From e9784703a2dda8d4ca14cb863beee4ac825fcdea Mon Sep 17 00:00:00 2001 From: JNK234 Date: Wed, 18 Mar 2026 15:15:48 -0500 Subject: [PATCH 3/5] docs: add README for baba-is-ai demo Covers the BALROG knowing-doing gap experiment context, setup prerequisites, 3 level descriptions with expected results, provider swapping instructions, and extension points. --- demos/baba-is-ai/README.md | 125 +++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 demos/baba-is-ai/README.md diff --git a/demos/baba-is-ai/README.md b/demos/baba-is-ai/README.md new file mode 100644 index 0000000..6f43ff4 --- /dev/null +++ b/demos/baba-is-ai/README.md @@ -0,0 +1,125 @@ +# Baba Is AI + +An LLM agent plays a simplified "Baba Is You" puzzle game where the rules of the world are physical word-block objects on a grid. The agent must push word-blocks to change or break rules in order to reach the goal. + +## The Experiment + +### Background + +Based on findings from the [BALROG benchmark](https://arxiv.org/abs/2411.13543) (Benchmarking Agentic LLM and VLM Reasoning On Games), which found that **all tested LLMs score near 0% on Baba Is You** despite understanding the rules perfectly when quizzed in isolation. + +### The Knowing-Doing Gap + +LLMs can explain that "rules are pushable objects" and "you need to rearrange word-blocks to change rules." But when given a spatial grid and asked to actually execute moves to push specific blocks in specific directions, they fail consistently. They *know* what to do but *cannot do* it. + +### What This Demo Tests + +Can an LLM agent, given a text observation of a 9x9 grid, figure out that it needs to: +1. Navigate to the right word-block +2. Push it in the right direction +3. Verify the rule changed +4. Navigate through the now-passable area to win + +This is **meta-rule discovery** -- the agent doesn't just follow rules, it manipulates them. + +### Why It Matters for ABM + +Agent-based models traditionally have fixed rules. This demo shows agents operating in a world where **the rules themselves are agents** (word-blocks) that can be moved. The rule engine is pure NetLogo ABM; the decision-making is LLM. Together they create a system where rules are emergent from the spatial arrangement of objects. + +## Prerequisites + +1. **Ollama** running locally with `qwen2.5:7b` pulled: + ```bash + ollama pull qwen2.5:7b + ``` +2. **NetLogo 7.0.3** with the LLM extension JAR installed +3. Built extension: run `./build.sh` from the extension root if needed + +## How to Run + +1. Open `baba-is-ai.nlogox` in NetLogo 7.0.3 +2. Select a level from the chooser +3. Click **Setup** to initialize +4. Click **Go** to let the LLM agent play autonomously, or **Step** for one move at a time +5. Toggle **show-observations?** to see the text observation sent to the LLM each turn +6. Watch the **Active Rules** monitor update as word-blocks are pushed + +## Levels + +### Level 1: Navigate (baseline) +``` +Rules: BABA IS YOU, FLAG IS WIN +Layout: baba on the left, flag on the right, clear path +Solution: Walk right to the flag (~7 moves) +Expected: Most LLMs solve this consistently +``` + +### Level 2: Break the Wall (medium) +``` +Rules: BABA IS YOU, WALL IS STOP, FLAG IS WIN +Layout: Wall column blocking the path to the flag +Solution: Navigate to the STOP word-block, push it away to break + "WALL IS STOP", then walk through walls to the flag +Expected: Some LLMs occasionally solve this; most get stuck +``` + +### Level 3: Push and Rearrange (hard) +``` +Rules: BABA IS YOU, ROCK IS PUSH, WALL IS STOP, FLAG IS WIN +Layout: Rocks near the WALL IS STOP rule, wall column, flag behind walls +Solution: Navigate around rocks, push STOP away, walk through walls +Expected: Very rarely solved -- demonstrates the knowing-doing gap +``` + +## Swapping Providers + +Edit `config` to try different LLM providers: + +``` +# OpenAI +provider=openai +model=gpt-4o-mini +api_key=YOUR_KEY_HERE + +# Anthropic +provider=anthropic +model=claude-sonnet-4-20250514 +api_key=YOUR_KEY_HERE + +# Gemini +provider=gemini +model=gemini-2.0-flash +api_key=YOUR_KEY_HERE +``` + +## Files + +| File | Purpose | +|------|---------| +| `baba-is-ai.nlogox` | Main NetLogo model with rule engine, levels, and LLM integration | +| `config` | LLM provider configuration (defaults to local Ollama) | +| `action-template.yaml` | Documents the prompt format (not used at runtime -- `llm:choose` builds its own prompt) | +| `README.md` | This file | + +## How It Works + +### Rule Engine +Three consecutive word-blocks in a horizontal or vertical line form a rule: `[NOUN] IS [PROPERTY]`. The engine scans all possible 3-tuples every tick and rebuilds the active rule set. + +### Push System +Word-blocks are **always pushable**. Other entities (rocks, walls) are pushable only if they have the PUSH property. Push chains propagate: pushing a block into another pushable block pushes both. + +### LLM Integration +Each tick, the agent receives a text observation including the grid layout, active rules, adjacent cell descriptions, and feedback from the last action. It chooses from `["up", "down", "left", "right"]` via `llm:choose`. History accumulates across ticks so the agent can learn from failed moves. + +## Extension Points + +- **New properties**: Add DEFEAT (touching kills baba), SINK (object + baba both destroyed), MELT/HOT combos +- **Multiple YOU entities**: What if two things are YOU and must coordinate? +- **Procedural level generation**: Random placement of word-blocks and obstacles +- **Rule construction**: Levels where the agent must *build* a rule, not just break one + +## Reference + +- BALROG paper: [arXiv 2411.13543](https://arxiv.org/abs/2411.13543) +- Baba Is You (original game): [hempuli.com/baba](https://hempuli.com/baba/) From 436feb4167f80a3e258998b794d81de731af2ce8 Mon Sep 17 00:00:00 2001 From: JNK234 Date: Wed, 18 Mar 2026 16:08:37 -0500 Subject: [PATCH 4/5] fix: inject game context, persist history, and safe-place permanent rules - Add llm:set-history system message in setup so the LLM knows game mechanics (push word-blocks, break rules, reach the flag) - Remove llm:clear-history from go loop so the agent remembers past moves and learns from failures - Move BABA IS YOU and FLAG IS WIN to row 8 (top edge) across all levels so the agent never accidentally pushes permanent rules - Improve observation builder with directional hints, fixed-width grid map, loop detection, and explicit blocked-move feedback --- demos/baba-is-ai/baba-is-ai.nlogox | 201 ++++++++++++++++++----------- 1 file changed, 128 insertions(+), 73 deletions(-) diff --git a/demos/baba-is-ai/baba-is-ai.nlogox b/demos/baba-is-ai/baba-is-ai.nlogox index a97c0b4..040b2a9 100644 --- a/demos/baba-is-ai/baba-is-ai.nlogox +++ b/demos/baba-is-ai/baba-is-ai.nlogox @@ -37,7 +37,7 @@ to setup set move-history [] carefully [ - llm:load-config "demos/baba-is-ai/config" + llm:load-config "config" set llm-config-loaded? true ] [ output-print (word "Config error: " error-message) @@ -53,6 +53,21 @@ to setup if level-num = 2 [ setup-level-2 ] if level-num = 3 [ setup-level-3 ] + ;; Inject game-aware system message so the LLM knows what it's playing + ask babas [ + llm:set-history (list + (list "system" (word + "You are playing Baba Is AI, a puzzle game on a 9x9 grid. " + "You move one square per turn: up, down, left, or right. " + "Word-blocks form rules when 3 align: [NOUN] IS [PROPERTY]. " + "WALL IS STOP means walls block you. FLAG IS WIN means reaching the flag wins. " + "You can PUSH word-blocks by walking into them to break rules. " + "If walls block your path, push the STOP word-block away to break WALL IS STOP. " + "Always move toward the FLAG. If blocked, push word-blocks to change the rules." + )) + ) + ] + evaluate-rules reset-ticks end @@ -64,13 +79,14 @@ end to setup-level-1 ;; Level 1: Navigate — walk right to the flag ;; Word-blocks: BABA IS YOU (top), FLAG IS WIN (bottom) - create-word-block-at 1 7 "BABA" "noun" - create-word-block-at 2 7 "IS" "verb" - create-word-block-at 3 7 "YOU" "property" + ;; Rules at top row — safe from accidental pushing + create-word-block-at 0 8 "BABA" "noun" + create-word-block-at 1 8 "IS" "verb" + create-word-block-at 2 8 "YOU" "property" - create-word-block-at 5 1 "FLAG" "noun" - create-word-block-at 6 1 "IS" "verb" - create-word-block-at 7 1 "WIN" "property" + create-word-block-at 6 8 "FLAG" "noun" + create-word-block-at 7 8 "IS" "verb" + create-word-block-at 8 8 "WIN" "property" create-babas 1 [ setxy 1 4 @@ -91,18 +107,20 @@ end to setup-level-2 ;; Level 2: Break the Wall — push STOP away to pass through walls - create-word-block-at 1 8 "BABA" "noun" - create-word-block-at 2 8 "IS" "verb" - create-word-block-at 3 8 "YOU" "property" + ;; Rules at top — safe from accidental pushing + create-word-block-at 0 8 "BABA" "noun" + create-word-block-at 1 8 "IS" "verb" + create-word-block-at 2 8 "YOU" "property" + create-word-block-at 6 8 "FLAG" "noun" + create-word-block-at 7 8 "IS" "verb" + create-word-block-at 8 8 "WIN" "property" + + ;; WALL IS STOP — the rule to break. STOP is at (3,4), pushable right create-word-block-at 1 4 "WALL" "noun" create-word-block-at 2 4 "IS" "verb" create-word-block-at 3 4 "STOP" "property" - create-word-block-at 5 0 "FLAG" "noun" - create-word-block-at 6 0 "IS" "verb" - create-word-block-at 7 0 "WIN" "property" - create-babas 1 [ setxy 1 6 set shape "person" @@ -146,9 +164,9 @@ to setup-level-3 create-word-block-at 1 2 "IS" "verb" create-word-block-at 2 2 "STOP" "property" - create-word-block-at 6 0 "FLAG" "noun" - create-word-block-at 7 0 "IS" "verb" - create-word-block-at 8 0 "WIN" "property" + create-word-block-at 6 8 "FLAG" "noun" + create-word-block-at 7 8 "IS" "verb" + create-word-block-at 8 8 "WIN" "property" create-babas 1 [ setxy 0 7 @@ -419,37 +437,74 @@ to-report build-observation let baba-x [xcor] of one-of babas let baba-y [ycor] of one-of babas - set obs (word obs "You are BABA at position (" baba-x ", " baba-y ").\n") - set obs (word obs "Goal: Reach the FLAG to win. You can push word-blocks to change rules.\n\n") + ;; Find flag position + let flag-x -1 + let flag-y -1 + if any? flags [ + set flag-x [xcor] of one-of flags + set flag-y [ycor] of one-of flags + ] + + ;; Game context + set obs (word obs "BABA IS AI PUZZLE GAME\n") + set obs (word obs "You control BABA. Move up/down/left/right on a 9x9 grid.\n") + set obs (word obs "Word-blocks like [BABA] [IS] [YOU] form rules when aligned.\n") + set obs (word obs "You can push word-blocks by walking into them.\n\n") + + ;; Position and goal with explicit direction + set obs (word obs "Your position: (" baba-x ", " baba-y ")\n") + if flag-x >= 0 [ + set obs (word obs "FLAG position: (" flag-x ", " flag-y ")\n") + ;; Explicit directional hint + let dir-hint "" + if flag-x > baba-x [ set dir-hint (word dir-hint "right") ] + if flag-x < baba-x [ set dir-hint (word dir-hint "left") ] + if flag-y > baba-y [ + if dir-hint != "" [ set dir-hint (word dir-hint " and ") ] + set dir-hint (word dir-hint "up") + ] + if flag-y < baba-y [ + if dir-hint != "" [ set dir-hint (word dir-hint " and ") ] + set dir-hint (word dir-hint "down") + ] + if dir-hint != "" [ + set obs (word obs "FLAG is " dir-hint " from you.\n") + ] + ] + set obs (word obs "\n") ;; Active rules set obs (word obs "Active Rules:\n") foreach active-rules [ r -> set obs (word obs "- " r "\n") ] + if has-property? "WALL" "STOP" [ + set obs (word obs "(Walls block movement. Push the STOP word-block away to break this rule.)\n") + ] set obs (word obs "\n") - ;; Grid - set obs (word obs "Grid (9x9, @=you, W=wall, F=flag, R=rock, [WORD]=word-block):\n") + ;; Grid map — fixed-width for readability + set obs (word obs "Map (row 8=top, row 0=bottom, col 0=left, col 8=right):\n") + set obs (word obs " 0 1 2 3 4 5 6 7 8\n") let grid-y max-pycor while [grid-y >= min-pycor] [ - let row "" + let row (word grid-y " ") + if grid-y < 10 [ set row (word " " row) ] let grid-x min-pxcor while [grid-x <= max-pxcor] [ let p patch grid-x grid-y - let cell " . " - ;; Check what's on this patch (priority: baba > word-block > wall > rock > flag) - if any? (flags-on p) [ set cell " F " ] - if any? (rocks-on p) [ set cell " R " ] - if any? (walls-on p) [ set cell " W " ] + let cell " . " + if any? (flags-on p) [ set cell " F " ] + if any? (rocks-on p) [ set cell " R " ] + if any? (walls-on p) [ set cell " W " ] if any? (word-blocks-on p) [ let wb one-of (word-blocks-on p) let txt [word-text] of wb - ;; Pad to 4 chars for alignment - if length txt < 4 [ set txt (word txt " ") ] - set cell (word "[" txt "]") + ;; Pad/trim to 4 chars + while [length txt < 4] [ set txt (word txt " ") ] + set cell (word "[" substring txt 0 4 "]") ] - if any? (babas-on p) [ set cell " @ " ] + if any? (babas-on p) [ set cell " YOU " ] set row (word row cell) set grid-x grid-x + 1 ] @@ -459,21 +514,40 @@ to-report build-observation set obs (word obs "\n") ;; Adjacent info - set obs (word obs "Adjacent:\n") + set obs (word obs "What is next to you:\n") set obs (word obs " up: " (describe-adjacent baba-x (baba-y + 1)) "\n") set obs (word obs " down: " (describe-adjacent baba-x (baba-y - 1)) "\n") set obs (word obs " left: " (describe-adjacent (baba-x - 1) baba-y) "\n") set obs (word obs " right: " (describe-adjacent (baba-x + 1) baba-y) "\n") set obs (word obs "\n") + ;; Recent move history — helps prevent looping + if not empty? move-history [ + let recent-count min (list 5 (length move-history)) + let recent sublist move-history (length move-history - recent-count) (length move-history) + set obs (word obs "Your last " recent-count " moves: " reduce [ [a b] -> (word a ", " b) ] recent "\n") + ;; Detect looping + if recent-count >= 4 [ + let unique-moves remove-duplicates recent + if length unique-moves <= 2 [ + set obs (word obs "WARNING: You are stuck in a loop! Try a completely different direction.\n") + ] + ] + set obs (word obs "\n") + ] + ;; Last action feedback if [last-action] of one-of babas != "" [ let b one-of babas let result ifelse-value [last-action-succeeded?] of b [ "succeeded" ] [ "FAILED - blocked" ] - set obs (word obs "Last action: " [last-action] of b " (" result ")\n\n") + set obs (word obs "Last action: " [last-action] of b " (" result ")\n") + if not [last-action-succeeded?] of b [ + set obs (word obs "That direction is blocked. Try a different direction.\n") + ] + set obs (word obs "\n") ] - set obs (word obs "Choose your move: up, down, left, or right.") + set obs (word obs "Which direction should you move?") report obs end @@ -563,61 +637,41 @@ to-report rules-report end ]]> - - - - - + + + + + - - - level-report - moves-report - llm-calls-report - status-report - rules-report - + + + level-report + moves-report + llm-calls-report + status-report + rules-report + - + plot total-moves - + - + plot total-llm-calls - + - ## Baba Is AI ### What Is It? @@ -657,7 +711,7 @@ A simplified recreation of "Baba Is You" where an LLM agent must solve puzzles b - Edit `config` to try different LLM providers (OpenAI, Claude, Gemini) - Add new word types (DEFEAT, SINK) for more complex puzzles - Create levels where the agent must *construct* rules, not just break them - ]]> + @@ -737,4 +791,5 @@ A simplified recreation of "Baba Is You" where an LLM agent must solve puzzles b + setup repeat 75 [ go ] From 9dd2168a6acae28a368fcc9c4bed79a4367b3581 Mon Sep 17 00:00:00 2001 From: JNK234 Date: Thu, 19 Mar 2026 10:32:28 -0500 Subject: [PATCH 5/5] fix: improve system prompt, seal wall gaps, add rate limit handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rewrite system prompt with explicit push mechanics and priority (break STOP first, then head to flag) - Observation now shows exact STOP block coordinates when WALL IS STOP is active - Extend wall columns to y=0-7 in levels 2 and 3 so agent cannot navigate around walls — must break the rule - Cap history to system msg + last 10 exchanges to avoid token bloat - Handle rate limit errors with 2s wait and retry on next tick --- demos/baba-is-ai/baba-is-ai.nlogox | 50 ++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/demos/baba-is-ai/baba-is-ai.nlogox b/demos/baba-is-ai/baba-is-ai.nlogox index 040b2a9..f368501 100644 --- a/demos/baba-is-ai/baba-is-ai.nlogox +++ b/demos/baba-is-ai/baba-is-ai.nlogox @@ -57,13 +57,16 @@ to setup ask babas [ llm:set-history (list (list "system" (word - "You are playing Baba Is AI, a puzzle game on a 9x9 grid. " + "You are playing Baba Is AI, a puzzle game on a 9x9 grid (0-8). " "You move one square per turn: up, down, left, or right. " - "Word-blocks form rules when 3 align: [NOUN] IS [PROPERTY]. " - "WALL IS STOP means walls block you. FLAG IS WIN means reaching the flag wins. " - "You can PUSH word-blocks by walking into them to break rules. " - "If walls block your path, push the STOP word-block away to break WALL IS STOP. " - "Always move toward the FLAG. If blocked, push word-blocks to change the rules." + "Word-blocks on the grid form rules when 3 align horizontally: [NOUN] IS [PROPERTY]. " + "Example: WALL IS STOP means walls block movement. FLAG IS WIN means touching the flag wins. " + "PUSHING: When you walk into a word-block, it slides one square in your direction. " + "If you push a word-block out of a 3-block alignment, that rule BREAKS. " + "STRATEGY: If walls block your path to the flag, find the [STOP] word-block on the grid. " + "Walk to it and push it away from [WALL] and [IS] — this breaks WALL IS STOP and walls become passable. " + "Then walk through the walls to reach the flag. " + "PRIORITY: 1) If blocked by walls, go break the STOP block first. 2) Then head to the flag." )) ) ] @@ -130,9 +133,9 @@ to setup-level-2 set last-action-succeeded? true ] - ;; Wall column at x=5 - let wall-y 2 - while [wall-y <= 6] [ + ;; Wall column at x=5, floor to row 7 — no way around + let wall-y 0 + while [wall-y <= 7] [ create-walls 1 [ setxy 5 wall-y set shape "square" @@ -181,8 +184,8 @@ to setup-level-3 create-rocks 1 [ setxy 3 3 set shape "circle" set color orange set size 0.9 ] create-rocks 1 [ setxy 3 2 set shape "circle" set color orange set size 0.9 ] - ;; Wall column at x=5 - let wall-y 1 + ;; Wall column at x=5, floor to row 7 — no way around + let wall-y 0 while [wall-y <= 7] [ create-walls 1 [ setxy 5 wall-y @@ -403,6 +406,12 @@ to go ask babas [ if has-property? "BABA" "YOU" [ + ;; Cap history to system message + last 10 exchanges to avoid token bloat + let hist llm:history + if length hist > 21 [ + llm:set-history (sentence (list item 0 hist) (sublist hist (length hist - 20) (length hist))) + ] + let obs build-observation if show-observations? [ output-print obs ] @@ -414,6 +423,12 @@ to go set move-history lput action move-history try-move action ] [ + ;; Rate limit: wait and retry next tick + if member? "rate_limit" error-message [ + output-print "Rate limited — waiting 2s..." + wait 2 + stop + ] output-print (word "LLM error: " error-message) ] ] @@ -479,7 +494,16 @@ to-report build-observation set obs (word obs "- " r "\n") ] if has-property? "WALL" "STOP" [ - set obs (word obs "(Walls block movement. Push the STOP word-block away to break this rule.)\n") + ;; Find the STOP block and tell the agent exactly where it is + let stop-block one-of word-blocks with [word-text = "STOP"] + ifelse stop-block != nobody [ + let sx [xcor] of stop-block + let sy [ycor] of stop-block + set obs (word obs "!! WALLS BLOCK YOU. The [STOP] block is at (" sx ", " sy "). " + "Go to it and push it away to break WALL IS STOP, then walls become passable.\n") + ] [ + set obs (word obs "(Walls block movement. Push the STOP word-block away to break this rule.)\n") + ] ] set obs (word obs "\n") @@ -669,7 +693,7 @@ end plot total-llm-calls - + ## Baba Is AI