ビルド手順
GBC ROM(MBC5 / ROM 128 KB / セーブなし / CGB 専用)のビルド環境と手順。
前提ツールの導入
RGBDS 1.0.3(rgbasm / rgblink / rgbfix / rgbgfx)と、E2E テスト用の Python 3.12 環境(uv 管理、PyBoy 2.7.0)を使う。
brew install rgbds
rgbasm --version
# rgbasm v1.0.3⚠ RGBDS のバージョンは 1.0.3 に固定である。 tools/test_build.py::test_rgbds_version_is_pinned と tools/check_conventions.sh の両方が rgbasm --version を検査するので、別バージョンではテストが落ちる。
依存関係を初回だけ導入する:
uv venv --python 3.12 .venv
uv pip install --python .venv -r tests/requirements.txttests/requirements.txt は pyboy==2.7.0 / pytest / Pillow を固定する。tools/requirements.txt(numpy / Pillow)はオフラインの減色ツール tools/quantize_gbc.py 専用で、ROM のビルドにも make test / make e2e にも要らない(docs/design/assets.md §6.1 / §8)。
ビルド
make # build/aidopagaki.gbc(製品 ROM)を生成
make debug # build/aidopagaki-debug.gbc(-D DEBUG=1 -D DEBUG_MENU=1)
make nowave # build/aidopagaki-nowave.gbc(-D DEBUG=1 -D DRUM_USE_WAVE=0 の A/B ビルド)
make test # all に加え tools の unittest と make lint
make e2e # all + debug + nowave に加え、PyBoy を使う tests/ の E2E(timeout 300s)
make lint # tools/check_conventions.sh のみ
make run # SameBoy で起動(open -a SameBoy build/aidopagaki.gbc)
make all # make と同じ(デフォルトターゲット)
make clean # build/ を削除⚠ NES 版の make hex に相当するターゲットは GB 版の Makefile にはない。ヘッダの確認は本書の hex ダンプ、または xxd -s 0x130 -l 0x20 build/aidopagaki.gbc を直接使う。
ビルドの成否は必ず exit code で確認する。 make が通っても make debug / make test / make e2e が個別に失敗しうる。
生成物(実測: 2026-09-03、make clean && make && make debug の直後)
| ファイル | バイト数 | 内容 |
|---|---|---|
build/aidopagaki.gbc | 131,072 バイト(128 KiB) | 製品 ROM |
build/aidopagaki-debug.gbc | 131,072 バイト(128 KiB) | DEBUG ビルド。src/link.ld が共通なのでサイズは製品版と同一 |
build/aidopagaki-nowave.gbc | 131,072 バイト(128 KiB) | ドラムが CH3 を借用しない A/B ビルド |
build/aidopagaki.map / .sym | — | リンカマップ・シンボル(ROM/RAM アドレスの参照元) |
build/main.o | — | rgbasm のオブジェクト |
build/art/*.2bpp / *.tilemap / *.attrmap | — | 一枚絵 5 枚を rgbgfx が並べ替えた中間生成物 |
3 本の ROM がすべて 131,072 バイトになるのは、src/link.ld が ROM0 + ROMX 7 バンクの計 8 バンクを固定で確保し、rgbfix -p 0xFF が末尾までパディングするためである。ビルド構成(DEBUG / DEBUG_MENU / DRUM_USE_WAVE)はサイズを変えない。
ROM の実使用量(build/aidopagaki.map の ROM0 / ROMX の bytes used を合計、2026-09-03 時点・issue #2〜#16 をすべてマージ済み):
| 項目 | 値 |
|---|---|
| 総容量 | 131,072 バイト(8 バンク) |
| 空き合計 | 70,156 バイト(ROM0 4,679 + ROMX 65,477) |
| 実使用 | 60,916 バイト(ROM0 11,705 + ROMX 49,211。59.5 KiB、46.5 %) |
⚠ これは全 issue をマージした完成時点の実測である。内訳と各シーンの予算は docs/design/architecture.md §4.7 の「最終実測」表を正典とする。
src/*_data.inc(スプライト・パレット・BG・ノーツ・判定文字フォント・かな・テキスト・BGM・譜面)と assets/*.2bpp / *.tilemap / *.attrmap は tools/gen_*.py が Makefile 経由で生成する。手で編集しない。 ⚠ 生成対象の一覧を本書に個別列挙しない。 NES 版の docs/build.md が build/hello.nes と書いたまま Makefile のデフォルトターゲット変更に追随できなかった(issue #17 の背景)ので、依存関係は Makefile の ASM_DEPS を正とし、本書は Makefile と tools/test_docs.py で機械的に突き合わせる。
テスト
make test # unittest + lint
make e2e # PyBoy E2E
.venv/bin/python -m unittest discover -s tools # アセット・静的解析だけ個別実行
.venv/bin/python -m pytest tests -q # PyBoy E2E だけ個別実行tools/ に 20 件、tests/ に 17 件のテストモジュールがある(2026-09-03 時点。unittest 330 件 / pytest 317 件)。make lint は tools/check_conventions.sh の 8 ゲート(RGBDS バージョン / テスト内の生アドレス / gb/ サブフォルダ禁止 / HDMA5 の配置 / ei の直後 nop / wFlowState の単一書込み / hardware.inc の SHA-256 / APU 直書き禁止)を通す。
ROM ヘッダの期待値
build/aidopagaki.gbc を実測した hex ダンプ(xxd -s 0x130 -l 0x20 build/aidopagaki.gbc、2026-09-03):
00000130: bbb9 333e 4149 444f 5041 4741 4b49 0041 ..3>AIDOPAGAKI.A
00000140: 4450 4ac0 4145 0019 0200 0033 006a 7191 DPJ.AE.....3.jq.バイト単位の注釈:
| アドレス | バイト数 | 値(hex) | 意味 |
|---|---|---|---|
$0104-$0133 | 48 | Nintendo ロゴ(固定) | 末尾 4 バイト BB B9 33 3E だけが上のダンプに写っている |
$0134-$013E | 11 | 41 49 44 4F 50 41 47 41 4B 49 00 | タイトル "AIDOPAGAKI"(10 文字)+ 終端 $00。rgbfix -t "AIDOPAGAKI" |
$013F-$0142 | 4 | 41 44 50 4A | メーカーコード "ADPJ"。rgbfix -i "ADPJ" |
$0143 | 1 | C0 | CGB フラグ = CGB 専用(DMG では起動しない)。rgbfix -C |
$0144-$0145 | 2 | 41 45 | 新ライセンシーコード "AE"。rgbfix -k "AE" |
$0146 | 1 | 00 | SGB フラグ = 非対応 |
$0147 | 1 | 19 | カートリッジタイプ = MBC5(RAM なし・バッテリなし)。rgbfix -m 0x19 |
$0148 | 1 | 02 | ROM サイズ = 128 KiB(8 バンク)。実ファイルサイズ 131,072 バイトと一致する |
$0149 | 1 | 00 | RAM サイズ = なし(セーブなし) |
$014A | 1 | 00 | 販売地域コード = 日本 |
$014B | 1 | 33 | 旧ライセンシーコード $33 = 新ライセンシーコードを使う印。rgbfix -l 0x33 |
$014C | 1 | 00 | マスク ROM バージョン = 0 |
$014D | 1 | 6A | ヘッダチェックサム。rgbfix -v が算出する |
$014E-$014F | 2 | 71 91 | グローバルチェックサム。rgbfix -v が算出する |
rgbfix の実行コマンド(Makefile。3 本の ROM で共通):
rgbfix -v -C -m 0x19 -p 0xFF -t "AIDOPAGAKI" -i "ADPJ" -k "AE" -l 0x33 build/aidopagaki.gbc⚠ $014E-$014F のグローバルチェックサムは ROM 全体の総和なので、ビルド構成ごとに違う。 上は製品 ROM の値で、build/aidopagaki-debug.gbc は 44 E0 になる。$0143 / $0147 / $0148 を含む $0143-$014D は 3 本とも同一である。
-v がヘッダ/グローバルチェックサムを計算して書き込むため、ヘッダが壊れていれば rgbfix 自体が非 0 で終了する。
実行
SameBoy(make run)
make run # open -a SameBoy build/aidopagaki.gbcSameBoy.app がインストールされている前提。Makefile は open -a SameBoy 固定で、環境変数による切替えを持たない。
mGBA(手動確認の代替)
Makefile に配線がないので、GUI から build/aidopagaki.gbc を直接開く。CGB 専用 ROM($0143 = $C0)なので、mGBA 側のモデル設定は GBC / CGB を選ぶこと。
PyBoy(E2E ハーネス)
make e2e が tests/harness.py 経由で製品 ROM・DEBUG ROM・nowave ROM を読み込む。シナリオと不変条件の設計は docs/design/e2e.md を参照。
構成
src/ # RGBDS アセンブリ(main.asm がエントリ)+ constants.inc / ram.inc / link.ld
src/*_data.inc # tools/gen_*.py の生成データ(コミットする。手編集禁止)
assets/ # 2bpp / tilemap / attrmap、一枚絵 PNG + .gbcpal、譜面・BGM の JSON
tools/ # アセット生成・静的解析(unittest 20 モジュール / 330 件)
tests/ # PyBoy E2E ハーネスとシナリオ(pytest 17 モジュール / 317 件)
docs/ # ドキュメントサイト(VitePress)+ 仕様書・設計書・手順書
manual-site/ # 説明書 LP の独立サイト設定(本文は docs/manual/parts/lp.md)
build/ # 生成物(git 管理外)備考(倍速モードと MBC5)
- CGB 倍速モード(
KEY1)を起動時から常時 ON にする(docs/design/architecture.md§1 D1)。通常速では VBlank ISR が 1 フレームの予算(4,560 dots)を超えて破綻するため、倍速が前提の設計になっている。 - MBC5 を採用しているのは、バンクを増やすときにコード変更が要らないためである。
$0148を書き換えるだけで 256 KB まで拡張できる(docs/design/architecture.md§2.1)。 - カートリッジタイプは RAM・バッテリともになし(
$0147 = $19)。セーブ機能はない(docs/spec/aidopagaki-gb-design.md§13 S4。追加するならヘッダ 2 バイト$0147 = $1B/$0149 = $02の変更になる)。 - 実機で動かす手順は
docs/cart-mod.md(カートリッジ改造)とdocs/writer.md(フラッシュ書込み)を参照。