Hi all!
I’m the developer of OpenSettlers, a game engine specific to design Settlers of Catan games written in Java. It contains a reference implementration of a SoC client using GWT ui codebase. GWT compiles Java to Javascript, enabling me to write java, but have a complete browserbased game. An alpha demo is up at opensettlers.sourceforge.net. Keep in mind that it’s an alpha demo (lotsa bugs, looks still ugly), I will upgrade it in the coming weeks to a much more playable version.
In this post, I will outline some of the design decisions and implementation strategies I used. I hope they inspire the Vassal team for the implementation of the v4 release.
Seperation of UI/data
The codebase of OpenSettlers has the seperation of concerns (ui and data). I have defined interfaces for most things, implementation of these interfaces use a “SimpleEventBus” to propagate changes in the objects. That way UI objects can subscribe to changes in the data. A truly seperated should be able to have different UI implementations. Currently, OpenSettlers has this: It uses SVG to draw the gameboard as only implementation. If you like code, here are some links to the Robber implementation (a robber can move, and has a location property):
Robber class:
github.com/generateui/OpenSettl … obber.java
Moved event:
github.com/generateui/OpenSettl … Event.java
Moved event handler:
github.com/generateui/OpenSettl … ndler.java
EventBus interface and SimpleEventBus are classes from GWT, but these are extracted from another project, code.google.com/p/simpleeventbus/. It should be easy to build a custom one for Vassal.
As OpenSettlers is mainly focused on offering a webbased playing experience, I’m writing code for GWT UI only. However, a dev wanting to make a swing or JavaFX would only need to implement a set of interfaces already defined. A browser itself offers a few possibilities also to write UI in: HTML, canvas, canvas3d (WebGL), SVG and flash. As such, a 3D version of OpenSettlers would be trivial to add, only the defined interfaces should be implemented, similar to adding a swing or JavaFX implementation. The data classes can be reused among those UI implementations. OpenSettlers is based on GWT 2.1, when it upgrades to GWT 2.2, I will add support for the canvas drawing, which only involves adding about 10-15 classes which implement the defined interfaces.
Abstracted definition of data
Another point of Uckelman is using another way to store the data into files. Uckelman proposed XML as a way of doing this. OpenSettlers has the same problem: the classes only consisting of data (no behaviour/methods) must be defined, and then some serialization technique should be added in order to read/write this data from disk/ssd. The solution I will use will be protobuf: code.google.com/p/protobuf-gwt/. Protobuf lets you define those dataclasses in a DSL, resulting in a set of protobuf files containing the definition of all dataclasses. With this platform and language independent definition, you have a basis which you can use ANY serialization technique with. Whether that’s XML, Java, Json, RelaxNG, plain text, it does not matter. Currently serializers exist for quite some languages, included the noted ones (XML, Json etc).
Some examples why this will benefit OpenSettlers:
I’d like to store some data into the local browser storage. For instance, I’d like to save board definitions of OpenSettlers locally, to prevent redownloading them each time a player connects to a server. I have an interface Board, with a corresponding implementation BoardImpl. To do this without protobuf, I must either create a new class taking a Board, then manually write code to serialize this to Json in order to write this to the local storage in the browser. I must do this for every data class definition I want to store into the local browser storage. When the definition changes, I need to update this manual code, you get the idea.
Instead, protobuf solves this for me. Using a generator, a Json implementation of the data class is generated from the protobuf definition. No need to write a single line of code. This would be no different when using XML.
I get very excited when I realize other SoC projects can reuse the protobuf defnition. Pioneers is such an implementation, written in C. It would be a matter of applying a C generator (which exists) to the protobuf definition. This generator then generates the dataclasses in C. If Pioneers would do this, Pioneers and OpenSettlers would become compatible. So, it not only saves writing manual code, it also allows to have a “standardized protocol”. No matter what language or platofrm is used: as long as a generator exists, it’s compatible. When no generator exist, it’s not very hard to write one. Lots of generators already exist.
I’m planning to add protobuf in a few weeks. It would be much better when I started with protobuf, but I only learned of them far in the implementation process. As OpenSettlers isn’t out of alpha yet, not all is lost .
My personal preference: I very much dislike XML, but like Json much more. That’s fine: a Json file will do just as good as an XML file. As long as there is a platform independent way to describe the data and then generate code from it, it’s just a matter of adding a generator to support another serialization technique.
GWT
Google Web Toolkit is not only a Java to Javascript compiler. It’s also a “set of best practices”. In working with GWT for about 6 months now, I came to learn that GWT is created with the unix philosophy in mind. Basically, GWT is a set of small, focused libs. Not only did I learn a lot of GWT specific stuff, but also lots of good idea’s, practices and good quality code. Examples are the ModelViewPresenter paradigm, handling of resources and RequestFactory.
GWT defines an application in three folders: shared, client and server. This makes sense: Seperating the code shared among the client and server, the client UI code, and the server specific code. You’re not forced to do it like this, but it turned out to be quite clarifying.
Vassal & OpenSettlers
I have looked to use Vassal for OpenSettlers to avoid writing code which I can reuse from Vassal. Uckelman describes the problems very accurately for why I dismissed it (for now). As parts of Vassal and OpenSettlers are pretty much alike, it would make sense to reuse those parts. When v4 successfully addresses above noted problems with the codebase, I’d very interested to reuse/include Vassal code into OpenSettlers. If solutions for the mentioned problems fall in my domain of expertise, I’d be happy to help with the transition, too.
I hope I add my 2 cents with this contribution. Greetz, generateui.