-
Notifications
You must be signed in to change notification settings - Fork 20
Project Design & Architecture
This project uses the default project structure for libGDX as generated by the libGDX Project Setup Tool. There is a sub-project for each supported platform. The actual game code resides in the core project.
The following are the most important components that make up the game.
This component does everything that modifies the internal game state, for example moving a unit. It also contains the AI. The component can be seen as the domain logic or business layer.
The UI component renders controls (e.g. buttons, tables) that make up the user interface. It contains screens that make up different parts of the game (e.g. the splash screen, ingame screen). Each of these screens can use multiple stages. A stage contains a set of UI controls for a given purpose. Example: the ingame screen displays the parameter input stage when generating the map. After starting the game, the heads up display (hud) stage is used to display the ingame buttons.
The renderer component is used for rendering the current gameState: water, the island and it's contents.
The UI and renderer components can be seen as the presentation layer of the game.
This component is used for persistence. This includes the settings as well as savegames. It is the data access layer of the game.
This component is responsible for detecting input events that are not linked to the UI controls like clicks on the map, keyboard input or touch gestures.
Most communication between the components is done using an event bus. This way, a loose coupling between the components is achieved. An exception to this is the gamelogic component using the preferences component directly. The reason for this is that data is requested and returned as a response. This is tedious to do using events.
The UI component uses the event bus for internal communication as well. Imho this is more elegant than attaching event listeners to every single screen.
Dependency injection is used wherever appropriate. This results in a desirable level of coupling and good testability. A DI/IoC framework is used to avoid manual creation of the object graph.
There are only a handful of automated tests in this project. One reason for this is that I did not know how to structure a game in the beginning which led to a lot of refactoring which would have been even more painful with many tests. The existing tests focus on the things that are hard to test manually. This is mostly the gamelogic component. Having some more tests would be good, of course.
-
libGDX is the core framework used for this game
- used for UI, 2D rendering, persistence
- cross-platform
- pure Java
- disadvantage: maintenance only mode
-
Dagger2 is the DI framework
- uses generated code instead of reflection
- in theory GWT compatible
-
Guava
- whenever I want to write a generic helper class, Guava already has it most of the times
- provides the event bus component
- JUnit and Mockito for unit tests
-
JUL is used via SLF4J for logging
- the libGDX logging is too basic
- Logback doesn't work on Android
- JUL works on Desktop and Android but I don't like the API (hence SLF4J)
- JUL has a MemoryHandler that can be used for data collection in crash situations
The project uses Java 8 because it is the latest version libGDX supports for all platforms.