Scala Game Library (SGL) is a library for developing cross-platform 2D video games in Scala. It provides a high-level API for building games, and can export games to the Desktop, Android, and the web. More platforms, including iOS and consoles, are on the roadmap.
SGL is still in development, but is intended to provide an extensive toolkit to facilitate game development in Scala, with a layer of abstraction on top of the platform-specific functionalities, and an out-of-the-box implementation for many common features needed in games, such as physics, collision detection, tilemaps, and scenes management.
SGL aims at providing a generic and cross-platform 2D game API. The API provides some layers of abstraction on top of the underlying systems, and a game written using the API should be able to get compiled and run on each platform with very litle platform-specific code. However, there are several non-goals of SGL:
The main selling point of SGL is to provide a platform-independent Scala game
framework to build games, and then deploy them to any platform. You can get
started by writing a core generic game implementation, and then configure any
backend with just a few lines of Scala. You can iterate on your game by
running the AWT backend from
sbt, which, depending on your configuration, is
as straighforward as:
Thus, you can quickly iterate on your game locally, without the need to waste a lot of time deploying to your target platforms, such as mobile or console.
The current implementation provides the following backends:
If you want to write games in Scala, you have a few alternatives. Here's a biased opinion on how SGL compares with these alternatives. But first a disclaimer: SGL is not production-ready and is under heavy development, so if you want to limit your interaction with the game engine, you probably should look somewhere else for now.
libGDX is an extremely mature game library written in Java and thus fully useable in Scala. It provides solid support for many platforms, and it supports 3D and you can make full use of OpenGL with it. You can't really compare SGL to libGDX, as they are just not playing in the same league. Today, if you decide to use SGL, you are betting on the future. You are betting on a future where SGL will get to feature-parity with libGDX, and where the Scala-first approach will pay off for your game.
I do think there are fundamental technical advantages with having the engine written in Scala, which might eventually justify using SGL over libGDX:
Indigo is a pure Scala game engine with a design focused on developer productivity. It offers a purely functional way of writing games, which is likely to appeal more to Scala developers. By contrast, SGL does not emphasize the funcitonal programming style, it limits itself at abstracting away multiple platforms into a consistent API. Indigo is currently in development so the set of features is constantly moving (just like SGL), so it's hard to truly compare them. Given the current state of the engines, I think it's fair to say that Indigo invested a lot of work into building the right API for the developer, while SGL invested a lot of work into supporting multiple platforms in a very native way (Android, AWT, Native, HTML5 are supported, while today Indigo runs only with Scala.js).
This is a work in progress, so please don't hesitate to get in touch if you are interested in writing a game in Scala. This is not production ready yet and things will need to be tweak in order to make them work, but I'm putting this project out there as I think it has a good potential, and I'm looking for feedback from people interested in such a library.
I'm developing new features on a need basis. I'm working on some Android games, and I started to use this library as it was much nicer to build and test the game on my Linux desktop, and only deploy to the phone for the final tests. I'm constantly adding new features to the library based on my needs for my games, but if you miss some other features, please let me know and I will add them! You're also very welcome to contribute :)
If you check out the latest master branch, and find out that some stuff is not working as expected, please understand that the project is evolving rapidly and I'm likely just breaking existing stuff to try to improve the overall design. The library does truly help in building actual games, and I successfully developed one published Android game with it. The library helped tremendously, by being entirely Scala-based and by allowing for transparent porting from the Desktop to the Android platform.
SGL is split across several sub-projects so that games built by the framework
only pack the necessary dependencies. The organization is to provide a
project, which defines all the APIs, and roughly one backend per platform. A
game should then depend on both the core abstraction and the platform on which
it will deploys. Cross-platform games can be further split into smaller units,
with a cross-platform core logic that will only depends on the core SGL
abstractions and various platform-specific implementations. The small
snake project demonstrates how you can organize a game to be
cross platform. A more advanced example can be found by looking at the sources
SGL is currently splited into the following sub-projects:
These projects are defined in the built.sbt file and have their sources in each corresponding subdirectory. Android definitions are in a sub-directory because the Android plugins does not work with the most recent sbt version.
For a long time, the only way to use SGL was to declare direct source dependencies. That proved relatively unsuccessful and most of the Scala community seems to believe that binary dependencies is the way to go. Since SGL is still an early prototype, I wasn't very keen on publishing a stable version as a binary that people could just depend on through Maven.
Nevertheless, to make SGL easier to use, I will soon start officially releasing
on Maven. The first release will be
0.0.1, with the intent to be clear that
this is a highly experimental version. Future versions will simply increase the
last digit, i.e.
0.0.2 and then
0.0.3. As long as SGL stays in the
version line, there will be no guarantee on backward compatibility, and each
new version could break absolutely everything the previous version introduced.
This is all in the name of velocity and innovation, of course. If you do give a
chance to SGL
0.0.X, just be aware that there will be bugs, and updates will
likely break your code. You must be willing to actively engage with the
developers of SGL.
The eventual goal is to reach the
0.1 version line, which at that point will
be a more stable release and future updates would hopefully better respect
At the current time, version
0.0.1 is not yet released on Sonatype. Most of
the build config and code is there, but I want to make a few adjustments before
publishing. Until then, you can use
publishLocal to publish the version
locally and use it on your own games.
I would like to ensure that the artifact for 0.0.1 is good enough to write interesting games without constantly requiring tweaking SGL. Currently, as I'm working on my games, I constantly need to go back and tweak SGL a little bit in order to get something working as I would expect. That tells me that the library is not quite stable enough to reach the highly unstable and experimental version 0.0.1. Of course, 0.0.1 should not be perfect, but we should have a reasonable chance to be able to complete a game without requiring an update to the library. There are a few things that I would like to get done before getting there:
This would prove that SGL can get the job done and make a feature-complete game.
Make sure that Desktop, Web, Android, and iOS (through Cordova) have complete support for the core providers. It's ok to be missing some addon providers (ads, analytics, etc) on some of the platforms, but we should at least be able to get a game with the fundamental providers on each of these platforms. We can ship with the experimental native backend, but we need to be clear that this is not supported and is still a PoC.
Provide a basic tutorial.
Provide a demo game. Scalavator is good for that, but it needs updating. This also doubles as another proof that the library can build games.
We probably don't need a website, but we should publish the scaladoc somehow.
Expand the scaladoc. In particular, we should have a starting point in the sgl root package, where we explain the high level design of the library and how to put a game together with the cake. Ideally this would serve as the documentation until we have a proper documentation (like an actual system manual, much more verbose).
Review the core API and make sure most of the obvious mistakes have been fixed. Examples that have already been fixed are using int coordinates in the canvas. Another one that is in the process of being addressed is the weird behavior when loading multi-dpi bitmaps. There are probably many more such stupid mistakes, and I should do a pass to make sure we aren't releasing something that's obviously bad. There will be plenty more design mistakes, and that's fine we can fix them later, but let's at least fix the ones we know today.
You can start with a step-by-step tutorial on writing a game with SGL. The tutorial explains some of the concept of the library.
If you want to see how a small, but complete, game looks like, I developed an open-source game with SGL. The game is intended to demonstrate some of the features of the library.
Games and only games. This is not a general media toolkit. The only things that should be build with this library are games. Yes, there's a feeling like we can do more with this cross-platform style, and that's probably true, but this is better left to other frameworks.
Pure and true Scala library. We want to expose a Scala-like library a much as possible. No compromise for compatibility with other languages, everything is done in Scala.
Entirely cross-platform, no cheating. The core library should abstract everything and only exposes features that are truly cross-platform. Any platform-specific extensions should be provided in a type-safe way.
Generic but pragmatic. We try to remain as generic as possible, in the sense that only features that would be useful for at least two different games would be integrated. However, we want to provide a very effective toolkit, so almost anything that is remotely useful for building games should be made available. Whenever a problem has many alternative implementations, we should try to provide an abstract interface, with each alternative implementation available and let the user select the one they prefer.
2D only. The library does not target 3D games. I believe there are an infinite number of wonderful games that can be build entirely in 2D, and I would rather focus on getting a great library to build 2D games than an average library to do everything.
No building magic. Everything is explicitly implemented in Scala. No additional code generator to handle the different platforms. Setting up a deployment platform should be simple enough to be done manually. That said, eventually a good sbt plugin would come in handy, as long as it is a light, and optional, layer on top.
Try to be as native as possible. We want to always use the platform native and standard APIs. We should try to map the SGL API as directly as possible to each system API. For example on Android, we want to try to map to the drawable-Xdpi built-in system to handle multiple pixel densities, instead of building a custom asset loading code. By mapping directly into the platform behavior, we get more optimized apps, and can take advantage of future evolution of the system (like app bundles on Android, which requires to use the standard drawable-xdpi layout).
SGL has been used so far to produce mobile-friendly games, usually cross-published to Android, iOS, and the web. That said it could be used to make more classic indie titles for Steam, it just hasn't been done yet.
The most ambitious game created with SGL is the cross-platform commercial game Fish Escape, available on:
Additionally, a small number of experimental games have been published with SGL:
If you are using SGL for your commercial game, please contact me and I'll be happy to mention you in this section.
I heavily use the cake pattern as a means to abstract the different backends and to correctly modularize the system. A good article to introduce using the cake pattern for dependencies injection is this one. There is also a great talk that describes how to use the cake pattern, which closely ressembles our usage here.
More recent articles seem to criticise the Cake pattern and many people seem to have drop it. The choice of using the cake pattern was made more than 4 years ago and I still haven't reached the point where I think the drawbacks outweight the benefits.
In order to run the tests for scala-native, you will need to follow the installation instructions on the Scala Native website if you have not done so already. Additionally, you will need to have development libraries to link against OpenGL, SDL2, and SDL2 Image.