A Playdate with Agents
1. Introduction
It’s no longer just hype: coding agents are everywhere.
I’ve been using Claude Code heavily at work. My current company runs on Spring Boot with Kotlin, while my previous one used Go. I understand our business logic well and the kinds of problems we solve every day, but I wouldn’t claim deep mastery of Spring’s internals or the most idiomatic Kotlin patterns.
Not long ago, that kind of deep framework knowledge and language fluency was one of the core virtues of a “great programmer,” at least to me. Knowing the framework’s dark corners, writing code in the most natural, expressive way for the language—that was something to aim for.
Now the agent does it better.
If someone had told me this three months ago, I would’ve laughed. Two months ago, I was using a coding agent maybe half the time, mostly to explore unfamiliar parts of the codebase. Today, I let it handle well over 90% of the implementation. My job has quietly shifted: I design the architecture, define constraints, and then spend most of my time reviewing for mistakes, edge cases, missing assumptions, and the occasional hallucination.
After finishing the main stories of all eight characters in Octopath Traveler II, I found myself wanting to understand this shift more deeply. So the second half of my year-end break became something of a personal experiment. I wasn’t trying to build anything revolutionary. I just wanted to watch myself work with these agents, carefully, and see what actually changes when you stop writing most of the code by hand.
This is that story.
2. Motivation
Into the Breach was one of the games that impressed me the most last year. I didn’t invest a huge amount of time into it, but its short-session, puzzle-like strategy design stayed with me. Around that time, I was also watching some Udemy courses on the Godot engine and had this simple goal: build a basic level editor for an isometric 2D tile map.
Then life happened. A new job, endless onboarding, too many things to run at once. The idea quietly went back on the shelf.
Fast forward to now. I started wondering what today’s coding agents could do with that same idea. Coincidentally, I had just subscribed to Google AI Ultra (mostly because of the recent hype of Gemini 3, and for the fun of NanoBanana), and right around the year-end, “opencode” suddenly started getting a lot of attention. It felt like the perfect moment to turn that old idea into a small personal experiment.
So I did.
3. Setup
Basically, I framed this as a head-to-head match: Antigravity vs. opencode.
I created two fresh Godot 4.5 projects manually. One was driven by Antigravity, the other by opencode.
3.1 Antigravity setup
For the Antigravity setup, I opened the project folder inside Antigravity and worked through its Agent window. I used Gemini 3 Pro (High) as the main model. At the same time, I also opened the same project in the Godot editor. So the development loop happened across two tools: the Godot editor and Antigravity.
3.2 Opencode setup
For the opencode setup, I again opened the project in the Godot editor, and I ran opencode from my terminal (iTerm2) inside the project directory. On top of opencode, I used oh-my-opencode, which is an opencode plugin. I think of it as an agent orchestration layer. It defines multiple cooperating agents, each with a clear role:
- Sisyphus: the main coordinator that drives the overall workflow and delegates tasks (recommended model: Opus 4.5 High)
- Oracle: design and debugging (recommended model: GPT 5.2 Medium)
- Librarian: documentation lookup, open-source references, and codebase exploration (recommended model: Claude Sonnet 4.5)
- Explorer: fast scanning and structural understanding of the codebase (recommended model: Grok Code)
The word “recommended (from the author)” is doing a lot of work here. Choosing the right models for each agent turned out to be one of the messiest parts of the setup.
Opencode offers its own Zen subscription with usage-based billing, which is one option. You can also connect external providers through OAuth or API tokens. In theory, that means using Anthropic’s Opus 4.5 and other top-tier models directly with their subscription plans. In practice, Anthropic has started blocking usage of their models outside of Claude Code when accessed via their subscription plans such as Claude Pro or Claude Max (usage via API tokens still works), and that restriction is written into their terms. I confirmed that the blocking is real.
Opencode does provide some free models, and GLM 4.7 is actually quite interesting. But the quid pro quo is that your data is sent to them, which I was comfortable with this experiment but I wanted to stay close to the recommended setup.
This is where Antigravity quietly became very useful. Antigravity doesn’t only provide Google’s Gemini models; it also gives access to Anthropic’s Opus and Sonnet. My assumption is that they have a direct commercial agreement, because the models are usable, although sometimes requests pause for about ten seconds, likely due to rate limits. Because opencode is open source (MIT license), there are many community plugins. One of them, opencode-antigravity-auth, lets opencode reuse Antigravity’s model access via the Google login. And that might also object to Antigravity’s ToS, but I thought Google might be more generous on it and they haven’t prohibited yet.
For OpenAI models like GPT 5.2, I used my ChatGPT Pro subscription. OpenAI explicitly allows this usage.
With that combination, I managed to assemble almost the exact recommended multi-agent environment. The only exception was Librarian, where I ended up using Gemini 3 Pro instead of Grok, which I don’t have any access to it.
At that point, the match was ready to begin.
4. The Prompt
I focused on designing and implementing a simple isometric 2D level editor. I used the same prompt for both experiments:
I want to develop an SRPG game similar to Into the Breach. I don’t have any specific game system design or story yet, but I want to start with the basic structure and tools first.
- It will be a quarter-view and isometric-view game, just like Into the Breach.
- It will use 2D graphics, and I haven’t decided whether it will be pixel-art style or higher-resolution graphics.
- I will use the Godot engine (version 4 or the most recent version).
- I have only created an empty project so far.
- I want to start with the basic project structure setup, and I want to make a level editor for it.
- Please make a plan for it first (project structure and the level editor).
- What kinds of art assets will be needed? 32x32 or 32x16 isometric field tile sets? Or higher resolution? In what format?
- How can the output of the editor be used in the main game? etc.
5. Antigravity Story
Overall, I felt that Antigravity consistently tried to solve the problem in the simplest possible way. From the very beginning, it steered the solution toward using Godot’s built-in TileMap editor instead of building any custom tooling.
It started by laying out a reasonable implementation plan: define the tile set, configure the TileMap, and rely on Godot’s existing editor features for placement and editing.
Antigravity:
I have created a plan for your project structure and level editor approach.
Key Recommendations:
1. Art Assets: I recommend a standardized Isometric 2:1 projection with a tile size of 64x32 pixels (top face). This balances pixel art aesthetics with enough resolution for detail.
2. Level Editor: Use Godot's built-in 2D Editor and TileMap system. It is powerful and built for this. We can wrap it in a custom Level scene to handle game logic (spawns, events).
3. Project Structure: I've outlined a clean folder structure separating core systems, assets, and scenes.
Please review the attachedimplementation_plan.mdand let me know if you agree with the 64x32 isometric standard and the project structure.
I didn’t particularly like that plan. What I actually wanted was to build a proper level editor, not just use Godot’s default tools. Still, I decided to go along with it and see where it would lead. So, I approved the plan and let Antigravity proceed.
Once I approved the plan, it immediately started working and completed the initial project setup.
Antigravity:
I have completed the initial project setup.
Completed Actions:
1. Project Structure: Created a clean folder hierarchy (src, scenes, assets).
2. Settings: Configured Godot for pixel art (Nearest neighbor, Viewport stretch)
3. Assets: Generated placeholder iso_grass and iso_stone tiles (64x32).
4. Level Editor: Created BaseLevel.tscn to serve as your level template and MapResource.gd for level metadata.
Next Steps: Open walkthrough.md for a guide on how to create your first level using BaseLevel.tscn. You will need to create a TileSet in the editor using the provided assets.
walkthrough.md
Project Initialization & Level Editor Walkthrough
I have set up the basic structure for your Isometric SRPG. Here is what has been configured:
1. Project Structure
The project is organized intores://src(scripts),res://scenes(tscn files), andres://assets(art/audio).project.godothas been configured for pixel-perfect rendering (Nearest scaling, Viewport stretch).
2. Assets
I've generated two placeholder isometric assets for you to start testing with:
* Grass Tile:res/assets/sprites/environment/iso_grass.png
* Stone Block:res/assets/sprites/environment/iso_stone.png
3. The Level Editor
Your "Level Editor" is the Godot Editor itself, structured around theBaseLevelscene.
How to Create a New Level
1. In Godot, navigate tores://scenes/levels/.
2. Right-clickBaseLevel.tscn-> New Inherited Scene.
3. Save the new scene (e.g.,Level01.tscn).
4. Select the Terrain node (TileMapLayer).
* Note: You will need to create a new TileSet resource here and drag your sprites into it. Set the Tile Shape to Isometric and Tile Layout to Diamond Down.
* Set Tile Size to 64 x 32.
5. Paint your level using the TileMap editor.
6. Select the root Level node and verify theLevel Datafield (drag aMapResourcehere if you want to define specific objectives).
Scripts* src/map/Level.gd: The brain of the level. It currently has a stub _initialize_grid() function where you will implement the logic to convert the TileMap cells into a game grid (A*).* src/data/MapResource.gd: A template for storing level data (Name, Turns, Objectives).
However, when I tried to create a new inherited scene from the BaseLevel, I go the following error.

