S2D Development Series - Snake,Day 1: Opening a Window.
Welcome to the first post of the S2D development series! In this series I will show you how to develop some small games step by step using my library S2D, and the first game in the list is... Snake!!
What is S2D?
Before we start writing any code we will quickly go over what S2D actually is.
S2D (Scala 2D) is a simple 2D game programming library for Scala. It was inspired by the simplicity of Raylib, being its main goal to remain as simple/basic as possible while giving you a minimal, direct API so you can focus on developing the game, not the engine.
There is one important thing that you must know about S2D, it targets Scala Native (Not the JVM or js).
In simple terms this means the game you build compiles to a native binary. There is no JVM dependencies, no JVM startup, no LWJGL wrappers. S2D is built directly on top of SDL2 and OpenGL.
Targetting Scala Native is, for me, what makes S2D special. Games need a language that lets you handle memory efficientely. With Native you have all the expressiveness of Scala while still having control over the Low Level design.
Why Snake first?
Well… why not? We’ve all built snake at least once in our lives haven’t we?
In all seriousness, I think Snake is a game that is small enough for you to actually finish building it but complete enough to at least teach you a few important concepts.
It has things like a Game Loop, User Input, Movement, Collision, States, etc. All of these are fundamental in game development.
It is also small enough that you can fit it in one single file which is, in my opinion, better when you are starting out.
In our case, it is good enough to introduce S2D’s API piece by piece, in small increments and in an order that makes sense.
What you need before we begin
To follow this series you will need:
Scala Native up and running on your machine. You should follow the official guide for this. (For this example we will use Scala 3.8.3 and Scala Native 0.5.12)
SDL2 and OpenGL binaries. S2D_CLI will take care of these for you.
Coursier. Follow the instructions here to install it.
Scala CLI. Same as Scala Native and Coursier, follow the official guide.
Installing S2D CLI
S2D uses a small CLI tool called “S2D-CLI”. This tool takes care of generating a basic template, downloading the necessary libraries, setting scala-cli up, etc. It basically sets up the environment for you to just open your code editor and start working on your game.
To install S2D-CLI we will use Coursier. Open a terminal and run this command:
cs install s2d —contribThis command will pull the latest release of the CLI tool and install it on your computer.
You can check if the CLI was installed running this on the same terminal window:
s2d —helpIf everything was installed correctly you should see something like this:
S2D - Scala 2D Native Library CLI Tool
Usage:
s2d --generate Generate a new S2D project template
s2d --help Show this help message
Creating the S2D project
In the same terminal window (or a new one if you closed the other one) navigate to wherever you want to create your projet folder. In my case I ran this command:
cd ~/Developments/Once you are positioned in your folder of choice, run this command:
s2d —generateNow the CLI will start asking you for a few things, don’t worry, I’ll guide you.
Project Name: choose whatever name you like, in my case I chose “snake-game”.
Build System: in this series we will be using scala-cli, but if you are familiar with SBT you can go ahead and choose that instead.
Project Path: don’t type anything here, just press enter.
Note: if you are on Linux the CLI will try to download all the needed libraries using sudo, so you might be prompted for you password.
The CLI will load a few things, show some messages on the terminal and once it stops, you should be able to see a folder with the name of your game and a few files inside.
snake-game/
assets/
project.scala
main.scala
SDL.dll
glew32.dll
We will quickly go over these files:
assetsthis is an empty folder where you can place all of the assets for your game, such as sprites, fonts, audio, etc.project.scalathis file contains the information for Scala-CLI. You can open it and take a look at what’s inside, but you won’t be editing it so don’t worry too much about it.main.scalathis is the entry point of the game and the only file we will be using in the series. You can go ahead an open it on your code editor of choice.
import s2d.core.*
import s2d.types.*
@main
def main(): Unit =
val screenWidth = 800
val screenHeight = 450
Window.create(screenWidth, screenHeight, "S2D Snake")
Input.setExitKey(Key.Escape)
Timing.setTargetFPS(60)
while Window.isOpen() do
Drawing.beginFrame()
Drawing.clear(Color.Black)
Drawing.endFrame()
Window.close()Lets go over this file line by line.
import s2d.core.*- This imports the “core” package from the S2D library. The core package has really important files inside that let you manage things like Windows, Cursor, User Input, Drawing, etc.import s2d.types.*- This imports the “types” package from the S2D library. Inside you’ll see things like “Vector2” or “Color”, these are data types used by the library and it is important to have them.Note: the “*” after the import means “import everything that is inside that package”. You can also choose to import only what you need to use.
@main- This tells the Scala compiler that the function “main” below is the entry point of the program.def main(): Unit =- This defines a new function called “main”. Since it has the@mainabove it, Scala will use it as the entry point of the program.val screenWidth = 800andval screenHeight = 450- These two lines create two values with the names screenWidth and screenHeight. In Scala the “val” keyword means these values cannot be changed. When a value cannot be change it is called “Immutable”.Window.create(screenWidth, screenHeight, “Snake”)- Ok this is the first line where we actually use the library, so what does it do? It opens a window! We use the “Window” class from the “core” package we imported earlier. You have to pass some parameters for it to work, following the order of the code above you give it a “window width”, “window height” and a “window title”. It is important to notice that we aren’t actually displaying anything yet, the window just exists there without an actual purpose.Input.setExitKey(Key.Escape)- Here we are using both the “core” package and the “types” package. We use the “Input” class (from core) to call the function “setExitKey”. This function needs a parameter of type “Key” (from types).
So we pass the “Escape” key as a parameter.
This function tells S2D what key we must press to close the window (and cleanup, stop the game loop, etc).Timing.setTargetFPS(60)- This line uses the “Timing” class and calls the function “setTargetFPS”. In simple terms this tells S2D to cap the the loop speed to 60 frames per second. If this isn’t set the game would run as fast as your CPU allows, so every computer would run the game at different speeds.while Window.isOpen() do- We’ve reached the “game loop”. This while statement uses a S2D function as an expression “Window.isOpen()”. This function returns a boolean, true if the window is open, false if it isn’t. So basically this while loop will run as long as the window stays open.Drawing.beginFrame()- The first line on the loop starts a new “frame”. What is a frame? Well to keep it as simple as possible, one frame is one complete image of the game, one complete draw. Above we set the loop speed to 60 frames per second, that means we are drawing 60 times every second. So we are calling “beginFrame” 60 times, every second. Every frame can be compared to a new “snapshot” of the game.Drawing.clear(Color.Black)- This line is simple, as its name says it “clears” the screen with a given “Color”. It paints the entire screen with the color you choose.Drawing.endFrame()- We called “beginFrame()” and now we need a way to end it. Everything between “beginFrame” and “endFrame” will be what you will be drawing on the screen for the current frame. By calling “endFrame” we tell S2D that there is nothing else to draw on that frame and it is ready to be displayed on the screen.Window.close()- We’ve made it to the end of the file!! The last line closes the window and also takes care of cleaning up all of the SDL2 and OpenGL resources from memory. This line is run once the “while” loop is over.
Running the code
Open the terminal again if you closed it. From inside the project folder run this:
scala-cli run .Scala-CLI will compile the entire project (it can take a moment the first time you run it) and launch the game.
If everything is correct you should see an 800x450 black window, with the title “S2D Snake”.
You can go ahead and close it by pressing Escape on your keyboard or the X on the window.
Congratulations, you just run your first S2D project!
Recommendations
I would suggest that you take a look at the files in the project, try to understand the code and mess around a bit with it.
Do things like changing the window color, the title, dimensions, the closing key, etc.
Familiarize yourself with the structure of the code and how it works.
Making games is a long and tough process, it takes time, effort, patience, lots of things.
In my opinion it is really important to know the tools that you are using for your project, understand how these tools work and what you can and cannot do with them.
Day 2
For day 2 we will start drawing things on the screen.
We will draw a simple game board (a grid) that will act as the “arena”.
We will use the “Basics” package, which includes lots of different shapes that we can use to build games, talk about how coordinates work and explain some more game related contents.
Hope you liked the post and let me know if there’s anything that I should work on to make it better for you!
Thanks and see you on Day 2.