
Architecting Pokémon Combat: Advanced Data Structures and Patterns in C++
Inquiry Framework
Question Framework
Driving Question
The overarching question that guides the entire project.How can we architect a scalable and decoupled turn-based combat engine in Unreal Engine that utilizes C++ design patterns and data structures to manage the complex logic of a Pokémon-style battle system?Essential Questions
Supporting questions that break down major concepts.- How can architectural patterns like Model-View-Controller (MVC) or Delegate patterns be used to decouple combat logic from the Unreal Engine UI/Visuals?
- Which data structures (TMaps, TArrays, or Structs) provide the most efficient way to manage a complex 'Type Effectiveness' matrix and a move database?
- How can a Finite State Machine (FSM) be implemented in C++ to handle the sequential phases of turn-based combat (e.g., Input, Calculation, Animation, Resolution)?
- How can we utilize polymorphism and inheritance to create a flexible 'Move' system that allows for diverse effects (damage, buffs, status changes) without hard-coding specific logic for every individual move?
- In what ways does using Data Assets in Unreal Engine improve the scalability of our software architecture compared to hard-coding Pokémon stats directly into C++ classes?
- How do we manage complex state dependencies—such as priority brackets, speed ties, and held items—using efficient sorting algorithms and conditional logic?
Standards & Learning Goals
Learning Goals
By the end of this project, students will be able to:- Implement a robust Finite State Machine (FSM) in C++ to manage discrete turn-based combat phases (Input, Calculation, Animation, Resolution).
- Architect a decoupled game system using the Model-View-Controller (MVC) or Delegate pattern to separate core combat logic from Unreal Engine's UI and visual components.
- Develop a scalable data management system utilizing Unreal Engine Data Assets, TMaps, and Structs to handle complex type-effectiveness matrices and move databases.
- Apply advanced Object-Oriented Programming (OOP) principles, specifically polymorphism and inheritance, to create an extensible 'Move' system that supports diverse gameplay effects without code duplication.
- Design and execute efficient sorting algorithms to resolve turn order based on complex state dependencies such as speed stats, priority brackets, and held items.
CSTA K-12 Computer Science Standards
ACM/IEEE CS2023 Curricula (Software Development Fundamentals)
ACM/IEEE CS2023 Curricula (Software Engineering)
Entry Events
Events that will be used to introduce the project to studentsThe 'God Object' Intervention
Students are handed a single, 4,000-line C++ file called 'BattleMaster.cpp' that contains everything from damage math to UI button clicks and sound triggers. Their task is to add a single 'Paralyze' status effect. As they struggle with the massive 'if-else' chains and spaghetti dependencies, they must identify how to 'shatter' the class into smaller, decoupled components like a 'DamageCalculator', a 'StateController', and a 'UIManager'.The 'Headless' Combat Challenge
Students are given a monolithic Pokémon battle class that is tightly coupled to Unreal Engine’s visual components. They are challenged to extract the core mathematical logic so it can run as a 'headless' (no graphics) C++ console application. This forces the separation of 'Logic' from 'Presentation,' requiring the breakdown of one giant class into reusable, engine-agnostic modules that can be tested independently.The Refactoring Bounty
Students are presented with a 'Spaghetti Code' version of a Pokémon battle engine where a single class is responsible for 15 different tasks. Each 'sub-system' they successfully extract into a standalone, reusable class or struct (like a 'TypeTable' module or a 'MoveLibrary' handler) earns them 'bounty' points, gamifying the process of identifying and fixing class bloat through refactoring.Portfolio Activities
Portfolio Activities
These activities progressively build towards your learning goals, with each submission contributing to the student's final portfolio.Data Architect: Building the Elemental Matrix
Before writing combat logic, students must architect the data layer. In this activity, students will design a scalable 'Type System' using Unreal Engine C++ Structs and TMaps. They will move away from hard-coded 'if-else' checks for damage multipliers and instead create a data-driven lookup table that can handle any number of elemental types (Fire, Water, Grass, etc.).Steps
Here is some basic scaffolding to help students complete the activity.Final Product
What students will submit as the final product of the activityA 'TypeChart' Data Asset and a 'PokémonBase' Data Asset that allow designers to define stats and elemental weaknesses without touching code.Alignment
How this activity aligns with the learning objectives & standardsAligns with CSTA 3B-AP-14 (Compare and contrast the performance of different data structures) and 3B-AP-12 (Construct solutions using student-created components). It specifically addresses the inquiry framework question regarding using TMaps and Structs for a Type Effectiveness matrix.Move Polymorphism: The Action Factory
Students will create a flexible 'Move' system using C++ inheritance. Instead of one giant 'Move' class with a switch statement for every effect, students will create a base 'BattleMove' class and extend it into specialized subclasses. This allows 'Thunder Bolt' (Damage) and 'Tail Whip' (Stat Debuff) to share a common interface while executing different internal logic.Steps
Here is some basic scaffolding to help students complete the activity.Final Product
What students will submit as the final product of the activityAn extensible Move Hierarchy consisting of a base class and at least three functional subclasses (DamageMove, StatusMove, and BuffMove).Alignment
How this activity aligns with the learning objectives & standardsAligns with ACM/IEEE SDF-OOD-01 (Design and implement a class hierarchy that includes inheritance and polymorphism). This activity directly tackles the 'Move' system essential question by using OOP to avoid code duplication.The Battle Conductor: State Machine Logic
Turn-based games are driven by states. In this activity, students will implement a Finite State Machine (FSM) to manage the flow of a battle. This prevents logic errors like players attacking during an animation or moves being processed before input is received. Students will define states such as Selection, Action, Calculation, and Resolution.Steps
Here is some basic scaffolding to help students complete the activity.Final Product
What students will submit as the final product of the activityA C++ BattleStateMachine component that transitions between combat phases and logs state entries/exits to the Unreal Output Log.Alignment
How this activity aligns with the learning objectives & standardsAligns with ACM/IEEE SDF-OOD-04 (Represent and implement a state machine to solve a problem with discrete states). It provides the core 'brain' for the turn-based nature of the project.Headless Hero: Decoupling Logic with Delegates
To ensure the combat engine is 'scalable' and 'headless,' students will use the Delegate pattern (Observer Pattern) to decouple the logic from the UI. The core C++ combat classes should never 'know' about a Progress Bar or a Button; instead, they will broadcast events that the UI 'listens' for.Steps
Here is some basic scaffolding to help students complete the activity.Final Product
What students will submit as the final product of the activityA 'Headless' combat simulation where the game logic runs entirely in the background, communicating with the UI via Broadcast Delegates.Alignment
How this activity aligns with the learning objectives & standardsAligns with ACM/IEEE SE-ARCH-01 (Describe the role of architectural patterns like MVC) and CSTA 3B-AP-12. This activity ensures the game logic is independent of the 'View' (Unreal's visuals).The Priority Sorter: Resolving the Turn Order
In the final architectural piece, students must handle turn order. Pokémon combat uses 'Priority Brackets' and 'Speed Stats' to determine who moves first. Students will implement a custom sorting algorithm using TArrays to organize 'Action' objects before they are executed by the State Machine.Steps
Here is some basic scaffolding to help students complete the activity.Final Product
What students will submit as the final product of the activityA Turn-Sequencer module that correctly sorts moves based on priority, speed, and status effects (like Trick Room or Paralysis).Alignment
How this activity aligns with the learning objectives & standardsAligns with CSTA 3B-AP-14 (Performance of data structures) and 3B-AP-12. It focuses on the specific learning goal of managing complex state dependencies and sorting.Rubric & Reflection
Portfolio Rubric
Grading criteria for assessing the overall project portfolioPokémon Combat Engine: Advanced C++ Architecture Rubric
Software Architecture & Logic Flow
Evaluates the high-level structural integrity and modularity of the software solution.Decoupling and Architectural Patterns (MVC)
Evaluation of the student's ability to separate game logic from the user interface using the Delegate/Observer pattern.
Exemplary
4 PointsThe combat engine is completely 'headless' with zero dependencies on UI classes. Utilizes Dynamic Multicast Delegates effectively to broadcast state changes. The UI only 'listens' and never drives the logic. Implementation shows advanced understanding of event-driven architecture.
Proficient
3 PointsSuccessfully decouples core logic from the UI using delegates. Most communication between the BattleController and the UI happens via events. There are no circular dependencies, though some UI-specific data might bleed into the logic layer.
Developing
2 PointsShows emerging understanding of decoupling. While some delegates are used, the core logic still maintains direct references to some UI elements or requires the UI to exist to function properly. Dependency management is inconsistent.
Beginning
1 PointsLogic and UI are tightly coupled. The combat engine relies on direct calls to UI widgets or hard-coded UI references. Changes to the UI would require significant rewrites of the combat logic.
State Management (Finite State Machine)
Assessment of the student's implementation of a Finite State Machine (FSM) to manage turn-based flow.
Exemplary
4 PointsImplements a robust, error-proof FSM using a state pattern or highly organized switch/case logic. Transitions are clean, and illegal actions (e.g., attacking during animation) are architecturally impossible. Handles complex transitions like mid-turn faints.
Proficient
3 PointsImplements a functional State Machine that accurately tracks turn phases (Selection, Action, Resolution). Transitions are predictable and log correctly to the console. Most edge cases are handled.
Developing
2 PointsThe system uses a basic state variable to track turns, but logic is prone to 'state leakage' where actions from one state can occur in another. Transitions are manually handled and somewhat brittle.
Beginning
1 PointsTurn logic is managed via scattered boolean flags and if-else chains. There is no clear centralized controller for the game state, leading to frequent logic bugs or out-of-order execution.
Data Modeling & Algorithmic Efficiency
Focuses on the efficiency, performance, and organization of data and algorithms.Data Structure Selection & Scalability
Evaluation of the use of C++ Structs, TMaps, and Unreal Data Assets for scalable game data.
Exemplary
4 PointsMasterful use of Data Assets and TMaps (O(1) lookup). The Type Effectiveness matrix is handled via a nested TMap or efficient lookup table. Designers can add new Pokémon or Types without changing a single line of C++ code.
Proficient
3 PointsEffective use of Data Assets and Structs. Type effectiveness and stats are stored externally from the logic classes. The system is scalable, though lookup logic could be slightly more optimized.
Developing
2 PointsData is partially externalized using Structs, but some stats or type interactions remain hard-coded. Use of TMaps is present but perhaps redundant or inefficiently structured.
Beginning
1 PointsStats and type relationships are hard-coded into C++ classes. The system is not scalable; adding a new Pokémon type would require significant manual code updates and recompilation.
Algorithmic Logic (Sorting & Turn Order)
Assessment of turn-order resolution using sorting algorithms and priority logic.
Exemplary
4 PointsImplements a sophisticated TArray sort using a custom Lambda predicate. Correctly resolves priority brackets first, then speed stats, and finally handles 'speed ties' using an RNG seed for fairness. The implementation is clean and highly efficient.
Proficient
3 PointsCorrectly sorts the turn order based on priority and speed. Uses TArray::Sort or a similar algorithm effectively. Handles the majority of turn-order scenarios accurately.
Developing
2 PointsBasic sorting is implemented, but the logic may fail to account for priority brackets or only checks speed. Speed ties are not handled or result in predictable/static outcomes.
Beginning
1 PointsTurn order is determined by the order of player input or simple index iteration. No sorting algorithm is present to handle priority or speed dependencies.
Object-Oriented Design (OOD)
Measures the depth of Object-Oriented Programming principles applied to the game systems.Inheritance & Polymorphism Implementation
Evaluation of the 'Move' system using C++ inheritance and polymorphism.
Exemplary
4 PointsImplements an elegant class hierarchy with a pure virtual base class. Move effects (Damage, Status, Buffs) are modular and can be stacked in a single move instance via a polymorphic array. Extremely easy to extend with new move types.
Proficient
3 PointsSuccessfully uses inheritance to create different Move types (e.g., DamageMove vs StatusMove). Overridden functions are used correctly to implement specialized behavior without code duplication in the base class.
Developing
2 PointsUses inheritance, but some logic is still duplicated across subclasses. The base class might contain too much 'knowledge' of its children, or polymorphism is used only for simple damage variations.
Beginning
1 PointsThe move system relies on a single class with a large 'switch' statement or nested 'if' blocks to determine move effects. No meaningful use of inheritance or polymorphism is present.