Every once in a while I get the opportunity from my employer to work on OpenPatrician for one working day and one non working day. So this year the target is to bring OpenPatrician to a modularized Java 9 build and update Maven.
Currently OpenPatrician only allows a view of the current state of affairs for example for fleet size, reputation or available wares. Even the personal balance records only the current and the past week. For statistical purposes these data should be recorded for the whole game time. This calls for a database. This post details the findings of the evaluation of these:
The first part of this was planed as the only part, however to keep things concise I decided to split it so here are some more in depth observations on way I am investing my time into this project.
Almost every time I tell someone new about this project the question ‚why‘ pops up inadvertently. While there are many reasons to motivate me for this project, one of the driving ones from the beginning was to have a project that allows to experiment with certain frameworks and technologies. In a project with paying customers you most often do not have the freedom to do this. In the end you can only gain experience with this new/yet unknown stuff by creating something with it. Basically this boils down to a learning experience that will improve my programming skills. In this blog post I will try to shed some light on what exactly this is, while following through development of Release 0.8.0.
To be able to implement the save/load functionality without too many headaches some preconditions have to be met.
The application builds upon the SpringFramework which initiates a context that manages singleton beans. The Spring context is started upon application startup. When a game is started many more beans are created to populate the model architecture representing a game. Some of these beans are singltons that are lazy initiated but the most part are prototype beans. Prototype beans are only instantiated by the context but no reference is held on them within the context object. There are prototype beans that are unbound, meaning during the progress of the application any number of them can be created, but there are also certain prototype beans that only exist in small number and generally do not change after initialization. Then there are prototype beans which are basically singletons but cannot be defined as such as they require constructor arguments.
To be able to save and load a game it is required that the state of the game can be stored and restored.
Aim of the Proof of Concept
Late spring context initialization
While it is possible to define a spring bean as lazy meaning it is instantiated only when it is first needed (autowired) this wires the creation of a bean to the creation of another bean. With many of the beans being singletons this requires at least one manual creation. It would be desirable to be able to define an event upon which the bean is created. As the event system is already in place the optimal solution would be to define an annotation which defines the event objects type as the trigger. The framework would then instantiate that bean upon an event of that type.
See the corresponding ticket #143.
Context managed prototype beans
Extend the spring context so it can hold references to the selected beans of the classical prototype stereotype. Mainly these will be the singleton beans that don’t have a default constructor and therefore must be defined as type prototype. Another case are beans that created a certain number of times (e.g. cities, players,…).
The hard part here is not the possibility of storing them in an extended spring context, but in tweaking the autowireing system so that it works. Naturally for beans that exist in the context multiple times autowireing should not be possible or would require some kind of qualifier that would allow selecting the correct instance.
See the corresponding ticket #141.
Context bean injection
Beans can categorized into three different type:
- Service beans that are created at startup and are not related to the game state. These are mainly the utilities that make up the system like resource loaders, factories, …
- The beans that are created at startup and hold some game state. The most prominent example is the Date object.
- The beans that are created upon game start and hold game state.
When saving a game the latter two must be serialized. When loading a game the beans of the second category are already present in the spring context and must be replaced with the counterparts from the unserialized game. Also the beans of the third kind must be injected into the context. This happens in a different way than when creating a new game.
The hard part here is that replacing an object in the context must also update all the reference on the object. To make this as simple as possible the beans of the second type should be avoided and the beans of the third kind should all have one single root object.
See the corresponding ticket #132.
As of today the Version 0.3 is available at Sourceforge and through the Maven repositories.
Main features are
- The Tavern where you can meet different people
- The Shipyard where you can order ships, repairs or upgrades
The next release will focus on technical issues like
- Implementation of the UI through JavaFX
- More consistent integration of Spring dependency injection
- Better testabilty
besides some new features.
We proudly present your second release. We achieved this in only 8 months versus the 11 for the first one. In reality the correct release number would be 0.2.0, so do not be alarmed when the next release number jumps up to 0.3.0. The last number is usually reserved for bug fixes.