Kitten
gleam add kitten
Kitten is a simple in-browser game engine, based on the HTML canvas element. It uses the model-view-update architecture and provides a handful of utility functions to make game development easier and safer.
Further documentation can be found at https://hexdocs.pm/kitten.
Look at the examples directory on github to learn more.
Example
import kitten/canvas
import kitten/color
import kitten/draw
import kitten/key
import kitten/vec2.{type Vec2, Vec2}
pub fn main() {
canvas.start_window(init, update, view, "canvas", 1920.0, 1080.0, [], [])
}
type Model {
Model(player_pos: Vec2)
}
const player_velocity = 5.0
const player_size = Vec2(80.0, 80.0)
fn init() {
Model(player_pos: Vec2(0.0, 0.0))
}
fn update(model: Model) {
let new_player_pos =
model.player_pos
|> case key.is_down(key.W) {
True -> vec2.add(_, Vec2(0.0, player_velocity))
_ -> vec2.id
}
|> case key.is_down(key.S) {
True -> vec2.subtract(_, Vec2(0.0, player_velocity))
_ -> vec2.id
}
|> case key.is_down(key.D) {
True -> vec2.add(_, Vec2(player_velocity, 0.0))
_ -> vec2.id
}
|> case key.is_down(key.A) {
True -> vec2.subtract(_, Vec2(player_velocity, 0.0))
_ -> vec2.id
}
Model(player_pos: new_player_pos)
}
fn view(model: Model) {
draw.context()
|> draw.background(color.black)
|> draw.rect(model.player_pos, player_size, color.red)
Nil
}
Quick start
Since kitten runs in the browser, you will need to compile your game code to javascript and attach it to an HTML file. To start, add target = "javascript"
to your gleam.toml
file. Next, create an index.html
file in your project folder and copy this markdown into it, replacing demo_proj
and demo
with the names of your project and main file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<canvas id="canvas"></canvas>
<script type="module">
import { main } from "./build/dev/javascript/demo_proj/demo.mjs";
main();
</script>
</body>
</html>
Now, just write some gleam code in your main file (I suggest you copy the example from above). Run gleam build
in the terminal, open the HTML file, and that’s it. You should be able to see a red box on your screen that you can move with the WASD keys.
To learn more about how the engine works, I suggest you look at the examples
directory in the Github repo. Make sure to read its README before looking at the example games.
Further development
The engine is far from complete at the moment. Particularly on the javascript side, the code is simply a mess of everything that I could get to work from other projects and ChatGPT. I am also not too happy with some of the modules, so expect changes in the near future.
Here are some things that I would like to add to the engine, but so far haven’t figured out how to implement them or how they would fit in:
-
a more consistent and general
simulate
module with higher-order abstractions and optimisations; possibly a lookahead collision system to prevent glitches - shaders (with WebGL)
- effects, like in Lustre, for tasks like communicating with a server; possible even a Lustre integration
- better documentation and a partial rewrite of the javascript code
- tests
- 3D and 3D-ish (eg isometric) support
If you have ideas on how to make any of this happen, please open a PR or a discussion on Github. All contributions are welcome.
Credits
The kitten engine is heavily inspired by the LittleJS engine by Frank Force (KilledByAPixel) and borrows many of its features and some of its code from LittleJS.
As part of the audio system, kitten includes ZzFX and ZzFXM by Frank Force and Keith Clark. Both sound systems have very useful websites for creating audio: ZzFX, ZzFXM.
The pre-defined colours in the color
module are taken directly from Pico CSS. Use their website to browse the colour collection online.
All of the above are licensed under the MIT license.