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


caviar stars caviar releases caviar License


⚡ native and web 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");

  override setup() {
    this.addChild([this.test, this.test2]);
  }
  override 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;

  override 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,
  });

  override setup() {
    this.addChild(this.test);
  }
  override 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 to your Deno command.

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

Tools

Maintainers

License

MIT