I'm experimenting with Clean Architecture for my turn-based strategy game project. I have use cases that form hierarchies and need to be coordinated with each other. I would like some advice on how to design these interactions.
My entry point to the game is the
TurnUseCase. It gives information about the current turn, the list of actions that are possible in that turn and allows to end the turn. The end of the turn bit is important as it is causing my issues.
Inside the turn, players can perform various actions. Each has its own use case, for example
DefendUseCase. After some actions, the turn should end.
AttackUseCase should pass information to the
TurnUseCase that the turn should now end? Without that information, the
TurnUseCase can't progress the game to another player.
- Should I have the dependency between these use cases? Do I need a Factory to create all these use cases and manage relationships between them?
- Should I use Observer to notify the other use case?
- Should I create some kind of System Use Case that will monitor the Entities and it will trigger the end of the turn when certain conditions are met (ie: number of possible actions is 0)? Could this logic be part of
I would appreciate any suggestions on how to solve this problem.
Here are some details as requested by @candied_orange to help with the answer.
Who should be responsible for use case creation? It does not seem to be efficient to create use cases from other use cases due to dependencies that the child use case requires (Presenter, Repositories, etc). At the same time, I'm reluctant to move that responsibility up as this is part of the domain (game rules) to know which operation is possible at any given moment in the game. Most of the examples and articles show use case created by Controller and only situations where one use case operate independently of other use cases. From Doc Brown's answer I understand that this kind of problems are not addressed by Clean Architecture rules. Nevertheless I would like to see some hints from people that have used this approach in larger system.
What should be the use case life cycle? In my particular problem, I create all the use cases dynamically when the turn starts. That is partly because the game is asymmetric and different players have different use cases to choose from. However, maybe it is needed to have all the use cases active all the time and validate if their usage is possible in any given moment of the game?
What is the best way to override the use case? This kind of operation I've planned to use for tutorial purposes where I have to interrupt the normal game flow and explain the game rules. I wanted the tutorial to decorate the normal game flow so the normal use cases are not aware of the tutorial. To make this work I would need to have a place where all use cases live so I can override them in runtime. This goes back to question about who should create use cases.
It there a concept of System use case? By that, I mean a use case that is triggered by the system rather than a user. This goes back to Bart van Ingen Schenau's question about user manually triggering the end of the turn. Yes, the user can do it manually when he doesn't want to move anything. However, in the normal scenario, I would like the turn to end automatically. This is also because I have other situations when child use case have to do something on the parent so I'm interested in solving this problem rather than forcing the user to confirm the end of the turn manually.