The End of Software Engineering? Not Quite — But AI is Changing the Game

The End of Software Engineering? Not Quite — But AI is Changing the Game

Apr 30, 2025

by

Mark Antonelli

Software engineers are still essential to the AI-driven development process, though their role is evolving.

Since time immemorial – or for the last decade at least – there have been predictions that the end of software engineering is near. The story goes, why would you need anyone to write software when you can just have the AI write it for you? Afterall, anyone can summon Claude, Gemini, ChapGPT or any of a dozen chatbots to write a calculator software in a variety of languages. All of them will do a credible job, with most getting it right within two or three directives.

Surely the software engineering profession is doomed!

But is it really? What happens when the application becomes more complex? Can you get to the finish line with the AI before it fails?

In this blog I’ll explore the limits of software engineering, using Claude Code to develop a complex application that requires structure and forethought. Along the way, I’ll discuss the advantages and pitfalls of developing software with AI – and most importantly try to develop some best practices for this endeavor.

Claude Code is not Claude, nor Copilot, nor Cursor, nor …

Right up front, I must clarify that my team used Claude Code, not Claude itself, nor Copilot, nor any of the many similar tools. In a world in which there are major advancements every week, Claude Code represents a leap forward – one that few of its peers has yet caught up to.

(The recently released OpenAI Codex CLI is the exception as it is in the same class as Claude Code. All of the best practices and observations that apply to Claude Code also apply to Codex CLI. Keep that in mind as you delve deeper in this blog.)

Claude Code is designed to seamlessly interact with the operating system, the file system and code repositories, either autonomously or without human intervention. Instead of cutting, pasting and organizing results from a web interface or integrating code snippets from an IDE suggestion, Claude Code will build a directory hierarchy that organizes the code into logical components – just as a human programmer would do.

