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 daybreak with WebGPU bindings with desktop and web support

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 test = new World({
  title: "test",
  width: 800,
  height: 600,
  resizable: true,
}, [Game]);

await test.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(0);

    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 test = new World({
  title: "test",
  width: 800,
  height: 600,
  resizable: true,
}, [Game]);

await test.start();

Texture Sprites

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

class Game extends Scene {
  sprite = 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.sprite);
  }
  update() {
    this.sprite.setX(this.sprite.x + 10);
  }
}

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

await test.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