- Notifications
You must be signed in to change notification settings - Fork9
Scala library for cross-platform 2D game development
License
regb/scala-game-library
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Scala Game Library (SGL) is a library for developing cross-platform 2D videogames in Scala. It provides a high-level API for building games, and can exportgames to the Desktop, Android, and the web. More platforms, including iOS andconsoles, are on the roadmap.
SGL is still in development, but is intended to provide an extensive toolkit tofacilitate game development in Scala, with a layer of abstraction on top of theplatform-specific functionalities, and an out-of-the-box implementation formany 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 providessome layers of abstraction on top of the underlying systems, and a game writtenusing the API should be able to get compiled and run on each platform with verylitle platform-specific code. However, there are several non-goals of SGL:
- The exported API hides the non-game specific features of each system,however it will export an API that ressembles the underlying systems, witha slight Scala stylisation when possible. What that means is that the API willbe imperative as this is the prevalent system architecture, and it will lookfamiliar to people used to write games directly on some of these systems. Incase you are interested in writing games with a fully functional style, youwill need to either build an abstraction on top of this API, or you can checkoutIndigo, another Scala game engine but with anexplicit goal of providing a purely functional API for game developers.
- SGL is not an opiniated way of building games. It's trying to provide themost simple yet general API that is cross-platform and enable programmersto create any 2D game. The design decisions are centered around what to exportin the API, in the best possible style without losing low-level control. SGLcan be thought of as alibGDX in pureScala and optimized for 2D games. Another source of inspiration for thedesign of SGL is theSimple DirectMedia Layer, andthe name SGL was chosen partly because it tries to be a sort of SDL for Scala.
- Although SGL is currently providing a lot of extra toolkit library (scenemanagement, game screen management, tiled maps, etc) to facilitate buildinggames, internally there's a relatively clear distinction between what is thecore cross-platform API and what are the components built on top of that. Alot of thoughts goes into desiging these core APIs, but components are kindof piled on top of each other quickly, mostly as the need arise in an actualgame development project. In the long term, it's possible that SGL will be splitbetween the core layers of abstraction, and the components that are built on top.The objective of SGL is to build the correct core abstraction, while the componentsare one possible take on a game engine API, it should be eventually possible toreplace all the components and choose a totally different programming style(including functional reactive programming) and still share the sameunderlying platform abstractions.
The main selling point of SGL is to provide a platform-independent Scala gameframework to build games, and then deploy them to any platform. You can getstarted by writing a core generic game implementation, and then configure anybackend with just a few lines of Scala. You can iterate on your game byrunning the AWT backend fromsbt
, which, depending on your configuration, isas straighforward as:
sbt mygame-awt/run
Thus, you can quickly iterate on your game locally, without the need to waste alot of time deploying to your target platforms, such as mobile or console.
The current implementation provides the following backends:
- Desktop with JVM and AWT. This is mostly convenient during development,but can also serve as a final release if you are able to distribute yourgame to people that have a JVM. It will be cross-platform across Windows,Mac, and Linux.
- Android. The Android backend is implemented with the native Android SDKfor Java, which means that SGL supports Android natively.
- Web with Scalajs. The web backend is implemented with scalajsand uses the HTML5 canvas for graphics, the HTML5 audio tag for audio, andother standard web features.
- Native (Experimental). The native backend implemented with scala-nativeis able to generate a native executable that can then be run on the targetplatform without a JVM. The support for native is not complete yet, butthe current implementation is a proof of concept. Further extensions tothis backend should enable SGL to eventually target iOS and variousconsoles.
- iOS while we do not yet support iOS natively, it is possible to use theweb backend combined with a tool like Cordova, to make an iOS app. Thishas been proven withthis game.
If you want to write games in Scala, you have a few alternatives. Here's abiased opinion on how SGL compares with these alternatives. But first adisclaimer: SGL is not production-ready and is under heavy development, so ifyou want to limit your interaction with the game engine, you probably shouldlook somewhere else for now.
libGDX is an extremely mature game librarywritten in Java and thus fully useable in Scala. It provides solid support formany 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 sameleague. Today, if you decide to use SGL, you are betting on the future. You arebetting on a future where SGL will get to feature-parity with libGDX, and wherethe Scala-first approach will pay off for your game.
I do think there are fundamental technical advantages with having the engine writtenin Scala, which might eventually justify using SGL over libGDX:
- Scala is a better language than Java (biased opinion, but I think it's true).
- Scala opens up extremely powerful design pattern for the core engine and theplugins built arount it.
- SGL leverages Scala Native and Scala.js to provide a high-level of control on eachtarget platform, which I think is superior to what can be done with traditionalcross-platform development offered by libGDX.
Indigo is a pure Scala game engine with a designfocused on developer productivity. It offers a purely functional way of writinggames, which is likely to appeal more to Scala developers. By contrast, SGLdoes not emphasize the funcitonal programming style, it limits itself atabstracting away multiple platforms into a consistent API. Indigo is currently indevelopment so the set of features is constantly moving (just like SGL), so it'shard to truly compare them. Given the current state of the engines, I think it'sfair to say that Indigo invested a lot of work into building the right API forthe developer, while SGL invested a lot of work into supporting multiple platformsin a very native way (Android, AWT, Native, HTML5 are supported, while today Indigoruns only with Scala.js).
This is a work in progress, so please don't hesitate to get in touch if you areinterested in writing a game in Scala. This is not production ready yet andthings will need to be tweak in order to make them work, but I'm putting thisproject out there as I think it has a good potential, and I'm looking forfeedback 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 thegame on my Linux desktop, and only deploy to the phone for the final tests. I'mconstantly 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 workingas expected, please understand that the project is evolving rapidly and I'mlikely just breaking existing stuff to try to improve the overall design. Thelibrary does truly help in building actual games, and I successfully developedone publishedAndroidgame withit. The library helped tremendously, by being entirely Scala-based and byallowing for transparent porting from the Desktop to the Android platform.
SGL is split across several sub-projects so that games built by the frameworkonly pack the necessary dependencies. The organization is to provide acore
project, which defines all the APIs, and roughly one backend per platform. Agame should then depend on both the core abstraction and the platform on whichit 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 SGLabstractions and various platform-specific implementations. The smallsnake project demonstrates how you can organize a game to becross platform. A more advanced example can be found by looking at the sourcesofScalavator.
SGL is currently splited into the following sub-projects:
- coreJVM, coreJS, coreNative (the core abstractions compiled for JVM,scalajs, and scala-native). Thecore project contains theabstract API for the platform as well as all the features that areplatform-agnostic.
- desktopAWT, depends on coreJVM and provide window and graphics with AWT.
- desktopNative, depends on coreNative and use scala-native and OpenGL tobuild a native executable.
- html5, depends on coreJS and use scala.js to generate a javascript game.
- coreAndroid and android, for the android platform.
- jvmShared, some non-core utilities shared by all JVM-based platform.
These projects are defined in thebuilt.sbt file and have theirsources in each corresponding subdirectory. Android definitions are in asub-directory because the Android plugins does notwork with the most recent sbt version.
For a long time, the only way to use SGL was to declare direct sourcedependencies. That proved relatively unsuccessful and most of the Scalacommunity seems to believe that binary dependencies is the way to go. Since SGLis still an early prototype, I wasn't very keen on publishing a stable versionas a binary that people could just depend on through Maven.
Nevertheless, to make SGL easier to use, I will soon start officially releasingon Maven. The first release will be0.0.1
, with the intent to be clear thatthis is a highly experimental version. Future versions will simply increase thelast digit, i.e.0.0.2
and then0.0.3
. As long as SGL stays in the0.0
version line, there will be no guarantee on backward compatibility, and eachnew 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 achance to SGL0.0.X
, just be aware that there will be bugs, and updates willlikely break your code. You must be willing to actively engage with thedevelopers of SGL.
The eventual goal is to reach the0.1
version line, which at that point willbe a more stable release and future updates would hopefully better respectbackward compatibility.
At the current time, version0.0.1
is not yet released on Sonatype. Most ofthe build config and code is there, but I want to make a few adjustments beforepublishing. Until then, you can usepublishLocal
to publish the versionlocally and use it on your own games.
I would like to ensure that the artifact for 0.0.1 is good enough to write interestinggames without constantly requiring tweaking SGL. Currently, as I'm working onmy games, I constantly need to go back and tweak SGL a little bit in order toget something working as I would expect. That tells me that the library is notquite 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 chanceto be able to complete a game without requiring an update to the library. There area few things that I would like to get done before getting there:
- Get a commercial game published. Fish Escape fits the bill here and is alreadypublished on iOS and Android. There are still extra features that I want to implementto tweak the games (ads on iOS, analytics on iOS, iAP on both platforms), so theseshould be implemented and deployed (although maybe iAP can wait for 0.0.2).
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) havecomplete support for the core providers. It's ok to be missing some addonproviders (ads, analytics, etc) on some of the platforms, but we should atleast be able to get a game with the fundamental providers on each of theseplatforms. We can ship with the experimental native backend, but we need to beclear 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 scaladocsomehow.
Expand the scaladoc. In particular, we should have a starting point in thesgl root package, where we explain the high level design of the library andhow to put a game together with the cake. Ideally this would serve as thedocumentation until we have a proper documentation (like an actual systemmanual, much more verbose).
Review the core API and make sure most of the obvious mistakes have beenfixed. Examples that have already been fixed are using int coordinates in thecanvas. Another one that is in the process of being addressed is the weirdbehavior when loading multi-dpi bitmaps. There are probably many more such stupidmistakes, and I should do a pass to make sure we aren't releasing something that'sobviously bad. There will be plenty more design mistakes, and that's fine wecan fix them later, but let's at least fix the ones we know today.
You can start witha step-by-step tutorial on writing a game withSGL.The tutorial explains some of the concept of the library.
If you feel ready to start a project from scratch, you can fork thestarterproject as a mostly blank slate.You can check out theexamples projects for how to use some of thefeatures of SGL.
If you want to see how a small, but complete, game looks like, I developedanopen-source game with SGL. The game isintended to demonstrate some of the features of the library.
Games and only games. This is not a general media toolkit. The only thingsthat should be build with this library are games. Yes, there's a feeling likewe can do more with this cross-platform style, and that's probably true, butthis is better left to other frameworks.
Pure and true Scala library. We want to expose a Scala-like library a much aspossible. No compromise for compatibility with other languages, everything isdone in Scala.
Entirely cross-platform, no cheating. The core library should abstracteverything and only exposes features that are truly cross-platform. Anyplatform-specific extensions should be provided in a type-safe way.
Generic but pragmatic. We try to remain as generic as possible, in the sensethat only features that would be useful for at least two different gameswould be integrated. However, we want to provide a very effective toolkit, soalmost anything that is remotely useful for building games should be madeavailable. Whenever a problem has many alternative implementations, we shouldtry to provide an abstract interface, with each alternative implementationavailable and let the user select the one they prefer.
2D only. The library does not target 3D games. I believe there are aninfinite number of wonderful games that can be build entirely in 2D, and Iwould rather focus on getting a great library to build 2D games than anaverage library to do everything.
No building magic. Everything is explicitly implemented in Scala. Noadditional code generator to handle the different platforms. Setting up adeployment 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 nativeand standard APIs. We should try to map the SGL API as directly as possibleto each system API. For example on Android, we want to try to map to thedrawable-Xdpi built-in system to handle multiple pixel densities, instead ofbuilding a custom asset loading code. By mapping directly into the platformbehavior, we get more optimized apps, and can take advantage of futureevolution of the system (like app bundles on Android, which requires to usethe standard drawable-xdpi layout).
SGL has been used so far to produce mobile-friendly games, usually cross-publishedto Android, iOS, and the web. That said it could be used to make more classicindie titles for Steam, it just hasn't been done yet.
The most ambitious game created with SGL is the cross-platform commercial gameFish Escape, availableon:
- Android(free lite version)
- iOS(free lite version)
- the web withKongregateandFacebook
Additionally, a small number of experimental games have been published withSGL:
- WinSmash, available forAndroid
- Scalavator, available forAndroidand for theWeb. Code sourceavailable onGitHub.
If you are using SGL for your commercial game, please contact me and I'll behappy to mention you in this section.
I heavily use the cake pattern as a means to abstract the different backendsand to correctly modularize the system. A good article to introduce using thecake pattern for dependencies injection isthisone. Thereis also agreat talk thatdescribes how to use the cake pattern, which closely ressembles our usage here.
More recent articles seem to criticise the Cake pattern and many people seemto have drop it. The choice of using the cake pattern was made more than 4years ago and I still haven't reached the point where I think the drawbacksoutweight the benefits.
In order to run the tests for scala-native, you will need to follow theinstallation instructions on the Scala Nativewebsiteif you have not done so already. Additionally, you will need to have developmentlibraries to link against OpenGL, SDL2, and SDL2 Image.