npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dryanovski/gamefoo

v0.4.0

Published

A lightweight 2D game engine with behavior-based component system

Readme

GameFoo

A lightweight, behavior-based 2D game engine written in TypeScript. Works in both browser (Canvas 2D) and terminal (ANSI/TTY) environments.

Features

  • Dual Renderer Support - Canvas 2D for browsers, ANSI truecolor for terminals
  • Behavior-Based Architecture - Compose complex game logic from reusable behaviors
  • Entity Hierarchy - Base entities, dynamic entities with physics, players, and text
  • Collision Detection - Spatial collision with AABB and circle shapes, layer filtering
  • Tilemap System - Multi-layer tilemaps with tileset support
  • A* Pathfinding - Configurable heuristics, 4-dir and 8-dir movement
  • Procedural Generation - Perlin noise, biome-based map generation
  • State Machine - Type-safe FSM with lifecycle hooks
  • Sprite System - Grid/atlas-based sprites, animations, bitmap fonts and icons

Installation

# Using Bun (recommended)
bun add @dryanovski/gamefoo

# Using npm
npm install @dryanovski/gamefoo

Quick Start

Browser

import {
  Engine,
  WebRenderer,
  Player,
  Control,
  Input,
  ObjectSystem,
} from "@dryanovski/gamefoo";

const renderer = new WebRenderer("game-canvas", 800, 600);
const engine = new Engine(renderer, { backgroundColor: "#1a1a2e" });

class Hero extends Player {
  render(ctx) {
    ctx.fillRect(this.x, this.y, 50, 50, "#5566ff");
  }
}

const player = new Hero("hero", 400, 300, 50, 50);
player.attachBehaviour(new Control(player, new Input()));

engine.use(new ObjectSystem([player]));
engine.setup(() => console.log("Game started!"));

Terminal

import {
  Engine,
  TerminalRenderContext,
  IntervalLoopDriver,
  ObjectSystem,
} from "@dryanovski/gamefoo";

const renderer = new TerminalRenderContext({ cols: 80, rows: 24 });
const engine = new Engine(renderer, {
  loopDriver: new IntervalLoopDriver(30),
});

engine.render = (ctx) => {
  ctx.drawText("Hello, Terminal!", 10, 5, "#ffffff");
};

engine.use(new ObjectSystem([]));
engine.setup();

Development

# Install dependencies
bun install

# Run web demos (dev server with HMR)
bun run dev

# Run terminal demo
bun terminal_demos/basic/index.ts

# Build the library
bun run build

# Run tests
bun test

# Type checking
bun run typecheck

# Lint and format
bun run lint
bun run format

Project Structure

gamefoo/
├── src/                     # Library source
│   ├── core/                # Engine, camera, collision, sprites
│   │   ├── behaviours/      # Built-in behaviors
│   │   ├── grid/            # 2D grid and isometric projection
│   │   ├── tilemap/         # Tilemap system
│   │   ├── renderer/        # Web and terminal renderers
│   │   ├── fonts/           # Bitmap fonts
│   │   ├── icons/           # Bitmap icons
│   │   └── utils/           # Pathfinding, map generation, noise
│   ├── entities/            # Entity classes
│   ├── subsystems/          # Engine subsystems
│   └── debug/               # Debug tools
├── web_demos/               # Browser demos
├── terminal_demos/          # Terminal demos
├── tools/                   # Tilemap/sprite editor
├── docs/                    # Documentation site
└── tests/                   # Test files

Web Demos

Run bun run dev and visit:

  • /demo - Basic collision and entity demo
  • /dungen - Dungeon crawler with fog of war and procedural generation
  • /isometric - Isometric world with NPCs and pathfinding
  • /endless-world - Infinite procedural world generation
  • /floppy - Flappy bird clone
  • /fonts - Bitmap font showcase
  • /icons - Bitmap icon showcase
  • /clock - Analog clock demo

Core Concepts

Behaviors

Entities gain functionality through attached behaviors:

const player = new Player("hero", 100, 100, 32, 32);
player.attachBehaviour(new Control(player, new Input()));
player.attachBehaviour(new Collidable(player, world, "player"));
player.attachBehaviour(new HealthKit(player, 100));

Built-in behaviors: Control, Collidable, HealthKit, SpriteRender, TerminalRender, PathFollower

Subsystems

Modular engine features that can be composed:

engine.use(new ObjectSystem([player, enemy]));
engine.use(new CollisionSystem(world));
engine.use(new CameraSystem(camera, player));
engine.use(new MonitorSystem());

Collision World

const world = new World();

world.register(player, { layer: "player", solid: true });
world.register(wall, { layer: "wall", solid: true, fixed: true });
world.register(pickup, { layer: "item", tag: "coin" });

// Query collisions
const hits = world.query(player, { layer: "item", tag: "coin" });

Tilemaps

const tileset = new TileSet(spriteSheet, 16, 16);
const layer = new TileLayer(mapWidth, mapHeight, tileData);
const tilemap = new TileMap(tileset, [layer]);

engine.use(new TilemapSystem(tilemap));

Pathfinding

const pathfinder = new AStarPathfinder(grid, {
  heuristic: "manhattan",
  allowDiagonal: false,
});

const path = pathfinder.findPath(startX, startY, endX, endY);

License

MIT