Skip to content

Latest commit

 

History

History
63 lines (45 loc) · 2.31 KB

File metadata and controls

63 lines (45 loc) · 2.31 KB

neslua assets

Sprite / background art -> CHR

The NES stores tiles as CHR (pattern tables): 8x8 tiles, 16 bytes each (two 1-bit planes = 2 bits per pixel). A pattern table holds 256 tiles.

  • The PICO-8 sprite-sheet convention maps perfectly: a 128 x 128 PNG is 256 8x8 tiles = exactly one pattern table.
  • neslua ships a bare cart with a built-in 1bpp font (uploaded to the BG pattern table at tile $40+) and three default sprite tiles. Import your own art to replace them.

PNG -> CHR

Convert a PNG sprite sheet to a raw CHR blob with the SDK's converter:

node compiler/chr-encode.mjs sheet.png -o sheet.chr

Each 8x8 tile must use at most 4 colors (one NES sub-palette: 3 colors + transparent/backdrop). The converter quantizes to the nearest NES palette and reports any tile that needed more colors than fit.

Raw CHR

--sheet accepts a raw .chr blob (used as-is) or a .png (quantized at build time by the same encoder). The bytes are uploaded to the sprite pattern table at boot, replacing the three default tiles:

neslua build main.lua --sheet sheet.chr -o game.nes   # raw CHR
neslua build main.lua --sheet sheet.png -o game.nes   # PNG, quantized in-build

Sprite sub-palettes

Each 8x8 tile is 3 colors + transparent. The NES has four sprite sub-palettes; nes.spal(0..3) selects which one the following spr() calls use, so different actors can wear different colors in the same frame (see examples/starfall: red invaders, a cyan ship, green shots, a yellow burst). The default palettes are a warm/cool actor set; a palette-set API is a later milestone.

Color-count reality

  • Each 8x8 sprite tile: 3 colors + transparent (one sprite sub-palette).
  • Each 16x16 background attribute region: 3 colors + backdrop (one BG sub-palette). BG palette choice has 16x16 px granularity - see DIFFERENCES.md.
  • The NES master palette is a fixed 64-entry hardware table. All art quantizes to it.

Tilemaps

A map()-drawable tilemap is imported as a byte array (the __map__ convention, 128 tiles wide). mget(x, y) reads a cell; map(cx, cy, sx, sy, cw, ch) stamps a block into the nametable.

Audio

sfx(n) fires a compiled effect on the APU. A build-time sfx table from a small text format and a music pattern driver are later milestones.