Skip to main content
Deno 2 is finally here 🎉️
Learn more


caviar stars caviar releases caviar License


⚡ blazing fast game engine built on top of gluten & dwm with WebGPU & WebGL rendering

Running In the Browser With WebGPU

Usage

Moving Squares

import { Rectangle, Scene, World } from "https://deno.land/x/caviar/mod.ts";

class Game extends Scene {
  test = new Rectangle(0, 0, 100, 100, "#00ff00");
  test2 = new Rectangle(0, 0, 100, 100, "#00ff00");

  setup() {
    this.addChild([this.test, this.test2]);
  }
  update() {
    this.test.x += 5;
    this.test2.x += 2;
  }
}

const world = new World({
  title: "",
  width: 800,
  height: 600,
  resizable: true,
}, [Game]);

await world.start();

Perlin Noise

import {
  Group,
  Rectangle,
  Scene,
  World,
} from "https://deno.land/x/caviar/mod.ts";
import { PerlinNoise } from "https://deno.land/x/caviar/src/plugins/Perlin.ts";

class Game extends Scene {
  chunkSize = 16;
  tileSize = 16;

  setup() {
    const group = new Group(this, 0, 0);
    this.world.loadPlugin("perlin", PerlinNoise);

    const perlin = this.world.usePlugin("perlin");
    perlin.setSeed(1000);

    for (let x = -40; x < this.chunkSize; x++) {
      for (let y = -40; y < this.chunkSize; y++) {
        const tileX = (1 * (this.chunkSize * this.tileSize)) +
          (x * this.tileSize);
        const tileY = (1 * (this.chunkSize * this.tileSize)) +
          (y * this.tileSize);
        const perlinValue = perlin.perlin2(tileX / 100, tileY / 100);
        if (perlinValue < 0.2) {
          group.addChild(
            new Rectangle(
              tileX,
              tileY,
              this.tileSize,
              this.tileSize,
              "#ff0000",
            ),
          );
        } else if (perlinValue >= 0.2 && perlinValue < 0.3) {
          group.addChild(
            new Rectangle(
              tileX,
              tileY,
              this.tileSize,
              this.tileSize,
              "#00ff00",
            ),
          );
        } else if (perlinValue >= 0.3) {
          group.addChild(
            new Rectangle(
              tileX,
              tileY,
              this.tileSize,
              this.tileSize,
              "#0000ff",
            ),
          );
        }
      }
    }
    this.addChild(group);
  }
}

const world = new World({
  title: "Perlin Noise Plugin Example",
  width: 800,
  height: 600,
  resizable: true,
}, [Game]);

await world.start();

Texture Sprites

import {
  PICO8,
  Scene,
  TextureSprite,
  World,
} from "https://deno.land/x/caviar/mod.ts";

class Game extends Scene {
  test = new TextureSprite(this, 0, 0, {
    data: [
      "..9..9..",
      "..9999..",
      ".AAAAAA.",
      ".A1F1FA.",
      ".AFFFFA.",
      ".FEEEEAA",
      ".EEEEEEA",
      "..E..E..",
    ],
    pixelWidth: 32,
    pixelHeight: 32,
    palette: PICO8,
  });

  setup() {
    this.addChild(this.test);
  }
  update() {
    this.test.setX(this.test.x + 10);
  }
}

const world = new World({
  title: "Texture Sprite Example",
  width: 800,
  height: 600,
  resizable: true,
}, [Game]);

await world.start();

As Caviar uses the Deno FFI, you will need to add the flags --allow-ffi --unstable to run the programs. You can also add other flags to skip the permissions check the Deno does. An example of starting the program in Deno with all these flags is

deno run --allow-ffi --allow-env --allow-read --allow-write --allow-net --unstable test.ts

Tools

Maintainers

License

MIT