AI coding assistants are the most significant change to programming practice in a generation. They're already in millions of editors, and they're only going to become more capable. This chapter is about how to use them well — which, it turns out, requires knowing C++ well. The two skills reinforce each other, and this is the chapter where we make that relationship explicit before we lean on it hard in the next three projects.
Why This Chapter Exists
You've now covered the core language — variables, control flow, loops, functions, pointers, collections, OOP, polymorphism, and a tour of the wider standard library. You can write real programs. You can read unfamiliar code and understand it. That puts you in exactly the right position to start working seriously with AI tools, because the most dangerous time to use an AI coding assistant is when you can't evaluate what it produces.
The aim here isn't to teach you which tool to use (they change too fast for any book to be current). It's to teach you the mental model that makes any of them work well for you.
The Four Failure Modes
AI coding assistants fail in four characteristic ways. Knowing them by name is the first step to avoiding them.
1. Plausible Nonsense
An AI will generate code that looks completely reasonable — correct syntax, sensible variable names, believable structure — but is subtly wrong. It might call a function that doesn't exist, use an API in a version it was never part of, invert a condition, or miss an off-by-one. The code compiles. It even runs. It just doesn't do what you asked.
This failure mode is the most dangerous because it's invisible to the inexperienced eye. The antidote is exactly the knowledge you've been building: if you know what std::vector::at does versus operator[], you'll spot when the generated code uses the wrong one. If you know how SDL 3's event model works, you'll catch when the AI writes SDL 2 code. You have to be able to read the output critically.
2. Helpful Drift
You ask for feature A. The AI delivers feature A, and also refactors half of your unrelated code, renames your variables to its preferred style, switches from your chosen pattern to a different one, and adds three helper functions you didn't ask for. Each individual change might be fine, but the cumulative effect is that you no longer recognise your own codebase.
Helpful drift is particularly common when you give the AI a large context window full of your existing code. The antidote is specificity: narrow prompts, small scopes, explicit "don't touch anything I haven't asked about."
3. The Confidence Problem
AI assistants almost never say "I'm not sure." They produce confident output whether they're right, slightly wrong, or completely off the rails. There's no tonal signal that says "treat this with skepticism." You have to bring your own doubt.
The practical rule: the more obscure or specific the domain — a particular SDL 3 function added in a minor release, a platform-specific compiler quirk, a niche library's API — the higher the chance of a confident error. Verify anything you can't personally check against your existing knowledge.
4. The Atrophy Trap
If you use AI to generate every function you need, you stop practising the skill of writing functions. That feels fine right up until the moment the AI gets something wrong and you can't diagnose why — because you've lost (or never developed) the muscle for reading and reasoning about unfamiliar code.
The antidote is intentional practice. Accept AI-generated code for boilerplate and scaffolding. Write the core logic yourself, especially while learning. Review every line the AI produces as if you wrote it — because once it's in your codebase, you're responsible for it.
Good Prompting Principles
Bad prompts produce inconsistent output. Good prompts produce consistent output. Here's what makes the difference.
Front-load the Constraints
Tell the AI the things it must not do before you tell it what it should. "Using SDL 3 (not SDL 2), C++17, no external libraries beyond SDL and its satellite libs, write a …" is far more reliable than just "write a …" followed by "oh and use SDL 3" after the AI starts with SDL 2.
For this book's projects, a good preamble for any prompt looks like:
I am writing C++17 with SDL 3. Do not use SDL 2 API.
Do not use deprecated SDL 3 functions.
Use #pragma once for header guards.
Keep all SDL resource management in RAII wrappers.
[Your actual request here]
Copy-pasting that header takes two seconds and saves you from 80% of "helpful" SDL 2 answers.
Be Specific About Structure
"Add a particle effect" is a poor prompt. "Add a particle effect as a ParticleSystem class in ParticleSystem.h/.cpp that takes an SDL_Renderer* and a Point in its constructor, stores up to 64 Particle structs, and draws with SDL_RenderFillRect" is a good prompt. The AI doesn't have to guess; it produces the code you actually want.
Ask for One Thing at a Time
Multi-part prompts yield multi-part outputs with multi-part bugs. "Add enemy movement, add sound effects, and add a high score system" in one prompt will produce code for all three that's harder to review and harder to debug. Do them separately.
Paste the Surrounding Code
The AI doesn't know your codebase. If you want it to add a method to your Entity class, paste the current Entity.h as context. If you want it to fix a bug in a function, paste that function. Without context, you get generic answers; with context, you get answers that fit your style.
The Accept / Edit / Reject Habit
Every time an AI produces code, put it through three questions before it goes into your file:
- Does it compile? Build before anything else. An AI that produces non-compiling code has given you nothing useful yet.
- Does it do what I asked? Run it against your mental model of the expected behaviour. For a game, this usually means running the game and checking the feature manually.
- Do I understand every line? If there's a line you don't understand, look it up or ask a follow-up question. Never commit code you can't explain.
Based on those three, you accept, edit, or reject. "Accept" means it's good as-is. "Edit" means it's close enough to be worth tweaking rather than re-prompting. "Reject" means you prompt again with more detail or write the code yourself.
Most AI output will fall into "edit" — the shape is right but the details need adjusting. This is expected and fine. The AI is a first-draft generator, not a finished-code generator.
Where AI Helps Most
Some tasks are well-suited to AI generation:
- Boilerplate. Getters, setters, constructors, serialisation code, file-handling loops — anything repetitive and low-risk.
- API translation. "Show me how to open a file with
std::ifstream" is a lookup task. AI is a searchable reference with examples. - Scaffolding. The skeleton of a class, the basic structure of a game loop, the outline of a state machine — then you fill in the logic.
- Error message decoding. Paste a C++ template error into the prompt. You'll usually get a clear explanation faster than you'd find it yourself.
- Alternative approaches. "What are three different ways I could implement a spatial hash?" — good for surveying options before committing to one.
Where AI Helps Least
Some tasks you should keep firmly in your own hands:
- Architecture decisions. "Should I use a component system or deep inheritance?" The AI will answer confidently in whatever direction your prompt leans. Your knowledge of the trade-offs, your project's constraints, and your own judgment are what matter here.
- Bug isolation. When something goes wrong, the fastest path to the root cause is usually you thinking carefully about the code. AI can help once you've identified a candidate, but "here's my bug, fix it" without your own hypothesis first trains you out of debugging.
- Performance-critical inner loops. Generated code is correct-first and fast-later. Hand-tune tight loops yourself after profiling.
- Security-sensitive code. Authentication, encryption, permission checks — these require expertise and careful review that AI output doesn't substitute for.
The Senior-Engineer Mindset
The best mental model for using an AI coding assistant is to think of yourself as a senior engineer working with a very fast but unreliable junior. The junior can type quickly, knows a lot of patterns, and produces plausible first drafts — but they don't know your codebase, they sometimes make things up, and they won't flag when they're out of their depth.
A good senior engineer doesn't rubber-stamp every junior's PR. They review it, ask questions, request changes, and mentor through mistakes. Apply the same standard to AI output. You're not abdicating judgment — you're leveraging a tool. The judgment still lives with you.
As you get faster with the language, you'll develop intuition for which parts of a feature to delegate to AI and which to own yourself. That intuition is built by reviewing lots of AI output critically — which means you have to understand the domain well enough to know good from bad.
Using AI in Visual Studio
Visual Studio integrates AI coding assistance through GitHub Copilot (built into Visual Studio 2022 v17.10 and later). Once the Copilot extension is installed and you're signed in with a GitHub account, you'll see inline code suggestions as you type — grey ghost text that you accept with Tab.
The Copilot Chat panel (View → GitHub Copilot Chat) lets you ask questions about your code, explain selected functions, or request modifications. To give it context about your current file, use the #file and #selection references in your chat message.
Useful commands in Copilot Chat include:
/explain— explain the selected code/fix— suggest a fix for the selected code/tests— generate unit tests for the selected function/doc— generate a documentation comment
For the projects in the next few chapters, you can use any AI assistant — Copilot inline in Visual Studio, the Copilot Chat panel, Claude, ChatGPT, or any other tool you prefer. The principles in this chapter apply regardless of which one you use.
A Note on the Next Three Chapters
Chapters 24 and 25 are "vibe-coding" projects: we'll use AI to generate most of the code for complete games, reviewing and guiding as we go. The point isn't to abandon everything you've learned — it's the opposite. The chapters work precisely because you've learned enough C++ to evaluate the AI's output and spot problems when they arise.
Chapters 26 and 27 then step back to cover two important design patterns — the Component pattern and Data Locality — that are hard for any AI to select wisely because they require understanding your specific constraints. You'll see both patterns in the final project.
Summary
- The four failure modes are plausible nonsense, helpful drift, the confidence problem, and the atrophy trap. Knowing them lets you watch for them.
- Good prompts front-load constraints, specify structure, ask for one thing at a time, and include relevant context.
- Apply the accept / edit / reject habit to every piece of AI-generated code. Never commit code you can't explain.
- AI is most useful for boilerplate, scaffolding, API lookup, and error decoding. Keep architecture, bug isolation, and security-sensitive code in your own hands.
- Think of yourself as the senior engineer. The judgment stays with you.