Pyxel Retro Game Engine for Python

repository·main·Indexed 12 days ago

https://github.com/kitao/pyxel

A retro game engine for Python designed for creating pixel-art-style games. Pyxel uses simplified specifications inspired by retro consoles, including a fixed 16-color palette and support for up to 4 simultaneous sound channels. Version 2.9.9 includes comprehensive APIs for audio playback (pyxel.play, pyxel.playm), input handling (btn, btnp, btnr), graphics constants, and optimized math and noise functions.

Tokens
37.8K
Snippets
136
Records
204
Agent score
94%

What's inside Pyxel

  1. Overview of Pyxel

    main

    Pyxel is a retro game engine for Python designed for creating pixel-art-style games. It uses simple specifications inspired by retro gaming consoles to limit scope and ease development, such as:

    • A fixed palette of 16 colors.
    • Support for up to 4 simultaneous sound channels.
    • Pixel-art aesthetic.

    Pyxel is open source under the MIT License.

  2. Overview of Pyxel Editor modes

    main

    The Pyxel Editor consists of four specialized editors that can be switched using buttons at the top of the screen:

    • Image Editor: Used for editing image banks (sprites and tiles).
    • Tilemap Editor: Used to arrange image bank images as tiles to compose maps.
    • Sound Editor: Used to edit individual sounds for effects and melodies.
    • Music Editor: Used to arrange sounds in playback order to compose BGM.
  3. Documentation and Commenting rules

    main

    Pyxel maintains high standards for code documentation and comments.

    Commenting Guidelines:

    • Language: All comments must be in English.
    • Intent: Comments should only exist to add intent that is not obvious from the code (e.g., explaining a bit-twiddling operation or a non-local invariant). Avoid tautologies like i += 1 # increment i.
    • Format: Use label-style comments (e.g., // Constructors) without a trailing period. For multi-sentence comments, punctuate every sentence.
    • Docstrings: Documentation comments (Rust ///, Python docstrings, JSDoc) are prohibited everywhere except in python/pyxel/__init__.pyi. The .pyi docstrings are automatically regenerated via scripts/generate_pyi_docstrings and should not be hand-edited.

    Prose Documentation:

    • Technical writing should follow the standard conventions of the target language.
    • For Japanese documentation, alphanumeric tokens must be separated from Japanese characters by a single half-width space (e.g., 「Web 版 Pyxel」).
  4. Performance standards for hot paths

    main

    In Pyxel, certain operations are identified as 'hot paths' where performance is critical. Developers must eliminate avoidable costs in these areas.

    Identified Hot Paths:

    • 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

    Optimization Rules:

    • On hot paths, avoid idiomatic patterns that incur measurable costs, such as per-frame heap allocations (Vec::new, format!, Box::new), avoidable copies, type conversions, or missed SIMD/inlining opportunities.
    • Outside hot paths, prioritize idiomatic and readable code (e.g., using standard for loops) over micro-optimizations.
  5. Naming and consistency standards

    main

    Pyxel follows strict naming and consistency rules to maintain a unified API across different languages (Rust, Python, Web).

    Key Naming Principles:

    • Symmetry: A symbol referenced from multiple files must use the same base name (e.g., a function name in pyxel-core must match its name in the Python .pyi stub). If variants are needed, use suffixes (e.g., gen_bgm_mml) rather than renaming.
    • Avoid Stuttering: Do not repeat the owner or type in a name (e.g., avoid Canvas.drawCanvas()).
    • Authoritative Surface: When mirrors disagree, the authoritative public surface wins. Between a Python binding and its .pyi stub, the .pyi is authoritative.
    • Exception Groups:
      • crates/pyxel-binding/src/*_wrapper.rs: These files intentionally mirror the Python API (using snake_case and Pyxel-historical names like blt or cls) rather than following Rust conventions.
      • SDL2 call sites: Preserve C-style names for recognizability.
      • Samples (python/pyxel/examples/): May use local names to improve readability for learners.
  6. Understand the difference between `update` and `draw`

    main

    Pyxel separates logic and rendering into two distinct functions:

    • update: Called every frame to handle game logic.
    • draw: Responsible for rendering. This function may be skipped if the processing time exceeds the allowable limit.

    This design ensures that even if rendering load or OS interrupts increase, the game logic (via update) remains consistent, enabling smoother animation.

  7. Understand the artifact dependency graph in manifest.tsv

    main

    The manifest.tsv file tracks the dependency graph of the audit artifacts. The graph is acyclic and follows these specific 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 (and current-diff.patch for change-driven inventories).
    • 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.
  8. Requirements for substantive evidence in audits

    main

    Evidence provided in an audit is only considered substantive if it meets the following criteria:

    • Names the exact subject and surface being inspected.
    • Explains why the verdict follows from the rule (rather than just providing an example).
    • Records measured or mechanical support where the rule requires it.
    • Names peers or dependencies for relation verdicts.
    • Avoids bare phrases like no issue, checked, or matches policy.

    Important Distinction: Search output, inventories, formatter success, test success, finding counts, and reviewer summaries are considered probes or command evidence, not findings. A finding must identify the current source or artifact row, criterion, actionable defect, and relevant peer or dependency evidence.

  9. Understand the Pyxel Resource File Format (.pyxres)

    main

    A .pyxres file is a ZIP archive containing a single TOML file named pyxel_resource.toml. This file stores all game assets: images, tilemaps, sounds, and music.

    File Structure:

    example.pyxres (ZIP archive)
    └── pyxel_resource.toml

    An optional palette file (.pyxpal) can be placed in the same directory to define a custom color palette.

  10. Understand the Coding Policy Audit Procedure

    main

    The Coding Policy Audit Procedure is an execution protocol used to prove that docs/coding-policy.md has been checked completely and evenly. It is not a set of standards itself, but a method to verify compliance with the standards defined in the policy.

    Key Principles:

    • No Sampling: Every in-scope file, criterion, and relation must be represented by an artifact row.
    • No Cherry-picking: A fix is only complete once all comparable subjects and affected relations are checked to the same depth.
    • No Majority Rule: Compliance is determined by the explicit policy or the language's established idiom, not by how much existing code deviates from it.
    • No Summary-only Evidence: Counts or success messages are insufficient; every verdict must be tied to a specific inspection row.
    • Frozen Target: The audit target (files, policy, and procedure) must remain immutable during a run. If the target changes, the current run must be preserved and a new one started.
  11. Difference between `update` and `draw` functions

    main
    In Pyxel, the update function is called every frame. However, the draw function may be skipped if the processing time exceeds the allowed limit. This design helps mitigate the impact of rendering load and OS interrupts, ensuring smoother animations.
  12. Use the Pyxel VS Code Extension

    main
    You can develop and run Pyxel applications within Visual Studio Code without manually installing Python or Pyxel by using the official extension. Search for "Pyxel" in the VS Code Extensions view and install the one provided by kitao.pyxel-vscode.