(tl;dr at the end)
Have you ever encountered the following situation?
You are the owner of a Minecraft minigame server. Your development team created a powerful dynamically-scaling backend with a proprietary API for all your minigame plugins. Some day, you discover a cool new open-source minigame you want to host on your server. However, there’s a slight problem: The minigame is not compatible with your proprietary API and implements its own environment (e.g. arena management). In order to host the minigame, you would need to rewrite large chunks of the code to make it work with your API. And that would have to be done after every update as well. In the end, you decide that it’s not worth it and move on.
Or does this situation sound familiar?
You are the developer of a cool new open-source Minecraft minigame plugin. During development, you’ve already wasted a lot of time by implementing your own arena management system. Although you’ve spent a lot of time on the system, it only works with one single server and is rather limited. After you published the plugin, everyone thinks it’s cool, but nobody is playing it because not a single big server hosts your minigame.
GameSpec is an attempt at solving this problem. The first component called GameSpec API defines a very flexible and small abstraction layer. Your next cool minigame can use that abstraction layer and doesn’t need to worry about the environment it will be running in. It just implements the game, and nothing else. Because the API is extremely flexible and doesn’t implement anything that isn’t absolutely necessary, GameSpec doesn’t force you into some kind of arena system. Instead, you tell GameSpec what to do, not the other way around.
The second component consists of several GameSpec Containers. Each container is implemented for a specific environment. If your server is big enough, you might also want to implement your own container for your environment. However, the minigames do not need to worry about those different environments. All containers provide an implementation of the GameSpec API somehow. That means that every possible game which is implemented using the API is able to run in your environment.
In short, plugins are written with the GameSpec API abstraction layer. That abstraction layer is then provided by a GameSpec Container. After some time, you will be able to choose from multiple containers. If you just want to develop a minigame plugin using the API and need to test it somewhere, it is not necessary to host a large dynamically-scaling container with multiple servers and proxies. Instead, you can run an extremely simple one-server container on your testing server. When you go into production, you use a production container like the dynamically-scaling one mentioned above.
The fact that a fully-featured open-source production container, which is able to manage multiple servers, will be available also solves another problem: If you have the monetary resources, you are now able to create a new big server without the need to developing your own backend system. Instead, you can just use the open-source container.
Each game is divided into several modules. Those modules require different maps and might run on different servers. For example, your game might need a
lobby module, which is the starting module and provides a countdown for the start of the actual game. During that time period, new players can join the game and vote for a map. Internally, they are transferred to the
lobby start module. When the game starts, the original start module launches a second module called
game with the voted map, transfers all players to the new module and stops itself. Now,
game executes the actual game. When the game is over, it kicks all players and stops itself as well.
The above construct is just an example composition of two different modules. All modules are packaged and distributed in a game archive file, which is just a ZIP file with your modules, some global configurations, and some default resources (e.g. configs). If your server wants to use its own lobby, you can just replace the original lobby module with your own version.
If you haven’t guessed already, a module is just a plugin which runs on a server. It is put there by the container. Each module must be able to coexist with other modules on the same server.
You might wonder: Well, that’s nice, but what happens if the container decides to use a server for two processor-heavy modules? How is the container able to decide which configurations make sense? Actually, solving this problem is rather difficult. For GameSpec, we will probably introduce a number that specifies how processor-heavy a specific module is. Using that number, the container can try to keep all servers balanced.
It is important to note that the maps a module wants to use must be defined when the module is launched. That is necessary so containers can select the server the new module instance will be running on depending on the maps it needs.
Moreover, each module is configured to use specific resources. Those resources might be configs, but they might also be schematics which are spawned in. They can be essentially anything. The game archive provides default resources which can be modified (configs) or overridden (others) by custom resources specified by the user. It is also possible to extract default resources into the custom user resource repository if they do not yet exist there. GameSpec might also support merging of updated configuration files (TO EDIT). Note that resources which are not absolutely required to be in the game archive as a default “fallback” should be supplied through a separate archive (e.g. default maps). That way, the main game archive is not polluted with content most servers don’t need.
Finally, each module is able to store persistent key-value pairs either globally or only for itself. The values must be primitives, strings, or lists of primitives and strings.
Of course, this list of abstractions is probably incomplete. However, it should’ve given you an idea of what GameSpec is all about.
GameSpec is not an API which makes creating Minecraft minigames easier by providing some fancy APIs. Instead, it functions as an abstraction layer which is implemented by different GameSpec containers. Depending on the use case, different containers (environments) implement different features. That way, a user can select the container which best fits his needs and is still able to host all minigames he wants to host.
Essentially, GameSpec is a standard for SpongeAPI minigames.
GameSpec API is already under development. Its first iteration is nearly finished. Since the API is planned to be small, the main portion of development will probably be completed in the near future.
Currently, we focus on implementing the simplest container, which is planned to manage games on only one server. It is called GameSpec Single.