コードのルール

大原則 ── スタンドアロン Pyxel として動くこと

Code & Magic で動かすコードは、Code & Magic を離れても Pyxel ゲームとして成立する ことを基本的な大原則としています。
そのため、Python 標準ライブラリであっても他のプログラムを実行するようなものや、ウェブブラウザの機能に依存したコードは動かせません。

これは、Pyxel ゲームを作りに来た冒険者が、Pyxel ゲームとして書き、Pyxel ゲームとして遊ぶ ── そのためのルールです。

使えるライブラリ(許可リスト)

Code & Magic で利用できる Python ライブラリを以下に挙げます。
コードを動かすたびに、含まれている import が自動チェックされます。

Pyxel

  • pyxel および子モジュール

Python 言語機能

  • __future__

数学・データ

  • math, random, statistics
  • dataclasses, typing, collections, enum, abc
  • itertools, functools, operator, copy
  • fractions, decimal, numbers

  • colorsys ── HSV / RGB / YIQ などの色変換。パレットアニメや色生成に。

文字列・データ形式

  • io, re, string, struct
  • base64, binascii, hashlib, zlib
  • textwrap, unicodedata

設定・データファイル

  • json, csv
  • tomllib(読み込みのみ。書き込みは Pyodide ビルトインの tomli-w を使う)

ファイル I/O

  • pathlib, tempfile

ゲームの進行状況やスコアを保存したいときは、Pyxel 標準の pyxel.user_data_dir() が返すフォルダにファイルを書き込みます。中身はあなた(プレイヤー)のアカウントに保存され、次に遊ぶときに読み戻せます。使い方はセーブデータのガイドを参照してください。

一時的な作業ファイル(保存しなくてよいもの)が必要なら、tempfile モジュールか /tmp パス配下を使えます。こちらはゲーム実行中の作業領域として読み書きできますが、リロードや別セッションでは内容が引き継がれません(永続化はされません)。

ファイル操作で os を使いたくなった場合は、代わりに pathlib を使ってください。

時刻・日付

  • time, datetime, calendar

データ構造

  • array, heapq, bisect

識別子・乱数

  • uuid ── セーブデータ ID や一意キーを作るときに。

その他

  • contextlib

Pyodide ビルトインパッケージ

ブラウザの Pyxel は内部で Pyodide 上で動いており、特に有用なパッケージはコードに import を書くだけで自動でロードされます。設定や UI は不要です。

パッケージサイズ目安主な用途コードでの import
numpy約 2.7 MB行列・procedural 生成・AI/アルゴリズム題材import numpy
pillow約 1.0 MB外部 PNG → Pyxel 画像、procedural スプライトfrom PIL import Image
pyyaml約 0.1 MBレベルデータや設定ファイル(手で書きやすい)import yaml
tomli-w約 6 KBTOML 書き込み(読み込みは標準の tomllib で OK)import tomli_w
jinja2約 0.14 MBノベルゲーム風のテキストテンプレートfrom jinja2 import Template

初回プレイ時にこれらのパッケージは jsdelivr CDN から fetch されるため、起動が数秒遅くなることがあります。2 回目以降はブラウザキャッシュにより素早く起動します。

使われていないパッケージはロードされません(import numpy を書かなければ numpy は fetch されません)。

自分のプロジェクト内の他ファイル

魔導書のページ(プロジェクト内の他の .py ファイル)への from xxx import yyy も通常どおり使えます。

音声・画像ファイルを使う(メディアアセット)

