Contents

The Refactorer: Tackling Large-Scale Changes with an AI Pair Programmer

With a solid plan in place, an AI assistant can become an invaluable pair programmer, helping you execute complex refactoring tasks with speed and precision. Learn how to use it to generate code, identify dependencies, and even spot architectural improvements.


In the previous articles, I discussed preparing a project for AI collaboration and using an AI to create architectural workplans. Now, it’s time to execute that plan. This is where the AI transitions from an architect to a hands-on pair programmer, helping to tackle the complex, often tedious work of a large-scale refactor.

Executing a Workplan with an AI

With a granular workplan, guiding the AI is simple. I can ask it to implement a specific phase or even a single task. For the MonoRpg project’s migration from Tiled to the LDtk map editor, a typical prompt would be:

“Implement Phase 2.2 of the LDtk migration workplan: Rendering Implementation. This involves removing the old TiledMapRenderer and creating a new DrawTileLayer() method that correctly calculates source and destination rectangles from the LDtk data.”

The AI, using the context of the workplan, can then generate the necessary code modifications with high accuracy.

AI for Code Transformation

One of the most powerful uses of an AI during a refactor is code transformation. The AI excels at applying a specific pattern change across multiple files.

A perfect example from the MonoRpg project was updating the EntityFactory. The old factory methods for creating game objects relied on reading string-based properties from Tiled map objects—a notoriously error-prone pattern.

Before: The Tiled-based method

public Entity CreateDoor(TiledMapObject obj)
{
    // String-based property access is fragile
    if (!obj.Properties.TryGetValue("TargetMap", out var targetMap))
        throw new ArgumentException("Door missing TargetMap property");

    var position = new Vector2(obj.X, obj.Y);
    // ...
}

My prompt to the AI was:

“Refactor the CreateDoor method in EntityFactory.cs to work with an LDtk EntityInstance instead of a TiledMapObject. It should use type-safe field access for the ’targetMap’ and ’targetSpawn’ properties.”

After: The AI-generated LDtk refactor

public Entity CreateDoor(EntityInstance ldtkEntity)
{
    // Type-safe field access is robust
    var targetMap = ldtkEntity.GetField<string>("targetMap");
    var targetSpawn = ldtkEntity.GetField<string>("targetSpawn");

    var position = new Vector2(ldtkEntity.Px[0], ldtkEntity.Px[1]);
    // ...
}

The AI correctly identified how to access the LDtk data, generated the new method signature, and updated the property access to be type-safe, significantly improving code quality. I then asked it to apply this same pattern to all other factory methods.

Uncovering Hidden Architectural Improvements

Sometimes, the AI’s greatest contribution is not just doing what you ask, but spotting opportunities you missed. During the LDtk migration, I asked the AI a high-level question:

“Is there a better way to position entities for rendering order? They should appear above house walls but behind roofs, like in Stardew Valley.”

My existing rendering approach was a simple 3-layer system that couldn’t handle this. The AI’s analysis was brilliant:

  1. It Identified the Problem: It correctly diagnosed that my simple layer system was the issue.
  2. It Proposed a Solution: It suggested implementing Y-Position Depth Sorting, a common technique in 2D RPGs where an entity’s render depth is calculated from its Y-coordinate. It even provided the complete C# code.
  3. It Made a Strategic Recommendation: This was the critical insight. The AI recommended that I implement this rendering refactor before the main LDtk migration. This would let me separate the concerns of rendering from the map format, test the new rendering with my existing Tiled maps, and significantly reduce the risk of the overall migration.

I accepted the recommendation, added a “Phase 0” to my workplan, and spent a few days on the rendering refactor. This AI-driven insight made the subsequent LDtk migration smoother and far less risky.

Conclusion: The AI as Your Tireless Partner

Using an AI as a pair programmer for refactoring is incredibly effective. It handles the repetitive work of applying pattern changes, freeing you to focus on the bigger picture. More importantly, its ability to analyze code from a fresh perspective can lead to critical architectural insights that you might have missed.

With a solid plan and the right prompts, the AI becomes a tireless partner, accelerating development and improving the quality of your code. In the final article of this series, I will cover the last crucial step: what to do when the AI gets it wrong.