Game development was not originally something I thought of as part of my technical portfolio. The more complicated the projects became, the less that distinction made sense.
A large game system can involve databases, networking, client/server authority, data schemas, state machines, UI architecture, automation, testing, asset pipelines & a lot of debugging. The fact that the final result is a game does not make those technical problems less real.
For me it has become one of the best environments for practicing systems thinking because everything eventually has to interact.
Build complex game features in a way that can survive iteration instead of only surviving the first implementation.
1. Working code is not automatically good architecture
This is probably the lesson I have had to learn the most often. It is very easy to make a feature work by connecting everything directly to everything else.
That feels fast until the feature changes.
If combat simulation, visual effects, UI, persistence & content definitions all depend directly on one another, a small change can spread through the entire project. Suddenly changing a presentation detail risks breaking game logic.
I have been moving toward clearer boundaries: simulation owns simulation, presentation displays the result, content data describes content, persistence stores state & adapters translate between systems where needed.
The point is not architecture for architecture's sake. The point is making future changes cheaper.
2. A lot of game bugs are really data-contract bugs
Games contain huge amounts of structured data: items, characters, actions, monsters, stats, progression, maps, routes, rewards & configuration.
If one resource expects a boolean called provisional_value & the schema does not define it, the content is not the only thing that is wrong. The contract between the content & the code has drifted.
That kind of problem taught me to care much more about registries, validation & schema alignment. A content file should not be able to quietly invent fields the consuming system does not understand.
3. Authority matters even outside cybersecurity
One concept that crosses over directly into security is authority. Which system gets to decide what is true?
In a multiplayer or server-backed game, the client should not necessarily be trusted to decide rewards, damage, inventory or progression. The client can request an action. The authoritative system validates it & determines the result.
That is fundamentally a trust-boundary problem.
Even in offline architecture, thinking this way helps because it separates input from truth. UI should not become the hidden owner of game state just because the button happened to initiate the action.
4. UI is an information system
I used to think about UI much more as presentation. The deeper I get into UI/UX work, the more I see it as information architecture.
The player needs to understand what state the game is in, what options are available, what changed & why. A technically powerful system can still feel terrible if the interface makes the rules invisible.
That is very similar to security tooling. A system can collect excellent information & still fail the operator if the interface makes that information difficult to interpret.
5. Debugging needs a memory
Some bugs are cheap. You fix a typo & move on.
Other bugs take hours because several systems interact in a way you did not expect. Those are the ones I want to preserve.
I have started maintaining lessons-learned documentation for exactly that reason. If I discover that a Godot resource parser, registry, schema or import process fails in a particular way, I want the next person — including future me or an AI agent — to start with that information.
If a bug was expensive to understand once, preserve enough of the lesson that it becomes cheaper the second time.
6. Tests protect decisions, not just code
A test is most useful when it captures behavior I care about. If a combat rule says speed changes turn order but never grants extra actions, that rule should be testable.
Otherwise a later refactor can change the behavior while every individual function still appears reasonable.
I am increasingly using preflight checks, regression tests & focused validation to protect these decisions. It is much easier to make aggressive changes when the project can tell me which promises I accidentally broke.
7. Git is part of the development architecture
Version control matters even more once AI enters the workflow. I want major changes isolated, reviewable & recoverable.
Branches let me experiment without pretending the experiment is already production. Commits give me milestones. Diffs show me exactly what changed. A repository also gives collaborators & tools a shared source of truth.
That is why I have been moving more project planning, documentation & lessons learned into the repositories themselves.
8. AI is useful when the project gives it structure
I use AI heavily for architecture review, debugging, implementation, test planning & documentation. The results get dramatically better when the project itself contains good context.
If the repository explains the architecture, preserves decisions & contains tests, the AI has something concrete to work against.
If the project is undocumented spaghetti, giving a model access to it does not magically make the architecture clear. It can just produce spaghetti faster.
That is another reason I care about structured project files & lessons learned. They help humans, but they also improve the quality of AI-assisted work.
9. Art pipelines are technical pipelines too
My projects also involve Blender, generated 3D assets, image-to-model workflows & Godot import pipelines. That introduces another class of technical problem: file formats, scale, orientation, materials, animation, naming & reproducibility.
An asset that looks correct in one tool can import sideways, at the wrong scale or with broken materials in another. Again, the solution is normally understanding the boundary between the systems instead of randomly changing settings until it looks right.
10. The larger lesson
The more complex the game becomes, the more I value explicit ownership. Who owns this state? Which layer is allowed to change it? Where is this data defined? Which test proves the behavior? What is presentation & what is simulation?
Those questions are not unique to games. They are systems-engineering questions.
Where this goes next
I want to continue tightening the architecture around combat, world systems, persistence, content validation & automated testing while improving how art, UI & AI-assisted development fit into the pipeline.
The games will keep changing. That is expected. The real technical objective is making sure the architecture can change with them without requiring a rewrite every time a design decision evolves.
