README.md

# Kitten

[![Package Version](https://img.shields.io/hexpm/v/net)](https://hex.pm/packages/kitten)
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/kitten/)

```sh
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

```gleam
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:

```html
<!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
- [ ] shaders (with WebGL)
- [ ] effects, like in [Lustre](https://github.com/lustre-labs/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](https://github.com/KilledByAPixel/LittleJS) 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](https://github.com/KilledByAPixel/ZzFX) and [ZzFXM](https://github.com/keithclark/ZzFXM) by Frank Force and Keith Clark. Both sound systems have very useful websites for creating audio: [ZzFX](https://killedbyapixel.github.io/ZzFX/), [ZzFXM](https://keithclark.github.io/ZzFXM/). 

The pre-defined colours in the `color` module are taken directly from [Pico CSS](https://picocss.com/docs/colors). Use their website to browse the colour collection online.

All of the above are licensed under the MIT license.