I asked Antigravity about it.
Me:
I got an error when I tried to create a new inherited scene from the BaseLevel. The error message was at the following message box (image attached).
Antigravity:
Debugging Missing Dependency
I found the UID forLevel.gd. I am updatingBaseLevel.tscnto explicitly include this UID in the resource reference. This should fix the "missing dependency" error.
Please try creating the inherited scene again.
If it still fails, right-click the file system dock in Godot and select "Reload" or restart the editor to ensure it refreshes its internal database.
So basically, it seemed that the errors were caused by Antigravity directly modifying files inside the project folder. The next challenge was that I didn’t know how to create a new TileSet resource inside the scene.
Me:
Now I'm wondering how I can create a new TileSet resource under the new scene.
Antigravity:
To create a new TileSet for your level:
1. Select the Terrain Node: In your new level scene (inherited from BaseLevel), click the node named Terrain (it's a TileMapLayer).
2. Create the Resource:
* Look at the Inspector (right side).
* Find the property Tile Set. It currently says <empty>.
* Click the dropdown arrow and select New TileSet.
3. Configure for Isometric (Important!):
* Click the newly created icon/box that says "TileSet" to expand its properties within the Inspector.
* Tile Shape: Change from Square to Isometric.
* Tile Layout: Change to Diamond Down Right (this is standard for Into The Breach style).
* Tile Size: Set x: 64, y: 32.
4. Add Your Sprites:
* Open the TileSet bottom panel (it should appear at the bottom of the editor when you edit a TileSet).
* Switch to the TileSet tab (not TileMap).
* Drag your images (res/assets/sprites/environment/iso_grass.pngandiso_stone.png) from the FileSystem into the TileSet panel.
* It will ask "Automatically create tiles in the atlas?". Click Yes.
Now you can click the TileMap tab at the bottom, select your grass, and start painting in the editor!
Actually, there was also a hallucination. It mentioned “Diamond Down Right,” not “Diamond Down,” but I could work around that. However, when I tried to drop the PNG file, I ran into another error.
Me:
I have a warning popup saying "Invalid Texture selected"
Antigravity:
I found the problem!
I apologize—the "PNG" files I generated were actually JPEGs disguised with the wrong file extension. Godot detected this mismatch and rejected them. JPEGs also don't support transparency, which is critical for these tiles.
I am fixing this right now by generating proper, valid PNGs with transparency using a script. Please wait a moment.
However, it seemed that nothing was in progress. So, I asked.
Me:
Did you change the files?
Antigravity (after a while)
Fixing Asset File Format
The previous GDScript execution failed with a file save error. I suspect save_png requires an absolute system path rather than a res:// path in this context. I am modifying the script to globalize the paths before saving.
1. Re-writing asset generation script in GDScript to avoid Python dependencies.
2. Updating GDScript to use absolute paths for file saving.
Yes, it actually re-wrote an image generation script code and updated the files. However, it said:
Antigravity:
I also found and fixed a deeper issue: Your project folder structure was nested incorrectly (everything was inside a second `res/ folder`), which was why Godot couldn't find the scripts or load the assets properly.
I tried to update the folder structure. There was a lot of back-and-forth, and when it finally finished, I ran into many new UID resolution issues.
Eventually, though, I was able to draw the map as instructed. It took about an hour but it was true that many delays were due to my lack of knowledge for Godot engine editor.

6. Opencode Story
Then it was opencode (and oh-my-opencode)’s turn.
After sending the initial prompt, I had to step away to prepare dinner for my family. I actually closed the terminal, and when I came back later, I found the session was still active. The very early dialogue history was gone, but the working context remained, so I was able to continue from there.
Me:
Would you let me know where we left?
Opencode:
Based on the last session, here's where we left off:
Project: Into The Breach-style SRPG (Godot 4)
Completed:
- Plan documented inPLAN.md
- Project folder structure created
- Core scripts:level_data.gd,grid_config.gd,game_board.gd
- Placeholder assets:iso_tile_64x32.svg,selector.svg
Pending (Your Action in Godot Editor):
You were about to manually set up the scene in Godot:
1. Import assets
2. Create TileSet → save toassets/sprites/terrain/terrain_tileset.tres
3. Create `GameWorld` scene with:
-TileMapLayer(with the TileSet)
-CursorSprite2D (with selector.svg)
- Attachgame_board.gdscript
4. Test mouse cursor snapping to grid
Next Step:
Once the Godot scene setup is confirmed working → Phase 3: Level Editor
Have you completed the Godot Editor setup, or do you need help with that first?
I did my part, and asked it to proceed.
Me:
I've done my part in the editor. I confirmed the mouse cursor snapping to grid. Would you please continue Phase 3?
Opencode (after a while):
Phase 3 complete. Here's what I created:
Files Createdsrc/editor/level_editor.gd
Core editor logic:
- Paint/Erase tools - Left-click to paint, right-click to quick-erase
- Drag painting - Hold mouse to continuously paint
- Unit placement - Place spawn markers (visual markers coming in Phase 4)
- Save/Load - UsesResourceSaver/ResourceLoaderto.tresfiles
- Map size control - Dynamically adjustable grid boundssrc/editor/editor_ui.gd
UI controller that wires buttons/dialogs to the editor.
Directories
-scenes/editor/- For your editor scene
-data/levels/- Where level files will be saved
Then, it gave me the guide of my part.
Scene Setup Instructions (Your Part)
1. Create LevelEditor.tscn
LevelEditor (Node2D)
├── TileMapLayer ← Use same TileSet as GameWorld
├── Cursor (Sprite2D) ← selector.svg, Z-Index: 100
└── CanvasLayer
└── EditorUI (Control)
├── VBoxContainer (left toolbar)
│ ├── Label ("Tools")
│ ├── Button ("Paint") → name: PaintButton
│ ├── Button ("Erase") → name: EraseButton
│ ├── Button ("Unit") → name: UnitButton
│ ├── HSeparator
│ ├── Button ("New") → name: NewButton
│ ├── Button ("Save") → name: SaveButton
│ └── Button ("Load") → name: LoadButton
├── HBoxContainer (bottom status bar)
│ ├── Label → name: ToolLabel
│ ├── Label → name: CoordLabel
│ └── Label → name: StatusLabel
└── FileDialog → name: FileDialog
2. Attach Scripts
| Node | Script |
|---|---|
LevelEditor (root) |
src/editor/level_editor.gd |
EditorUI |
src/editor/editor_ui.gd |
3. Wire Inspector References
On LevelEditor node:
Tile Map Layer→ TileMapLayerCursor Highlight→ Cursor
On EditorUI node:
Level Editor→ LevelEditor (root node)Paint Button→ PaintButtonErase Button→ EraseButtonUnit Button→ UnitButtonNew Button→ NewButtonSave Button→ SaveButtonLoad Button→ LoadButtonFile Dialog→ FileDialogTool Label→ ToolLabelStatus Label→ StatusLabelCoord Label→ CoordLabel
4. Test
- Run
LevelEditor.tscn - Click "Paint" → Left-click on grid to place tiles
- Right-click to erase
- Click "Save" → Save to
res://data/levels/test_level.tres - Click "New" → Clears the map
- Click "Load" → Load your saved level
Every step was precise (actually there were more details). Whenever I wasn’t sure how to proceed with the UI, the agent provided clear, concrete instructions. For example,
Me:
I'm doing Step 9's 4. For Filters, I have trouble clicking to add Filters. The Filters section has a value PackedStringArr and I cannot change it. Below it, I can see Filename Filter section but I cannot input any text in the box. How can I resolve it?
Opencode:
TheFiltersproperty is aPackedStringArray- you need to expand it first to add items.
How to Add Filters:
1. Click the word "Filters" (or the arrow next to it) to expand the array
2. You'll see "Size: 0" with a number field
3. Change Size from0to1(type1and press Enter)
4. A new field "0:" appears below
5. In that field, type:*.tres ; Level Files
- Format is:pattern ; description
It should look like this after:
Filters: PackedStringArray
Size: 1
0: *.tres ; Level Files
I never ran into the UID resolution issues that plagued me with Antigravity. My guess is that this came down to the model choice (Opus 4.5 is usually excellent at this kind of work), or simply that opencode avoided risky direct file operations and instead guided me to perform them myself, which turned out to be a much safer and smoother workflow.
It also took about an hour, but almost all of that time was spent on my own confusion about the difference between running the main scene and running the current scene. I simply couldn’t figure out how to launch the level editor UI at first, which finally opencode let me know.
And this was the final result. It was remarkably close to what I had originally imagined.

7. Conclusion
It was a really fun (though a bit scary) experience.
What I felt most strongly is that what now matters more than how. For a long time, many lessons and trainings focused on how to do things. But now, how is becoming cheap. At the same time, when we use the right technology and the right models, there are still many unexpected factors. People with experience, who can recognize those differences and make the right decisions, become even more important. And in practice, they can achieve far more than before.
Some worry that if AI does 99% of the work, then 99% of people will lose their jobs. Maybe. But that assumes we continue producing the same amount. If the same 100% of people can produce 100 times more, the world changes dramatically. A large portion of that output may be garbage, but evolution often comes from that surplus. That’s how progress happens.
After this experience during the year-end break, I found myself genuinely wanting to dig deeper into AI and agents. I’ll keep writing about what I learn from time to time. It really is an exciting era.