pxart help LOOKING

Looking

LOOKING
  render FILE... [-o preview.png] [--scale 8] [--no-grid] [--variant V] [--png [DIR]] [--plain]
         [--slots N|K=I] [--dry-run]
      Preview sheet with a pixel grid and x/y rulers every 4px (default --scale 8; sheet,
      anim and onion too). --png also writes each single-frame .px at 1x, FILE.png beside it
      or in DIR, and says so. --plain writes -o as the one frame alone, its exact size
      (--scale 1 by default), no grid, rulers, labels or --bg: for diff (--no-grid still
      pads and labels).
  sheet FILE|DIR... -o sheet.png [--scale 8] [--cols 8] [--grid] [--variant V] [--bg COLOR]
        [--fit] [--align bottom|pivot] [--rows cols|group] [--slots N|K=I] [--exclude GLOB]
        [--dry-run]
      Compare any mix of .px/.png frames, labeled with id, WxH and color count. A directory
      stands for every .px under it, recursively, sorted by path (PNGs in it are left out, a
      sheet rendered there too). --exclude GLOB (repeatable) leaves files out: one whose
      name or path under the directory matches ('_*.px', 'wip/*.px'), or every file under a
      directory that does ('wip'). A glob that leaves out every file is E_FILE. A palette
      file (no frames) among the inputs, a directory's or a glob's, is skipped with a note
      ('note: sheet skips palette.px: a palette file, no frames'); given alone it is
      E_NO_FRAMES. Every cell is the largest frame's size (a frame over 8x the median
      frame's area gets a note); --fit makes each cell its own frame's width (or its
      label's, if wider) and each row as tall as its tallest frame, --cols cells to a row,
      frames bottom-aligned in their row. A PNG whose four corners are exactly the --bg
      color (a scene rendered with the same --bg) doesn't count that color: it's the
      backdrop. Frames with the same id from different files are labeled with their file's
      stem in front (hero:idle/0, beast:idle/0); render and anim label them the same way.
      --align pivot lines up each animation group's frames by pivot, as anim and onion do:
      the group's frames are drawn on one canvas, every pivot on the same pixel. The
      default, --align bottom, bottom-aligns each frame in its cell.
      --rows group starts a row for each animation group (one file's walk/down, then its
      walk/up, ...; a file's top-level frames share one; a PNG has its own) and wraps within
      a group only when it has more than --cols frames: 'sheet party.px --fit --rows group
      --align pivot -o party.png' is one walk per row. The default, --rows cols, fills each
      row with --cols frames.
  anim FILE... [-o walk.gif|DIR] [--scale 8] [--fps N] [--variant V] [--dry-run]
      walk.gif (one file: each frame at --scale, its 1x and 2x copies beside it in the same
      picture), plus walk.strip.png: row 1 = frames, row 2 = what changed from the previous
      frame after removing the whole-sprite shift ("shift dx,dy then N px (P%) (no shift: M px)";
      P: N as a percent of the frame's opaque pixels, or of both frames' if more; a bob alone
      shows "then 0px (0%)"). The numbers print too, a line per frame (a FILE of several
      groups: a block each, top-level and @still frames skipped; -o a DIR);
      without -o, anim prints only those lines and writes nothing. Read the strip: the Read
      tool shows only a GIF's first frame. Durations come from the file (@anim/@frame ms)
      unless --fps. A group with repeat=1 plays once: frame 0 gets no wrap-around diff.
      --variant V counts V's render: a halo transparent in the base counts, at any alpha.
      An idle: when the bottom stays exactly put (rows Y down identical, 0 px changed) and
      only the part above moves (a breath), shifting would light up the legs, so the strip
      shows the unshifted diff: "no shift then M px (P%) (rows Y+ still; shift dx,dy: N px)".
      Both counts are always shown. That is for an idle, whose legs keep their shape in every
      frame of the animation: a walk whose leg moved even 1px keeps the shift, and in a walk
      a frame whose legs happen to stay put is the body's bob: "shift +0,+1 then 23px (6%) (no
      shift: 201px)". A frame recolored whole (a glow) doesn't count as the legs moving; a
      shadow that changes shape does. So that the rise and the fall of a breath read alike,
      once one frame shows rows still and rows Y down are identical in every frame of the
      animation, every frame whose shift would light them up shows the unshifted diff too; a
      walk over a static shadow keeps every shift.
      Tiles and overlays: frames that fill the canvas and are a ground tile (every pixel
      opaque) or a sparse overlay (at most 1/4 opaque: snow) also try every wrap-around scroll
      (shift --wrap), shown when it leaves strictly fewer pixels changed than the best plain
      shift: "shift dx,dy (wrap) then N px (P%) (no shift: M px)". A character sprite never wraps.
  onion A B -o x.png [--scale 8] [--rows Y0-Y1 | --feet N] [--tint-a [COLOR] | --fade-a]
        [--variant V] [--dry-run]
      B at 80% opacity drawn over A as a flat silhouette in a translucent red (#ff4060a0),
      with render's grid and rulers: where A shows past B is plain.
      Prints where each frame's opaque pixels sit on the shared canvas and how B's edges moved
      from A's, then the whole-sprite shift that best explains B, as anim finds it:
      "B vs A: left +0, right +0, top -1, bottom +0; best shift +0,-1 then 4px changed (no
      shift: 20px)": the head rose 1px, the feet stayed. Two different sprites (other sizes, or
      more than half the larger one's opaque pixels still changed at the whole sprites' best
      shift; --rows and --feet don't change that; two frames of one animation in one file
      are always one sprite, however much changed) print
      "...; different sprites: edges only": their edges still compare where the feet stand,
      but a best shift between two characters means nothing. y grows down, so +1 is lower.
      The edges are the sides of each frame's opaque bounding box: 'top -1' is B's top row 1px
      above A's.
      --rows Y0-Y1 (canvas rows as the readout prints them, both included; one row: --rows Y)
      or --feet N (the bottom N rows) limit the edges and the best shift to that band, so a
      weapon swing above doesn't hide what the feet did: 'B vs A (bottom 4 canvas rows 20-23;
      A opaque in 20-23, B in 21-23): left +0, ...'. The shift still moves all of A (pixels
      come into the band from above) and counts only the band's pixels; when the bottom edges
      agree, one up or down only lines up what moved above them, and the readout says no
      shift. The PNG darkens the rows outside the band.
      --tint-a COLOR draws the silhouette in another color. --fade-a draws A itself at 35%
      opacity instead.
  scene -o s.png [--scale 4] [--size WxH] [--bg #472d3c] [--map M --tile 16x16] [--variant V]
        [--tint #rrggbbaa] [--dry-run] ITEM@x,y ...
      Default --scale 4 (render's: 8).
      Size: --size, else the map's, else 96x64 (six 16x16 tiles by four). Pixels past the
      edge are cropped, with a note per item (and one for the map) saying how many; at the
      default size a note also names the --size that holds every item.
      ITEM is FILE[:frame][%variant][+h|+v|+hv]: +h mirrors it left-right, +v top-bottom
      (hero.px:walk/0+h@3,4; '+' needs no quoting, where '!' would be history expansion). Map legend entries (which also take +b, see
      Placement) and compose layers take +h/+v too. --map draws a text tilemap first:
      legend lines '<char> <FILE[:frame][%variant]>', a blank line, then rows of legend
      chars ('.' = empty). In a legend line the rest of the line is the path, relative to
      the map file: spaces are fine ('b ../png/trees and bushes/bush.png'), "quotes"
      optional. A legend entry that can't load is an error at its legend line.
      Items are then drawn on top. '#' lines are comments only before the first row;
      after that every non-blank line is a row, so '#' works as a map char (a wall row
      '####'). Before the rows, a line that is exactly
      '# FILE.px[:frame][%variant]' or '# FILE.png' (one token after '#', no spaces) is the
      legend line for '#', not a comment, and so is a quoted path ('# "my tiles/wall.png"');
      check and scene print a note for it. Any other line starting with '#' is a comment
      ('# see wall.px' too).
      Layers (a tile and a sprite in one cell): a line '---' after the rows starts another
      grid of rows over the same legend. Layers draw in order, later over earlier, and '.'
      is empty in each; the map is as big as its widest row and tallest layer.
      Placement: a map item draws with its top-left at its cell's top-left (column * tile
      w, row * tile h), so a 32x32 stall on 16x16 tiles hangs right and down over the next
      cells.
      A legend entry ending in +b (with flips: +hb, +vb, +hvb) draws bottom-aligned to its
      cell and centered across it, odd pixel left: x = cell x + (tile w - w) // 2,
      y = cell y + tile h - h. A tall lamp then stands on its cell and rises into the row
      above (cut off at the top edge on row 0). +b is for legend entries only.
      A worked map, market.map, on 16x16 tiles (tiles.px:cobble, :water/0 and :crate are
      16x16, stall.px is 32x32, lamp.px is 16x32):
          # ground layer, then props
          c tiles.px:cobble
          w tiles.px:water/0
          x tiles.px:crate+h
          S stall.px+b
          L lamp.px+b
          l lamp.px+hb

          cccccc
          cccccc
          wwwwww
          ---
          ......
          .S.L.l
          x.....
      'pxart scene --map market.map -o market.png' is 96x48: cobbles and water, then the
      props over them (compose --map builds the same room as a .px). The stall's cell is
      16,16, so it draws at 16 + (16-32)//2, 16 + 16 - 32 = 8,0; the lamps at 48,0 and 80,0
      (mirrored); the crate, mirrored, at its cell's top-left, 0,32.
      --variant V renders every map tile and .px item with V (a whole dark room), except
      those with their own %variant, which wins; a .px without V is an E_SELECT error.
      %base is the base palette, so 'lamp.px%base@40,20' (or a legend entry 'L lamp.px%base')
      stays unrecolored in a --variant night scene (a lit window, a glowing lamp). '%base'
      works wherever %variant does, and a variant can't be named base.
      Items and legend entries can be PNGs (hero.png@3,4). x,y may be negative (drawn
      partly off the left/top edge), in scene and in compose.
      --tint '#10183080' lays that color, at its alpha, over the whole finished scene (bg,
      map, every item, those with their own %variant too) at 1x, before --scale: a night
      scene in one step. To keep a light bright, mask its circle out of the untinted render
      and lay that over the tinted one.
  tint IN.png '#rrggbbaa' [-o OUT.png]
      scene --tint on a PNG (a rendered scene): lays the color, at its alpha, over every
      pixel; each pixel keeps its alpha, so transparent pixels stay transparent. Without -o,
      IN is rewritten.
  world W.world|ROOM.tmj -o world.png [--scale 2] [--dry-run]
  Centering: frames of different sizes are bottom-aligned and centered, the odd pixel
  left (x = (canvas - frame) // 2). render and sheet put a grey checkerboard
  behind frames; --bg (render, sheet, scene) takes a flat #rrggbb, #rrggbbaa or 'transparent'
  (as does every color typed on the command line: --tint, tint, palette --add
  k=transparent; the '#' may be left off, and in a script a '#' color needs quotes, or the
  shell reads a comment).
  --dry-run (render, sheet, anim, onion, scene) prints the readout and each output's size and
  layout, writes nothing and says '(dry run; nothing written)'. -o may then be left off. An
  image over 4096 px on a side or 16M px gets a WARNING, dry run or not.
This page is built from site/src/data/reference.json in the repository.Edit on GitHub