Nocker Pixel — Pixel fonts for Canvas games.

NOCKER PIXEL 1616 × 16

Sizes side by side

16 × 16 · @nocker/font/16x16

8 × 8 · @nocker/font/8x8

BITMAP FONT / VERSION 1

Pixel fonts for Canvas games.

A binary bitmap font for building Canvas games with AI. Inspect every pixel, tune the spacing, and take the data straight into your renderer.

Color per characterOrange = spacePurple = letter spacingBlue = line gap

Letter spacing

Letter spacing adds to the pen advance: 16px for kana, 8px for Latin. Small kana also use a 16px cell. The glyph stays unchanged; only the next glyph's starting position moves.

Compare the same text below. Spacing 0 gives 104px width; 1 gives 112px; 2 gives 120px. The visible ink gap also includes each glyph's side bearings. At 3× zoom, one extra logical pixel becomes three canvas pixels.

0px letter spacing · 104px total width

1px letter spacing · 112px total width

2px letter spacing · 120px total width

Playground

Zoom
6×
Letter spacing
0px
Line gap
4px
Logical bitmap
0 × 0px
Line height
20px / 12px
Lines
0

16 × 16

8 × 8

Glyph inspector

Hiragana

Katakana

Latin & numbers

Symbols

In-game examples

Dialogue · kana & small kana

Menu · katakana & English

Status · numbers & Japanese

Render in Canvas

Data contract

Use the same data in your game, or hand this contract to your coding agent.

rows[y] is hex, the left pixel in the high bit. Fill each 1 as a square. Move by advance + letterSpacing. Use integer positions and scale. Normalize text to NFC; use ? for missing glyphs.

Download spec for AI

Install

npm install @nocker/font
// Import the size you use; only its data is loaded.
import { renderText, layoutText } from '@nocker/font/16x16'
// 8 × 8: import { renderText } from '@nocker/font/8x8'

const canvas = document.querySelector('canvas')!
canvas.width = 960
canvas.height = 240
const ctx = canvas.getContext('2d')!

renderText(ctx, 'こんにちワールド、はじめもして。', {
  x: 8, y: 8,
  scale: 3,
  letterSpacing: 1,
  maxWidth: 304,
  color: '#ffffff',
})

const { width, height } = layoutText('こんにちは', { maxWidth: 304 })

Use the JSON directly

Without the library: each row is hex, the left pixel in the high bit. Fill each 1 as a square, then move by advance plus letter spacing.

const font = await fetch('/fonts/nocker-pixel-16.json')
  .then(response => response.json())

const { width } = font.cell
const scale = 3, letterSpacing = 1
let penX = 0
ctx.fillStyle = '#fff'

for (const char of 'ふぉんと Font'.normalize('NFC')) {
  const glyph = font.glyphs[char] ?? font.glyphs['?']

  glyph.rows.forEach((row, y) => {
    const bits = parseInt(row, 16)

    for (let x = 0; x < width; x++)
      if ((bits >> (width - 1 - x)) & 1) ctx.fillRect(
        (penX + x) * scale, y * scale, scale, scale
      )
  })

  penX += glyph.advance + letterSpacing
}

LicenseSIL OFL 1.1 / Misaki

16 × 16 — Derived from DotGothic16. Includes kana, Latin, numbers and punctuation; no kanji. The full OFL license is embedded in the JSON. Use in commercial games, modify and redistribute with the original copyright and OFL intact. Do not sell the font by itself.

8 × 8 — Derived from Misaki Gothic by Num Kadoma (8 × 8). Includes kana, Latin, numbers and punctuation; no kanji. The license is embedded in the JSON. Free software: use, copy and redistribute, with or without modification, commercially or not. Provided as is, without warranty.