How AI can help you to be a solo game developer


Intro
I interestingly got into programming. It all kicked off with a Half-Life 2 modification back in the day. I wanted to make something cool for my favorite game. Then I realized that I'm really bad at level design or modelling. So I then attempted to dip into the game logic, scripting and programming, and later began experimenting with the source code. Since then, I have built my career in web development and experimented with mobile apps, but game development has always been my interest. There’s nothing quite like building a world where players can dive in, make choices, and feel the magic of an interactive story.
That passion led me to Sorcery Duel, my latest project—a fast-paced, strategy-driven game where wizards clash in intense spell-slinging battles. Picture tactical duels packed with clever combos and a touch of fantasy flair. But here’s the wild part: I’m crafting it solo. No team, no big studio—just me.
Going solo sounds intense, and it is, but AI tools have made it possible. I’ve leaned hard on Claude Code, Grok, and ChatGPT to bring Sorcery Duel to life. These tools aren’t just sidekicks; they’re like having a virtual dev team, helping me code, brainstorm, design, and create visuals completely on my own. My roots in programming and game modding gave me the foundation to start, but AI is what’s enabling me to proceed with this dream. Even 5 years ago, when I was thinking about solo gamedev, it always felt that I needed at least a designer and an artist, who would share passion, have free time, and be interested in doing that just as a hobby, which seems almost impossible. But not now.
This article’s my chance to share the ride of building Sorcery Duel—the wins, the struggles, and how tools like Claude, Grok, and ChatGPT became my secret weapons. Whether you’re a coder, a gamer, or just curious about solo game dev, I hope this sparks something in you. Let’s jump into the spellcraft of making a game, one line of code at a time.
Overview of Sorcery Duel
Imagine two wizards squaring off, arcane sparks flying, each casting spells with cunning and flair. That’s Sorcery Duel. It’s a strategy-driven, head-to-head battler where every choice matters—think chess with a magical twist.
The setting is a vivid fantasy world—misty arenas, glowing runes, ancient towers humming with power. You play as a sorcerer wielding a spellbook packed with abilities from different magic schools. Each spell has unique costs, cooldowns, and effects, so strategy is everything. Want to freeze your opponent’s mana and follow with a fireball? Go for it. Prefer to summon a lava golem to smash through their defences while you prep a big finisher? That’s a vibe, too. The mechanics reward thoughtful planning, but keep things simple enough for anyone to dive in. It's still a mobile game, not an airplane control panel.
My landmarks for tactical battle pieces were Heroes of Might and Magic 3/5 and World of Warcraft combat systems. It is going to be turn-based, but with a little spark: spells are resolved at the same time, so the result would depend on what both wizards are casting. I decided to add this little real-time element to the classic turn-based approach. I am going to release the first version on iOS, with matches lasting 5–10 minutes, perfect for a quick session with a friend. I’m eyeing other platforms, such as PC or Android, down the road, but for now, it’s all about making those iOS duels shine.
But okay, let’s stop advertising my game. I know everyone here is interested in technologies and learning how to build staff.
AI Tools: The Game-Changer for Solo Development and how I used them
Image generation with ChatGPT
Visuals are the central part of the game, and for every game, it is what makes it feel like a whole fantasy world. I’ll admit, I don’t have a skill in illustration—my hands are better suited to a keyboard than a sketchpad. But what I do have is a sharp vision, formed from years of diving into games, soaking up fantasy universes like Warcraft or Skyrim, and getting a feel for how mechanics and aesthetics click.
That intuition guided me, even without artistic chops. Then came ChatGPT’s new image generation, and it flipped the script! Unlike the old days, when every AI-generated image was a fresh roll of the dice and tweaking meant starting over, this tool maintains consistency across generations. That lets me tweak specifics, such as replacing the staff with a glowing orb or swapping a button’s design with a single prompt. Sure, smart tools like “magic eraser” still help clean up edges, but this level of control, where I can refine without losing context, is a game-changer.
For example, here is how I modified this character's appearance
Using the prompt: “Perfect! One small change - make her not wear a hood, the head should be uncovered”
It is also great at generating buttons and being very consistent with it:
All 3 generated within the same chat.
Another thing - animations. Most of animations on 2D games are just a few frames, so for simple effects I just asked ChatGPT to generate a grid of effects frame by frame, and it works quite well. Here is the flying and pulsing fireball:
If you play every frame for 0.1 second, you get a nice animation.
The result is not always positioned perfectly. Sometimes, it still require a manual adjustment. So for flying boulder, where the position is important, I made a simple grid in the Pinta editor to perfectly position and align every frame:
Claude code
I don’t have a huge experience with Swift, so Claude Code helped me learn some language features in practice. As the initial point, I started with a plan, so Claude drafted a nice 10-step process, and updated it when completing the next task. Then I stepped away from that plan, when I got something working, but this is the last used version:
# SorceryDuel Implementation Progress
## Completed Tasks
### 1. Core Architecture & Data Models
- Created enums (MagicSchool, SpellType, SpellDirection, GameState)
- Implemented Wizard and Creature classes
- Built Spell protocol with concrete implementations (Attack, Defense, Summon, Curse)
- Created Effect system for ongoing spell effects
- Implemented SpellFactory for centralized spell management
- Designed TurnAction class for player actions
- Added Shield Defense system with directional protection
### 2. Game Scene & UI Layout
- Create 10x10 grid battlefield
- Position wizards at opposite corners
- Implement UI panels for spell selection
- Add status display (health, mana)
### 3. Player Wizards & Positioning
- Initialize wizards with appropriate textures
- Set up grid-based positioning system
- Implement visual indicators for active wizard
### 4. Bug Fixes & Implementation Updates (May 15, 2025)
- Fixed missing direction parameter in takeDamage method calls
- Updated DefenseEffect initialization with proper parameters
- Implemented addEffect method in Wizard class
- Added useMana method to Wizard class
- Made DefenseEffect properly implement the Effect protocol
- Improved spell effect handling in Wizard class
### 5. Turn-Based Gameplay Flow (Completed May 15, 2025)
- Built state machine for game phases
- Implemented selection sequence: school → type → spell → target → direction (if target is other wizard)
- Created turn resolution logic with visual effects
- Added support for direct, left, and right spell directions
- Implemented directional arrow sprites for spell targeting with visual feedback
- Created dynamic projectile paths for different directions (direct, left, right)
- Added smooth animation transitions between selection phases
### 6. Spell Direction & Resolution System
- Implement spell casting mechanics
- Build direction-based interaction rules
- Create damage calculation with magic school advantages
## Next Steps
### 7. Summoned Creatures & Battlefield Grid
- Implement creature summoning and positioning
- Create creature attack logic (they only shoot the closest target, whatever it is the opponent's wizard or opponent's creature)
- Build grid management system
### 8. Visual Effects
- Design and implement spell animations
- Create feedback for spell outcomes
- Add visual indicators for active effects
### 9. Game State Management
- Implement win/lose conditions
- Create game over screen
- Add restart functionality
### 10. AI Opponent (Optional)
- Implement basic decision-making logic
- Create difficulty levels
## Notes
- Core data models are complete and well-structured
- The SpellFactory provides a centralized way to access all spells
- The visual effects system is designed but will need implementation in GameScene
- Effect system is now properly implemented with protocol conformance
- Wizard class now handles effects and mana usage correctly
- Shield defense system implemented with directional protection (100% for primary direction, 50% for other directions)
- Magic school effectiveness is applied to shields (strong vs. weak schools)
- Each magic school has a unique shield spell that can absorb up to 100 damage points
- Shields last for 2 turns or until their protection value is depleted
It is always a really good idea to give Claude Code a lot of extra information and describe everything in detail. For instance, I usually formulated tasks in a separate text files, giving some particular code references and details. Here is an example that worked good for adding the spellpower ability to wizards:
I want you to work on a new Wizard stat - spellpower.
For every point of spellpower, Wizard's spells become 5% stronger.
It has following effects for different spells:
1. For attack spells - spellpower increases the damage.
For instance, ifa fireball does 20 damage by default, then it will do 21 damage with 1 point in spellpower.
2. For shields - spellpower increases the shield absorbed amount, also by 5% per every point.
For instance, if a fire shield absorbs 60 damage, then with 2 points in spellpower, it will absorb 66 damage.
3. For summon spells - spellpower increases the creature's maximum health and damage.
For instance, if a golem has 50 health and does 3 damage by default, then with 4 points in spellpower,
it will be 60 health and 4 damage (3 + 3 * 0.05 * 4 = 3.6 --> 4)
4. For other future spells, I will implement them later myself
In case of a fraction resulting value, all numbers are rounded to the closest value. 4.4 --> 4; 4.6 --> 5; 4.5 --> 5.
And this is an example of refactoring, performed by Claude Code, but when I described a particular required changes:
Refactor GameState enum. The current implementation:
```
enum GameState {
// Turn phases
case player1Turn
case player2Turn
// Selection phases
case selectingMagicSchool
case selectingSpellType
case selectingSpell
case selectingTarget
case selectingDirection
// Resolution phases
case spellResolution
case gameOver
}
```
Selection phases should go into a separate enum `TurnState`, with these members:
```
enum TurnState {
case selectingSpell
case selectingTarget
case selectingDirection
}
```
Game state goes between these states:
player1Turn --> player2Turn --> spellResolution --> player1Turn
|
|
v
gameOver
Turn state:
selectingSpell --> selectingTarget --> selectingDirection
selectingTarget and selectingDirection and optional for some spells
In the project, I created a separate folder for all the text files, so Claude can refer to them if needed to remember game rules or project tree, and I am saving completed tasks for the history. Here is my directory structure:
info/
├── Completed
│ ├── defence_spell_logic.txt
│ ├── task_animated_chars.txt
│ ├── task_animated_sprites.txt
│ ├── task_game_state.txt
│ ├── task_shield_effect.txt
│ ├── task_spellbook.txt
│ ├── task_spellpower.txt
│ ├── task_spells_limit.txt
│ ├── task_summon.txt
│ └── ui_task.txt
├── game_rules.txt
├── implementation_progress.txt
├── plan.txt
├── project_tree.txt
├── task_dispell.txt
├── ui_layout.txt
└── used_assets.txt
2 directories, 17 files
I also added some important game facts to CLAUDE.md
file, as recommended in this article
Grok
I am, honestly, not a big fan of X. Even when it was Twitter, I kind of avoided that social network. But I have to assume - Grok is really good for certain tasks.
Even in the free version, it supports up to 25 attachments in one chat, which is excellent for the task of refactoring. This means that in the free version, it would almost certainly train on my codebase, but I don’t see a big problem with it if someone has some random modules from my hobby project.
So how I used it - I gave it a file and asked for refactoring plan:
I am implementing a 2D game in Swift for iOS. I have my main class with game logic called
GameManager
. However, it is becoming a bit too large. Are there any ways I can refactor it? Come up with a plan for now, do not write the code yet!📄 GameManager.swift
Grok proposed a good plan. Here is the first part of the response with first 2 items:
The
GameManager
class in yourGameManager.swift
file is indeed large and handles multiple responsibilities, which can make it difficult to maintain and extend. Refactoring it will improve modularity, readability, and testability. Below is a detailed plan to refactor theGameManager
class by breaking it into smaller, more focused components while preserving the existing functionality.Refactoring Goals
Single Responsibility Principle (SRP): Split the
GameManager
into smaller classes or structs, each responsible for a specific aspect of the game logic.Improved Readability: Organize related functionality into cohesive units to make the codebase easier to navigate.
Testability: Isolate logic to enable unit testing of individual components.
Maintainability: Make it easier to add new features or modify existing ones without altering the core
GameManager
.Reusability: Create components that can be reused in other parts of the game or future projects.
Analysis of Current Responsibilities
The
GameManager
class currently handles:
Game State Management: Tracks game state (
gameState
,turnState
,currentPlayerTurn
), player turns, and selection states (selectedSpell
,selectedTarget
,selectedDirection
).Wizard Management: Initializes and manages wizards (
player1Wizard
,player2Wizard
,activeWizard
).Creature Management: Tracks and manages creatures (
allCreatures
, summoning, removal, and auto-attacks).Spell Management: Handles spell selection, targeting, direction selection, and resolution (including collision detection).
UI and Visual Integration: Interacts with
UIManager
,VisualEffectsManager
,SpellbookUI
, andGameCamera
for UI updates and visual feedback.Grid Interaction: Works with
GridManager
for position validation, highlighting, and creature placement.Game Flow: Manages turn switching, spell resolution phases, and game-over conditions.
Given these responsibilities, we can split
GameManager
into several smaller components.Refactoring Plan
1. Extract Game State Management
New Component:
GameStateManager
(Class)
Responsibility: Manage the game state, turn state, and player turns.
Functions to Move:
currentPlayerTurn
,gameState
,turnState
,spellSelectionComplete
setCurrentPlayerTurn(_:)
switchPlayerTurn()
beginSpellResolutionPhase()
resetTurnActions()
checkGameOverCondition()
handleGameOver()
resetGame()
Dependencies: Will need references to
UIManager
,GameCamera
, wizards (player1Wizard
,player2Wizard
), and stored actions (player1SelectedAction
,player2SelectedAction
).Purpose: Centralizes game flow logic (turn management, game phases, and game-over conditions) and reduces the
GameManager
’s responsibility for high-level state transitions.Interaction:
GameManager
will delegate turn-related and game state operations toGameStateManager
.2. Extract Spell Management
New Component:
SpellManager
(Class)
Responsibility: Handle spell selection, targeting, direction selection, and resolution.
Functions to Move:
selectedSpell
,selectedTarget
,selectedDirection
startSpellCastingSequence()
showValidTargets()
handleTargetingGridSelection(_:in:)
showDirectionOptions(for:)
cancelSpellSelection()
storeSelectedSpell()
resolveSpell()
resolveSpellsInOrder(_:)
checkAttackSpellCollisions(_:)
applySpellEffects(_:)
applyAttackEffectsWithCollisions(_:collisionResult:)
calculateCollisionWorldPoint(from:to:direction1:from2:to2:direction2:)
areDirectionsCrossing(_:_:)
calculateHalfDistancePoint(from:to:direction:cellSize:)
Dependencies: Will need references to
GridManager
,VisualEffectsManager
,UIManager
,SpellbookUI
, and wizards/creatures for targeting and effect application.Purpose: Isolates all spell-related logic, including selection, targeting, and resolution (including collision detection), into a single component.
Notes:
The
SpellManager
will handle the complex logic of spell interactions (e.g., collision detection and resolution order).Consider creating a
SpellCollisionHandler
struct or class to encapsulate collision-specific logic (checkAttackSpellCollisions
,calculateCollisionWorldPoint
,areDirectionsCrossing
,calculateHalfDistancePoint
) for further modularity.Interaction:
GameManager
will callSpellManager
for spell-related actions, andGameStateManager
will coordinate withSpellManager
during the resolution phase.……
Then you can execute that plan step-by-step, and it will provide new and updated files, so it is very easy to apply to the project:
I feel like this combo of Claude Code for adding code and Grok for refactoring modules worked really well for me. Grok does not always generate working code, and sometimes it mixes up variables, so you definitely need to keep an eye on it. But it's the same for all the AI-generated code.
I also used it as a generic AI assistant, when I need to chat about my game for free, since it also has memory feature now, and remembers many facts about it, same as ChatGPT.
Conclusion
I like the possibilities that get unlocked with the help of AI assistants. It's great when you can work on your hobby projects with good progress, even if you have only an hour or two a day or over the weekend. That looks fascinating, but it's also important to understand, predict, and analyze the consequences and influence that AI can have worldwide. From small projects like mine to drastic societal effects, and changing the whole way we work. Here are some of my thoughts.
AI is not a replacement for professionals, at least, for now. Despite of being helpful on generating images or code, it is still far from the professional level of understanding things deeply. For instance, the example above shows, that it put 2 different entities: turn state and game state into the same enum -
GameState
. Probably same applies to illustrations. Designers and illustrators make things look estetic and bringing some additional ideas or features into their characters, sometimes even not seen at the first glance, but understood subconsciously. Despite its complexity, AI is essentially about optimizing error minimization in data processing. So it would output a “middle”, “good” and “satisfying” solution, loosing some deep features. It would lack originality in the art images or generate suboptimal code. It leads to the next point.AI makes things that work. But how exactly work - could be missing. For instance, there are multiple ways to implement concurrently executed tasks. At the first glance, it all is executed in the end, and it all working, but the actual result could be different. It plays even bigger role when you step away from the prototyping to the actual project, and trying to optimize it. For instance, when I implemented FitAssist, AI sometimes put some code on the main thread, which works fine while you don’t have much data, but if I would miss that, users could report, that the app is slow, and the more you use it, the slower it gets. So you really need to know your codebase.
We all started small. Learned how to code basic things and operations. Then built more knowledge on top of that. Now, AI can handle simple operations and tasks. People start saying that some Junior developer work could be replaced with AI. Yes, we might save money and human labour hours, but it would also mean that the person is not getting experience. Would not be able to proceed to being a middle and senior engineer later. Suppose we project for 10 years (which is always a silly idea, since processes never develop linearly, but just a mental exercise). In that case, we have products that somehow work, which were created with the active participation of AI, and the last person who manually worked with the codebase retired a year ago. Not a big win in the long term, right?
Also, with the help of AI, a beginner developer is not required to learn everything. All answers are so easily available, all the tasks are solved magically. I still remember nights debugging my self-written graphics engine about 15 years ago, kept getting an empty black screen and trying to understand - what was wrong there, and why was my level not drawn. Now, why would you bother learning how it actually works, when the result is achievable with AI, and the provided solution seems to be doing its job. Why would you ask questions about why it is structured that way, and what are the other options to organize the codebase? AI probably would know, what architecture to choose, right?
Some people can say that it already happened many times. Look at the car manufacturing facility in 1920:
And at the modern South Korean manufactory with robots:
Everything looks good - routine hard work gets automated, car quality and assembly precision increase significantly, and people are transitioning from manual labour workers to advanced robot operators.
But I feel like the AI shift is different. I believe it is the first time in human history that automation is occurring in the creative class and intellectual professions. And it might have a bigger impact than we thought. It may be the first time we might delegate decision-making to a non-human. Not a particular algorithm, developed by a person, to work with a specific type of data, and output the decision. But to a generic AI model, that can perform reasoning on provided data, emulate a thinking process, and form a final decision, supporting it with facts from the provided data and its existing knowledge. And even if it could create some additional jobs for more AI engineers or AI ethics specialists, it feels like it might eventually shrink the total number of jobs available.
Probably, if progress continues at the same speed, within the next 3-5 years, an experienced developer equipped with a range of AI tools can handle the entire team's workload, especially during the product's prototyping phase. A senior lawyer might delegate contract analysis and matching it with the rules of law to AI. So the company would be happy to increase their salaries, since they are so productive. However, that would also mean they no longer need junior specialists. As well as illustrators and designers for small companies, since SEO can do those things on their own in their free time. That might increase economic inequality even further, as the number of jobs may shrink.
Yes, somebody might say, that it is a dog-eat-dog world, and you have to adapt. However, if the process of replacing human labour is avalanche-like, and about 50% of the population is left behind, it's only a matter of time before the consequences affect everyone.
Economic inequality is not just a social justice theoretical concept, it might have broad real-world consequences. In the Russian Empire before the revolution, wealth distribution was quite extreme: 1.5% of the population owned 25% of the land, while most people were peasants or urban industrial workers living in poverty. That all, after communists seized power by force as a result of a civil war, led to an extreme process of repressing the wealthy, successful peasants - Dekulakization.
Of course, it is an extreme case, but even now, people who have been left behind the progress are becoming easy targets for populist politicians. Who promise to return to the good old times, defeat all enemies, and solve all the complex problems with simple solutions. This only leads to increased polarization and tension in society, making the world more chaotic and less safe for everyone.
Do I propose stopping the progress and development of AI? Of course, not. You can never stop progress; all reactionary forces and ideas have historically lost, and we have to embrace the progress, make it our friend, not our enemy. But let’s keep in mind the consequences of our actions. Let’s stay in control of our fate. Let’s put people first. Let’s build things that would help people, not replace them. Let’s be mindful, because with great power comes great responsibility.
Subscribe to my newsletter
Read articles from Alexander Polev directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
