Make 2D games using the Odin Programming Language! Karl2D is a beginner friendly game creation library. It strives to minimize the number of dependencies, making you feel in control of the technology stack. Using Karl2D you can create desktop games, as well as web games (NO emscripten needed!)
See karl2d.doc.odin for an API overview.
Support the project by becoming a sponsor here on GitHub or on Patreon.
- Install the Odin compiler using the instructions on odin-lang.org
- Create a folder for your game
- Within your game folder, put the contents of this repository into a subfolder called
karl2d - Within your game folder, create a file called
game.odin(orwhatever_you_want.odin) and copy this into it:
package hello_world
import k2 "karl2d"
main :: proc() {
k2.init(1280, 720, "Greetings from Karl2D!")
for k2.update() {
k2.clear(k2.LIGHT_BLUE)
k2.draw_text("Hellope!", {50, 50}, 100, k2.DARK_BLUE)
k2.present()
}
k2.shutdown()
}- Navigate into the your game folder using a command prompt and run your game by writing
odin run .(note the period!) - A simple program that just shows the word "Hellope!" will appear. See the examples below for ideas on what to do next, or read karl2d.doc.odin for an API overview.
- Enjoy!
- If you want to make a web build of your game, continue to the Making a web build section below.
Note
On Linux, you may run into build errors due to missing depdencies. Exactly what you need to install may vary from distribution to distribution. On Ubuntu / Debian, something like this may help:
sudo apt install libasound2-dev libgl1-mesa-dev libudev-dev libwayland-dev libegl1-mesa-dev
Did you have to install something else on your distro? Let me know!
Discuss and get help in the #karl2d channel on my Discord server.
See the examples folder for a wide variety of example programs.
Here are links to live web builds of some of the examples:
- Basics - Draw texture, process some input
- SPACE CAT - Small top-down game demo
- Camera - How to use a camera
- Dual grid tilemap - Minimal tilemap editor using dual grid tilemap technique
- Positional audio - Playing sounds panning them based on world location
- Render Texture - Drawing into a texture and then drawing that texture multiple times
- Box2D
- Fonts
- Gamepad
- Mouse
- Snake
Let's look at how to make your game playable on the web.
Here I assume that you've set your project up like the Getting started guide above says. Change the the following code:
package hello_world
import k2 "karl2d"
main :: proc() {
k2.init(1280, 720, "Greetings from Karl2D!")
for k2.update() {
k2.clear(k2.LIGHT_BLUE)
k2.draw_text("Hellope!", {50, 50}, 100, k2.DARK_BLUE)
k2.present()
}
k2.shutdown()
}into this:
package hello_world
import k2 "karl2d"
main :: proc() {
init()
for step() {}
shutdown()
}
init :: proc() {
k2.init(1280, 720, "Greetings from Karl2D!")
}
step :: proc() -> bool {
if !k2.update() {
return false
}
k2.clear(k2.LIGHT_BLUE)
k2.draw_text("Hellope!", {50, 50}, 100, k2.DARK_BLUE)
k2.present()
return true
}
shutdown :: proc() {
k2.shutdown()
}There is still a main procedure that is used for desktop builds. The web builds will use the init and step procedures directly. This is because the web build can't have an "loop" like for k2.update() {}. Instead, it will run step when the browser wants to redraw its content.
To compile the web build, run the build_web tool that is bundled with karl2d. Using a command prompt, navigate to your game folder and run (note the double dash and the period! The period is the path to where your game lives, where a single . means "current folder")
odin run karl2d/build_web -- .
The web build will end up in bin/web. Run your game by navigating into it and opening index.html
Warning
If you open the index.html file and see nothing, then there might be an error about "cross site policy" stuff in the browser's console. In that case you can use python to run a local web-server and access the web build through it. Run python -m http.server in the bin/web folder and then navigate to https://localhost:8000.
Warning
On Linux / Mac you may need to install some lld package that contains the wasm-ld linker. It's included with Odin on Windows.
Note
To get better in-browser debug symbols, you can add -debug when running the build_web script:
odin run karl2d/build_web -- . -debug
Note that it comes after the --: That's the flags that get sent on to the build_web program! There are also -o:speed/size flags to turn on optimization.
The build_web tool will copy odin.js file from <odin>/core/sys/wasm/js/odin.js into the bin/web folder. It will also copy a HTML index file into that folder.
It will also create a build/web folder. That's the package it actually builds. It contains a bit of wrapper code that then calls the init and step functions of your game. The result of building the wrapper (and your game) is a main.wasm file that also ends up in bin/web.
Procedures such as k2.load_texture_from_file("image.png") do not work on the web because they depend on there being a file system. Instead you can do k2.load_texture_from_bytes(#load("image.png")). The #load call will bake the image into your executable at compile time.
If you want to load using k2.load_texture_from_file on desktop and k2.load_texture_from_bytes + #load on web, then you can create an abstraction.
Desktop version (put in a file with #+build !js at the top):
load_texture :: proc($name: string) -> k2.Texture {
return k2.load_texture_from_file(name)
}Web version (put in a file with #+build js at the top):
load_texture :: proc($name: string) -> k2.Texture {
return k2.load_texture_from_bytes(#load(name))
}The $ in front of the name parameter ensures that you're passing a compile-time constant, which makes it possible to use #load within the web version.
Some kind of gameplay code hot reload is planned as part of the library. Currently, there is an experimental implementation of this in a separate repository: https://github.com/karl-zylinski/karl2d-hot-reload-template
Karl2D is currently in its THIRD BETA period. If you find any issues, then please create an issue here on GitHub!
Beta 3 has these features:
- Rendering of shapes, textures and text with automatic batching
- Audio playback using custom software mixer
- Support for shaders and cameras
- Windows support (D3D11 and OpenGL)
- Mac support (OpenGL)
- Linux support (OpenGL)
- Web support (WebGL, no emscripten needed!)
- Input: Mouse, keyboard, gamepad
The platform-independent parts and the API lives in karl2d.odin. There is a karl2d.doc.odin file that is generated from karl2d.odin. It simply strips the bodies of the procedures, creating a nice overview.
karl2d.odin in turn uses interfaces for creating abstractions for the platform, rendering and audio.
The platform abstraction depends on the operating system. I do not use anything like GLFW in order to abstract away window creation and event handling. Less libraries between you and the OS, less trouble when shipping!
The rendering abstraction tells Karl2D how to talk to the GPU. I currently support three rendering APIs: D3D11, OpenGL and WebGL. On some platforms you have multiple choices, for example on Windows you can use both D3D11 and OpenGL (using the compile flag -define:KARL2D_RENDER_BACKEND=gl/d3d11). Using GL on windows may be beneficial if you want to share shader code between the desktop and web version (as they use almost the same verions of glsl). Some kind of shader-cross-API-compilation is planned, but not implemented.
The platform independent code in karl2d.odin creates a list of vertices for each batch it needs to render. That's done independently of the rendering backend. The backend is just fed that list, along with information about what shader and such to use.
The audio support in Karl2D is done using a software mixer that is part of karl2d.odin. The audio abstraction is small, it takes care of feeding the mixed audio samples into the platform's audio API. I wrote a blog post called Audio in Karl2D: Software mixing, OS APIs and general design where I describe how the audio system works.
The web builds do not need emscripten, instead I've written a WebGL backend and make use of the official Odin JS runtime.
Are you interested in helping with Karl2D development? Thank you! You can look at open issues here on GitHub. You get your contributions into the project using a Pull Request.
You can always open a draft Pull Request and work on your stuff in there. There are no rules for draft pull requests. When you want to turn your draft into a ready-for-review Pull Request, then please follow this rule checklist: https://github.com/karl-zylinski/karl2d/blob/master/.github/pull_request_template.md