I’m interested in discussing which design patterns fit with the existing workflow/patterns in the engine. More specifically, what patterns/design decisions are a best fit for common game related problems. I hope this thread can turn into a resource we can all use to apply to our own projects. To start off, here’s an example I’m working to solve at the moment.
Suppose we have a team-based multiplayer game mode with the following requirements:
- A team is a group of players
- There are N different types of teams (Assume a Blueprint to represent each type of team; all teams derived from a base class ATeamBase, which derives from AActor)
- Each player must belong to a team; Each player derives from base class ACharacter
- Each team has a persistent unique ID, which is used to retrieve persistent data that describes the team i.e Type, Name, Skin etc
- When a player joins a game, if their team doesn’t already exist in the world (i.e. team mate already in server), it is instantiated into the world through (World()->SpawnActor()) which is visually represented i.e TeamHQ
- Players must be able to send messages to their team mates
- Players always spawn at their TeamHQ
- When all players from the same team leave the game, the team Actor is destroyed
This presents a few decisions that have to be made:
- Who is responsible for creating the team and type i.e. Aliens/Marines, Cowboys/Indians etc? They must have knowledge of which Blueprint corresponds to each team type
- Who is responsible for keeping references to the teams? So we can check if a team already exists, perform a function on a specific team, or iterate over all the teams
- Who is responsible for deleting the team (When no players are left)?
There are a few potential solutions to this:
- Allow the GameMode to be responsible for everything. i.e. Create the team, Add the player to the team, Delete the team when the last player leaves. (Violates single responsibility principle)
- Create a ‘Team Manager’ class to handle the creation, store references and delete the team. The Team class then just becomes a container for players in the team. GameMode calls Team Manager functions. (Manager classes are generally considered as a sign of not understanding the problem properly. Most of the functionality can be moved into the Team class itself. Would use IoC solution to DI the manager into classes where it’s a dependency. Unsure of implementation in UE4. Need to locate something like C# Autofac)
- Create static methods/variables in the team class to create/store references and delete teams. (Much like the singleton pattern, this makes Unit Testing difficult and is not loosely coupled)
- Encapsulate each function into its own class. i.e. Team Factory Class to handle creation etc. (Can lead to fragmented code base for little benefit in some cases)
I’d be interested to hear how you would design a solution to this common problem as it pops up quite frequently. i.e. Particle System. Who is responsible for creating/deleting, keeping references so the particles can be iterated over.