pyxel Documentation

A retro game engine for Python

18,440 stars Rust Rust 11 files ยท ~36,993 tokens #game#game-development#game-engine#gamedev#graphics#html#opengl#pico-8
RAW Doc

Technical Documentation: kitao/pyxel

โ„น๏ธ Provenance: Multi-Tier Ingestion ยท CodeWiki Reference

Overview (`README.md`)

[](https://kitao.dev/pyxel/)




A retro game engine for Python

โ–ธ Website

text
<a href="https://kitao.dev/pyxel/user-examples/"
      ></a>
    <a href="https://gihyo.jp/book/2025/978-4-297-14657-3"
      ></a>
  


    <a href="https://kitao.dev/pyxel/showcase/examples/02-jump-game.html">
      
    </a>
    <a href="https://kitao.dev/pyxel/showcase/examples/10-platformer.html">
      
    </a>
    <a href="https://kitao.dev/pyxel/showcase/apps/30sec-of-daylight.html">
      
    </a>
    <a href="https://kitao.dev/pyxel/showcase/apps/megaball.html">
      
    </a>
    <a href="https://kitao.dev/pyxel/showcase/tools/image-editor.html">
      
    </a>
    <a href="https://kitao.dev/pyxel/showcase/tools/sound-editor.html">
      
    </a>
    <a
      href="https://kitao.dev/pyxel/showcase/examples/c04-mesh-and-motion.html"
    >
      
    </a>
    <a
      href="https://kitao.dev/pyxel/showcase/examples/c05-3d-collision.html"
    >
      
    </a>
    <a href="https://kitao.dev/pyxel/showcase/examples/c06-3d-physics.html">
      
    </a>

Api Reference (`docs/api-reference.md`)

Pyxel API Reference

This document was auto-generated from the Pyxel API Reference web page, which also offers multilingual support.

System

`width` โ€” variable

The width of the screen.

  • Type: int

`height` โ€” variable

The height of the screen.

  • Type: int

`frame_count` โ€” variable

The number of elapsed frames.

  • Type: int

`init(width, height, title="Pyxel", fps=30, quit_key=KEY_ESCAPE, display_scale=None, capture_scale=2, capture_sec=10, headless=False)` โ€” function

Initialize the Pyxel application with the screen size (width, height).

Parameters:

  • width (int) โ€” Screen width
  • height (int) โ€” Screen height
  • title (str) โ€” Window title. Defaults to "Pyxel".
  • fps (int) โ€” Frame rate. Defaults to 30.
  • quit_key (int) โ€” Key to quit the application. Defaults to KEY_ESCAPE.
  • display_scale (int) โ€” Display scale factor. If omitted, automatically determined.
  • capture_scale (int) โ€” Screen capture scale factor. Defaults to 2.
  • capture_sec (int) โ€” Maximum recording time for screen capture video. Defaults to 10.
  • headless (bool) โ€” Run without a window. Defaults to False.

Example:

python
pyxel.init(
    160,
    120,
    title="My Pyxel App",
    fps=60,
    quit_key=pyxel.KEY_NONE,
    capture_scale=3,
    capture_sec=0,
)

`run(update, draw)` โ€” function

Start the Pyxel application and call the update function for frame update and the draw function for drawing.

Parameters:

  • update (callable) โ€” Function to update game logic each frame
  • draw (callable) โ€” Function to draw the screen each frame

`show()` โ€” function

Show the screen and wait until the quit key is pressed.

`flip()` โ€” function

Refresh the screen by one frame. The application exits when the quit key is pressed. This function is not available in the web version.

`quit()` โ€” function

Quit the Pyxel application.

`reset()` โ€” function

Restart the Pyxel application from the beginning.

`title(title)` โ€” function *(Advanced)*

Set the window title.

Parameters:

  • title (str) โ€” Window title

`icon(data, scale, colkey=None)` โ€” function *(Advanced)*

Set the application icon. Specify the icon image as a list of strings.

Parameters:

  • data (list[str]) โ€” Icon image as a list of strings
  • scale (int) โ€” Scale factor
  • colkey (int/None) โ€” Transparent color. If omitted, no transparency.

`fullscreen(enabled)` โ€” function *(Advanced)*

Set whether to run in fullscreen mode.

Parameters:

  • enabled (bool) โ€” Enable fullscreen

`resize(width, height)` โ€” function *(Advanced)*

Change the screen size at runtime.

Parameters:

  • width (int) โ€” New screen width in pixels
  • height (int) โ€” New screen height in pixels

`screen_mode(scr)` โ€” function *(Advanced)*

Set the screen mode (0: crisp, 1: smooth, 2: retro).

Parameters:

  • scr (int) โ€” Screen mode number (0: crisp, 1: smooth, 2: retro)

`perf_monitor(enabled)` โ€” function *(Advanced)*

Show or hide the performance monitor.

Parameters:

  • enabled (bool) โ€” Enable the performance monitor

`integer_scale(enabled)` โ€” function *(Advanced)*

Enable integer scaling for the display.

Parameters:

  • enabled (bool) โ€” Enable integer scaling

Resource

`load(filename, exclude_images=False, exclude_tilemaps=False, exclude_sounds=False, exclude_musics=False)` โ€” function

Load the resource file (.pyxres). If an option is set to True, the corresponding resource will be excluded from loading.

Parameters:

  • filename (str) โ€” Resource file name
  • exclude_images (bool) โ€” Exclude image banks. Defaults to False.
  • exclude_tilemaps (bool) โ€” Exclude tilemaps. Defaults to False.
  • exclude_sounds (bool) โ€” Exclude sounds. Defaults to False.
  • exclude_musics (bool) โ€” Exclude music tracks. Defaults to False.

Note: If a palette file (.pyxpal) with the same name exists, the palette display colors will also be updated.

`user_data_dir(vendor_name, app_name)` โ€” function *(Advanced)*

Return the user data directory created based on vendor_name and app_name. If the directory does not exist, it will be created automatically.

Parameters:

  • vendor_name (str) โ€” Vendor name
  • app_name (str) โ€” Application name

Returns: str โ€” Path to the user data directory

Example:

python
pyxel.user_data_dir("Takashi Kitao", "Pyxel Shooter")

`save(filename, exclude_images=False, exclude_tilemaps=False, exclude_sounds=False, exclude_musics=False)` โ€” function *(Advanced)*

Save the resource file (.pyxres). If an option is set to True, the corresponding resource will be excluded from saving.

Parameters:

  • filename (str) โ€” Resource file name
  • exclude_images (bool) โ€” Exclude image banks. Defaults to False.
  • exclude_tilemaps (bool) โ€” Exclude tilemaps. Defaults to False.
  • exclude_sounds (bool) โ€” Exclude sounds. Defaults to False.
  • exclude_musics (bool) โ€” Exclude music tracks. Defaults to False.

`screenshot(filename=None, scale=2)` โ€” function *(Advanced)*

Take a screenshot.

Parameters:

  • filename (str/None) โ€” File name. If omitted, saved to desktop.
  • scale (int/None) โ€” Scale factor. Defaults to capture_scale.

`screencast(filename=None, scale=2)` โ€” function *(Advanced)*

Save the screen recording as a GIF file.

Parameters:

  • filename (str/None) โ€” File name. If omitted, saved to desktop.
  • scale (int/None) โ€” Scale factor. Defaults to capture_scale.

`reset_screencast()` โ€” function *(Advanced)*

Reset the screen recording buffer.

`load_pal(filename)` โ€” function *(Advanced)*

Load a palette file (.pyxpal).

Parameters:

  • filename (str) โ€” Palette file name

`save_pal(filename)` โ€” function *(Advanced)*

Save a palette file (.pyxpal).

Parameters:

  • filename (str) โ€” Palette file name

Input

`mouse_x` โ€” variable

The current x position of the mouse cursor.

  • Type: int

`mouse_y` โ€” variable

The current y position of the mouse cursor.

  • Type: int

`mouse_wheel` โ€” variable

The current value of the mouse wheel.

  • Type: int

`input_keys` โ€” variable *(Advanced)*

List of keys input in the current frame.

  • Type: list[int]

`input_text` โ€” variable *(Advanced)*

Text input in the current frame.

  • Type: str

`dropped_files` โ€” variable *(Advanced)*

List of files dropped in the current frame.

  • Type: list[str]

`btn(key)` โ€” function

Return True if the key is pressed, otherwise return False.

Parameters:

  • key (int) โ€” Key code

Returns: bool โ€” True if pressed

`btnp(key, hold=0, repeat=0)` โ€” function

Return True if the key is pressed in that frame. When hold and repeat are specified, after holding the key for hold frames, return True every repeat frames.

Parameters:

  • key (int) โ€” Key code
  • hold (int) โ€” Frames to hold before repeat starts. Defaults to 0.
  • repeat (int) โ€” Repeat interval in frames. If 0, no repeat.

Returns: bool โ€” True if pressed in that frame

`btnr(key)` โ€” function

Return True if the key is released in that frame, otherwise return False.

Parameters:

  • key (int) โ€” Key code

Returns: bool โ€” True if released in that frame

`mouse(visible)` โ€” function

Show the mouse cursor if visible is True, and hide it if False. The cursor position continues to update even when hidden.

Parameters:

  • visible (bool) โ€” Show or hide the cursor

`btnv(key)` โ€” function *(Advanced)*

Return the analog value of the specified key (e.g., gamepad axis value).

Parameters:

  • key (int) โ€” Key code

Returns: int โ€” Analog value of the key

`set_btn(key, state)` โ€” function *(Advanced)*

Set the press/release state of the specified key. Mainly for headless mode input simulation.

Parameters:

  • key (int) โ€” Target key
  • state (bool) โ€” True for press, False for release

`set_btnv(key, val)` โ€” function *(Advanced)*

Set the analog value of the specified key. Mainly for headless mode input simulation.

Parameters:

  • key (int) โ€” Target key
  • val (int) โ€” Analog value to set

`set_mouse_pos(x, y)` โ€” function *(Advanced)*

Set the mouse cursor position. Mainly for headless mode input simulation.

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate

`set_input_text(text)` โ€” function *(Advanced)*

Set the text input for the current frame. Replaces any existing text. Mainly for headless mode input simulation.

Parameters:

  • text (str) โ€” Text input

`set_dropped_files(files)` โ€” function *(Advanced)*

Set the dropped file list for the current frame. Replaces any existing list. Mainly for headless mode input simulation.

Parameters:

  • files (list[str]) โ€” List of file paths

Key Constants

Special Keys:

KEY_UNKNOWN KEY_RETURN KEY_ESCAPE KEY_BACKSPACE KEY_TAB KEY_SPACE KEY_NONE

Letters:

KEY_A KEY_B KEY_C KEY_D KEY_E KEY_F KEY_G KEY_H KEY_I KEY_J KEY_K KEY_L KEY_M KEY_N KEY_O KEY_P KEY_Q KEY_R KEY_S KEY_T KEY_U KEY_V KEY_W KEY_X KEY_Y KEY_Z

Numbers:

KEY_0 KEY_1 KEY_2 KEY_3 KEY_4 KEY_5 KEY_6 KEY_7 KEY_8 KEY_9

Symbols:

KEY_EXCLAIM KEY_QUOTEDBL KEY_HASH KEY_PERCENT KEY_DOLLAR KEY_AMPERSAND KEY_QUOTE KEY_LEFTPAREN KEY_RIGHTPAREN KEY_ASTERISK KEY_PLUS KEY_COMMA KEY_MINUS KEY_PERIOD KEY_SLASH KEY_COLON KEY_SEMICOLON KEY_LESS KEY_EQUALS KEY_GREATER KEY_QUESTION KEY_AT KEY_LEFTBRACKET KEY_BACKSLASH KEY_RIGHTBRACKET KEY_CARET KEY_UNDERSCORE KEY_BACKQUOTE

Function:

KEY_F1 KEY_F2 KEY_F3 KEY_F4 KEY_F5 KEY_F6 KEY_F7 KEY_F8 KEY_F9 KEY_F10 KEY_F11 KEY_F12 KEY_F13 KEY_F14 KEY_F15 KEY_F16 KEY_F17 KEY_F18 KEY_F19 KEY_F20 KEY_F21 KEY_F22 KEY_F23 KEY_F24

Navigation:

KEY_INSERT KEY_HOME KEY_PAGEUP KEY_DELETE KEY_END KEY_PAGEDOWN KEY_RIGHT KEY_LEFT KEY_DOWN KEY_UP

Modifiers:

KEY_CAPSLOCK KEY_LCTRL KEY_LSHIFT KEY_LALT KEY_LGUI KEY_RCTRL KEY_RSHIFT KEY_RALT KEY_RGUI KEY_SHIFT KEY_CTRL KEY_ALT KEY_GUI

Numpad:

KEY_NUMLOCKCLEAR KEY_KP_DIVIDE KEY_KP_MULTIPLY KEY_KP_MINUS KEY_KP_PLUS KEY_KP_ENTER KEY_KP_1 KEY_KP_2 KEY_KP_3 KEY_KP_4 KEY_KP_5 KEY_KP_6 KEY_KP_7 KEY_KP_8 KEY_KP_9 KEY_KP_0 KEY_KP_PERIOD KEY_KP_EQUALS KEY_KP_COMMA KEY_KP_EQUALSAS400 KEY_KP_00 KEY_KP_000 KEY_KP_LEFTPAREN KEY_KP_RIGHTPAREN KEY_KP_LEFTBRACE KEY_KP_RIGHTBRACE KEY_KP_TAB KEY_KP_BACKSPACE KEY_KP_A KEY_KP_B KEY_KP_C KEY_KP_D KEY_KP_E KEY_KP_F KEY_KP_XOR KEY_KP_POWER KEY_KP_PERCENT KEY_KP_LESS KEY_KP_GREATER KEY_KP_AMPERSAND KEY_KP_DBLAMPERSAND KEY_KP_VERTICALBAR KEY_KP_DBLVERTICALBAR KEY_KP_COLON KEY_KP_HASH KEY_KP_SPACE KEY_KP_AT KEY_KP_EXCLAM KEY_KP_MEMSTORE KEY_KP_MEMRECALL KEY_KP_MEMCLEAR KEY_KP_MEMADD KEY_KP_MEMSUBTRACT KEY_KP_MEMMULTIPLY KEY_KP_MEMDIVIDE KEY_KP_PLUSMINUS KEY_KP_CLEAR KEY_KP_CLEARENTRY KEY_KP_BINARY KEY_KP_OCTAL KEY_KP_DECIMAL KEY_KP_HEXADECIMAL

System & Media:

KEY_PRINTSCREEN KEY_SCROLLLOCK KEY_PAUSE KEY_APPLICATION KEY_POWER KEY_EXECUTE KEY_HELP KEY_MENU KEY_SELECT KEY_STOP KEY_AGAIN KEY_UNDO KEY_CUT KEY_COPY KEY_PASTE KEY_FIND KEY_MUTE KEY_VOLUMEUP KEY_VOLUMEDOWN KEY_ALTERASE KEY_SYSREQ KEY_CANCEL KEY_CLEAR KEY_PRIOR KEY_RETURN2 KEY_SEPARATOR KEY_OUT KEY_OPER KEY_CLEARAGAIN KEY_CRSEL KEY_EXSEL KEY_THOUSANDSSEPARATOR KEY_DECIMALSEPARATOR KEY_CURRENCYUNIT KEY_CURRENCYSUBUNIT

Mouse Constants

Cursor & Wheel:

MOUSE_POS_X MOUSE_POS_Y MOUSE_WHEEL_X MOUSE_WHEEL_Y

Buttons:

MOUSE_BUTTON_LEFT MOUSE_BUTTON_MIDDLE MOUSE_BUTTON_RIGHT MOUSE_BUTTON_X1 MOUSE_BUTTON_X2

Gamepad Constants

Gamepad 1:

GAMEPAD1_AXIS_LEFTX GAMEPAD1_AXIS_LEFTY GAMEPAD1_AXIS_RIGHTX GAMEPAD1_AXIS_RIGHTY GAMEPAD1_AXIS_TRIGGERLEFT GAMEPAD1_AXIS_TRIGGERRIGHT GAMEPAD1_BUTTON_A GAMEPAD1_BUTTON_B GAMEPAD1_BUTTON_X GAMEPAD1_BUTTON_Y GAMEPAD1_BUTTON_BACK GAMEPAD1_BUTTON_GUIDE GAMEPAD1_BUTTON_START GAMEPAD1_BUTTON_LEFTSTICK GAMEPAD1_BUTTON_RIGHTSTICK GAMEPAD1_BUTTON_LEFTSHOULDER GAMEPAD1_BUTTON_RIGHTSHOULDER GAMEPAD1_BUTTON_DPAD_UP GAMEPAD1_BUTTON_DPAD_DOWN GAMEPAD1_BUTTON_DPAD_LEFT GAMEPAD1_BUTTON_DPAD_RIGHT

Gamepad 2:

GAMEPAD2_AXIS_LEFTX GAMEPAD2_AXIS_LEFTY GAMEPAD2_AXIS_RIGHTX GAMEPAD2_AXIS_RIGHTY GAMEPAD2_AXIS_TRIGGERLEFT GAMEPAD2_AXIS_TRIGGERRIGHT GAMEPAD2_BUTTON_A GAMEPAD2_BUTTON_B GAMEPAD2_BUTTON_X GAMEPAD2_BUTTON_Y GAMEPAD2_BUTTON_BACK GAMEPAD2_BUTTON_GUIDE GAMEPAD2_BUTTON_START GAMEPAD2_BUTTON_LEFTSTICK GAMEPAD2_BUTTON_RIGHTSTICK GAMEPAD2_BUTTON_LEFTSHOULDER GAMEPAD2_BUTTON_RIGHTSHOULDER GAMEPAD2_BUTTON_DPAD_UP GAMEPAD2_BUTTON_DPAD_DOWN GAMEPAD2_BUTTON_DPAD_LEFT GAMEPAD2_BUTTON_DPAD_RIGHT

Gamepad 3:

GAMEPAD3_AXIS_LEFTX GAMEPAD3_AXIS_LEFTY GAMEPAD3_AXIS_RIGHTX GAMEPAD3_AXIS_RIGHTY GAMEPAD3_AXIS_TRIGGERLEFT GAMEPAD3_AXIS_TRIGGERRIGHT GAMEPAD3_BUTTON_A GAMEPAD3_BUTTON_B GAMEPAD3_BUTTON_X GAMEPAD3_BUTTON_Y GAMEPAD3_BUTTON_BACK GAMEPAD3_BUTTON_GUIDE GAMEPAD3_BUTTON_START GAMEPAD3_BUTTON_LEFTSTICK GAMEPAD3_BUTTON_RIGHTSTICK GAMEPAD3_BUTTON_LEFTSHOULDER GAMEPAD3_BUTTON_RIGHTSHOULDER GAMEPAD3_BUTTON_DPAD_UP GAMEPAD3_BUTTON_DPAD_DOWN GAMEPAD3_BUTTON_DPAD_LEFT GAMEPAD3_BUTTON_DPAD_RIGHT

Gamepad 4:

GAMEPAD4_AXIS_LEFTX GAMEPAD4_AXIS_LEFTY GAMEPAD4_AXIS_RIGHTX GAMEPAD4_AXIS_RIGHTY GAMEPAD4_AXIS_TRIGGERLEFT GAMEPAD4_AXIS_TRIGGERRIGHT GAMEPAD4_BUTTON_A GAMEPAD4_BUTTON_B GAMEPAD4_BUTTON_X GAMEPAD4_BUTTON_Y GAMEPAD4_BUTTON_BACK GAMEPAD4_BUTTON_GUIDE GAMEPAD4_BUTTON_START GAMEPAD4_BUTTON_LEFTSTICK GAMEPAD4_BUTTON_RIGHTSTICK GAMEPAD4_BUTTON_LEFTSHOULDER GAMEPAD4_BUTTON_RIGHTSHOULDER GAMEPAD4_BUTTON_DPAD_UP GAMEPAD4_BUTTON_DPAD_DOWN GAMEPAD4_BUTTON_DPAD_LEFT GAMEPAD4_BUTTON_DPAD_RIGHT

Graphics

`colors` โ€” variable

List of the palette display colors. Specified by 24-bit numerical value. Supports Python list operations.

  • Type: list[int]

Example:

python
old_colors = list(pyxel.colors)
pyxel.colors[15] = 0x112233

`images` โ€” variable

Image banks (Image instances) (0-2).

  • Type: list[Image]

Example:

python
pyxel.images[0].load(0, 0, "title.png")

`tilemaps` โ€” variable

Tilemaps (Tilemap instances) (0-7).

  • Type: list[Tilemap]

`screen` โ€” variable *(Advanced)*

The screen image (Image class instance).

  • Type: Image

`cursor` โ€” variable *(Advanced)*

The cursor image (Image class instance).

  • Type: Image

`font` โ€” variable *(Advanced)*

The font image (Image class instance).

  • Type: Image

`clip(x, y, w, h)` โ€” function

Set the drawing area of the screen from (x, y) with a width of w and a height of h. Call clip() to reset to full screen.

Parameters:

  • x (float) โ€” X coordinate of the upper-left corner
  • y (float) โ€” Y coordinate of the upper-left corner
  • w (float) โ€” Width of the clipping area
  • h (float) โ€” Height of the clipping area

`clip()` โ€” function

Reset the drawing area to full screen.

`camera(x, y)` โ€” function

Set the drawing offset to (x, y). All subsequent drawing operations will be shifted by (-x, -y).

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate

`camera()` โ€” function

Reset the drawing offset to (0, 0).

`pal(col1, col2)` โ€” function

Replace color col1 with col2 when drawing.

Parameters:

  • col1 (int) โ€” Color to replace
  • col2 (int) โ€” Replacement color

`pal()` โ€” function

Reset the palette to the initial state.

`dither(alpha)` โ€” function

Apply dithering (pseudo-transparency) when drawing. Set alpha in the range 0.0-1.0.

Parameters:

  • alpha (float) โ€” Opacity (0.0: transparent, 1.0: opaque)

`cls(col)` โ€” function

Clear the screen with color col.

Parameters:

  • col (int) โ€” Color

`pget(x, y)` โ€” function

Get the color of the pixel at (x, y). The coordinates are absolute and not affected by the camera offset.

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate

Returns: int โ€” Color of the pixel

`pset(x, y, col)` โ€” function

Draw a pixel of color col at (x, y).

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate
  • col (int) โ€” Color

`line(x1, y1, x2, y2, col)` โ€” function

Draw a line of color col from (x1, y1) to (x2, y2).

Parameters:

  • x1 (float) โ€” Start X coordinate
  • y1 (float) โ€” Start Y coordinate
  • x2 (float) โ€” End X coordinate
  • y2 (float) โ€” End Y coordinate
  • col (int) โ€” Color

`rect(x, y, w, h, col)` โ€” function

Draw a filled rectangle of width w, height h, and color col at (x, y).

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate
  • w (float) โ€” Width
  • h (float) โ€” Height
  • col (int) โ€” Color

`rectb(x, y, w, h, col)` โ€” function

Draw the outline of a rectangle of width w, height h, and color col at (x, y).

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate
  • w (float) โ€” Width
  • h (float) โ€” Height
  • col (int) โ€” Color

`circ(x, y, r, col)` โ€” function

Draw a filled circle of radius r and color col at (x, y).

Parameters:

  • x (float) โ€” Center X coordinate
  • y (float) โ€” Center Y coordinate
  • r (float) โ€” Radius
  • col (int) โ€” Color

`circb(x, y, r, col)` โ€” function

Draw the outline of a circle of radius r and color col at (x, y).

Parameters:

  • x (float) โ€” Center X coordinate
  • y (float) โ€” Center Y coordinate
  • r (float) โ€” Radius
  • col (int) โ€” Color

`elli(x, y, w, h, col)` โ€” function

Draw a filled ellipse of width w, height h, and color col at (x, y).

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate
  • w (float) โ€” Width
  • h (float) โ€” Height
  • col (int) โ€” Color

`ellib(x, y, w, h, col)` โ€” function

Draw the outline of an ellipse of width w, height h, and color col at (x, y).

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate
  • w (float) โ€” Width
  • h (float) โ€” Height
  • col (int) โ€” Color

`tri(x1, y1, x2, y2, x3, y3, col)` โ€” function

Draw a filled triangle with vertices (x1, y1), (x2, y2), (x3, y3) and color col.

Parameters:

  • x1 (float) โ€” Vertex 1 X
  • y1 (float) โ€” Vertex 1 Y
  • x2 (float) โ€” Vertex 2 X
  • y2 (float) โ€” Vertex 2 Y
  • x3 (float) โ€” Vertex 3 X
  • y3 (float) โ€” Vertex 3 Y
  • col (int) โ€” Color

`trib(x1, y1, x2, y2, x3, y3, col)` โ€” function

Draw the outline of a triangle with vertices (x1, y1), (x2, y2), (x3, y3) and color col.

Parameters:

  • x1 (float) โ€” Vertex 1 X
  • y1 (float) โ€” Vertex 1 Y
  • x2 (float) โ€” Vertex 2 X
  • y2 (float) โ€” Vertex 2 Y
  • x3 (float) โ€” Vertex 3 X
  • y3 (float) โ€” Vertex 3 Y
  • col (int) โ€” Color

`fill(x, y, col)` โ€” function

Fill the area connected with the same color as (x, y) with color col.

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate
  • col (int) โ€” Fill color

`blt(x, y, img, u, v, w, h, colkey=None, rotate=0, scale=1)` โ€” function

Copy the region of size (w, h) from (u, v) of image bank img (0-2 or Image instance) to (x, y). Negative w/h flips the image. colkey sets the transparent color. rotate and scale apply transformations.

Parameters:

  • x (float) โ€” Destination X
  • y (float) โ€” Destination Y
  • img (int/Image) โ€” Image bank number (0-2) or Image instance
  • u (float) โ€” Source X in the image bank
  • v (float) โ€” Source Y in the image bank
  • w (float) โ€” Width (negative to flip)
  • h (float) โ€” Height (negative to flip)
  • colkey (int/None) โ€” Transparent color. If omitted, no transparency.
  • rotate (float) โ€” Rotation angle in degrees (centered on the copy region). Defaults to 0.
  • scale (float) โ€” Scale factor (centered on the copy region). Defaults to 1.

`bltm(x, y, tm, u, v, w, h, colkey=None, rotate=0, scale=1)` โ€” function

Copy the region of size (w, h) from (u, v) of tilemap tm (0-7 or Tilemap instance) to (x, y). Each tile is 8x8 pixels stored as (image_tx, image_ty). Negative w/h flips the image. colkey sets the transparent color. rotate and scale apply transformations.

Parameters:

  • x (float) โ€” Destination X
  • y (float) โ€” Destination Y
  • tm (int/Tilemap) โ€” Tilemap number (0-7) or Tilemap instance
  • u (float) โ€” Source X in the tilemap
  • v (float) โ€” Source Y in the tilemap
  • w (float) โ€” Width (negative to flip)
  • h (float) โ€” Height (negative to flip)
  • colkey (int/None) โ€” Transparent color. If omitted, no transparency.
  • rotate (float) โ€” Rotation angle in degrees (centered on the copy region). Defaults to 0.
  • scale (float) โ€” Scale factor (centered on the copy region). Defaults to 1.

`blt3d(x, y, w, h, img, pos, rot, fov=60, colkey=None)` โ€” function *(Advanced)*

Draw the image bank img (0-2 or Image instance) with perspective projection onto the screen rectangle (x, y, w, h). pos is the camera position where x, y match 2D coordinates and z is height. rot is the rotation in degrees. fov sets the field of view in degrees. colkey sets the transparent color.

Parameters:

  • x (float) โ€” Destination X
  • y (float) โ€” Destination Y
  • w (float) โ€” Display width
  • h (float) โ€” Display height
  • img (int/Image) โ€” Image bank number (0-2) or Image instance
  • pos ((float, float, float)) โ€” Camera position (x, y, z). x, y match 2D coordinates, z is height
  • rot ((float, float, float)) โ€” Rotation in degrees. rot_x is vertical, rot_y is horizontal, rot_z is tilt
  • fov (float) โ€” Field of view in degrees. Defaults to 60.
  • colkey (int/None) โ€” Transparent color. If omitted, no transparency.

`bltm3d(x, y, w, h, tm, pos, rot, fov=60, colkey=None)` โ€” function *(Advanced)*

Draw the tilemap tm (0-7 or Tilemap instance) with perspective projection onto the screen rectangle (x, y, w, h). pos is the camera position where x, y match 2D coordinates and z is height. rot is the rotation in degrees. fov sets the field of view in degrees. colkey sets the transparent color.

Parameters:

  • x (float) โ€” Destination X
  • y (float) โ€” Destination Y
  • w (float) โ€” Display width
  • h (float) โ€” Display height
  • tm (int/Tilemap) โ€” Tilemap number (0-7) or Tilemap instance
  • pos ((float, float, float)) โ€” Camera position (x, y, z). x, y match 2D coordinates, z is height
  • rot ((float, float, float)) โ€” Rotation in degrees. rot_x is vertical, rot_y is horizontal, rot_z is tilt
  • fov (float) โ€” Field of view in degrees. Defaults to 60.
  • colkey (int/None) โ€” Transparent color. If omitted, no transparency.

`text(x, y, s, col, font=None)` โ€” function

Draw a string s in color col at (x, y).

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate
  • s (str) โ€” String to draw
  • col (int) โ€” Color
  • font (Font) โ€” Custom font. If omitted, the standard font is used.

Color Constants

  • COLOR_BLACK โ€” 0 โ€” Black (#000000)
  • COLOR_NAVY โ€” 1 โ€” Navy (#2b335f)
  • COLOR_PURPLE โ€” 2 โ€” Purple (#7e2072)
  • COLOR_GREEN โ€” 3 โ€” Green (#19959c)
  • COLOR_BROWN โ€” 4 โ€” Brown (#8b4852)
  • COLOR_DARK_BLUE โ€” 5 โ€” Dark Blue (#395c98)
  • COLOR_LIGHT_BLUE โ€” 6 โ€” Light Blue (#a9c1ff)
  • COLOR_WHITE โ€” 7 โ€” White (#eeeeee)
  • COLOR_RED โ€” 8 โ€” Red (#d4186c)
  • COLOR_ORANGE โ€” 9 โ€” Orange (#d38441)
  • COLOR_YELLOW โ€” 10 โ€” Yellow (#e9c35b)
  • COLOR_LIME โ€” 11 โ€” Lime (#70c6a9)
  • COLOR_CYAN โ€” 12 โ€” Cyan (#7696de)
  • COLOR_GRAY โ€” 13 โ€” Gray (#a3a3a3)
  • COLOR_PINK โ€” 14 โ€” Pink (#ff9798)
  • COLOR_PEACH โ€” 15 โ€” Peach (#edc7b0)

Resource Constants

  • NUM_COLORS โ€” 16 โ€” Number of palette colors
  • NUM_IMAGES โ€” 3 โ€” Number of image banks (0-2)
  • IMAGE_SIZE โ€” 256 โ€” Image width and height
  • NUM_TILEMAPS โ€” 8 โ€” Number of tilemaps (0-7)
  • TILEMAP_SIZE โ€” 256 โ€” Tilemap width and height
  • TILE_SIZE โ€” 8 โ€” Tile size in pixels
  • FONT_WIDTH โ€” 4 โ€” Built-in font width
  • FONT_HEIGHT โ€” 6 โ€” Built-in font height

Audio

`channels` โ€” variable *(Advanced)*

Audio channels (Channel instances) (0-3).

  • Type: list[Channel]

`tones` โ€” variable *(Advanced)*

Tone definitions (Tone instances) (0-3).

  • Type: list[Tone]

`sounds` โ€” variable

Sounds (Sound instances) (0-63).

  • Type: list[Sound]

Example:

python
pyxel.sounds[0].speed = 60

`musics` โ€” variable

Music tracks (Music instances) (0-7).

  • Type: list[Music]

`play(ch, snd, sec=0, loop=False, resume=False)` โ€” function

Play the sound snd on channel ch (0-3). snd can be a sound number (0-63), a list of numbers, a Sound instance, a list of Sounds, or an MML string.

Parameters:

  • ch (int) โ€” Channel number (0-3)
  • snd (int/list/Sound/str) โ€” Sound number (0-63), list of numbers, Sound instance, list of Sounds, or MML string
  • sec (float) โ€” Playback start position in seconds. Defaults to 0.
  • loop (bool) โ€” Loop playback. Defaults to False.
  • resume (bool) โ€” Resume previous sound after playback ends. Defaults to False.

`playm(msc, sec=0, loop=False)` โ€” function

Play the music msc (0-7).

Parameters:

  • msc (int) โ€” Music number (0-7)
  • sec (float) โ€” Playback start position in seconds. Defaults to 0.
  • loop (bool) โ€” Loop playback. Defaults to False.

`stop(ch)` โ€” function

Stop playback of the specified channel ch (0-3).

Parameters:

  • ch (int) โ€” Channel number (0-3)

`stop()` โ€” function

Stop playback of all channels.

`play_pos(ch)` โ€” function

Get the sound playback position of channel ch (0-3) as a tuple of (sound_index, sec). Return None when playback has stopped.

Parameters:

  • ch (int) โ€” Channel number (0-3)

Returns: tuple[int, float]/None โ€” (sound_index, sec) or None

`gen_bgm(preset, transp, instr, seed, play=False)` โ€” function

Generate a BGM MML list using an algorithm. preset (0-7) selects the preset, instr (0-3) selects the instrumentation.

Parameters:

  • preset (int) โ€” Preset number (0-7). 0-1: title, departure (medium tempo), 2-3: town, peaceful (slow tempo), 4-5: field, adventure (medium tempo), 6-7: battle, crisis (fast tempo)
  • transp (int) โ€” Transpose in semitones (-5 to +5).
  • instr (int) โ€” Instrumentation (0-3). 0: melody+reverb+bass (3ch), 1: melody+bass+drums (3ch), 2: melody+sub+bass (3ch), 3: melody+sub+bass+drums (4ch).
  • seed (int) โ€” Random seed
  • play (bool) โ€” Play the generated MML. Defaults to False.

Returns: list[str] โ€” List of MML strings

Tone & Effect Constants

Tones:

  • TONE_TRIANGLE โ€” 0 โ€” Triangle wave
  • TONE_SQUARE โ€” 1 โ€” Square wave
  • TONE_PULSE โ€” 2 โ€” Pulse wave
  • TONE_NOISE โ€” 3 โ€” Noise

Effects:

  • EFFECT_NONE โ€” 0 โ€” No effect
  • EFFECT_SLIDE โ€” 1 โ€” Slide
  • EFFECT_VIBRATO โ€” 2 โ€” Vibrato
  • EFFECT_FADEOUT โ€” 3 โ€” Fade out
  • EFFECT_HALF_FADEOUT โ€” 4 โ€” Half fade out
  • EFFECT_QUARTER_FADEOUT โ€” 5 โ€” Quarter fade out

Resource Constants

  • NUM_CHANNELS โ€” 4 โ€” Number of audio channels (0-3)
  • NUM_TONES โ€” 4 โ€” Number of tone types (0-3)
  • NUM_SOUNDS โ€” 64 โ€” Number of sounds (0-63)
  • NUM_MUSICS โ€” 8 โ€” Number of music tracks (0-7)

Math

`ceil(x)` โ€” function

Return the smallest integer greater than or equal to x.

Parameters:

  • x (float) โ€” Value

Returns: int โ€” Smallest integer >= x

`floor(x)` โ€” function

Return the largest integer less than or equal to x.

Parameters:

  • x (float) โ€” Value

Returns: int โ€” Largest integer <= x

`clamp(x, lower, upper)` โ€” function

Return x clamped between lower and upper.

Parameters:

  • x (float) โ€” Value to clamp
  • lower (float) โ€” Minimum value
  • upper (float) โ€” Maximum value

Returns: float โ€” Clamped value

`sgn(x)` โ€” function

Return 1 when x is positive, 0 when it is 0, and -1 when it is negative.

Parameters:

  • x (int/float) โ€” Value

Returns: int/float โ€” Sign of the value (1, 0, or -1)

`sqrt(x)` โ€” function

Return the square root of x.

Parameters:

  • x (float) โ€” Value

Returns: float โ€” Square root of x

`sin(deg)` โ€” function

Return the sine of deg degrees.

Parameters:

  • deg (float) โ€” Angle in degrees

Returns: float โ€” Sine value

`cos(deg)` โ€” function

Return the cosine of deg degrees.

Parameters:

  • deg (float) โ€” Angle in degrees

Returns: float โ€” Cosine value

`atan2(y, x)` โ€” function

Return the arctangent of y/x in degrees.

Parameters:

  • y (float) โ€” Y value
  • x (float) โ€” X value

Returns: float โ€” Angle in degrees

`rseed(seed)` โ€” function

Set the seed of the random number generator.

Parameters:

  • seed (int) โ€” Seed value (non-negative integer)

`rndi(a, b)` โ€” function

Return a random integer from a to b (inclusive).

Parameters:

  • a (int) โ€” Minimum value (inclusive)
  • b (int) โ€” Maximum value (inclusive)

Returns: int โ€” Random integer from a to b

`rndf(a, b)` โ€” function

Return a random float from a to b (inclusive).

Parameters:

  • a (float) โ€” Minimum value (inclusive)
  • b (float) โ€” Maximum value (inclusive)

Returns: float โ€” Random float from a to b

`nseed(seed)` โ€” function

Set the seed of Perlin noise.

Parameters:

  • seed (int) โ€” Seed value (non-negative integer)

`noise(x, y=0, z=0)` โ€” function

Return the Perlin noise value for the specified coordinates.

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate. Defaults to 0.
  • z (float) โ€” Z coordinate. Defaults to 0.

Returns: float โ€” Perlin noise value

Font Class

`Font(filename, font_size=10.0)` โ€” class *(Advanced)*

Create a Font instance from a font file (BDF/OTF/TTF/TTC).

Parameters:

  • filename (str) โ€” Font file name (BDF/OTF/TTF/TTC)
  • font_size (float) โ€” Font size. Defaults to 10.0. Not used for BDF.

Returns: Font โ€” New Font instance

`Font.text_width(s)` โ€” function *(Advanced)*

Return the display width of the string s in this font.

Parameters:

  • s (str) โ€” String to measure

Returns: int โ€” Width in pixels

Image Class

`Image(width, height)` โ€” class *(Advanced)*

Create a new Image instance with the specified size.

Parameters:

  • width (int) โ€” Image width
  • height (int) โ€” Image height

Returns: Image โ€” New Image instance

`Image.from_image(filename, include_colors=False)` โ€” class *(Advanced)*

Create an Image instance from an image file.

Parameters:

  • filename (str) โ€” Image file name
  • include_colors (bool) โ€” Include palette colors from file. Defaults to False.

Returns: Image โ€” Image instance from file

`Image.width` โ€” variable

The width of the image.

  • Type: int

`Image.height` โ€” variable

The height of the image.

  • Type: int

`Image.set(x, y, data)` โ€” function

Set the image at (x, y) using a list of hex-digit strings. Each character represents a color index (0-f).

Parameters:

  • x (int) โ€” X coordinate
  • y (int) โ€” Y coordinate
  • data (list[str]) โ€” Image data as a list of strings

Example:

python
pyxel.images[0].set(10, 10, ["0123", "4567", "89ab", "cdef"])

`Image.load(x, y, filename, include_colors=False)` โ€” function

Load an image file (PNG/GIF/JPEG) at (x, y).

Parameters:

  • x (int) โ€” X coordinate
  • y (int) โ€” Y coordinate
  • filename (str) โ€” Image file name (PNG/GIF/JPEG)
  • include_colors (bool) โ€” Include palette colors from file. Defaults to False.

`Image.pget(x, y)` โ€” function

Get the color of the pixel at (x, y). The coordinates are absolute and not affected by the camera offset.

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate

Returns: int โ€” Color of the pixel

`Image.pset(x, y, col)` โ€” function

Draw a pixel with the color col at (x, y).

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate
  • col (int) โ€” Color

`Image.{cls, line, rect, rectb, circ, circb, elli, ellib, tri, trib, fill, blt, bltm, blt3d, bltm3d, text, clip, camera, pal, dither}` โ€” function

Image instances support all drawing functions from the Graphics section. They work the same way but draw on the image instead of the screen.

`Image.data_ptr()` โ€” function *(Advanced)*

Return the raw data pointer of the image as a ctypes c_uint8 array.

Returns: Any โ€” Raw data pointer

`Image.save(filename, scale)` โ€” function *(Advanced)*

Save the image to a file.

Parameters:

  • filename (str) โ€” Output file name
  • scale (int) โ€” Scale factor

Tilemap Class

`Tilemap(width, height, img)` โ€” class *(Advanced)*

Create a new Tilemap instance.

Parameters:

  • width (int) โ€” Tilemap width
  • height (int) โ€” Tilemap height
  • img (int/Image) โ€” Image bank number (0-2) or Image instance

Returns: Tilemap โ€” New Tilemap instance

`Tilemap.from_tmx(filename, layer)` โ€” class *(Advanced)*

Create a Tilemap instance from a TMX file.

Parameters:

  • filename (str) โ€” TMX file name
  • layer (int) โ€” Layer number (0-)

Returns: Tilemap โ€” Tilemap instance from TMX file

`Tilemap.width` โ€” variable

The width of the tilemap.

  • Type: int

`Tilemap.height` โ€” variable

The height of the tilemap.

  • Type: int

`Tilemap.imgsrc` โ€” variable

The image bank (0-2) or Image instance referenced by the tilemap.

  • Type: int/Image

`Tilemap.set(x, y, data)` โ€” function

Set the tilemap at (x, y) using a list of strings. Each tile is a 4-digit hex value representing (image_tx, image_ty), separated by spaces.

Parameters:

  • x (int) โ€” X coordinate
  • y (int) โ€” Y coordinate
  • data (list[str]) โ€” Tilemap data as a list of strings

Example:

python
pyxel.tilemaps[0].set(0, 0, ["0000 0100 a0b0", "0001 0101 a1b1"])

`Tilemap.load(x, y, filename, layer)` โ€” function

Load the layer (0-) from the TMX file at (x, y).

Parameters:

  • x (int) โ€” X coordinate
  • y (int) โ€” Y coordinate
  • filename (str) โ€” TMX file name
  • layer (int) โ€” Layer number (0-)

`Tilemap.pget(x, y)` โ€” function

Get the tile at (x, y). The coordinates are absolute and not affected by the camera offset. A tile is a tuple of (image_tx, image_ty).

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate

Returns: tuple[int, int] โ€” (image_tx, image_ty)

`Tilemap.pset(x, y, tile)` โ€” function

Set a tile at (x, y). A tile is a tuple of (image_tx, image_ty).

Parameters:

  • x (float) โ€” X coordinate
  • y (float) โ€” Y coordinate
  • tile (tuple[int, int]) โ€” Tile as (image_tx, image_ty)

`Tilemap.{cls, line, rect, rectb, circ, circb, elli, ellib, tri, trib, fill, blt, clip, camera}` โ€” function

Tilemap instances support drawing functions from the Graphics section. They work the same way but draw tiles on the tilemap instead of pixels on the screen. Use a tile tuple (image_tx, image_ty) instead of a color value.

`Tilemap.collide(x, y, w, h, dx, dy, walls)` โ€” function

Resolve collisions after applying pixel movement (dx, dy) to the pixel rectangle at (x, y) with pixel size (w, h), and return the adjusted (dx, dy). walls is a list of tile coordinates that act as obstacles.

Parameters:

  • x (float) โ€” Rectangle X position
  • y (float) โ€” Rectangle Y position
  • w (float) โ€” Rectangle width
  • h (float) โ€” Rectangle height
  • dx (float) โ€” Movement in X
  • dy (float) โ€” Movement in Y
  • walls (list[tuple[int, int]]) โ€” List of wall tiles (image_tx, image_ty)

Returns: tuple[float, float] โ€” Adjusted (dx, dy)

`Tilemap.data_ptr()` โ€” function *(Advanced)*

Return the raw data pointer of the tilemap as a ctypes c_uint16 array (4 bytes per tile: image_tx, image_ty).

Returns: Any โ€” Raw data pointer

Sound Class

`Sound()` โ€” class *(Advanced)*

Create a new Sound instance.

Returns: Sound โ€” New Sound instance

`Sound.notes` โ€” variable

List of notes (0-59). Higher values produce higher pitches. 33 = 'A2' (440 Hz). Rests are -1.

  • Type: list[int]

`Sound.tones` โ€” variable

List of tones (0: Triangle, 1: Square, 2: Pulse, 3: Noise).

  • Type: list[int]

`Sound.volumes` โ€” variable

List of volumes (0-7).

  • Type: list[int]

`Sound.effects` โ€” variable

List of effects (0: None, 1: Slide, 2: Vibrato, 3: FadeOut, 4: Half-FadeOut, 5: Quarter-FadeOut).

  • Type: list[int]

`Sound.speed` โ€” variable

Playback speed. 1 is the fastest, and the larger the number, the slower the playback speed. At 120, one note equals 1 second.

  • Type: int

`Sound.set(notes, tones, volumes, effects, speed)` โ€” function

Set notes, tones, volumes, and effects using strings. If the tones, volumes, or effects string is shorter than the notes, it repeats from the beginning.

Parameters:

  • notes (str) โ€” Note string
  • tones (str) โ€” Tone string
  • volumes (str) โ€” Volume string
  • effects (str) โ€” Effect string
  • speed (int) โ€” Playback speed

`Sound.set_notes(notes)` โ€” function

Set the notes using a string made of note names (CDEFGAB), optional sharp (#) or flat (-), octave (0-4), and rests (R). Case-insensitive, whitespace is ignored.

Parameters:

  • notes (str) โ€” Notes string

Example:

python
pyxel.sounds[0].set_notes("g2b-2d3r rf3f3f3")

`Sound.set_tones(tones)` โ€” function

Set the tones with a string of TSPN (or 0-9 for custom tone numbers). Case-insensitive, whitespace is ignored.

Parameters:

  • tones (str) โ€” Tones string

Example:

python
pyxel.sounds[0].set_tones("ttss pppn")

`Sound.set_volumes(volumes)` โ€” function

Set the volumes with a string of 01234567. Whitespace is ignored.

Parameters:

  • volumes (str) โ€” Volumes string

Example:

python
pyxel.sounds[0].set_volumes("7777 7531")

`Sound.set_effects(effects)` โ€” function

Set the effects with a string of NSVFHQ. Case-insensitive, whitespace is ignored.

Parameters:

  • effects (str) โ€” Effects string

Example:

python
pyxel.sounds[0].set_effects("nfnf nvvs")

`Sound.mml(code)` โ€” function

Switch to MML mode with the given MML string. In MML mode, normal parameters such as notes and speed are ignored. For available MML commands, see the Pyxel MML Commands page.

Parameters:

  • code (str) โ€” MML string

Example:

python
pyxel.sounds[0].mml("T120 Q90 @1 V100 O5 L8 C4&C<G16R16>C.")

`Sound.mml()` โ€” function

Exit MML mode and return to normal mode.

`Sound.pcm(filename)` โ€” function

Load an audio file (WAV/OGG) for playback.

Parameters:

  • filename (str) โ€” Audio file name (WAV/OGG)

Example:

python
pyxel.sounds[0].pcm("sounds/bgm.ogg")

`Sound.pcm()` โ€” function

Exit PCM mode and return to normal mode.

`Sound.save(filename, sec, ffmpeg=False)` โ€” function *(Advanced)*

Create a WAV file from the sound with the specified duration in seconds.

Parameters:

  • filename (str) โ€” Output WAV file name
  • sec (float) โ€” Duration in seconds
  • ffmpeg (bool) โ€” Also create MP4 file (requires FFmpeg). Defaults to False.

`Sound.total_sec()` โ€” function *(Advanced)*

Return the playback time in seconds. Return None for infinite loops.

Returns: float/None โ€” Playback time in seconds, or None for infinite loops

Music Class

`Music()` โ€” class *(Advanced)*

Create a new Music instance.

Returns: Music โ€” New Music instance

`Music.seqs` โ€” variable

A two-dimensional list of sounds (0-63) across multiple channels.

  • Type: list[list[int]]

`Music.set(seq0, seq1, seq2, ...)` โ€” function

Set the lists of sounds (0-63) for each channel. An empty list means the channel is not used.

Parameters:

  • seq0, seq1, ... (list[int]) โ€” Sound lists for each channel. Empty list = unused.

Example:

python
pyxel.musics[0].set([0, 1], [], [3])

`Music.save(filename, sec, ffmpeg=False)` โ€” function *(Advanced)*

Create a WAV file from the music with the specified duration in seconds.

Parameters:

  • filename (str) โ€” Output WAV file name
  • sec (float) โ€” Duration in seconds
  • ffmpeg (bool) โ€” Also create MP4 file (requires FFmpeg). Defaults to False.

Channel Class

`Channel()` โ€” class *(Advanced)*

Create a new Channel instance.

Returns: Channel โ€” New Channel instance

`Channel.gain` โ€” variable *(Advanced)*

The gain (volume) of the channel. Defaults to 0.125.

  • Type: float

`Channel.detune` โ€” variable *(Advanced)*

Pitch detune in cents (100 cents = 1 semitone). Defaults to 0.

  • Type: int

`Channel.play(snd, sec=0, loop=False, resume=False)` โ€” function *(Advanced)*

Play the sound snd on this channel. snd can be a sound number, a list, a Sound instance, a list of Sounds, or an MML string.

Parameters:

  • snd (int/list/Sound/str) โ€” Sound number (0-63), list of numbers, Sound instance, list of Sounds, or MML string
  • sec (float) โ€” Playback start position in seconds. Defaults to 0.
  • loop (bool) โ€” Loop playback. Defaults to False.
  • resume (bool) โ€” Resume previous sound after playback ends. Defaults to False.

`Channel.stop()` โ€” function *(Advanced)*

Stop playback on this channel.

`Channel.play_pos()` โ€” function *(Advanced)*

Get the playback position as a tuple of (sound_index, sec). Return None when playback has stopped.

Returns: tuple[int, float]/None โ€” (sound_index, sec) or None

Tone Class

`Tone()` โ€” class *(Advanced)*

Create a new Tone instance.

Returns: Tone โ€” New Tone instance

`Tone.mode` โ€” variable *(Advanced)*

Tone mode (0: Wavetable, 1: ShortPeriodNoise, 2: LongPeriodNoise).

  • Type: int

`Tone.sample_bits` โ€” variable *(Advanced)*

Sample bits for the wavetable (1-16). Defaults to 4.

  • Type: int

`Tone.wavetable` โ€” variable *(Advanced)*

Wavetable data as a list of sample values. Each value must be in range 0 to (2^sample_bits - 1).

  • Type: list[int]

`Tone.gain` โ€” variable *(Advanced)*

Tone gain. Defaults to 1.0.

  • Type: float

Coding Policy Audit (`docs/coding-policy-audit.md`)

Coding Policy Audit Procedure

This file defines how to run an exhaustive audit against
docs/coding-policy.md. It does not define coding standards, add exceptions, or
weaken the policy. If this procedure and the policy disagree, the policy wins
and this procedure must be corrected before the audit is accepted.

An auditor reads both files in this order:

  • docs/coding-policy.md: the source of truth for standards, scope, and
    examples.
  • docs/coding-policy-audit.md: the execution protocol used to prove that the
    policy was checked completely and evenly.

Operating Rules

  • No sampling. Every in-scope file, normative criterion, applicable subject,
    cross-file relation, hot-path surface, and required verification gate is
    represented by an artifact row.

  • No cherry-picking. A local fix is incomplete until every comparable subject
    and affected relation is checked to the same depth.

  • No unstated memory. Previous conversations, old audit notes, prior summaries,
    and repository prevalence may suggest probes, but they are not evidence until
    rechecked against the frozen target and recorded in the current artifacts.

  • No majority rule. Explicit policy determines departures from the relevant
    language's established idiom; otherwise that idiom determines the correct
    form. Existing repetition is used only to discover related subjects and uneven
    application.

  • No example criteria. An example illustrates its parent rule and is recorded
    as example coverage; matching or differing from the example alone never
    determines a verdict.

  • No summary-only evidence. Counts, search results, formatter success, test
    success, and reviewer summaries do not prove a check unless its row names what
    was inspected and why the verdict follows.

  • Use precise result labels. A run is an exhaustive audit only when the
    Completion Gate is satisfied. Until then, or when the requested scope is
    intentionally narrower, report the work as a targeted review, fix pass, gate
    check, or pending audit according to the artifacts actually produced.

  • The worktree under review is the audit target. Start from git ls-files, add
    intended untracked files, and apply the policy's Scope section to that combined
    set.

  • The frozen target is immutable within a run. If its files, intended additions,
    policy, or procedure change, preserve the run and start another. Regenerate an
    artifact when only one of its recorded in-run inputs changes; a stale row is
    pending, never reused as proof. The final report names every preserved run
    that led to the completed one.

When to Run

Run this procedure:

  • when an exhaustive coding-policy audit is explicitly requested;
  • before a release tag, as part of the release checklist;
  • after a substantive revision of docs/coding-policy.md, on every subject
    whose verdict may change because of the revision;
  • after a substantive revision of this procedure, on this procedure and every
    affected audit artifact or subject.

Artifact Rules

Each run writes artifacts to one directory named in the final report. Every TSV
has a header, uses one row per declared unit, and has the declared column count
on every row. Text artifacts use UTF-8 without a BOM, LF line endings, and one
terminal LF. JSON objects use the declared key order and no insignificant
whitespace. TSV fields contain no literal tabs or newlines. Lists are compact
JSON arrays with no duplicate logical entries; an aligned value list retains one
value per key even when values are equal. Reference lists preserve the defining
artifact's row order, enum lists preserve this procedure's declaration order,
and other lists are sorted bytewise unless a recorded source command defines
their order.

Path values encode repository-relative Git path bytes: / and ASCII letters,
digits, ., _, and - remain literal; every other byte is %HH with uppercase
hex digits. Plural TSV fields are JSON arrays unless their schema says otherwise;
policy_line is one policy source reference and policy_lines is an array of
them. Artifact rows are sorted bytewise by their identifier.

Every data row has the explicit identifier declared by its artifact. Except for
the separately defined file and artifact IDs, an ID is its column name without
_id, followed by - and the lowercase SHA-256 of its natural-key JSON array.
That array uses the key values below in listed order, with no whitespace, only
required JSON escapes, and literal non-ASCII characters. Each
verdict-independent row ID is assigned before that row's verdict; finding and
review IDs are computed when those rows are created. IDs use the path-encoding
alphabet and never contain :.

Completeness of verdict-independent sets is validated from natural keys, never
from IDs or observed verdicts; post-verdict sets follow their declared
derivations. Natural keys are: policy source lines and normalized rule text for
criteria; policy line for policy coverage; artifact path for the manifest;
path for target files and scope; kind and family for relations; family for hot
paths; cwd, command, and trigger for commands; criterion and subject for
applicability and checks; source and target references plus finding text for
findings; criterion and subject family for balance rows; and review kind and
subject key for independent-review rows.
Missing or duplicate identifiers or natural keys, unknown criteria or subjects,
invalid enum values, empty required fields, and column-count errors are artifact
failures.

An evidence reference is one of:

  • source::<line> or source::<first>-<last>;
  • source: for a whole-file check;
  • row:<artifact>:<row_id> for a TSV row;
  • artifact:<artifact>, optionally followed by :<line> or
    :<first>-<last>, for whole-artifact or raw-line evidence.

Source lines are one-based and ranges are inclusive. Paths use the encoding above;
artifact is a required artifact filename. A deleted path is cited through its
hunk in current-diff.patch, not as current source.

Every reference resolves to exactly one current source location, artifact
location, or row. The evidence graph is acyclic and terminates in current source,
a frozen-target root artifact, or a successful target-bound command row. Broken,
cyclic, or unterminated evidence blocks completion.

manifest.tsv binds manifested artifacts to their exact inputs and the frozen
target. A manifested artifact is stale when its current hash, input hashes, or
target_sha256 differs from the manifest. The independent review is stale when
its target or manifest hash differs; the summary is stale when any of its three
hashes differs. Immediately before completion, the target snapshot and diff are
independently re-derived from the live worktree; comparing stored artifacts with
one another is insufficient. No artifact hash, fingerprint, or verdict is an
input to its own computation. Identifiers only locate units derived from natural
keys; an observed identifier set never proves its own completeness.

Required Artifacts

  • target_files.tsv

    • Columns: file_id, path, source, git_mode, content_sha256.
    • Contains every tracked path not deleted by the frozen diff, plus every
      intended untracked file, whether the policy later includes or excludes it.
      A missing sparse- or skip-worktree path blocks the freeze rather than being
      treated as a deletion. source is tracked or untracked_intended.
    • file_id equals the encoded path. git_mode is the six-digit mode the
      frozen target tree would record. content_sha256 hashes the working-tree
      bytes, the link-target bytes for a symlink, or the hexadecimal bytes of the
      recorded commit ID for a gitlink.
  • freeze.json

    • Contains exactly: schema_version, branch, base_commit,
      head_commit, policy_sha256, procedure_sha256,
      target_files_sha256, diff_sha256, target_sha256, and artifact_dir.
    • schema_version is the integer 1 for this schema and increments whenever a
      required artifact's fields or meaning change. branch is the short branch
      name using the path-byte encoding above, or null; commits are full object
      IDs; digests are lowercase SHA-256 strings; and artifact_dir is the absolute
      run-directory path.
    • base_commit is the previous release commit for a release audit; otherwise
      it is the explicitly requested comparison base, the merge base of HEAD and
      its configured upstream when no base was requested, or HEAD when no
      upstream exists.
    • target_sha256 is the SHA-256 of a UTF-8 JSON array containing, in order,
      schema_version, branch, base_commit, head_commit, policy_sha256,
      procedure_sha256, and target_files_sha256. The serialization uses no
      whitespace and only required JSON escapes.
    • The object records the target before any verdict is written.
  • current-diff.patch

    • Contains the exact diff against base_commit, including intended untracked
      files as added-file patches, in Git's binary-capable full-index format.
      The tracked diff comes first; added-file patches follow in encoded-path order.
    • Its SHA-256 equals freeze.json.diff_sha256.
  • manifest.tsv

    • Columns: artifact_id, path, sha256, input_artifact_ids,
      input_sha256s, target_sha256.
    • Contains one row for every required artifact except itself,
      independent_review.tsv, and audit_summary.json.
    • artifact_id is the artifact filename and path is its path relative to the
      run directory.
    • Input ID and hash arrays have equal length and preserve dependency order.
    • The dependency graph is acyclic and contains these direct edges:
      • target_files.tsv and current-diff.patch are roots;
      • freeze.json depends on both roots;
      • criteria.tsv and policy_coverage.tsv depend on freeze.json;
      • scope.tsv depends on target_files.tsv, criteria.tsv, and
        policy_coverage.tsv;
      • relations.tsv, hot_paths.tsv, and commands.tsv depend on
        criteria.tsv and scope.tsv, with change-driven inventories also
        depending on current-diff.patch;
      • applicability.tsv depends on criteria.tsv, scope.tsv, relations.tsv,
        hot_paths.tsv, and commands.tsv;
      • checks.tsv depends on applicability.tsv and commands.tsv;
      • coverage_balance.tsv depends on criteria.tsv, applicability.tsv, and
        checks.tsv;
      • findings.tsv depends on checks.tsv and coverage_balance.tsv.
    • Each row also names every additional direct artifact input it actually uses.
  • criteria.tsv

    • Columns: criterion_id, policy_lines, subject_types,
      surface_kinds, file_selector, rule_text.
    • Contains one row for each top-level rule bullet and each normative
      introductory paragraph in docs/coding-policy.md.
    • Nested authoritative enumerations belong to their parent criterion.
      e.g. bullets and hypothetical anti-patterns never create criteria.
    • subject_types is a non-empty JSON array drawn from file, relation,
      hot_path, process, and command.
    • file governs a file surface; relation compares files; hot_path governs
      a policy-listed performance family; process governs a repository-wide or
      audit obligation with no narrower subject; and command requires execution.
      Every applicable type is listed.
    • surface_kinds is a JSON array used only by file criteria and drawn
      from path, source, test, prose, translation,
      release_notes, policy, configuration, and structured_data.
      It is non-empty exactly when subject_types contains file.
    • file_selector is empty for a non-file criterion. Otherwise it states the
      rule-derived predicate that selects governed content within the candidate
      surface kinds. It is all only where the rule governs every candidate file;
      examples and hand-picked repository paths cannot define it.
    • rule_text is the normative text with internal whitespace collapsed to one
      ASCII space. Any text change changes the criterion ID; a semantic addition,
      removal, split, or merge changes the criterion set.
  • policy_coverage.tsv

    • Columns: coverage_id, policy_line, line_text, coverage_kind,
      criterion_ids, rationale.
    • Contains exactly one row for every non-blank policy line; line_text is the
      exact line content.
    • coverage_kind is criterion, example, or structural.
      Criterion and example rows name their parent criteria. Structural rows have
      an empty criterion_ids array and explain why the line imposes no
      requirement.
  • scope.tsv

    • Columns: file_id, path, source, scope_status,
      surface_kinds, reason, policy_lines.
    • Contains exactly the files in target_files.tsv, with the same file IDs,
      paths, and sources.
    • source is tracked or untracked_intended; scope_status is
      included or excluded.
    • Every included file's surface_kinds contains path plus every applicable
      kind. Excluded files have an empty surface list. Every row cites the governing
      policy lines and explains its inclusion or exclusion.
    • path applies to every included file; source to syntax, structure,
      identifiers, comments, or other non-prose content; test to verification
      code or data; prose to documentation, descriptive metadata, or user-facing
      natural language other than code comments; translation to content with
      language variants; release_notes to changelog entries; policy to these
      two policy documents; configuration to configuration content; and
      structured_data to machine-parsed non-code data. Kinds overlap and follow
      content and role, not filename extension alone.
  • relations.tsv

    • Columns: relation_id, relation_kind, family, member_file_ids,
      criterion_ids, policy_lines, rationale, derivation_refs.
    • Expands every cross-file concern before checking begins. A file may belong
      to any number of relations.
    • member_file_ids contains unique IDs from included scope.tsv rows. It is
      empty only for a policy-mandated family with no current member, proved by
      derivation_refs.
    • relation_kind is sibling, mirror, translation, exception, or
      change_dependency.
    • criterion_ids contains every relation criterion governing the family;
      policy_lines cites those rules.
    • Required relations include applicable naming and error-message families,
      API/binding/stub mirrors, translated content, policy exception groups,
      release notes against code changes, and tests against changed behavior.
    • A change-dependency relation cites deleted or renamed inputs through the
      frozen diff; its member IDs still name only current included files.
    • An exception relation cites the exact policy lines, convention, and reason.
      Repository prevalence is not a rationale.
  • hot_paths.tsv

    • Columns: hot_path_id, family, member_file_ids, entry_points,
      criterion_ids, cost_risks, derivation, derivation_refs.
    • Contains exactly one row for every policy-listed hot-path family and
      aggregates every implementation surface in that row.
    • criterion_ids contains every hot-path criterion governing the family.
    • member_file_ids contains unique IDs from included scope rows and is empty
      only in an absence row.
    • cost_risks names every concrete cost implied by the rule and inspected
      implementation; it is not limited to examples or a fixed category list.
    • entry_points and derivation_refs contain evidence references;
      derivation explains how they establish completeness.
    • A family with no implementation surface has an explicit absence row with
      repository-wide derivation evidence.
  • commands.tsv

    • Columns: command_id, criterion_ids, cwd, command, trigger,
      target_sha256, exit_status, key_output.
    • Declares every required and targeted command before it runs.
    • cwd is . or an encoded repository-relative directory; command records
      the exact non-interactive invocation.
    • criterion_ids contains every command criterion the invocation checks. It
      may be empty only for a procedure-level validation command; such a command
      remains subject to its trigger and the Completion Gate.
    • exit_status is a non-negative integer or not_run; zero passes and any
      other integer fails. A not_run row records the blocker and cannot clear a
      command criterion.
    • A successful command is evidence only when its target digest matches
      freeze.json.target_sha256.
  • applicability.tsv

    • Columns: check_id, criterion_id, subject_ref,
      derivation_refs.
    • Contains the complete expected check set, derived before verdicts.
    • subject_ref is file:<file_id>, relation:<relation_id>,
      routing:<criterion_id>, hot_path:<hot_path_id>,
      process:<criterion_id>, command:<command_id>, or
      absence:<criterion_id>:<subject_type>.
    • File candidates are the intersections of criterion and included-file surface
      kinds. The selector produces the file checks from those candidates, and every
      file criterion also produces one routing check whose derivation proves that
      the selector was applied exhaustively. Relation, hot-path, and command checks
      come from the corresponding criterion_ids; each process criterion produces
      one process check.
    • Each declared non-file subject type with no concrete subject produces one
      absence check. Its derivation proves the absence; it passes only when absence
      satisfies the rule. A criterion missing any required applicability row, or a
      row not produced by these rules, is an artifact failure.
  • checks.tsv

    • Columns: check_id, criterion_id, subject_ref, verdict,
      evidence, evidence_refs.
    • Contains exactly one row for every applicability.tsv row, with the same
      ID, criterion, and subject.
    • A local check does not replace a relation or hot-path check, and one
      subject's pass does not override another subject's non-pass.
    • A routing check proves selection completeness only; it never proves that a
      selected file satisfies the criterion.
  • findings.tsv

    • Columns: finding_id, source_ref, severity, target_ref,
      criterion_ids, finding, proposed_fix.
    • Contains one or more rows for every current fix verdict in checks.tsv or
      coverage_balance.tsv, one row per distinct target defect, and no rows from
      any other verdict.
    • source_ref names the originating fix row; target_ref names the defective
      source or artifact; and criterion_ids includes the source criterion and any
      other directly violated criterion.
    • severity is blocker, high, medium, or low; severity never
      changes whether a policy finding must be resolved.
  • coverage_balance.tsv

    • Columns: balance_id, criterion_id, subject_family, check_ids,
      comparator_balance_ids, verdict, rationale, evidence_refs.
    • Contains one row for every criterion and subject family represented in
      applicability.tsv. Subject families are file:<surface_kind>,
      routing, relation:<relation_kind>, hot_path:<family>, process, and
      command, plus absence:<subject_type>.
    • verdict is pass, fix, review, or pending.
    • Comparators are other families for the same criterion and structurally
      analogous criterion-family rows. The comparator list is empty only when no
      such row exists and the rationale proves why.
    • Fix counts need not match. A zero-fix family passes only when its
      checks and evidence show depth comparable to its named comparator rows.
  • independent_review.tsv

    • Columns: review_id, reviewer, review_kind, subject_key, source_ref,
      target_sha256, manifest_sha256, verdict, evidence_refs.
    • review_kind is expected_key, check, balance, or artifact;
      subject_key is a compact JSON array beginning with the artifact filename,
      followed by that unit's natural-key values. The whole-manifest key is
      ["manifest.tsv"]; each manifest-row key adds its artifact path.
    • Contains one row for every independently expected natural key in target
      files, policy extraction, scope, subject inventories, and applicability; one
      row for every check and balance row; and artifact rows for the manifest as a
      whole and for every manifest row.
    • source_ref resolves to the corresponding current row or artifact. It is
      empty only when an expected unit is missing, which requires a non-pass
      verdict.
    • Every row names the independent reviewer and the reviewed target and manifest
      hashes. verdict is pass, fix, or pending.
  • audit_summary.json

    • Contains exactly: schema_version, target_sha256, manifest_sha256,
      review_sha256, expected_checks, actual_checks, verdict_counts,
      finding_counts, command_counts, balance_counts, review_counts,
      validation_errors, stale_artifacts, and completion_status.
    • schema_version and target_sha256 equal the freeze; manifest_sha256 and
      review_sha256 are the lowercase SHA-256 hashes of the current files.
    • verdict_counts has exactly pass, fix, review, and pending;
      finding_counts has blocker, high, medium, and low;
      command_counts has passed, failed, and not_run;
      balance_counts has pass, fix, review, and pending;
      and review_counts has pass, fix, and pending.
    • validation_errors has exactly schema, identifier, enum, reference,
      expected_key, dependency, evidence_cycle, and
      evidence_termination.
    • expected_checks, actual_checks, every count member, and every validation
      member are non-negative integers. stale_artifacts is an array of artifact
      IDs.
    • completion_status is complete or pending and is derived from the
      source artifacts; it never overrides them.

Verdicts and Evidence

Every checks.tsv.verdict is one of:

  • pass: the governed check obligation is satisfied, with substantive current
    evidence;
  • fix: the governed policy or procedure obligation is violated;
  • review: semantic judgment is required;
  • pending: required evidence, execution, or review is incomplete.

Coverage-balance verdicts use the same four meanings for their audit obligation.

Do not use not applicable. Applicability is decided before verdicts, and only
applicable criterion/subject pairs enter applicability.tsv.

Evidence is substantive only when it:

  • names the exact subject and surface inspected;
  • explains why the verdict follows from the rule rather than an example;
  • records measured or mechanical support where the rule requires it;
  • names peers or dependencies for relation verdicts;
  • avoids bare phrases such as "no issue", "checked", or "matches policy".

Search output, inventories, formatter success, test success, finding counts, and
reviewer summaries are probes or command evidence, not findings by themselves. A
finding identifies the current source or artifact row, criterion, actionable
defect, and relevant peer or dependency evidence.

Phases

Run phases in order. Missing expected rows, invalid references, stale artifacts,
or schema errors block the current phase. Non-pass verdicts proceed through
balance and internal resolution, but block independent review and final
validation until resolved.

  1. Freeze the target.

    • Record every target file's mode and content digest, the branch, base and
      head commits, policy and procedure digests, artifact directory, and exact
      diff.
    • Write target_files.tsv, freeze.json, and current-diff.patch before
      verdicts.
  2. Extract the policy.

    • Build criteria.tsv from normative units only.
    • Build policy_coverage.tsv, classifying every non-blank line as criterion,
      example, or structural.
  3. Build scope.

    • Classify every target snapshot row.
    • Apply policy exclusions and assign all applicable surface kinds.
  4. Build subject inventories.

    • Expand all cross-file relations.
    • Enumerate every hot-path surface.
    • Declare required and targeted commands.
  5. Derive applicability.

    • Generate applicability.tsv from criteria and subject inventories.
    • Validate the complete expected check set before writing verdicts.
  6. Perform checks and run commands.

    • Inspect every applicable subject and write one checks.tsv row per
      expected check.
    • Inspect source directly; searches and automation remain probes.
    • Execute every triggered command and record its target-bound result.
    • Run make format after code or formatter-managed document changes.
    • Run make lint and make lint-wasm in every exhaustive run.
    • Run make test after code changes.
    • Run targeted parsers and validators for changed structured files, applicable
      prose or documentation tests, and git diff --check.
    • If a command changes the frozen target, preserve the run and start another.
  7. Check audit balance.

    • Compare each criterion-family row with every comparator it names.
    • Re-run the same probes on an unexplained zero-fix family and keep the
      balance row pending until the difference is justified.
  8. Resolve reviews and record findings.

    • Resolve every review as pass or fix from current evidence, without
      inventing exceptions. Keep missing evidence or blocked execution pending.
    • Generate findings.tsv from the resulting fix rows.
    • Correct an audit-evidence defect in place and regenerate every dependent
      artifact. To correct the frozen target, preserve the current pending run and
      start a new run against the changed target.
    • Repeat the affected phases until every check and balance row is pass and
      findings.tsv is empty.
  9. Run independent review.

    • A reviewer who produced none of the audited artifacts independently derives
      policy, inventory, and applicability natural keys from the frozen source
      before opening the run's verdicts or findings.
    • Give that reviewer both documents, the frozen target, complete inventories,
      applicability, checks, findings, balance evidence, and manifest for
      comparison and source review. Record every required review row in
      independent_review.tsv.
    • The reviewer validates every expected key, verdict, and evidence chain;
      review sampling cannot clear this gate.
    • Every actionable review result is fix regardless of severity. Propagate
      source defects to checks and findings, and artifact defects to validation
      errors.
    • Correct audit evidence in place; for a target correction, preserve the run
      and start another. Repeat review after either change.
    • If independent review is unavailable, completion remains pending.
  10. Validate completion.

    • Validate every schema, enum, identifier, natural key, reference, dependency,
      evidence chain, count, and manifest hash from its source artifact.
    • Re-derive the target file snapshot and diff from the live worktree and
      require exact equality with the freeze.
    • Require the independent-review set to be exact, every review verdict to be
      pass, and every row to name the current target and manifest hashes.
    • Write audit_summary.json only after the independent review is clean.

Delegation Rules

When an audit is split, the lead auditor gives each auditor both documents, the
frozen target, complete subject inventories, exact assigned check IDs, and all
dependencies needed by those checks.

Delegated summaries are not evidence. The lead reads every returned row,
validates its references, rejects copied or shallow evidence, and resolves
conflicting verdicts by re-reading the subjects.

Completion Gate

The audit is complete only when:

  • the live target snapshot and diff exactly match the freeze;
  • every required artifact exists, every manifested artifact matches its schema
    and manifest inputs, and every artifact is bound to the frozen target;
  • policy coverage, scope, subject inventories, and applicability contain exactly
    their independently derived expected natural keys;
  • checks.tsv contains exactly the applicability set and every verdict is
    pass;
  • every coverage_balance.tsv verdict is pass;
  • findings.tsv is empty;
  • independent_review.tsv contains exactly its independently derived expected
    natural keys, every verdict is pass, and its target and manifest hashes are
    current;
  • every evidence reference resolves, the evidence graph is acyclic, and every
    chain terminates in current source, a frozen-target root artifact, or successful
    target-bound command evidence;
  • every triggered command succeeded against the frozen target;
  • audit_summary.json matches the current target, manifest, and review hashes,
    reports matching check counts, zero validation errors, zero stale artifacts, and
    completion_status: complete.

Do not claim completion before every condition is proved. If any condition is
uncertain, the verdict is pending.


Coding Policy (`docs/coding-policy.md`)

Pyxel Coding Policy

Principles

  • Determinism. A rule produces the same verdict on the same frozen input regardless of who applies it or when. Taste alone never determines a verdict.
  • Self-applicability. Every rule applies to every in-scope surface it governs (see Verification > Scope), including the corresponding parts of this document.
  • Performance first. Subject to correctness, demonstrated hot-path cost overrides language conventions and idiomatic style.
  • Cross-file consistency. Explicit policy determines required departures from language idiom; otherwise language idiom determines the correct form, which comparable sites use uniformly.
  • Read naturally. Code reads concisely to a fluent reader of its language; the language's idioms are preferred over invented forms.

Standards

Source Code

Performance

  • Code on the hot paths eliminates avoidable cost. The hot paths are:

    • per-pixel blit and primitive draws (line, circle, rect);
    • per-pixel 3D rasterization (triangle fill and shading);
    • per-sample voice synthesis;
    • per-frame voice update for MML and BGM;
    • per-frame 3D collision and BVH queries;
    • the PyO3 FFI boundary (argument marshaling and return paths);
    • SIMD or multi-threaded sections.
  • On hot paths, idiomatic patterns with a measured or mechanically demonstrated avoidable cost are not used.

    • e.g., per-frame heap allocations (Vec::new, format!, Box::new in inner loops); avoidable copies or type conversions; bounds checks in tight loops; missed SIMD, loop-unrolling, or inlining opportunities.
  • Outside hot paths, code stays idiomatic and readable. Micro-optimization is reserved for the listed hot paths.

    • e.g., for x in xs { f(x) } in a config loader is preferred over a hand-unrolled alternative.

Naming

  • Mechanical naming rules (the language's standard case conventions and lint-enforced patterns) apply first.

  • File and directory names use a policy-compliant, language-idiomatic base-name, separator, and role-suffix pattern uniformly within their sibling group. Public URLs, generated paths, and author-titled assets keep their established spelling unless every mirrored reference is renamed together.

    • e.g., *_wrapper.rs files keep the wrapper suffix, web/*/index.html keeps the route directory as the page identity, and laser-jetman.html keeps its author-chosen hyphenation.
  • A symbol referenced from more than one file uses the same base name at every site (function and type names, CSS classes, HTML IDs, i18n keys, public API entries). Suffixed variants of the base name are allowed when each variant is exposed as a separate public entry. When mirrors disagree, the authoritative public surface wins; between a binding and the .pyi, the .pyi wins. If no authoritative surface exists, the language-idiomatic name is chosen and every mirrored reference is updated together.

    • e.g., a pyxel-core function gen_bgm keeps the same base name in crates/pyxel-binding/src/*_wrapper.rs and python/pyxel/__init__.pyi; if it is split for separate exposure, the split uses suffixes (gen_bgm_mml, gen_bgm_json) rather than a renaming.
  • A name is rewritten when it gives one concept a different base from its peers, breaks a symmetric verb family, repeats its owner or type without distinguishing meaning, or names an obsolete concept.

    • e.g., titleBlock and titleDiv for the same UI concept โ€” anti-pattern; Canvas.drawCanvas() โ€” anti-pattern (stutter).
  • A language's idiomatic abbreviations are kept as-is.

    • e.g., Python and Rust use i for a loop counter and e for an exception variable; JavaScript uses e for an event and el for a DOM element.
  • A locally reasonable name with no peer to harmonize with is left as-is. The rename rule above applies when peers exist; with no peer, taste alone is not grounds for renaming.

    • e.g., a self-contained file using titleDiv stays as it is when no comparable sibling exists; the same name in a file with sibling files using titleBlock is renamed to match.

Ordering

  • Definitions are ordered top-down: high-level structures and public types come before the free functions that consume them.

    • e.g., a Rust file places pub struct Foo { ... } and its impls before any free function consuming Foo.
  • Where the language requires forward declarations, they precede their use, overriding top-down ordering at the local level.

  • Configuration files follow each format's idiomatic grouping; within each group, entries are sorted alphabetically unless the format itself prescribes another order.

    • e.g., Cargo.toml keeps dependencies, build dependencies, features, and release profiles in their conventional tables and sorts entries within each table.

Comments

  • Every comment is in English.

  • A comment exists only when it adds intent that neither the code nor an existing comment shows; a shared rationale lives once, at the site that owns the decision, unless another rule requires the repetition. Required cases are mechanical or non-obvious operations (bit-twiddling, format-specific encoding) and non-local invariants.

    • e.g., i += 1 # increment i โ€” anti-pattern; i += 1 # wrap at frame boundary โ€” typical; the same workaround explained at its deciding and dependent sites โ€” anti-pattern.
  • A comment is as short as its intent allows; comments expressing equally complex intent use comparable granularity.

    • e.g., a five-line header on a short helper where sibling files use one-line headers โ€” anti-pattern (surplus wording); a widget's # Variables: and # Events: blocks matching the convention across widget files โ€” typical.
  • A one-line separator comment identifies a meaningful group only when the language's structure does not make the group equally clear; no size threshold alone requires one. It uses the language's idiomatic single-line comment form, in sentence case, without decorative dashes or banners.

    • e.g., Python # Event handlers, Rust // Constructors, JavaScript // HTML helpers.
  • A label-style comment does not end with a period; a comment of two or more sentences punctuates every sentence, including the last. A single-sentence comment's terminal period is optional; either form is left as-is.

    • e.g., // Constructors (label); // Playback has ended and // Playback has ended. โ€” both typical single-sentence forms.
  • No documentation comments (Rust //////!, Python docstrings, JSDoc /** */) anywhere except python/pyxel/__init__.pyi. The .pyi docstrings are regenerated by scripts/generate_pyi_docstrings and are not hand-edited.

  • Every comment is understandable at its site without historical or external context. No self-referential gloss, no tautological phrasing.

    • e.g., the Pyxel API (the API of Pyxel) โ€” anti-pattern (gloss restates the term); // explanations to aid understanding โ€” anti-pattern (tautology).

Formatting

  • Surface formatting (indentation, line wrapping, quoting) is delegated to make format for the file types it covers; hand-written .md is formatted by hand; every other file follows the standard conventions of its language or data format without unrelated reformatting.

    • e.g., a Rust match arm is not hand-aligned; a Cargo.toml table is not hand-reformatted.
  • Exactly one blank line separates meaningful chunks unless make format prescribes otherwise. Runs of blank lines and blank lines inside a chunk are not used.

    • e.g., one blank line between class methods; no double blank between imports; no blank line between a function signature and its first statement.

Consistency

  • Each file participates in every structurally comparable sibling group identified by a common directory, naming pattern, or shared role. Consistency is judged within each group; codebase-wide prevalence does not determine correctness.

    • e.g., sibling groups include crates/pyxel-binding/src/*_wrapper.rs; python/pyxel/editor/widgets/*.py; python/pyxel/editor/*_editor.py; HTML pages under web/*/index.html; language JSON files under web/**/*.json.
  • A sibling group is an exception group only where this policy names the group, the convention it departs from, and the reason. The exception applies only to that convention; every other rule remains in force.

    • The exception groups are:
      • crates/pyxel-binding/src/*_wrapper.rs: mirrors the Python API rather than following Rust conventions (snake_case names, Python-style argument ordering, and Pyxel-historical short names like blt/cls/pset rather than the Rust-idiomatic counterparts in pyxel-core) and adopts the PyO3 binding conventions (#[new] for __init__, #[getter]/#[setter] for Python attributes);
      • SDL2 call sites: preserve the external SDL2 API's C-style names so calls remain recognizable against its documentation;
      • samples in python/pyxel/examples/: direct control flow and example-local names may stay when production-style decomposition or abstraction would make the sample harder to follow.
  • Parallel mirrors โ€” shapes deliberately repeated across sibling files for API symmetry or data-structure parallelism โ€” preserve their shared structure. A correction is applied to every affected mirror rather than preserving a shared defect.

    • e.g., binding wrappers mirror the Python API one-to-one; image and tilemap drawing primitives mirror each other; each i18n JSON file repeats the languages array.
  • Error and warning messages form codebase-wide families by failure kind rather than per-file groups: a message that mirrors a standard Python error keeps CPython's exact wording, a parameter constraint starts with the parameter as written, and any other message reuses its family's policy-compliant, language-idiomatic shape and casing rather than introducing a new form.

    • e.g., fps must be greater than 0 and scale must be greater than 0 โ€” typical (one constraint family across files); a lone draw: <message> prefix among sentence-style siblings โ€” anti-pattern.
  • The .pyi API stub records each parameter's effective default โ€” the value the implementation resolves to โ€” while its binding may take None as a sentinel and resolve it internally. The .pyi default and the binding-signature default may therefore differ; that divergence is intentional, not an inconsistency.

    • e.g., the .pyi writes init(title="Pyxel", fps=30, ...) while the binding takes Option sentinels and resolves them; None stays in the .pyi only where None is itself the default behavior (display_scale auto, colkey / font none).

Testing

Tests cover the product in four layers: Rust unit tests for platform-independent pure logic; Python API tests for the public interface surface; reference regression of screenshots from the bundled examples, apps, and editor plus rendered audio; and a manual pass on running samples for look, sound, and feel. Test code itself is in scope for every Source Code rule.

  • A behavior is unit-tested when its breakage would not surface in the reference regression or the manual pass. These cases qualify:

    • numeric boundaries and degenerate inputs (zero, empty, maximum, negative);
    • rarely-taken branches (special syntax, edge inputs);
    • determinism contracts whose silent change alters existing users' assets;
    • compatibility surfaces (deprecated aliases keep working and warn);
    • save/load and serialization roundtrips;
    • error paths (exception type and message).
    • e.g., the BGM generator's seed-determinism snapshot โ€” typical (a silent change rewrites existing users' music).
  • A behavior already exercised by the reference regression and the manual pass, whose breakage is plainly visible or audible there, is not duplicated by an internal unit test.

    • e.g., a music mixing change is caught by the committed audio renders and the manual pass โ€” typical; a unit test re-asserting the same waveform sample-by-sample โ€” anti-pattern (duplicates the reference regression).
  • A test verifies what its name and comments claim; a test that cannot fail for the claimed reason is fixed or removed.

    • e.g., a wraparound test whose inputs never wrap โ€” anti-pattern.
  • A deterministic outcome is pinned exactly. An assertion accepting several outcomes is reserved for genuine nondeterminism, with the source named in a comment.

    • e.g., play_pos() may be None right after play() (audio-thread timing) โ€” typical; "level is 0.0 or 1.0" for a deterministic envelope โ€” anti-pattern.
  • Every automated test executes in make test.

Documentation

Prose

  • Documentation prose reads as natural technical writing in its own language, using the target language's standard conventions for compound-noun chains rather than literal translation from another language.

    • e.g., English "package installation guide" โ€” typical; "installation of the package guide" โ€” anti-pattern (translationese).
  • Japanese text separates Japanese characters from adjacent alphanumeric tokens with a single half-width space, regardless of which file the text lives in; code spans keep their literal spacing.

    • e.g., ใ€ŒWeb ็‰ˆ Pyxelใ€ใ€Œ16 ่‰ฒใ€ใ€Œ.pyxres ใƒ•ใ‚กใ‚คใƒซใ€ โ€” typical; ใ€ŒWeb็‰ˆใ€ใ€Œ16่‰ฒใ€ โ€” anti-pattern (missing separation).
  • Japanese technical loanwords follow the project's adopted spelling rather than a mechanical English-suffix rule. Unlisted terms follow established usage in comparable developer documentation, then stay consistent across sibling documentation.

    • Adopted spellings: ใ€Œใƒ–ใƒฉใ‚ฆใ‚ถใ€ใ€Œใ‚จใƒ‡ใ‚ฃใ‚ฟใ€ใ€Œใƒ‘ใƒฉใƒกใƒผใ‚ฟใ€ใ€Œใƒใƒƒใƒ•ใ‚กใ€ใ€Œใ‚ณใƒณใ‚นใƒˆใƒฉใ‚ฏใ‚ฟใ€ใ€Œใƒฆใƒผใ‚ถใƒผใ€ใ€Œใ‚ตใƒผใƒใƒผใ€ใ€Œใ‚ณใƒณใƒ”ใƒฅใƒผใ‚ฟใ€.
    • e.g., ใ€Œใƒ–ใƒฉใ‚ฆใ‚ถไธŠใงๅฎŸ่กŒใ€ โ€” typical; mixing ใ€Œใƒ–ใƒฉใ‚ฆใ‚ถใ€ and ใ€Œใƒ–ใƒฉใ‚ฆใ‚ถใƒผใ€ for one concept in sibling pages โ€” anti-pattern.
  • Japanese text chooses parenthesis width by content: parentheses containing Japanese characters are full-width and sit flush; parentheses with ASCII-only content are half-width, separated by half-width spaces except when adjacent to punctuation.

    • e.g., ใ€Œใ‚คใƒกใƒผใ‚ธใƒใƒณใ‚ฏ๏ผˆImage ใ‚ฏใƒฉใ‚นใฎใ‚คใƒณใ‚นใ‚ฟใƒณใ‚น๏ผ‰ใฎใƒชใ‚นใƒˆ (0-2)ใ€ โ€” typical; ใ€Œใƒชใ‚นใƒˆ๏ผˆ0-2๏ผ‰ใ€ โ€” anti-pattern (full-width around ASCII-only content).

Translation

  • The maintainer writes in Japanese; Japanese is the source of truth for translation. Translations route through English first, then to every other language.

  • Each target language follows its own technical-writing conventions and retains established English loanwords where the target language conventionally uses them.

    • e.g., German, Spanish, Italian, and Portuguese keep loanwords like "Editor" and "Gamepad" in English; French instead uses native forms such as "รฉditeur" and "manette", keeping only product names like "Pyxel Editor" in English.
  • A target-language translation is compared against the English version, not the Japanese source.

    • e.g., a German "Installation des Pakets Anleitung" mirrors a Japanese compound-noun chain and is rewritten as "Paket-Installationsanleitung".

Proper Nouns

The authoritative Pyxel product names are: Pyxel, Pyxel Cube, Pyxel Editor, Pyxel Showcase, Pyxel Code Maker, Pyxel MML Studio, Pyxel Web Launcher, Pyxel User Examples, and Pyxel Composer. The abbreviations Pyxel Web (the web version), Pyxel MML (the MML variant), and Pyxel API (the public API) may stand in for their full forms.

  • Listed product names are not translated and their casing is not altered.

    • e.g., Pyxel Editor in every language โ€” never pyxel editor, Pyxel-Editor, or ใƒ”ใ‚ฏใ‚ปใƒซใ‚จใƒ‡ใ‚ฃใ‚ฟ.
  • Every other proper noun retains the author's chosen representation, including hyphens, spacing, and casing.

    • e.g., laser-jetman.html keeps its hyphen; author-titled examples are not renamed to fit a Pyxel-prefixed pattern.
  • A descriptive label may stand in for a product name when the surrounding context establishes the reference and the label reads naturally there. Outside such contexts, the product name follows the casing rule above.

    • e.g., a "Related Sites" section that introduces Pyxel Showcase as "the Pyxel community showcase" reads naturally; references to the same product elsewhere still write Pyxel Showcase.

Release Notes

  • A CHANGELOG.md entry exists when the change carries (a) a concrete user benefit, or (b) a debugger breadcrumb a future maintainer can follow. Changes that match neither are not recorded.

    • User benefits include: feature addition, bug fix, visible behavior change, performance improvement.
    • Breadcrumbs include: dependency update; shipped runtime update; build-toolchain update that affects release artifacts; build-configuration change that alters compilation; feature flag addition; internal runtime change; scoped refactor or cleanup; public API rename; release-process change.
  • A breadcrumb names a concrete investigation surface; test-only, policy-only, and ignore-file changes are omitted unless they also change product, build, or release behavior.

    • e.g., Updated pyo3 crate to version 0.29 remains useful, Updated dependencies is too broad, and adding tests or .gitignore entries is not a breadcrumb by itself.
  • Sub-changes within a single commit are evaluated separately under the rule above.

    • e.g., a commit that fixes a bug and renames a public type produces two entries; a sub-change that is neither a user benefit nor a breadcrumb is omitted.
  • Entries describe the change relative to the previous release. A change to code that has not shipped folds into the entry that introduces that code and does not produce its own entry.

    • e.g., a fix to a feature added earlier in the same unreleased version is absorbed by that feature's Added entry rather than gaining a Fixed entry.
  • Each entry uses a language-idiomatic verb, grammar form, and level of object specificity. It matches compliant prior entries of the same change category for consistency; prevalence does not determine the form.

  • Each entry fits a single line of at most 80 characters; entries typically run around 60 characters. An overlong entry is shortened without losing specificity and is split only when it contains independent sub-changes.

    • e.g., Fixed Pyxel Editor color picker cursor shape across palette sizes (65 chars) fits the typical band; independent user-visible changes become separate entries, while an atomic change is tightened into one line.
  • Each entry is verified against the actual code diff, not the commit message. Commit messages may understate or misstate the diff.

  • Documentation wording and translation touch-ups bundle into a single summary line.

    • e.g., Update web titles and docs wording covers a commit touching many doc strings.

Verification

Scope

  • This policy applies to every file present in the audit target that is git-tracked or an intended addition and that .gitattributes does not mark as binary, including this file.

  • Files excluded because they are toolchain output:

    • *.tmx (Tiled tilemap editor output)
    • *.bdf (font tooling output)
    • Cargo.lock and *-lock.json (package-manager lockfiles)
    • web/styles.css (a Tailwind CSS build artifact)
    • .md files whose first line begins with <!-- This file is generated (output of scripts/generate_docs)
  • A file's code-side aspects (structure, syntax, identifiers, non-prose elements) remain in scope even when its prose content is reviewed separately.

Format, Lint, and Test

  • After a code change, make format runs before the commit.

  • make lint (native build) and make lint-wasm (WebAssembly build) are warning-free at all times. The two builds use different feature sets and target environments; both pass.

    • Clippy warnings count as failures. Suppression with #[allow(...)] requires that the suppression itself be justified.
  • After a code change, make test passes before completion is claimed. A flaky failure does not waive the rule; the failure is reproduced and the underlying cause fixed.

Conventions of This File

  • A new concern joins an existing section before a new section is added. A new section is warranted only when no existing section fits.

    • e.g., a wording guideline for CHANGELOG entries belongs under Standards > Release Notes, not as a top-level section.
  • Individual past incidents are not recorded. An enduring lesson tightens the nearest existing rule; an example changes only when it clarifies a reusable boundary, replacing or rebalancing existing examples rather than accumulating another case.

    • e.g., a one-off false-positive finding belongs in a commit message or the contributor's working notes, not as a named bullet here.
  • A section with an authoritative enumeration separates the list from the rules. The list appears either in the introductory prose, followed by rule bullets, or as sub-bullets or numbered items under the rule that needs the detail.

    • e.g., Standards > Documentation > Proper Nouns lists product names and abbreviations in its intro and uses bullets for casing rules; Standards > Source Code > Performance enumerates hot paths as sub-bullets under the rule that introduces them.
  • Each rule may be followed by at most one compact e.g., sub-bullet containing only the examples needed to clarify a reusable boundary.

    • Hypothetical anti-patterns read clearly as anti-patterns and are not asserted to exist in the code.
    • An e.g. line illustrates its rule and never substitutes for it; matching the example alone does not satisfy the rule.
    • A language-specific rule names the language in its rule statement.
  • After revising any section, the whole file is re-read and its balance is confirmed. Adding or splitting a rule or authoritative enumeration triggers a review of structurally comparable peers for parallel gaps; a change confined to wording or examples does not. Proportionality is checked by section length and bullet count.


Editor Manual (`docs/editor-manual.md`)

Pyxel Editor Manual

This document was auto-generated from the Pyxel Editor Manual web page, which also offers multilingual support.

Overview

Pyxel Editor is a built-in resource editing tool for Pyxel. It consists of four editors, which can be switched using the editor buttons at the top of the screen.

  • Image Editor: Edit images (image banks) used for sprites and tiles
  • Tilemap Editor: Arrange image bank images as tiles to compose maps
  • Sound Editor: Edit sounds used for sound effects and melodies
  • Music Editor: Arrange sounds in playback order to compose music such as BGM

Getting Started

Launch Pyxel Editor with the following command:

pyxel edit [PYXEL_RESOURCE_FILE]

If the specified Pyxel resource file (.pyxres) exists, it will be loaded. If it does not exist, a new file with the specified name will be created. If the filename is omitted, my_resource.pyxres will be created.

Common Operations

Operations common to all editors.

The menu bar at the top of the screen contains four editor switching buttons, Undo/Redo buttons, and a Save button. The help message area on the right displays context-sensitive information based on the cursor position.

  • Switch to Image Editor
  • Switch to Tilemap Editor
  • Switch to Sound Editor
  • Switch to Music Editor
  • Ctrl(Cmd)+Z โ€” Undo
  • Ctrl(Cmd)+Y โ€” Redo
  • Ctrl(Cmd)+S โ€” Save

Other Shortcuts

Shortcut Action
Alt(Option)+Left/Right Switch between editor types
Shift+Ctrl(Cmd)+C Copy the entire editing target
Shift+Ctrl(Cmd)+X Cut the entire editing target (copy and clear)
Shift+Ctrl(Cmd)+V Paste the copied target
Shift+Click ([+]/[-] buttons) Change number or value in increments of ยฑ10

Using from Programs

The created resource file can be loaded and used in a Pyxel application with the pyxel.load() function.

Switching Resource Files

While the editor is running, you can drag and drop another .pyxres file onto the window to load its contents. This operation overwrites all current edits, so be careful if you have unsaved changes.

Image Editor

A mode for editing images in each image bank. You can create pixel art for sprites and tiles.

Specifications

  • Image Banks: 0โ€“2 (3 banks)
  • Size: 256ร—256 pixels each
  • Coordinate System: Origin (0,0) at top-left, X+ rightward, Y+ downward

Screen Layout

Image Canvas

The editing area selected in the image bank view is displayed magnified. Click and drag with the mouse to draw.

Shortcut Action
Right Click Pick the color at the cursor position (color pick)
Right Drag Pan the view

Image Bank View

A thumbnail view of the entire image bank. The white frame indicates the current editing area.

Shortcut Action
Arrow Keys Move the editing area (white frame)
Click Move the editing area to the clicked position
Right Drag Pan the view

Tool Buttons

Select a tool for drawing.

  • S โ€” Select a rectangular area
  • P โ€” Draw freehand. Hold Shift for straight lines
  • R โ€” Draw a rectangle outline. Hold Shift for a square
  • Shift+R โ€” Draw a filled rectangle. Hold Shift for a square
  • C โ€” Draw an ellipse outline. Hold Shift for a circle
  • Shift+C โ€” Draw a filled ellipse. Hold Shift for a circle
  • B โ€” Fill a connected region of the same color

Selection Tool Shortcuts

The following shortcut keys are available while using the selection tool.

Shortcut Action
Ctrl(Cmd)+A Select the entire canvas
Ctrl(Cmd)+C Copy the selection
Ctrl(Cmd)+X Cut the selection (copy and clear)
Ctrl(Cmd)+V Paste the copied area
H Flip the selection horizontally
V Flip the selection vertically

Color Palette

Select a drawing color from the 16-color palette.

Shortcut Action
1โ€“8 Select colors 0โ€“7
Shift+1โ€“8 Select colors 8โ€“15

Bank Number

Switch the target image bank (0โ€“2).

Loading External Files

Drag and drop an image file such as PNG or JPG onto the Image Editor to load the image at the editing area position. The original image colors are automatically converted to Pyxel's color palette, and any parts exceeding the image bank boundaries are clipped.

Tilemap Editor

A mode for arranging image bank images as tile patterns and editing tilemaps.

Specifications

  • Tilemaps: 0โ€“7 (8 maps)
  • Size: 256ร—256 tiles each
  • Tile Image: 8ร—8 pixel region of the image bank
  • Reference Image Bank: One per tilemap

Screen Layout

Tilemap Canvas

The editing area selected in the tilemap view is displayed magnified. Place tile images selected in the tile image view. Drawing tools and selection shortcuts are shared with the Image Editor. Note that all cells default to tile (0,0), so it is recommended to keep image bank position (0,0) empty.

Shortcut Action
Right Click Pick the tile at the cursor position (tile pick)
Right Drag Pan the view

Tilemap View

A thumbnail view of the entire tilemap. The white frame indicates the current editing area.

Shortcut Action
Arrow Keys Move the editing area (white frame)
Click/Drag Move the editing area to the clicked position

Tile Image View

Displays the referenced image bank. Select tile images with the white frame.

Shortcut Action
Shift+Arrow Keys Move the selection
Drag Select multiple tiles in a rectangle
Right Drag Pan the view

Tilemap Number

Switch the target tilemap (0โ€“7).

Ref. Image Bank Number

Switch the image bank (0โ€“2) referenced for tile images.

Tool Buttons

Select a tool for drawing.

  • S โ€” Select a rectangular area
  • P โ€” Draw freehand. Hold Shift for straight lines
  • R โ€” Draw a rectangle outline. Hold Shift for a square
  • Shift+R โ€” Draw a filled rectangle. Hold Shift for a square
  • C โ€” Draw an ellipse outline. Hold Shift for a circle
  • Shift+C โ€” Draw a filled ellipse. Hold Shift for a circle
  • B โ€” Fill a connected region of the same color

Placing Multiple Tiles

When you draw with multiple tile images selected by dragging in the tile image view, the selected tiles are placed as a repeating pattern. For example, if you select two tiles vertically and draw with the pen, the two tiles are placed alternately in a repeating pattern. The same applies when selecting multiple tiles both horizontally and vertically. The drawing start position corresponds to the top-left of the selection.

Loading TMX Files

Drag and drop a TMX file created with Tiled Map Editor (Tiled) onto the Tilemap Editor to load the contents of layer 0 at the editing area position.

Sound Editor

A mode for editing sounds used for melodies and sound effects.

Specifications

  • Sounds: 0โ€“63 (64 sounds)
  • Pitch Range: C0โ€“B4
  • Max Length: 48 notes
  • Polyphony: 1 note (or rest)
  • Per-Note Settings: Tone, volume, effect

Screen Layout

Sound Number

Switch the target sound (0โ€“63).

Playback Speed

Sets the playback duration per note. This is a common setting for all notes, specified in the range 1โ€“99. Smaller values result in faster playback (1 speed unit = 1/120 second; e.g., speed 60 = 0.5 seconds per note). For sound effects, 1โ€“9 is typical; for melodies, 10 or higher is recommended.

Play / Stop / Loop

  • Space โ€” Play
  • Space โ€” Stop (press Space during playback to stop)
  • L โ€” Toggle loop playback

Piano Roll

Click to input note pitch. Red squares represent notes, blue squares represent rests. During piano roll editing, a blue cursor is displayed; during property area editing, a different cursor shape appears. Notes are played from left to right, and rests are automatically inserted in empty positions. Clicking an already-filled position overwrites it. Dragging inputs notes continuously with linear interpolation.

Shortcut Action
Up/Down Switch between piano roll and property area
Left/Right Move the cursor
Delete(fn+delete) Delete the note at the current position
Backspace(delete) Delete the note before the current position
Shift+Space Play from the cursor position
Ctrl(Cmd)+A Select the entire range
Shift+Left/Right Start range selection

Range Selection

Shortcut Action
Ctrl(Cmd)+C Copy the selection
Ctrl(Cmd)+X Cut the selection (copy and clear)
Ctrl(Cmd)+V Paste the copied area
Ctrl(Cmd)+U Raise the pitch of the selection by 1
Ctrl(Cmd)+D Lower the pitch of the selection by 1

Octave Bar

Displays the starting octave (0โ€“3) for keyboard input. The keyboard covers two octaves from the selected octave.

Shortcut Action
PageUp(fn+Up) Raise the octave by 1
PageDown(fn+Down) Lower the octave by 1

Keyboard Input

You can input notes using the PC keyboard. The upper row (QWE row + number row) and the lower row (ZXC row + ASD row) each correspond to one octave of piano keys, covering two octaves simultaneously. White keys are assigned to natural notes and gray keys to sharps. Select the starting octave (0โ€“3) with the octave bar.

Upper Octave (QWE row + number row)

Note Key
C Q
C# 2
D W
D# 3
E E
F R
F# 5
G T
G# 6
A Y
A# 7
B U

Lower Octave (ZXC row + ASD row)

Note Key
C Z
C# S
D X
D# D
E C
F V
F# G
G B
G# H
A N
A# J
B M

| Rest | A |

Shortcut Action
Keyboard Key โ†’ Enter Input the pressed keyboard note into the piano roll
1 Cycle the preview tone for keyboard input (4 types)

Property Area (TON / VOL / EFX)

Set the tone (TON), volume (VOL), and effect (EFX) for each note. Press the โ†“ key or click the TON row during piano roll editing to move to the property area. Cursor movement, range selection, copy & paste, and other operations are shared with the piano roll. Press a key on each row to input the corresponding value. For example, pressing P on the TON row sets Pulse. To change the tone partway through, set the value for all notes from the desired position onward. The same applies to VOL and EFX.

Tone

With the cursor on the TON row, press the following keys to set the tone. The default when not set is T (Triangle).

Key Name Description
T Triangle Triangle wave. Soft and gentle tone. Similar to a flute
S Square Square wave. Electronic and clear tone. Similar to a clarinet or organ
P Pulse Pulse wave. Bright and flashy tone. Similar to a trumpet
N Noise Noise. Unpitched sound. Suitable for percussion and explosion effects

Volume

With the cursor on the VOL row, press number keys 0โ€“7 to set the volume (0 = silent, 7 = maximum). The default when not set is 7. Using maximum volume on multiple channels simultaneously may result in excessive loudness.

Effect

With the cursor on the EFX row, press the following keys to set the effect. The default when not set is N (None).

Key Name Description
N None No effect
S Slide Smoothly glide the pitch from the previous note
V Vibrato Periodically oscillate the pitch
F FadeOut Gradually decrease the volume over the entire note. Also used to separate notes of the same pitch
H Half-FadeOut Gradually decrease the volume in the second half of the note. Longer sustain than F
Q Quarter-FadeOut Gradually decrease the volume in the last quarter of the note. Longer sustain than H

Music Editor

A mode for arranging sounds in playback order to compose music tracks.

Specifications

  • Music Tracks: 0โ€“7 (8 tracks)
  • Channels: 4
  • Sounds per Channel: Max 32

Screen Layout

Music Number

Switch the target music (0โ€“7).

Play / Stop / Loop

  • Space โ€” Play
  • Space โ€” Stop (press Space during playback to stop)
  • L โ€” Toggle loop playback

Sequence Editor (CH0โ€“CH3)

Place sound numbers in playback order across four channels (CH0โ€“CH3). Copy and paste between channels is also supported.

Shortcut Action
Up/Down Switch the editing channel
Left/Right Move the editing cursor
Delete(fn+delete) Delete the sound at the current position
Backspace(delete) Delete the sound before the current position
Shift+Space Play from the cursor position
Ctrl(Cmd)+A Select the entire range of the current channel
Shift+Arrow Keys Select a range within the channel
Ctrl(Cmd)+C Copy the selection
Ctrl(Cmd)+X Cut the selection (copy and clear)
Ctrl(Cmd)+V Paste the selection (also across channels)
Ctrl(Cmd)+U Increment the sound number of the selection by 1
Ctrl(Cmd)+D Decrement the sound number of the selection by 1

Sound Buttons (0โ€“63)

Buttons for inserting sound numbers (0โ€“63). Pressing a button inserts the sound number at the editing cursor position. Created sounds are shown in blue, uncreated ones in gray. Hovering over a button previews the sound.


Faq Ja (`docs/faq-ja.md`)

Pyxel ใ‚ˆใใ‚ใ‚‹่ณชๅ•

Pyxel ใฎๅญฆใณๆ–น

Pyxel ใ‚’ๅญฆ็ฟ’ใ™ใ‚‹ใซใฏใฉใ“ใ‹ใ‚‰ๅง‹ใ‚ใ‚Œใฐใ„ใ„ใงใ™ใ‹๏ผŸ

Pyxel ใฎใ‚ตใƒณใƒ—ใƒซใ‚ณใƒผใƒ‰ใ‚’ไปฅไธ‹ใฎ้ †ใซ่ฉฆใ™ใฎใŒใŠใ™ใ™ใ‚ใงใ™ใ€‚

  1. 01_hello_pyxel โ€” Pyxel ใฎๅŸบๆœฌ
  2. 05_color_palette โ€” ใ‚ซใƒฉใƒผใƒ‘ใƒฌใƒƒใƒˆ
  3. 03_draw_api โ€” ๆ็”ป API
  4. 04_sound_api โ€” ใ‚ตใ‚ฆใƒณใƒ‰ API
  5. 02_jump_game โ€” ใ‚ฒใƒผใƒ ๅฎŸ่ฃ…

ใ‚ตใƒณใƒ—ใƒซใ‚ณใƒผใƒ‰ใฏ pyxel copy_examples ใงใ‚ณใƒ”ใƒผใงใใ‚‹ใปใ‹ใ€Pyxel Showcase ใงใƒ–ใƒฉใ‚ฆใ‚ถไธŠใงใ‚‚ๅฎŸ่กŒใงใใพใ™ใ€‚

Pyxel ใซ้–ขใ™ใ‚‹ๆ›ธ็ฑใฏใ‚ใ‚Šใพใ™ใ‹๏ผŸ

ๆ—ฅๆœฌ่ชž็‰ˆใฎใฟใงใ™ใŒใ€ๅ…ฌๅผใฎๆ›ธ็ฑ ใŒ็™บๅฃฒใ•ใ‚Œใฆใ„ใพใ™ใ€‚

API ไป•ๆง˜ใจไฝฟใ„ๆ–น

update ้–ขๆ•ฐใจ draw ้–ขๆ•ฐใฎ้•ใ„ใฏไฝ•ใงใ™ใ‹๏ผŸ

update ้–ขๆ•ฐใฏๆฏŽใƒ•ใƒฌใƒผใƒ ๅ‘ผใณๅ‡บใ•ใ‚Œใพใ™ใŒใ€draw ้–ขๆ•ฐใฏๅ‡ฆ็†ๆ™‚้–“ใŒ่จฑๅฎน้™็•Œใ‚’่ถ…ใˆใŸๅ ดๅˆใซใ‚นใ‚ญใƒƒใƒ—ใ•ใ‚Œใ‚‹ใ“ใจใŒใ‚ใ‚Šใพใ™ใ€‚Pyxel ใฏใ“ใฎ่จญ่จˆใซใ‚ˆใ‚Šใ€ใƒฌใƒณใƒ€ใƒชใƒณใ‚ฐ่ฒ ่ทใ‚„ OS ใฎๅ‰ฒใ‚Š่พผใฟๅ‡ฆ็†ใฎๅฝฑ้Ÿฟใ‚’่ปฝๆธ›ใ—ใฆใ€ๆป‘ใ‚‰ใ‹ใชใ‚ขใƒ‹ใƒกใƒผใ‚ทใƒงใƒณใ‚’ๅฎŸ็พใ—ใฆใ„ใพใ™ใ€‚

Pyxel MML ใฎไฝฟใ„ๆ–นใ‚’ๆ•™ใˆใฆใใ ใ•ใ„

MML (Music Macro Language) ใฏใ€้Ÿณ็ฌฆใ‚„ใƒ†ใƒณใƒใชใฉใ‚’ๆ–‡ๅญ—ๅˆ—ใง่จ˜่ฟฐใ—ใฆใ‚ตใ‚ฆใƒณใƒ‰ใ‚’ๅฎš็พฉใ™ใ‚‹่จ€่ชžใงใ™ใ€‚

Sound ใ‚ฏใƒฉใ‚นใฎ mml ้–ขๆ•ฐใซ MML ๆ–‡ๅญ—ๅˆ—ใ‚’ๆธกใ™ใจใ€ใใฎ Sound ใŒ MML ใฎๅ†…ๅฎนใซๆฒฟใฃใฆๅ†็”Ÿใ•ใ‚Œใ‚‹ใ‚ˆใ†ใซใชใ‚Šใพใ™ใ€‚mml() ใ‚’ๅผ•ๆ•ฐใชใ—ใงๅ‘ผใถใจ MML ่จญๅฎšใ‚’่งฃ้™คใงใใพใ™ใ€‚

python
pyxel.sounds[0].mml("CDEFGAB>C")

play ้–ขๆ•ฐใซใ‚ตใ‚ฆใƒณใƒ‰็•ชๅทใฎไปฃใ‚ใ‚Šใซ MML ๆ–‡ๅญ—ๅˆ—ใ‚’็›ดๆŽฅๆธกใ—ใฆๅ†็”Ÿใ™ใ‚‹ใ“ใจใ‚‚ใงใใพใ™ใ€‚

python
pyxel.play(0, "CDEFG")

ๅˆฉ็”จใงใใ‚‹ MML ใ‚ณใƒžใƒณใƒ‰ใฏ Pyxel MML ใ‚ณใƒžใƒณใƒ‰ ใ‚’ๅ‚็…งใ—ใฆใใ ใ•ใ„ใ€‚ไฝฟ็”จไพ‹ใฏใ‚ตใƒณใƒ—ใƒซ 09_shooter.py ใฎ ใƒ‡ใƒข ใ‚„ ใ‚ณใƒผใƒ‰ ใง็ขบ่ชใงใใพใ™ใ€‚

ใพใŸใ€Pyxel MML Studio ใ‚’ไฝฟใˆใฐใ€MML ใ‚’ใƒ–ใƒฉใ‚ฆใ‚ถไธŠใงไฝœๆˆใƒปๅ…ฑๆœ‰ใงใใพใ™ใ€‚

ใƒ•ใ‚กใ‚คใƒซๆ“ไฝœใจใƒ‡ใƒผใ‚ฟ็ฎก็†

็’ฐๅขƒใŒๅค‰ใ‚ใ‚‹ใจใƒ•ใ‚กใ‚คใƒซใ‚’่ชญใฟ่พผใ‚ใชใใชใ‚‹ใฎใฏใชใœใงใ™ใ‹๏ผŸ

ใƒ•ใ‚กใ‚คใƒซใ‚’่ชญใฟ่พผใ‚€้š›ใซใ€ใ‚ซใƒฌใƒณใƒˆใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใŒๆ„ๅ›ณใ—ใŸใ‚‚ใฎใซใชใฃใฆใ„ใ‚‹ใ‹ใ‚’็ขบ่ชใ—ใฆใใ ใ•ใ„ใ€‚

Pyxel ใฎ init ้–ขๆ•ฐใŒๅ‘ผใฐใ‚Œใ‚‹ใจใ€ใ‚ซใƒฌใƒณใƒˆใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใฏใใฎใ‚นใ‚ฏใƒชใƒ—ใƒˆใƒ•ใ‚กใ‚คใƒซใจๅŒใ˜ๅ ดๆ‰€ใซๅค‰ๆ›ดใ•ใ‚Œใ€ใใ‚Œไปฅ้™ใฏ็›ธๅฏพใƒ‘ใ‚นใงใƒ•ใ‚กใ‚คใƒซใ‚’ๆŒ‡ๅฎšใงใใพใ™ใ€‚ใ—ใ‹ใ—ใ€init ใ‚’ๅ‘ผใถๅ‰ใซใƒ•ใ‚กใ‚คใƒซใ‚’้–‹ใ“ใ†ใจใ—ใŸๅ ดๅˆใ‚„ init ใฎๅพŒใซใ‚ซใƒฌใƒณใƒˆใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‚’ๅค‰ๆ›ดใ—ใŸๅ ดๅˆใซใฏ่ชญใฟ่พผใฟใซๅคฑๆ•—ใ™ใ‚‹ๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใพใ™ใ€‚

ใƒใ‚คใ‚นใ‚ณใ‚ขใ‚„ใ‚ฒใƒผใƒ ใฎ้€ฒ่กŒ็Šถๆณใชใฉใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณๅ›บๆœ‰ใฎใƒ‡ใƒผใ‚ฟใ‚’ไฟๅญ˜ใ™ใ‚‹ๆ–นๆณ•ใฏใ‚ใ‚Šใพใ™ใ‹๏ผŸ

้–‹็™บ่€…ๅ (vendor_name) ใจใ‚ขใƒ—ใƒชๅ (app_name) ใ‚’ user_data_dir(vendor_name, app_name) ้–ขๆ•ฐใซๆธกใ™ใจใ€ใƒ—ใƒฉใƒƒใƒˆใƒ•ใ‚ฉใƒผใƒ ใซ้ฉใ—ใŸใƒ‡ใƒผใ‚ฟไฟๅญ˜็”จใฎใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใ‚’ไฝœๆˆใ—ใ€ใใฎใƒ‘ใ‚นใ‚’่ฟ”ใ—ใพใ™ใ€‚ใ“ใฎใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใฎไธ‹ใงใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณ็”จใฎใƒ•ใ‚กใ‚คใƒซใฎไฟๅญ˜ใ‚„่ชญใฟ่พผใฟใ‚’่กŒใฃใฆใใ ใ•ใ„ใ€‚

Pyxel ใƒ„ใƒผใƒซใฎไฝฟใ„ๆ–น

ใ‚คใƒณใ‚นใƒˆใƒผใƒซใ›ใšใซ Pyxel ใ‚’่ฉฆใ›ใพใ™ใ‹๏ผŸ

Pyxel Code Maker ใ‚’ไฝฟใˆใฐใ€ใƒ–ใƒฉใ‚ฆใ‚ถไธŠใง Pyxel ใ‚ขใƒ—ใƒชใฎไฝœๆˆใƒปๅฎŸ่กŒใŒใงใใพใ™ใ€‚ใŸใ ใ—ใ€่ค‡ๆ•ฐใƒ•ใ‚กใ‚คใƒซๆง‹ๆˆใซใฏๅฏพๅฟœใ—ใฆใ„ใชใ„ใŸใ‚ใ€ๆœฌๆ ผ็š„ใช้–‹็™บใซใฏใƒญใƒผใ‚ซใƒซ็’ฐๅขƒใ‚’ใŠใ™ใ™ใ‚ใ—ใพใ™ใ€‚

Pyxel Showcase ใงใฏใ€ใ‚ตใƒณใƒ—ใƒซใ‚ณใƒผใƒ‰ใ‚„ใ‚ขใƒ—ใƒชใ‚’ใƒ–ใƒฉใ‚ฆใ‚ถไธŠใงไธ€่ฆงใƒปๅฎŸ่กŒใงใใพใ™ใ€‚

่‡ชไฝœใฎ Pyxel ใ‚ขใƒ—ใƒชใ‚’ Web ใงๅ…ฌ้–‹ใ™ใ‚‹ใซใฏใฉใ†ใ™ใ‚Œใฐใ„ใ„ใงใ™ใ‹๏ผŸ

Pyxel Web Launcherใ€app2htmlใ€HTML ใ‚ซใ‚นใ‚ฟใƒ ่ฆ็ด ใฎ 3 ใคใฎๆ–นๆณ•ใŒใ‚ใ‚Šใพใ™ใ€‚่ฉณใ—ใใฏ Web ็‰ˆ Pyxel ใฎไฝฟใ„ๆ–น ใ‚’ๅ‚็…งใ—ใฆใใ ใ•ใ„ใ€‚

Pyxel Editor ใงใƒ‘ใƒฌใƒƒใƒˆใฎ่‰ฒใ‚’ๅค‰ๆ›ดใงใใพใ™ใ‹๏ผŸ

Pyxel ใƒชใ‚ฝใƒผใ‚นใƒ•ใ‚กใ‚คใƒซ (.pyxres) ใจๅŒใ˜ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใซใ€ๆ‹กๅผตๅญใ‚’ .pyxpal ใซๅค‰ใˆใŸๅŒๅใฎใƒ•ใ‚กใ‚คใƒซใ‚’้…็ฝฎใ™ใ‚‹ใจใ€Pyxel Editor ใฎใƒ‘ใƒฌใƒƒใƒˆ่กจ็คบ่‰ฒใŒๅค‰ๆ›ดใ•ใ‚Œใพใ™ใ€‚ใƒ‘ใƒฌใƒƒใƒˆใƒ•ใ‚กใ‚คใƒซใฏ save_pal ้–ขๆ•ฐใงไฝœๆˆใงใใ‚‹ใปใ‹ใ€1 ่กŒใซ 1 ่‰ฒใฎ RRGGBB ๅฝขๅผใฎ 16 ้€ฒๆ•ฐใ‚ซใƒฉใƒผใ‚ณใƒผใƒ‰ใ‚’่จ˜่ฟฐใ—ใŸใƒ†ใ‚ญใ‚นใƒˆใƒ•ใ‚กใ‚คใƒซใจใ—ใฆๆ‰‹ๅ‹•ใงไฝœๆˆใ™ใ‚‹ใ“ใจใ‚‚ใงใใพใ™ใ€‚

ใƒใƒผใ‚ธใƒงใƒณ็งป่กŒใ‚ฌใ‚คใƒ‰

ใƒใƒผใ‚ธใƒงใƒณ 2.4 ใธใฎ็งป่กŒๆ–นๆณ•

Pyxel 2.4 ใงใฏใ‚ตใ‚ฆใƒณใƒ‰ใ‚จใƒณใ‚ธใƒณใจ MML ๆ–‡ๆณ•ใŒๅˆทๆ–ฐใ•ใ‚Œใฆใ„ใพใ™ใ€‚

ใ‚ณใƒผใƒ‰ใ‚’ใƒใƒผใ‚ธใƒงใƒณ 2.4 ใซๅฏพๅฟœใ•ใ›ใ‚‹ใซใฏใ€ไปฅไธ‹ใฎๅค‰ๆ›ดใ‚’่กŒใฃใฆใใ ใ•ใ„ใ€‚

  • Tone ใ‚ฏใƒฉใ‚นใฎ waveform ใƒ•ใ‚ฃใƒผใƒซใƒ‰ใ‚’ wavetable ใซใƒชใƒใƒผใƒ ใ™ใ‚‹
  • play ้–ขๆ•ฐใ€playm ้–ขๆ•ฐใฎ tick ๅผ•ๆ•ฐใ‚’ sec๏ผˆๅฐๆ•ฐๅฝขๅผใฎ็ง’ๆ•ฐ๏ผ‰ใซๅค‰ๆ›ดใ™ใ‚‹
  • play_pos ้–ขๆ•ฐใฎๆˆปใ‚Šๅ€คใŒ (sound_index, sec) ใซๅค‰ใ‚ใฃใŸใ“ใจใซๅฏพๅฟœใ™ใ‚‹
  • Sound ใ‚ฏใƒฉใ‚นใ€Music ใ‚ฏใƒฉใ‚นใฎ save ้–ขๆ•ฐใฎ count ๅผ•ๆ•ฐใ‚’ sec ใซๅค‰ๆ›ดใ™ใ‚‹
  • ใ‚ตใ‚ฆใƒณใƒ‰ใฎๅ†็”Ÿ็ง’ๆ•ฐใŒๅฟ…่ฆใชๅ ดๅˆใฏใ€Sound ใ‚ฏใƒฉใ‚นใฎ total_sec ้–ขๆ•ฐใ‚’ๅˆฉ็”จใ™ใ‚‹
  • Sound ใ‚ฏใƒฉใ‚นใฎ mml ้–ขๆ•ฐใซใฏๆ–ฐ MML ๆ–‡ๆณ•ใซๆฒฟใฃใŸใ‚ณใƒผใƒ‰ใ‚’ๆŒ‡ๅฎšใ™ใ‚‹๏ผˆๆ—งๆ–‡ๆณ•ใฏ่‡ชๅ‹•ๆคœๅ‡บใ•ใ‚Œใ‚‹ใ€‚old_mml ้–ขๆ•ฐใฏ้žๆŽจๅฅจ๏ผ‰
  • saveใ€load ้–ขๆ•ฐใฎ excl_* ใ‚ชใƒ—ใ‚ทใƒงใƒณใ‚’ exclude_* ใซๅค‰ๆ›ดใ™ใ‚‹
  • saveใ€load ้–ขๆ•ฐใฎ incl_* ใ‚ชใƒ—ใ‚ทใƒงใƒณใฎๆŒ‡ๅฎšใ‚’ๅ‰Š้™คใ™ใ‚‹

ๆ–ฐใ—ใ„ MML ๆ–‡ๆณ•ใฏไธŠ่จ˜ใฎใ€ŒPyxel MML ใฎไฝฟใ„ๆ–นใ€ใ‚’ๅ‚็…งใ—ใฆใใ ใ•ใ„ใ€‚

ใƒฉใ‚คใ‚ปใƒณใ‚นใจใ‚นใƒใƒณใ‚ตใƒผใ‚ทใƒƒใƒ—

Pyxel ใ‚’ไฝœ่€…ใฎ่จฑๅฏใชใๅ•†ๆฅญ็›ฎ็š„ใงไฝฟ็”จใ™ใ‚‹ใ“ใจใฏใงใใพใ™ใ‹๏ผŸ

MIT ใƒฉใ‚คใ‚ปใƒณใ‚นใซๅพ“ใ„ใ€ใ‚ฝใƒผใ‚นใ‚ณใƒผใƒ‰ใ‚„ใƒฉใ‚คใ‚ปใƒณใ‚น่กจ็คบ็”จใฎใƒ•ใ‚กใ‚คใƒซใซ่‘—ไฝœๆจฉใŠใ‚ˆใณใƒฉใ‚คใ‚ปใƒณใ‚นใฎๅ…จๆ–‡ใ‚’ๆ˜Ž็คบใ™ใ‚Œใฐใ€ไฝœ่€…ใฎ่จฑๅฏใ‚’ๅพ—ใ‚‹ใ“ใจใชใ่‡ช็”ฑใซ่ฒฉๅฃฒใ‚„้…ๅธƒใŒๅฏ่ƒฝใงใ™ใ€‚ใŸใ ใ—ใ€Pyxel ใฏๅ€‹ไบบใง้–‹็™บใ—ใฆใ„ใ‚‹ใŸใ‚ใ€ไฝœ่€…ใธใฎใ”้€ฃ็ตกใ‚„ใ‚นใƒใƒณใ‚ตใƒผใซใ‚ˆใ‚‹ใ”ๆ”ฏๆดใ‚’ใ„ใŸใ ใ‘ใ‚‹ใจใ‚ใ‚ŠใŒใŸใ„ใงใ™ใ€‚


Faq (`docs/faq.md`)

Pyxel FAQ

Learning Pyxel

Where do I start to learn Pyxel?

We recommend trying Pyxel's example code in the following order.

  1. 01_hello_pyxel โ€” Pyxel basics
  2. 05_color_palette โ€” Color palette
  3. 03_draw_api โ€” Drawing API
  4. 04_sound_api โ€” Sound API
  5. 02_jump_game โ€” Game implementation

You can copy the examples with pyxel copy_examples, or run them in your browser on Pyxel Showcase.

Are there any books on Pyxel?

The official book is available in Japanese only.

API Specification and Usage

What is the difference between the update and draw functions?

The update function is called every frame, but the draw function may be skipped if the processing time exceeds the allowable limit. Pyxel uses this design to reduce the impact of rendering load and OS interrupts, enabling smooth animation.

How do I use Pyxel MML?

MML (Music Macro Language) is a language for defining sounds by describing notes, tempo, and other parameters as a string.

Pass an MML string to the Sound class's mml function, and that Sound will play back following the MML. Calling mml() with no arguments clears the MML setting.

python
pyxel.sounds[0].mml("CDEFGAB>C")

You can also play an MML string directly by passing it to the play function instead of a sound number.

python
pyxel.play(0, "CDEFG")

For available MML commands, see Pyxel MML Commands. For usage examples, see the demo and code of the 09_shooter.py example.

You can also create and share MML in your browser using Pyxel MML Studio.

File Operations and Data Management

Why does file loading fail when the environment changes?

Make sure that the current directory is set as intended when loading files.

When Pyxel's init function is called, the current directory is changed to the same location as the script file. After that, files can be specified using relative paths. However, loading may fail if you try to open a file before calling init or if the current directory is changed after calling init.

How can I save application-specific data like high scores or game progress?

Pass the developer name (vendor_name) and application name (app_name) to the user_data_dir(vendor_name, app_name) function. It will create a directory suitable for data storage on the current platform and return its path. Use this directory to save and load your application's files.

Using Pyxel Tools

Can I try Pyxel without installing it?

With Pyxel Code Maker, you can create and run Pyxel apps in your browser. However, it does not support multi-file projects, so a local environment is recommended for full-scale development.

Pyxel Showcase lets you browse and run sample code and apps in your browser.

How do I publish my Pyxel app on the web?

There are three methods: Pyxel Web Launcher, app2html, and HTML Custom Elements. For details, see How to Use Pyxel for Web.

Can I change the palette colors in Pyxel Editor?

If you place a file with the same name but the .pyxpal extension in the same directory as the Pyxel resource file (.pyxres), Pyxel Editor will display the palette using those colors. Palette files can be created with the save_pal function, or manually as a text file with one RRGGBB hex color per line.

Migration Guide

How to migrate code to version 2.4

In Pyxel 2.4, the sound engine and MML syntax have been revamped.

To make your code compatible with version 2.4, please make the following changes:

  • Rename the waveform field of the Tone class to wavetable
  • Change the tick argument of the play and playm functions to sec (a float value in seconds)
  • Update code to handle the return value of the play_pos function, which is now (sound_index, sec)
  • Change the count argument of the save function in the Sound and Music classes to sec
  • If you need the playback duration of a sound, use the total_sec function of the Sound class
  • For the Sound class's mml function, use code that follows the new MML syntax (old syntax is auto-detected; the old_mml function is deprecated)
  • Change the excl_* option in the save and load functions to exclude_*
  • Remove the incl_* option from the save and load functions

For details on the new MML syntax, see "How do I use Pyxel MML?" above.

Licensing and Sponsorship

Can I use Pyxel for commercial purposes without the author's permission?

As long as you comply with the MIT License and clearly display the full text of the copyright and license in the source code or license file, you are free to sell or distribute your work without the author's permission. That said, Pyxel is developed by a single individual, so reaching out to the author or becoming a sponsor would be greatly appreciated.


Mml Commands (`docs/mml-commands.md`)

Pyxel MML Commands

This document was auto-generated from the Pyxel MML Commands web page, which also offers multilingual support.

Command Description
T Sets the tempo (BPM). Range: 1-. Default is 120.
Q <gate_percent> Sets the gate time as a percentage. Range: 0-100. 100 means the note is played with no gap, 0 means it is not played at all. Default is 80.
@ <tone> Sets the tone. Range: 0-3 (by default: 0:Triangle / 1:Square / 2:Pulse / 3:Noise). Default is 0.
V <vol> Sets the volume. Range: 0-127. Default is 100.
K <key_offset> Sets the transpose amount in semitones. 12 raises the pitch by one octave. Default is 0.
Y <offset_cents> Sets detune in cents. 100 raises by a semitone, -100 lowers by a semitone. Default is 0.
@ENV <slot> Switches the envelope (volume curve) slot. Range: 0-. 0 turns it off.
@ENV <slot> { init_vol, dur_ticks1, vol1, dur_ticks2, vol2, ... } Slot range: 1-. Sets and switches to the specified envelope slot. Slot 0 cannot be specified. Inside { }, specify "initial volume (once)", then repeat "duration (tick), volume (vol)". 1 tick is 1/48 of a quarter note. Example: @ENV1 { 30, 20, 100, 50, 0 }
@VIB <slot> Switches the vibrato (pitch modulation) slot. Range: 0-. 0 turns it off.
@VIB <slot> { delay_ticks, period_ticks, depth_cents } Slot range: 1-. Sets and switches to the specified vibrato slot. Slot 0 cannot be specified. Inside { }, specify "delay (tick), period (tick), depth (cent)". 1 tick is 1/48 of a quarter note. Example: @VIB1 { 24, 12, 100 }
@GLI <slot> Switches the glide (pitch slide) slot. Range: 0-. 0 turns it off.
@GLI <slot> { offset_cents, dur_ticks } Slot range: 1-. Sets and switches to the specified glide (pitch slide) slot. Slot 0 cannot be specified. Inside { }, specify "initial pitch offset (cent), time to return to 0 (tick)". 1 tick is 1/48 of a quarter note. Specifying * for each parameter automatically applies the pitch offset as the difference from the previous note and the return time as the playback duration of each note, respectively. Example: @GLI1 { -100, 24 }
O <oct> Sets the octave. Range: -1-9. O4's A is 440 Hz. Default is 4.
> Raises the octave by 1 (max 9).
< Lowers the octave by 1 (min -1).
L <len> Sets the default note/rest length. Range: 1-192. L4 is a quarter note, L8 is an eighth note, and L12 is an eighth note triplet. Default is 4.
C/D/E/F/G/A/B Plays the specified note. You can specify the length after the note, e.g., F16.
R Rest. Range: 1-192. You can specify the length after the rest, e.g., R8.
# Raises the note by a semitone.
+ Raises the note by a semitone.
- Lowers the note by a semitone.
. Dotted note/rest. Extends the length by half. Can be repeated for multiple dots.
& Tie/Slur. When connecting the same pitch, it ties the notes into one. When connecting different pitches, it plays them legato (no gap). You can also specify only the length, e.g., C4&16.
[ Start of repeat section.
] <count> End of repeat section. Count range: 1-. Repeats the section between [ and ] the specified number of times. If omitted, repeats infinitely. Nested repeats are supported.

Pyxres Format (`docs/pyxres-format.md`)

Pyxel Resource File Format (.pyxres)

This document describes the internal format of Pyxel resource files (.pyxres).

Overview

A .pyxres file is a ZIP archive containing a single TOML file named pyxel_resource.toml. All resource data โ€” images, tilemaps, sounds, and music โ€” is stored as human-readable text in TOML format.

An optional palette file (.pyxpal) can accompany the resource file to define a custom color palette.

File Structure

text
example.pyxres (ZIP archive)
โ””โ”€โ”€ pyxel_resource.toml
text
example.pyxpal (optional, same directory)

TOML Format

The pyxel_resource.toml file has the following top-level structure:

toml
format_version = 1

[[images]]
...

[[tilemaps]]
...

[[sounds]]
...

[[musics]]
...

The format_version field and all four section arrays (images, tilemaps, sounds, musics) are required. Empty fields inside an entry use empty arrays (e.g., notes = []), and a section intentionally skipped by save(..., exclude_*) is written as an empty array. A normal save writes the runtime banks (3 images, 8 tilemaps, 64 sounds, 8 musics); files with fewer entries are accepted on load.

Pyxel currently writes format_version = 1 for maximum backward compatibility. On load, files with format version up to 4 (the current maximum) are accepted. Files that contain the legacy archive layout (pyxel_resource/version + separate files) are detected and loaded with automatic conversion.

Images

Up to 3 image banks, each 256ร—256 pixels. Each pixel is a palette color index (u8, 0โ€“15 for the default palette; 0โ€“255 for the extended palette of up to 256 colors).

toml
[[images]]
width = 256
height = 256
data = [[0, 0, 10, 12, 12, 0, ...], [0, 7, 7, ...], ...]

All fields are required.

Field Type Description
width u32 Image width in pixels
height u32 Image height in pixels
data array of arrays of u8 2D pixel data, one sub-array per row. Each value is a color index

Compression: Trailing elements in each row that repeat the last distinct value are omitted. Trailing rows that are identical to the last distinct row are also omitted. When loading, omitted values are filled by repeating the last value.

For example, a row [0, 0, 5, 5, 5, 5] is stored as [0, 0, 5], and an image where the last 200 rows are all [0] stores only the first 56 rows plus one [0] row.

Tilemaps

Up to 8 tilemaps, each 256ร—256 tiles. Each tile references an 8ร—8 pixel region in an image bank.

toml
[[tilemaps]]
width = 256
height = 256
imgsrc = 0
data = [[10, 6, 11, 6, 12, 6, 0, 0, ...], ...]

All fields are required.

Field Type Description
width u32 Tilemap width in tiles
height u32 Tilemap height in tiles
imgsrc u32 Source image bank index (0โ€“2)
data array of arrays of u16 2D tile data in interleaved format (see below)

Each tile in the tilemap is a coordinate pair (tile_x, tile_y) (u16, u16) pointing to the position of the 8ร—8 tile in the source image bank. In the TOML data, these pairs are interleaved within each row: [tx0, ty0, tx1, ty1, ...], so each row has width ร— 2 elements.

For example, a tilemap row of 3 tiles referencing image positions (10, 6), (11, 6), and (12, 6) is stored as [10, 6, 11, 6, 12, 6].

The same trailing-value compression as images is applied.

Sounds

Up to 64 sounds. Each sound is a sequence of notes with per-note tone, volume, and effect settings.

toml
[[sounds]]
notes = [28, 28, 24, 19, -1, -1]
tones = [2]
volumes = [6]
effects = [2, 3, 3, 0]
speed = 25

All fields are required. Empty sounds use empty arrays (e.g., notes = []).

Field Type Description
notes array of i8 Note values. -1 = rest, 0 (C0) to 59 (B4)
tones array of u8 0 = Triangle, 1 = Square, 2 = Pulse, 3 = Noise
volumes array of u8 0 (silent) to 7 (max)
effects array of u8 0 = None, 1 = Slide, 2 = Vibrato, 3 = FadeOut, 4 = Half-FadeOut, 5 = Quarter-FadeOut
speed u16 Playback speed in ticks per note (1 tick = 1/120 second). Default: 30

The tones, volumes, and effects arrays are stored exactly as set on the sound and may be shorter than notes. During playback, values are read cyclically (index modulo array length), and an empty array falls back to the default: tone 0 (Triangle), volume 7, effect 0 (None).

Note mapping: Notes are encoded as base + octave ร— 12, where C=0, D=2, E=4, F=5, G=7, A=9, B=11, and octave ranges from 0 to 4. For example, C0=0, A4=57, B4=59.

MML-defined sounds: Sounds defined with Sound.mml() cannot be saved to .pyxres; only the notes, tones, volumes, effects, and speed fields are persisted. To preserve MML-based sounds, keep the MML strings in your source code and call sound.mml() at runtime.

Musics

Up to 8 music tracks. Each track arranges sounds across up to 4 channels for sequential playback.

toml
[[musics]]
seqs = [[0, 1], [2, 3], [4]]

The seqs field is required. Empty music uses an empty array (seqs = []).

Field Type Description
seqs array of arrays of u32 Sound sequences per channel. seqs[0] is channel 0, seqs[1] is channel 1, etc. Each value is a sound index (0โ€“63)

Trailing empty channels are omitted when saving.

Palette File (.pyxpal)

An optional text file with one RGB color per line in 6-digit hexadecimal format. The file uses the same base name as the .pyxres file (e.g., sample.pyxres โ†’ sample.pyxpal).

text
000000
2b335f
7e2072
19959c
...
Property Value
Default colors 16
Maximum colors 256
Format One RRGGBB hex value per line

If no .pyxpal file is present, the built-in default palette is used:

Index Color Hex
0 Black 000000
1 Navy 2b335f
2 Purple 7e2072
3 Green 19959c
4 Brown 8b4852
5 Dark Blue 395c98
6 Light Blue a9c1ff
7 White eeeeee
8 Red d4186c
9 Orange d38441
10 Yellow e9c35b
11 Lime 70c6a9
12 Cyan 7696de
13 Gray a3a3a3
14 Pink ff9798
15 Peach edc7b0

User Guide (`docs/user-guide.md`)

Pyxel User Guide

This document was auto-generated from the Pyxel User Guide web page, which also offers multilingual support.

Pyxel (/หˆpษชksษ™l/) is a retro game engine for Python. With simple specifications inspired by retro gaming consoles, such as displaying only 16 colors and supporting 4 sound channels, you can easily enjoy making pixel-art-style games.

Pyxel is open source under the MIT License and free to use. Let's start making retro games with Pyxel!

Also, this project is developed by one person, kept going by your GitHub stars. If you enjoy it, please give it a star!

Specifications

  • Runs on Windows, Mac, Linux, and Web
  • Programming in Python
  • Customizable screen size
  • 16-color palette
  • 3 256x256 image banks
  • 8 256x256 tilemaps
  • 4 channels with 64 definable sounds
  • 8 music tracks that can combine any sounds
  • Keyboard, mouse, and gamepad inputs
  • Image and sound editing tools
  • User-extensible colors, sound channels, and banks

Color Palette

GIMP palette file (.gpl)

How to Install

Windows / Mac / Linux

After installing Python 3 (version 3.11 or higher), run the following command:

sh
pip install -U pyxel

Note: On Windows, if installing Python using the installer from python.org, make sure to check Add python.exe to PATH to enable the pyxel command.

Web

The web version of Pyxel can be used without installation on PCs, smartphones, tablets, and other devices with a compatible browser.

The web-based development environment Pyxel Code Maker is ready to use simply by opening it in your browser.

For other usage, such as embedding Pyxel apps on your own site, please refer to How to Use Pyxel for Web.

VS Code

By adding the Pyxel extension to Visual Studio Code (VS Code), you can develop and run Pyxel apps without installing Python or Pyxel.

To add the Pyxel extension, search for "Pyxel" in the VS Code Extensions view and click the install button.

Basic Usage

Pyxel Command

Installing Pyxel adds the pyxel command. Specify a command name after pyxel to perform various operations.

Run it without arguments to see the list of available commands:

sh
pyxel
text
Pyxel, a retro game engine for Python
usage:
    pyxel run PYTHON_SCRIPT_FILE(.py)
    pyxel watch WATCH_DIR PYTHON_SCRIPT_FILE(.py)
    pyxel play PYXEL_APP_FILE(.pyxapp)
    pyxel edit [PYXEL_RESOURCE_FILE(.pyxres)]
    pyxel package APP_DIR STARTUP_SCRIPT_FILE(.py)
    pyxel app2exe PYXEL_APP_FILE(.pyxapp)
    pyxel app2html PYXEL_APP_FILE(.pyxapp)
    pyxel copy_examples

Try Examples

The following command copies Pyxel examples to the current directory:

sh
pyxel copy_examples

You can run examples locally with the following commands:

sh
# Run example in examples directory
cd pyxel_examples
pyxel run 01_hello_pyxel.py

# Run app in examples/apps directory
cd apps
pyxel play 30sec_of_daylight.pyxapp

Examples can also be viewed and run in the browser from Pyxel Showcase.

Creating Applications

Create a Program

In your Python script, import Pyxel, set the window size with init, and start the application with run.

python
import pyxel

pyxel.init(160, 120)


def update():
    if pyxel.btnp(pyxel.KEY_Q):
        pyxel.quit()


def draw():
    pyxel.cls(0)
    pyxel.rect(10, 10, 20, 20, 11)


pyxel.run(update, draw)

The arguments of the run function are the update function, which processes frame updates, and the draw function, which handles screen drawing.

In an actual application, it is recommended to wrap Pyxel code in a class, as shown below:

python
import pyxel


class App:
    def __init__(self):
        pyxel.init(160, 120)
        self.x = 0
        pyxel.run(self.update, self.draw)

    def update(self):
        self.x = (self.x + 1) % pyxel.width

    def draw(self):
        pyxel.cls(0)
        pyxel.rect(self.x, 0, 8, 8, 9)


App()

For creating simple graphics without animation, you can use the show function to simplify your code.

python
import pyxel

pyxel.init(120, 120)
pyxel.cls(1)
pyxel.circb(60, 60, 40, 7)
pyxel.show()

Run a Program

A created script can be executed using the python command:

sh
python PYTHON_SCRIPT_FILE

It can also be run with the pyxel run command:

sh
pyxel run PYTHON_SCRIPT_FILE

Additionally, the pyxel watch command monitors changes in a specified directory and automatically re-runs the program when changes are detected:

sh
pyxel watch WATCH_DIR PYTHON_SCRIPT_FILE

Stop directory monitoring by pressing Ctrl(Cmd)+C.

Special Key Controls

The following special key actions are available while a Pyxel application is running:

Shortcut Action
Esc Quit the application
Alt(Option)+R or A+B+X+Y+BACK on gamepad Reset the application
Alt(Option)+1 Save the screenshot to the desktop
Alt(Option)+2 Reset the recording start time of the screen capture video
Alt(Option)+3 Save a screen capture video to the desktop (up to 10 seconds)
Alt(Option)+8 or A+B+X+Y+DL on gamepad Toggle screen scaling between maximum and integer
Alt(Option)+9 or A+B+X+Y+DR on gamepad Switch between screen modes (Crisp/Smooth/Retro)
Alt(Option)+0 or A+B+X+Y+DU on gamepad Toggle the performance monitor (FPS/update time/draw time)
Alt(Option)+Enter or A+B+X+Y+DD on gamepad Toggle fullscreen
Shift+Alt(Option)+1/2/3 Save image bank 0, 1, or 2 to the desktop
Shift+Alt(Option)+0 Save the current color palette to the desktop

Creating Resources

Pyxel Editor

Pyxel Editor creates images and sounds used in a Pyxel application.
The created data is saved as a Pyxel resource file (.pyxres).

For detailed usage instructions, see the Pyxel Editor Manual.

Other Creation Methods

Pyxel images and tilemaps can also be created using the following methods:

  • Create images or tilemaps from lists of strings with the Image.set or Tilemap.set functions
  • Load palette-ready image files (PNG/GIF/JPEG) with the Image.load function

Pyxel sounds and music can also be created using the following method:

  • Create them from strings with the Sound.set or Music.set functions

Refer to the API reference for the use of these functions.

Distributing Applications

Pyxel supports a cross-platform distribution format called a Pyxel application file.

Create a Pyxel application file (.pyxapp) with the pyxel package command:

sh
pyxel package APP_DIR STARTUP_SCRIPT_FILE

If you need to include resources or additional modules, place them in the application directory.

Metadata can be displayed at runtime by specifying it in the following format within the startup script. Fields other than title and author are optional.

python
# title: Pyxel Platformer
# author: Takashi Kitao
# desc: A Pyxel platformer example
# site: https://github.com/kitao/pyxel
# license: MIT
# version: 1.0

The created application file can be run using the pyxel play command:

sh
pyxel play PYXEL_APP_FILE

A Pyxel application file can also be converted to an executable or an HTML file using the pyxel app2exe or pyxel app2html commands.

API Reference

A complete list of Pyxel APIs is available at Pyxel API Reference.

Pyxel also includes advanced APIs that require specialized knowledge. You can view them by checking the "Advanced" checkbox on the reference page.

If you're confident in your skills, try using the Advanced API to create truly amazing works!

Documentation

Examples & Tools

Other Information

How to Contribute

Submitting Issues

Use the Issue Tracker to submit bug reports and feature or enhancement requests. Before submitting a new issue, make sure there are no similar open issues.

Functional Testing

Anyone who manually tests the code and reports bugs or suggestions for enhancements in the Issue Tracker is very welcome!

Submitting Pull Requests

Patches and fixes are accepted in the form of pull requests (PRs). Make sure that the issue the pull request addresses is open in the Issue Tracker.

Submitting a pull request implies that you agree to license your contribution under the MIT License.

License

Pyxel is licensed under the MIT License. It can be reused in proprietary software, provided that all copies of the software or its substantial portions include a copy of the MIT License terms and a copyright notice.

Recruiting Sponsors

Pyxel is looking for sponsors on GitHub Sponsors. Please consider sponsoring Pyxel to support its continued maintenance and feature development. As a benefit, sponsors can consult directly with the Pyxel developer. For more details, please visit here.


Web Usage (`docs/web-usage.md`)

How to Use Pyxel for Web

This document was auto-generated from the How to Use Pyxel for Web web page, which also offers multilingual support.

Pyxel for Web is a version of Pyxel that runs in web browsers using WebAssembly technology. No installation of Python or Pyxel is required, and it is accessible from PCs, smartphones, and tablets.

Ways to Use Pyxel for Web

There are four ways to use Pyxel for Web.

Method Description
Pyxel Code Maker An online development environment for writing and running code in the browser
Pyxel Web Launcher Run a GitHub repository in the browser by specifying its URL
app2html Command Convert a Pyxel application file (.pyxapp) to an HTML file
HTML Custom Elements Add HTML custom elements to run Pyxel apps on any HTML page

Pyxel Code Maker

Pyxel Code Maker is an online development environment that lets you develop and run Pyxel apps in the browser without installing Python or Pyxel. Just open it in your browser with no setup required, making it a great way to try Pyxel.

For detailed usage, see the Pyxel Code Maker Manual.

Pyxel Web Launcher

Pyxel Web Launcher is a tool that runs Python scripts and Pyxel apps (.pyxapp) published on GitHub simply by specifying their URL.

Launch URLs can be created on the Pyxel Web Launcher page by entering the required information, or manually using the format below. Note that Pyxel Web Launcher always uses the latest version of Pyxel.

URL Format

text
https://kitao.github.io/pyxel/web/launcher/?<command>=<username>/<repository>/<branch>/<path>/<filename without extension>

Commands

Command Action
run Run a Python script (.py)
play Run a Pyxel app (.pyxapp)
edit Edit a resource file (.pyxres) in Pyxel Editor

URL Examples

To run src/scenes/title.py in user taro's repository my_repo, branch main:

text
https://kitao.github.io/pyxel/web/launcher/?run=taro/my_repo/main/src/scenes/title

To run dist/games/shooter.pyxapp in the same repository:

text
https://kitao.github.io/pyxel/web/launcher/?play=taro/my_repo/main/dist/games/shooter

Additional Parameters

The following additional parameters can be specified for the run and play commands.

Parameter Description
gamepad=enabled Display a virtual gamepad on touch devices (smartphones and tablets)

Example URL with additional parameters for the run command:

text
https://kitao.github.io/pyxel/web/launcher/?run=taro/my_repo/main/src/scenes/title&gamepad=enabled

The edit command has the editor parameter to specify which editor to launch: image, tilemap, sound, music

Example URL for the edit command:

text
https://kitao.github.io/pyxel/web/launcher/?edit=taro/my_repo/main/assets/shooter&editor=tilemap

Apps consisting of multiple Python files load faster when bundled into a .pyxapp file with pyxel package and run with play.

app2html Command

The pyxel app2html command converts a Pyxel application file (.pyxapp) into a standalone HTML file.

sh
pyxel app2html your_app.pyxapp

All code and resource data are embedded in the HTML, so the generated file can be published simply by distributing it.

The Pyxel version is pinned to the one used at conversion time, so future updates will not affect behavior.

The virtual gamepad is enabled by default and automatically displayed on touch devices. To disable it, remove gamepad: "enabled" from the generated HTML.

HTML Custom Elements

By adding HTML custom elements provided by Pyxel to an HTML file, you can run Pyxel apps on any HTML page.

Setup

Add the following script tag to your HTML. If no version is specified, the latest version of Pyxel is always used.

html
<script src="https://cdn.jsdelivr.net/gh/kitao/pyxel/wasm/pyxel.js"></script>

You can pin the Pyxel version by specifying a version number after @.

html
<script src="https://cdn.jsdelivr.net/gh/kitao/[email protected]/wasm/pyxel.js"></script>

Loading this script makes three HTML custom elements available, corresponding to Pyxel's run, play, and edit commands: pyxel-run, pyxel-play, and pyxel-edit.

pyxel-run

A tag for running Python scripts.

To run Python code directly, write the code in the script attribute.

html
<pyxel-run
  script="
import pyxel
pyxel.init(200, 150)
pyxel.cls(8)
pyxel.line(20, 20, 180, 130, 7)
pyxel.show()
"
></pyxel-run>

To load an external file, specify root and name. root is the base directory for file lookup, and name is the file path.

html
<pyxel-run root="." name="test.py"></pyxel-run>

If root is the current directory (root="."), the root attribute can be omitted.

pyxel-play

A tag for running Pyxel applications (.pyxapp).

A URL can also be specified for root.

html
<pyxel-play
  root="https://cdn.jsdelivr.net/gh/kitao/pyxel/python/pyxel/examples/apps"
  name="megaball.pyxapp"
></pyxel-play>

pyxel-edit

A tag for editing resource files (.pyxres) in Pyxel Editor.

Use the editor attribute to specify which editor to launch.

html
<pyxel-edit root="assets" name="shooter.pyxres" editor="image"></pyxel-edit>

Common Attributes

The following common attributes are available for pyxel-run and pyxel-play.

Attribute Description
gamepad="enabled" Enable the virtual gamepad (automatically displayed on touch devices)

Customizing Screen Display

By default, the Pyxel screen is displayed across the entire page. Place a `` tag with id="pyxel-screen" in the HTML to render the screen inside that element, allowing you to adjust its position and size.

Running in a Local Environment

When using HTML custom elements that load external files, a server is required because browser security restrictions prevent opening local files directly.

If you have a Python environment, you can start a simple server with the following command.

sh
python -m http.server
# Use python3 on macOS and Linux

After starting the server, access http://localhost:8000/test.html in your browser.


--- METRICS ---