The interaction with the file system means it can easily scan code, run helper functions and commit code on its own. Since Claude Code can run the developing program itself, it can identify syntax errors automatically and self correct. (Note that it's likely that competitors will soon emerge with capabilities equal to or surpassing those of Claude Code.)

Real-World Test Case: Building a Game with AI

For our project, we decided to recreate the classic Chris Sawyer game Transport Tycoon and its successor, Locomotion. For those unfamiliar, it's a strategy game where players build and manage a transportation empire, utilizing trains, buses, boats and planes to earn money and outcompete AI-driven rivals. 

At first glance, this might appear an odd choice because our company develops business and engineering software, not games. However, we wanted to showcase the AI in the best way possible. One can easily write a game in Python with a very fast iteration time since no compile is needed, yet the language is still rich and well-known enough that the AI has lots of code examples from which to learn.

Goal and Guidelines

Our project had one clear goal: push the limits of what we could build without writing a single line of code by hand. Beyond that, we performed typical engineering tasks – specifying functionality, reviewing code, suggesting architecture, breaking down bigger tasks into smaller ones, etc. For debugging, we copied debug and interpreter output back into Claude Code without modification. We appreciate that this can be automated to an extent, but we wanted to do it manually to better understand the process.

Progress Report: 50 Hours In

As of this writing, we are about 50 hours of developer time into the project. Thus far, we’ve completed map generation, time scale, road building, basic economics, save and load, vehicles and routing. Some of that time, especially early in the process, was spent waiting for Claude Code to respond.

Moving forward, we’re doing a bit more multitasking. The total lines of Python code is currently around 13,000 with an AI cost around $150. While we’ve had setbacks, we have not yet reached diminishing returns and plan to continue as a background task.

Here is a screenshot of our current working version – with roads, vehicles, economics, and time scale implemented.

Claude game example

 

The Implementation Experience: What Worked – and What Didn’t

The implementation experience can be a bit of an emotional roller coaster. Often there is a euphoria with an initial success, but then this can later be tempered by frustration as the implementation of a fairly straightforward task goes awry. Contrary to popular belief, the AI will not do exactly what you tell it to do. In a way, it comes with its own biases, background and experience that vary depending on the nature of the software project.

Since we’re writing a game in Python and there is a lot of training data for games and Python, our AI has a lot of personality. On the positive side, it implemented features that we wanted but initially forgot to specify. For instance, during playtest, we were laying out roads and wanted a shortcut to change the orientation of the road. Right click seemed the appropriate choice for this feature – and much to our surprise, when we tried that we discovered it was already implemented!

(To be fair, a more in-depth review of the code would have revealed this, but in any case we found it useful for the AI to fill in the gaps for such simple things.)

On the other hand, sometimes the AI would go off the wall and needed to be reigned in. Here’s what I mean. Sometimes, it can look like everything is going smoothly so you ask Claude Code to do something it has already done in a different context. Should be a straightforward request but instead all hell breaks loose.

Here’s one example, related to when we added economics. First, we added vehicle economics by asking the AI to subtract daily vehicle costs per vehicle type based on the game clock. This worked in one iteration. Woo hoo! The next step was to account for costs of road building. Simple enough, but the subtracted costs were three times the amount they should have been.

Asking Claude Code to fix this resulted in lots of churning with no forward progress. In the end, we had to review the code to provide guidance to help Claude Code know where to look. Turns out that we were adding the same cost handler in three different places. We asked Claude Code where the best place to add it was, agreed with the recommendation, and moved forward.

Best Practices: Stay in Control While Collaborating with AI

Working with Claude Code is powerful—but also unpredictable. These best practices will help you stay efficient, maintain quality and avoid common pitfalls when integrating AI into your development workflow.

General Flow

We quickly adopted a development flow with Claude Code. Everything was centered around specific tasks because it's easier for the AI to understand, easier for the engineer to test, and easier to revert when things go wrong. Our flow looked something like this:

Development Flow with Claude Code

If the feature is chosen at the right level of difficulty and not too broad, we should be able to converge and finish the task after about three iterations. (Note this might correspond to over 30 minutes in real time.) After a bit of use, we developed a sense of whether we’re converging or not.

If you use this flow and are not converging, you need to stop and start again. Here’s where using git is invaluable. Asking Claude Code to undo what it has done will not always work. Instead ask Claude Code to do a git hard reset. This will revert everything to the start of the task. Now you will need to modify your original task taking into account how the AI failed or failed to grasp. Sometimes just restating all the requirements and adjustments up front is enough to fix the problem.

One caveat: it is better to deal with most problems head on and not delay the fix. We found that if the code generated by Claude Code has too many issues or strays too far from the intended goal, it is better to revert the code and restart than leave the code as is and try to fix it later.

Planning and Implementation

Never let Claude Code implement anything without first seeing a plan. While itmight work, there is a good chance that it will not. Claude Code needs to be monitored so always have it first provide an implementation plan. That way, you can be sure you understand what is going on and can modify the plan as needed.

Asking for architectural details can be very useful. Do not be afraid to suggest improvements. For instance, Claude Code can do a reasonable job of subclassing especially if you have an overall architecture in mind and can guide it in anticipation of features not yet implemented.

Source Code Control

Git is the source code control of choice as it is essentially built-in to Claude Code. It will make commits for you with a detailed commit message – and will happily take credit as well. Because Claude Code does go off the rails at times, you need to be able to easily get back to a last known working version. You can ask Claude Code to undo the code changes that it has made, but that costs tokens and rarely works 100%. A hard reset is better, faster, and cheaper.

Branching is also highly recommended both in general and in the converging flow. In other words, the functionality you’re adding looks like it is trending in the right direction but is still not complete. By committing it to a branch, you have a useful piece of working code that you can revert to if your refinements go awry. It can be very frustrating to almost be there when that last tweak wreaks havoc!

Debugging

For basic syntax and interpreter errors, we never had a failure when we just copied the error lines back into Claude Code. For more complex problems, like our issues with cost calculation, we had explicit instructions regarding where to print debug output to identify the problem. It was something like:

  • Print the money value just before it is printed

  • At the turn of every day, print a list of vehicles and their operating cost for the day.

The volume of debug output quickly becomes overwhelming so organizing into both functional areas and debug level is critical. This is something that can be done at the beginning of the project (it will show up in the CLAUDE.md file) and then referenced as needed.

Architecture

While Claude Code does understand subclassing and good coding practice to some extent, it has an unfortunate tendency to repeat the same or similar code in many different places. Case in point, the hover and select functionality for creating and selecting vehicles and roads was implemented three times and the same visual error or a variant was repeated in all the implementations.

When we decided to fix this issue, we had just come off a very unproductive refactoring session. We were tired so we simply asked Claude Code to identify all the places it was implemented and fortunately Claude Code was able to successfully fix it in place.

Certainly we would not consider this approach to be best practice. Rather, it’s beneficial to anticipate and suggest architecture directives like subclassing and utility functions. Architecture suggestions are best done before functionality is implemented because refactoring with Claude Code can be a nightmare.

Taking this to heart, when we wanted a moving toast to show the cost of only a created road or vehicle, we suggested putting the common code in a UI utility library. It followed our directions and we were easily able to refine the functionality without things breaking.


Code Review

On a regular basis, we hit issues where redirecting Claude Code was insufficient. That’s why a human needs to review and understand the code, as well as suggest improvements. You can always ask the AI for suggestions along the lines of “Can you review the code that calculates expenditures and find the issue where the cost calculation is three times what it should be?” It is also nice that you can ask where code is, for example “Show me the code that generates the map.” This can often be easier than doing a search by keyword in the IDE.

Command Tracking

Creating requirements and user stories are a significant part of any software development project. However, those are not sufficient especially as complexity rises. You need to add greater detail and how-to-implement instructions. A lot of this can be planned in advance, but the nature of Claude Code programming is interactive – meaning you will be creating new instructions on the fly, just as you might do when helping a junior programmer fix issues with their code. So keeping track of the interactions is very useful.

We asked it to save all of our inputs into a CLAUDE_REQUESTS.md file. This worked reasonably well with the caveat that it would forget after doing a /compact – even after we pointed this out and the instructions ended up in the CLAUDE.md file. For now, we reissue this request after each /compact. (Editor’s note: by the time you read this, auto-compact may already be implemented, but controlling the compact manually is still useful)

Here’s a snippet from the CLAUDE_REQUESTS.md file. In retrospect, it would be more useful to also have Claude Code’s planning responses but not its reasoning or debugging.


The Evolving Role of Software Engineers

Good software engineers have many roles and responsibilities, including designing, developing, testing and maintaining software systems. As part of their duties, they collaborate with internal teams, analyze user needs and ensure software quality. Their skills include problem-solving, programming, software design and communication.

None of this fundamentally changes when AI is brought into the mix. However, the AI can perform tasks that the engineer would have previously handled manually – or that might have been completed by other team members. With AI, the engineer gains greater capability, and with it greater responsibility.

With AI in the mix, every software engineer is being called to play a broader role—not just as a developer, but also as a software architect, lead engineer, and even project manager. Where once there was a single human engineer, there is now a hybrid team: one human, supported by a growing group of AI-powered "co-engineers."

This AI team can be a tireless workhorse, occasionally brilliant—but also unpredictable. It can make mistakes, misjudge decisions, and implement solutions in unexpected or inefficient ways. That’s why it must be closely supervised. Despite rapid progress in AI, this need for human oversight isn’t going away anytime soon.

Human Insight Still Essential in AI-Driven Development

Software engineering isn’t going anywhere—but it is undergoing a major transformation. Tools like Claude Code and its competitors are becoming powerful force multipliers, turning individual developers into self-contained mini-teams.

But this isn't a hands-off process. Outside of the simplest tasks, AI-driven software development isn’t “fire-and-forget.” It demands that engineers take on a more strategic, managerial role to guide and correct the AI’s output.

When everything runs smoothly, using AI feels effortless—but when things go wrong, a deep understanding of software fundamentals is still your safety net. In this new era, knowing how to code is just the beginning. Knowing how to lead—even if it’s a team of AIs—is key to success.

About the author

Mark Antonelli

Mark Antonelli is a technology specialist with particular expertise in the realm of audio/video systems development and machine learning. For more than a decade he headed the development team creating a robust, market-leading, multi-channel video surveillance system and multiple follow-on products.

©2025 Boston AI® • A Division of ICS • Privacy PolicyCookie Policy

230 Second Avenue • Waltham, MA 02451 • Phone: 781.552.3715

©2025 Boston AI® • A Division of ICS
Privacy PolicyCookie Policy

230 Second Avenue • Waltham, MA 02451 • Phone: 781.552.3715