1. Architecture with The System Stack
Many software developers struggle with architecture. There is a common misconception that architecture is something you can fully design up front and all your software will slot into place. This has not been my experience, nor the experience of any experienced developer I know.
However, that doesn't mean we can't create a broad overview and come up with a plan for how to tackle a complex program like a game.
Rather than teaching you only how to program specific features, I'm going to teach you how to come up with the features you need to program.
You'll need an outline of the things you want to be able to do in your game. This can start out rough, using comparisons to other games for brevity's sake. If you don't know any other games with similar activities then you'll want to use more descriptive, specific language.
To be clear, this is not a Game Design Document. We are creating a System Stack.
Verb Extraction
Here's a simple pitch for the vertical slice we are making, without referring to other games (yet):
Explore a quaint town, battle monsters outside, and help the locals with their problems.
Explore, battle, help: These are the verbs. Verbs describe what can be done in your game.
With just these three, we can infer that we need the following systems. I'll start at a high level and then later we can extrapolate down.
Verbs to Systems
Explore: Character controller, collision system, scenes (battle vs explore, and somewhere to explore)
Battle: Stats, combat system, encounter system
Help: Quest system, dialogue system, interaction system
This is a good start! We already have a bunch of things we could start work on. However, we should try extrapolating from these and see what turns up. We can do this by asking questions.
I'm going to ask myself questions and provide my answers. This is a genuine representation, not fabricated for this lecture. I.E. These are my real questions and answers. Though, I have added some beginner-style questions to challenge my assumptions. As I have experience already, I will intuit things that others may not.
Character Controller
Q: If the character needs a controller, what is a character? What are the physical properties you are imagining?
A: I'm imagining a 2D sprite moving around in a 3D world, similar to Octopath Traveler.
Q: Will other similar sprites be moving around the screen?
A: Yes.
Q: Will these sprites be the same?
A: No. They should be different. One for the player, one for the blacksmith, one for the mayor, etc.
Q: So then we need different animations and different behaviors? When the player walks, it plays the walking animation only for that character?
A: Yes.
Then we probably want a system to handle this, rather than having hard-coded characters. So, we'll create an "Entity" system.
I have taken a shortcut here, because I already know what an Entity system is. There will probably be solutions outside of our sphere of understanding, but we can still draw conclusions from patterns. If I didn't know I wanted an Entity system, then I may have settled on a "Character" system - where NPCs and the player character can be handled.
We've also teased out that we need some way of playing sprite animations as well as (potentially) NPC path-finding.
Conclusion: From thinking about movement and animation, we've uncovered:
- A need for an Entity System to manage different characters
- A need for a Sprite Animation system
- Future implications like NPC AI/pathfinding
We can extrapolate from this that we also need some way to load and reference assets such as sprite sheets, textures, models, etc.
Designing just one interaction like "walking around" forced us to define how characters exist and behave in the world.
Collision System
Q: Say the player character moves to the left and a wall is obstructing them? How could we detect that?
A: I'm not sure, yet, but I know we should prevent walking out of bounds or through objects and terrain.
It's okay to leave things until more information about the specifics comes into focus.
Q: If the player character is controllable, how can we control it? What must the user do to move the character left?
A: Press Left on the gamepad or keyboard.
Q: How will we know when they do that?
A: We need to query and capture it.
Q: What if they switch between gamepad and keyboard? Should either work?
A: We should make either work, yes.
Q: If we decide to show prompts (Press A to Interact), what happens if the user switches input devices?
A: We should swap the prompt text/icons between kb/m<->gamepad.
Q: And if the user wants to rebind these controls?
A: We should facilitate that, which means... Menus, UI, and saving configuration between play sessions.
We have realised we need some kind of collision system, but not sure what it is yet. We have also teased out another few systems: an Input system, UI system, Menu system, and Configuration system. As you can see, there are a lot of hidden complexities under the surface, should you choose to investigate. Teasing these out gives a more accurate understanding of the project's scope.
Conclusion: From exploring collision, we've realised:
- We need to know where entities are, and where they can/can't go
- Input from devices must be abstracted for flexibility
- This leads to new systems: Input, UI/Menus, Config
What starts as "don't walk through walls" quickly develops into base engine requirements. This is normal.
Scenes
I've presupposed that we want a battle scene separate from the scene we walk around in.
Q: The player character is walking around, in what?
A: In a town!
Q: What does this town look like?
A: I'm not sure, I'm imagining a tilt-shift fantasy town like Octopath Traveler.
Q: Can the camera be rotated? What about moved?
A: Probably not - that way the visuals can be designed precisely. I think the camera should follow the player, so the scenes can be a bit larger.
Q: Can the player jump?
A: I don't think that's necessary.
Not all questions come up in the relevant sections. This is normal as we can't control the connections our brains make.
Q: Can the player leave the town? What's outside?
A: Vaguely... The wilderness. Just more scenes but in a wilderness area. Monsters live outside town.
Q: Are the monsters visible in the scene or are the encounters random?
A: They are visible in the scene.
Q: Do the monsters move around? Patrol an area? Do they chase the player?
A: They move around, they do not chase the player - the player can choose to interact or not.
Q: Are there slopes? Or is the world flat?
A: I'd prefer slopes.
Looking at Octopath Traveler gives us a decent frame of reference. We need 3D models, we need 2D animated sprites, we need some way to transition between scenes. We need some NPC (monster) AI system, and a way to trigger that the player and monsters started a battle.
Conclusion: From this scene discussion, we've established:
- A world context (towns, wilderness)
- A 3D world + 2D sprite w/ follow camera system for the scenes
- A way to determine entity collisions and trigger battle start
Even without deep technical decisions, we're forming a vision of our game's feel, and what that means for the codebase's structure.
Stats
I know from playing other RPGs that I want stats to affect things like turn speed, damage, health, or mana (assuming we have those).
Q: Can the player choose the character's stats?
A: At level-up or via gear, perhaps. I'm not sure.
Q: Does each party member start with set stats?
A: Probably, yes - perhaps a simple Tank/Damage/Healer setup.
Conclusion: Drawing on knowledge from other RPGs, we know:
- Stats must be per-character (probably tied to Entity)
- Stats will affect turn order, damage, ability effectiveness
- Stats will have a base per character, but perhaps modified in unconventional ways
We are missing detail here, but that's fine for a system like this as it's so advanced in terms of requirements.
Combat System
I know I need some system to manage this code cycle: Input (characters, enemies), Processing (taking turns), Output (exp gained, items found, etc).
I have an idea of what It'll be from playing other RPGs. Just FYI, I'll program something similar to the Conditional-Turn-Based system of Final Fantasy X. But, as you'll find out soon, you can do something entirely different - so long as our inputs and outputs match.
Q: What kind of actions can the player take during combat?
A: They can use items or abilities, guard, or skip.
So we need items in the game. And abilities.
Q: Can characters move around the screen during battle?
A: No. Not unless you count running up to something and attacking it, or casting a spell as moving.
Q: So, animations - but not positional combat?
A: That's right.
We already teased out the animation syste requirement above, but this solidifies it.
Q: What happens if all the player characters die?
A: That's a game-over and they'll need to start from the last save.
So... We need a save game system of some kind!
Conclusion: Defining the combat somewhat reveals:
- The need for a "Combat Manager" that handles turns
- An interface for abilities, items, status effects, animations
- Win/Lose conditions that connect to the save/load system
Encounter System
This was already covered above, in the scenes section. So, I will tailor my questions to be more specific here.
Q: Can the player sneak up on enemies?
A: Yes, if the player walks into the enemy from behind, they will get a "back attack" - giving the player free turns at the start of the battle.
Q: Can the player run away from enemies?
A: Yes. There should be some "escape" option in battle. No exp is received for escaping battle.
This probably should have been in the combat section, but for the sake of authenticity, I left it here.
Q: How sparse or dense will the enemies be in the world?
A: Not so sparse that they can all be avoided easily, but also not so dense that it's annoying. I guess this will take some play-testing.
Q: Will enemies have set spawn points or be random?
A: Set spawn points.
Q: Will enemies respawn?
A: Yes, if you leave a scene and walk back in, all enemies are repsawned... Or! Maybe it'd be cool if the enemies respawn after 1 day (or after the player sleeps at an inn - if there are inns).
We've identified another potential feature here which is the player sleeping, and also the concept of a day/night cycle OR time in general progressing as the player plays the game.
That means we need to keep track of the time of day to managed things like respawns, cooldowns (if any), etc.
Quest System
Q: How will the player get quests?
A: Talking to NPCs, picking up an item, maybe even after killing a certain monster.
Q: Those are three very different interactions the player has with the game. How could these all plug into the quest system?
I already had an answer for this, it's hard not to steer my own questions towards the pre-conveived answer. So, I'll end it here.
A: Using an event system that will be accessible to all other systems.
Dialogue System
Q: Will the player be able to make dialogue choices?
A: Yes. I think that would be great.
Q: How extensive will these choices be?
A: I'm imagining something like Skyrim where NPCs have specific things they can talk about and actions they are willing to take, as well as quests they can give.
Q: So, a list of pre-defined options?
A: Yeah.
Q: Would you want the text to be translated into other languages?
A: Yes, probably. So I guess that means we need to load the text from files.
Interaction System
Q: What kinds of objects should the player character be able to interact with?
A: Chests, NPCs, Doors... That's about all I can think of right now.
Chests means items, NPCs means actors/entities and doors... Well, we can make all of these things Entities.
Q: So if a Door is an Entity, that means some entities can stop the player from moving through (I.E. has static collision)?
A: Yes, that means we need to link the collision and entity systems and allow for flexible options.
Q: How will the game know when a Chest is opened?
A: I guess we need to fire off an event, or mark it in the game state, somehow.
Q: What happens when a chest is opened? Does the item appear in the world?
A: I think it's satisfying for items to appear on the ground and then you pick them up. However, that could be a "nice to have".
Conclusion: By examining the interaction events, we discovered:
- Many kinds of objects can be interacted with, so make them entities
- Entities must be linked with collisions somehow
- We probably need an Event System
- We may want particles or other effects when opening chests
- We need a way for items to appear in the game world
The 2nd point illuminates the coupling of the entity and collision systems.
We haven't yet discussed how inventory is going to work. We can assume it'll be a simple list until we get further into development and then may revisit it.
NPC Schedules
Something I didn't mention at all in the Q/A is a feature I want. It's NPC Schedules - for example they may wake up at certain times, walk around town and run errands, and go to the pub in the evening.
Q: Are NPC schedules fixed? Do they do the same thing every day?
A: I think for simplicity we should keep them doing the same routine every day. It also means if the player hears "John is at the butcher shop between 10am and 11am each day" then that'll be true.
Q: Can they ever update their schedules?
A: I think they should be able to... For example if an NPCs loved one dies, they may visit their grave each day.
Action Extraction
Before we create the System Stack, we need to make sure we've found as many systems as we can up-front.
Some came from questions, but others may be implied by what the player sees, feels, or expects. Those can be easy to miss until play-testing, so we want to find them early.
Here's a quick 3-pass method I use for this, Action Extraction:
Pass 1: Verbs -> Systems
Our pitch says: explore, battle, help.
For each verb, ask this: "What does the player do here, and what system(s) makes that possible?"
| Verb | Action | Systems |
|---|---|---|
| Explore | Walk, Enter Doors, Enter Areas | Character Controller, Collision, Scene Management |
| Battle | Choose Abilities, Take Turns, Use Items | Combat System, Stats, Inventory, Abilities |
| Help | Talk, Accept Quests | Dialogue, Quest System, Event System |
Pass 2: Simulation Systems
Question: "What is changing or running in the background?"
- Enemy Respawns: Time System, Spawn Manager
- Dialogue/Quest flags/state: Quest/State System
- Time of Day: Day/Night, Time System
- NPC Schedules: Time System, NPC Schedule System
Pass 3: Presentation Systems
Question: "What makes the game feel alive?"
- Animated sprites: Animation System
- NPCs walking around: NPC Schedule System
- Talk to any NPC: Dialogue System, Input
- Weather effects?: Shaders, Particles
- Animated grass?: Shaders
- Sound effects: Sound System
Creating the System Stack
Alright, so we have a bunch of systems, or requirements that we can assign to systems. Now we need to organise these by dependency so we know where to start.
1. Write Down System Dependencies
For each system, ask:
- What does this depend on?
- What does this provide to others?
For example:
- Combat depends on Stats, Abilities, Inventory, UI, Entities, Scenes, ...
- UI depends on Input
- Inventory depends on Item Data, UI
2. Group Systems by Responsibility
Roughly group systems together based on dependencies.
Here are my groupings:
- Entities, Input, Time, Assets, Save/Load - No dependencies
- Camera, Shaders, Animation, UI, Particles
- Player, Collisions, AI/Pathfinding, Scenes
- Stats, Combat, Inventory, Equipment, Abilities
- Dialogue, Quests, NPC Schedules
Each group depends on things from previous ones, but not the other way around.
There will be some exceptions to this. Some systems will be hard-coupled, such as collisions and entities.
Remember, this is a plan we are building. Not a fully specified blueprint.
We need a plan to know where to begin. We can always modify it later if things don't work out exactly as expected. (And, they rarely do).
3. Review
As I said, some systems will be hard-coupled and knowing what those are up-front comes from experience.
For everything else, make sure it looks right, and then optionally create a little diagram to refer to. Here's ours:
![[system_stack_rpg_image.png]]
System Stack Conclusion
We started with three verbs: explore, battle, and help.
By asking questions, we uncovered systems.
By exploring those systems, we uncovered dependencies, features, and even design choices we hadn't considered.
This is how architecture really works:
It's never a perfect upfront plan.
It's a process of discovery, constraints, and iteration.
The System Stack gives us a broad map of the vertical slice we want to build.
In the future lectures, we'll zoom into each part of that map and begin building systems using the Fractal Code Cycle to guide our implementation at every level.