自作の 音声(.ogg画像(.png を魔導書に持ち込めます。羽根筆のゆりかごのファイル追加メニュー 「メディアをアップロード」 から、パソコンのファイルを選んで登録してください(1 ファイル最大 3MB)。

登録したファイルは、Pyxel の標準機能でそのまま読み込めます(from js import などは不要 ── スタンドアロン Pyxel と同じ書き方です):

import pyxel


class App:
    def __init__(self):
        pyxel.init(160, 120)

        # パレットを読み込む(アップロード時に palette.pyxpal に作られます)。最初に1回だけ。
        pyxel.load_pal("palette.pyxpal")

        # 画像を読み込む(あとで draw から使えるよう self に持たせます)
        self.bg = pyxel.Image.from_image("background.png")

        # 音声をサウンド枠に読み込んで BGM としてループ再生
        pyxel.sounds[0].pcm("whale.ogg")
        pyxel.channels[0].gain = 0.8   # 音量(既定 0.125)
        pyxel.play(0, 0, loop=True)

        pyxel.run(self.update, self.draw)

    def update(self):
        pass

    def draw(self):
        # 画像を表示する
        pyxel.blt(0, 0, self.bg, 0, 0, self.bg.width, self.bg.height)


App()
  • 画像はパレットに合わせて表示されます。Pyxel は画像の色を「いま読み込んでいるパレット」の中で一番近い色に置きかえて表示するため、パレットが合っていないと色がずれます。アップロードのとき 「画像の色をパレットにまとめる」 にチェックしておくと、palette.pyxpal という共有パレット1枚にその画像の色が追加されます(Pyxel 標準16色も入っています)。作品のはじめで pyxel.load_pal("palette.pyxpal")1回だけ呼べば、入れた画像が全部そのままの色で出ます。
    • 画像を2枚3枚と足しても、色は同じ palette.pyxpal にまとまります(同じ色は共有)。パレットを画像ごとに切り替える必要はありません。
  • 音声は OGG のみです。MP3 は Pyxel が再生できないので、あらかじめ OGG に変換してください(例: ffmpeg -i in.mp3 -c:a libvorbis -q:a 5 out.ogg)。音質のロスを避けるため 22.05kHz への変換が推奨です。
  • pcm() はサウンド枠 1 つとチャンネル 1 つを使います。Pyxel は同時 4 チャンネルなので、録音音声の BGM とチップチューンの効果音を混ぜて鳴らせます。
  • 効果音や単純な BGM は、Pyxel の音楽エディタ(チップチューン)の方が軽く滑らかにループします。録音音声・環境音など、チップチューンで作れないものに OGG を使うのがおすすめです。

使えないもの(よくある例)

許可リストに無いものは自動的にブロックされます。代表的な例:

カテゴリなぜ
JS interopfrom js import ..., import pyodideスタンドアロン Pyxel では存在しない
OS 操作import os, import sys, import subprocessos.system() / os.popen() / os.exec*() などシェル・外部コマンドを実行する経路を含むため禁止。ファイル操作は pathlib で代替
ネットワークimport socket, import urllib, import requestsCode & Magic で動くコードからの外部通信は禁止
低レベル・並行import ctypes, import threading, import multiprocessingゲームには不要、escape vector
動的 importimport importlib, __import__()ランタイムのサンドボックス境界をすり抜ける手段になる

加えて、コードの中で別のコードを動かす仕組み ── eval() / exec() / compile() / getattr(__builtins__, ...) も使えません。書かれているソースを読めば、その作品の全挙動が予測できる状態を保つためです。

どこでチェックが走る?

許可リスト・動的実行のチェックは コードを実行するたび に行われます。具体的には:

  1. エンコーディアのワンダー攻略中の実行 ── 穴を埋めたコードや書き換えたコードを動かす瞬間
  2. 羽根筆のゆりかごの「動かしてみる」 ── あなたが書いた魔導書を試走する瞬間
  3. クリスタル化の前のプレビュー(スクショ撮影前) ── 公開申請の最初の段階
  4. GitHub の黒い魔導書を試走するとき ── 取り込んだ外部コードに対して

違反があると行番号付きのエラーが表示され、コードは動きません。

すでに公開されている作品をプレイするとき(魔法研究会の作品再生、共有 URL 経由のプレイ等)は、これらのチェックは走りません。

困ったとき

  • 使いたいライブラリが許可リストに無い → Code & Magic の運営にお知らせください。スタンドアロン Pyxel と互換で、安全に使えるものは追加を検討します。
  • 既に公開している作品が新しいチェックに引っかかる → 既存の公開作品はそのまま遊べます。再びクリスタル化(編集して再公開)するときに新しい基準が適用されます。

関連記事