Chromaticがようやく届いたので、Webで作っていた「ゆうあどろっぷ」を、手元の本体でも遊べるようにしました。Codexと相談しながら、ゲームボーイカラー用に作り直した「ゆうあどろっぷ GB版」です。

今回使った機材は、通常版のChromatic、付属のテトリス、手持ちのMacとUSB-Cケーブル。EverDriveやmicroSD、専用の書き込み機は買い足していません。
できあがったゲームは、付属テトリスのカートリッジ内に書き込みました。 テトリスのゲームデータをバックアップしてから、そのカートリッジを自作ゲーム用に書き換えています。Chromatic本体にゲームをインストールしたわけではありません。
途中で「追加のカートリッジが必要?」「USB-Cでは何をしている?」「GitHubから入れたものは何?」と、自分でも仕組みが分からなくなりました。この記事では、実際に使った道具とデータの流れを整理します。
確認日は2026年10月18日。通常版の透明モデルと、手元の付属カートリッジで成功した記録です。カートリッジの部品やツールの版が変われば、同じ処理をそのまま適用できるとは限りません。

用意したものは、本体・付属カートリッジ・Mac・ケーブル

| 用意したもの | どんなものか/今回の役割 |
|---|---|
| ModRetro Chromatic Transparent | 購入した通常版の透明モデル。ゲームの実行と、カートリッジの読み書きに使用 |
| 付属のTetrisカートリッジ | 本体背面に差すゲームソフト。中の書き換え可能なメモリへ自作ゲームを保存 |
| 手持ちのMac | Codexでの開発、ROMの生成、動作検証、USB経由の読み書きを実行 |
| データ通信に対応するUSB-Cケーブル | MacとChromaticを接続。充電専用ケーブルではデータ通信できない |
| バックアップ用のMacの空き容量 | 元テトリス、元セーブ、更新前のゲームとスコアを保管 |
購入したのは、公式のChromatic Transparent+Tetrisセットです。DevDay Editionを買い直したり、追加の開発用カートリッジを購入したりはしていません。
EverDriveはmicroSDに入れたゲームを読み込む方式なので、その方式を選ぶならmicroSDが必要です。今回は付属カートリッジへ直接書いたため、EverDrive・microSD・Mac用カードリーダーを使わずに済みました。M5Stack Stamp-P4も使っていません。
「追加購入なし」は、Macやデータ通信ケーブルをすでに持っていた今回の機材についての話です。自作ゲームを書けば、元のテトリスのまま遊べる状態も変わります。元ソフトをそのまま残したい人は、書き換える前に別の運用を選んでください。
Chromaticは、ゲームボーイのカートリッジを動かすFPGA互換機
Chromaticは、Game Boy・Game Boy Color・Chromatic用のカートリッジを差して遊ぶ携帯ゲーム機です。内部では、回路の構成を変更できる部品「FPGA」を使ってゲームボーイの動作を再現しています。
今回の透明版について、開発に関係する仕様を拾うと次のようになります。
| 仕様 | 今回どう関係したか |
|---|---|
| 160×144ピクセル、2.56インチIPS液晶 | この小さな画面に合わせて、ゲーム画面・文字・画像を作り直した |
| Game Boy/Game Boy Color互換 | GBC用の実行ファイルを作って動かした |
| FPGAによる構成 | 通常のゲーム実行に加え、読み書き作業時には一時的な別構成を利用した |
| USB-C | Macとのデータ通信、外部給電、実機の映像・音声確認に利用した |
| 十字キー、A・B、START・SELECT | タッチ操作を物理ボタン向けに置き換えた |
透明版の筐体はABSプラスチック、画面のカバーはGorilla Glassです。別モデルのマグネシウム筐体やサファイアガラスの説明とは分けて読む必要があります。リンクケーブル端子や赤外線通信もありますが、このゲームでは使っていません。仕様の出典は透明版の公式商品ページです。
USB-Cでつないだだけでは、何をしているかは分かりません。ゲーム映像をMacへ取り込んでいる場合もあれば、給電しているだけの場合もあります。今回は、準備したツールを使ってカートリッジと通信する用途にも使いました。公式の録画・配信ガイドには、映像・音声を取り込む手順が載っています。
MacでROMを作り、USB-C経由でカートリッジへ書いた
「ROM」は、ゲームのプログラムや画像・音声をまとめた実行用ファイルです。今回の拡張子は .gbc。それを物理カートリッジ内の書き換え可能な記憶部品「フラッシュメモリ」に保存しました。
全体の流れは、次のとおりです。

ここで混同しやすいのが、「本体の回路構成」と「ゲームデータ」の違いです。
読み書き作業では、ChromaticのFPGAに、Cart Clinic用の回路構成を一時的に読み込みました。これによって、本体をカートリッジの読み書き装置として使えます。その間に、ゲームのROMをカートリッジ側へ書き込みます。
FPGAへ一時的に読み込むデータと、カートリッジへ保存するゲームのROMは別物です。今回、本体ファームウェアの恒久更新はしていません。作業後は本体を通常のゲーム実行へ戻し、カートリッジに入ったゲームを起動しました。FPGAの一時的なSRAM設定と永続的なflash設定の違いは、openFPGALoaderの公式説明でも確認できます。
GitHubから入れたものは、それぞれ役割が違う
ゲームを作る道具、Mac上で試す道具、カートリッジへ書く道具を分けると理解しやすくなりました。

ゲームを作る:CodexとGBDK
Codexには、元のWeb版のコードを読ませ、移植の実装・ビルド・検証・補助スクリプトの作成を進めてもらいました。WebのJavaScriptをそのまま本体で動かしたわけではありません。
ゲームボーイ用の実行ファイルを作る開発キットが、GBDK-2020です。C言語のコードを機械が実行できる形へ変換するコンパイラーと、画面やボタンなどを扱うライブラリ、関連ツールが含まれています。今回は4.5.0のmacOS版を使いました。
画像はPythonのPillowでGB向けの小さな画像データへ、音声はFFmpegなどで低いサンプリング周波数・少ないビット数のデータへ変換しています。Pythonの仮想環境 .venv は、こうした変換や検証に必要な部品を、このプロジェクト用にまとめて置く場所です。
Macで試す:PyBoyとSameBoy
この二つは開発中にMacで使うエミュレーターです。Chromatic上でPyBoyやSameBoyを動かしているわけではありません。また、今回作ったブラウザプレビューには音声出力がないため、そこで画面が動くだけでは音の確認は終わりません。
カートリッジを扱う:公式Cart Clinicの部品と専用スクリプト
ModRetro公式のMR Updaterには、ModRetroゲームの更新やセーブのバックアップなどを行うCart Clinic機能があります。今回使用したアプリは1.7.5でした。
元テトリスのセーブは、公式画面の「Backup Save Data」で取得しました。一方、カートリッジ全体の読み出しと自作ROMの書き込みには、公式アプリに同梱された部品を呼び出す、今回専用のPythonスクリプトを使っています。
| 部品 | 何を担当したか |
|---|---|
| Cart Clinic用FPGAデータ | Chromaticをカートリッジ読み書き用の構成に切り替える |
| openFPGALoader | その構成を本体FPGAのSRAMへ一時的に読み込む |
libpyretro.cartclinic | MacからUSBでCart Clinicと通信する、公式アプリ同梱のPython部品 |
| 今回作成した補助スクリプト | 部品の識別、二重バックアップ、書込範囲の制限、スコア領域の保護、読み戻し照合を行う |
libpyretroという名前が出てきますが、ここではUSB通信のために使いました。RetroArchでゲームを実行したという意味ではありません。公式部品を動かすPython 3.10環境と、ゲームの開発・検証に使うPython 3.12以降の環境も分けています。
「公式GUIで好きなROMを選ぶだけ」という手順ではありません。 補助スクリプトは、識別済みのカートリッジと更新前のデータに合わせて作りました。汎用の書き込みアプリとして公開・配布したものではないため、別の個体へそのまま流用する手順にはしていません。
途中で調べたFlashGBXとの違い
fredemmott/chromatic-flashgbx-fpgaは、ChromaticをFlashGBXというカートリッジ管理ソフトから扱うためのFPGAプロジェクトです。これも途中で調査・試行しました。
ただ、今回試した版では、手元のカートリッジのヘッダー情報を正しく読めませんでした。無理に続けず、最終的には上で説明した公式Cart Clinicの部品を使う経路へ切り替えています。「GitHubで見たFlashGBXのツールが、今回の最終的な書き込みに使われた」と覚えると、ここが食い違います。
最初にしたのは、テトリスとセーブを残すこと
付属カートリッジの中身を書き換えるので、最初の作業はバックアップでした。今回確認したフラッシュメモリは SST39VF1681、容量は2MiB、消去の単位は64KiBです。この部品を識別してから、その仕様に合う処理を使っています。
テトリスのゲーム本体は256KiBでしたが、バックアップは物理メモリ全体の2MiBも取得しました。ゲーム本体だけでは、周辺の保存データなどを取りこぼすためです。全体を2回読み、内容が完全に一致することを確認しました。
元のセーブデータ32KiBも2回取得し、全体バックアップから取り出した内容との一致を確認しています。こうして、元のゲーム、元セーブ、全体のバックアップをMacに保管してから書き込みへ進みました。
ただし、元のテトリスへ戻す実機テストは行っていません。バックアップの一致を確認できたことと、復元を最後まで試したことは別です。テトリスのROMや元セーブを、この記事で配布することもありません。
Web版は、GBに合わせて作り直した
元のゆうあどろっぷには、Webの画面表示、物理計算、Supabaseによるオンラインランキングがあります。それらをゲームボーイ上でそのまま動かす構成にはしていません。
持ってきたのは「狙って落とす」「同じ段階のぬい同士を合体する」「11段階で進化する」という遊びと、元の画像・BGM・ボイスです。ゲーム処理と画面表示はC言語で作り直しました。
最初の版は、積もったぬいが細かく動き続けて重くなりました。GB版では落ち着いたぬいを静止させ、新しく落ちたぬいや合体の近くだけを再計算します。背景の枠も静止画にし、変化した箇所を中心に描き直すようにしました。Web版の動きを全部残すより、ボタンへの反応と遊びやすさを優先しています。
残した機能は、NEXT、コンボ、MAXでの消滅とJACKPOT、最高点・上位5件の保存、一時停止などです。ショップ・通貨・キャラクター切り替えなどは含めていません。物理挙動や難易度もGB向けに調整したため、Web版と点数を直接比べるものではありません。
BGM6曲と、ゆうあのボイス24本も入れた
推しのゲームなので、音を省いたままでは物足りません。最終版にはWeb版シーズン3のBGM6曲と、合体・終了時のボイス24本を収録しました。ボイス中はBGMを一時中断し、終わったら続きから再開します。落下などの効果音は、別の音源で重ねています。
音声は8192Hz・モノラル・4bitへ変換しました。GBカラーの波形メモリにデータを少しずつ渡して再生するため、Macで元音声を鳴らす方法とは違います。元音源と同じ高音質になるわけではありませんが、録音された声を使っています。
調整中には、BGMの手前で「ぶーーー」という音や、別の音割れが出ました。音源のオン・オフや、波形メモリにデータを渡すタイミングを見直し、SameBoyの音源処理でも出力を照合しています。その後、実機で聴き直して、遊べる音になったことを確認しました。エミュレーターのテストが通ることと、本体スピーカーで気持ちよく聴けることは、両方確認する必要がありました。
スコアもカートリッジに保存している
GB版はオフラインです。Supabaseへの接続もログインもなく、Web版のランキングとは別に、最高点と上位5件を記録します。
今回の付属カートリッジ向けROMでは、ゲーム本体と別に確保したフラッシュメモリの領域へ、スコアを追記する方式にしました。各記録に番号と破損検出用の値を付け、正常なもののうち最新の記録を読み込みます。元テトリスのセーブ形式をそのまま使っているわけではありません。
BESTは合体時に保存し、ゲームオーバー、またはSTARTで一時停止してSELECTでタイトルへ戻ったときに、そのプレイを上位5件へ登録します。電源を入れ直しても記録が残ることを実機で確認しました。
更新時には、この保存領域を消さない処理も必要です。最終更新では、保存領域を含む末尾256KiBを保持し、書き込み後に全バイトの一致を確認しました。途中で新しいスコアが増えていたときには、更新前の照合で自動停止し、最新の状態を取り直してから更新しています。
自分でも始めるなら、まずMacで動くROMを作る
初めてなら、最初からカートリッジを書き換える必要はありません。まずMac上で、小さなゲームボーイカラー用ROMを作り、エミュレーターでボタン入力や画面表示を試すところから始められます。GBDKの公式入門には、導入とサンプルのビルド方法があります。
Codexへ最初に渡すなら、例えばこんな依頼です。
MacでGBDK-2020を使い、ゲームボーイカラー用の小さなゲームを作りたい。
まず文字表示、左右移動、Aボタンの反応があるROMを作って、
エミュレーターで動くところまで進めてください。
ソース、変換素材、生成したROMを別々に管理し、起動方法をREADMEに残してください。
実機やカートリッジへの書き込みは、まだ行わないでください。
実機へ進む段階では、次の依頼を足します。
通常版Chromaticと付属Tetris、USBのデータ通信に対応するケーブルがある。
追加購入を前提にせず、現在の公式資料と実際のUSB認識を確認してほしい。
まず読み取りだけで、本体とカートリッジの部品・容量・保存方式を識別する。
元ゲーム、全フラッシュ、元セーブをバックアップし、二度読みの一致を確認する。
使用するツールの名前・出典・役割と、一時FPGA設定/本体の恒久更新/
カートリッジ書き込みの違いを説明してほしい。
この個体に対応する手段が確認できなければ、推測で書き込まない。
自作ROMの書き込み前に、対象・変更範囲・復元をどこまで確認したかを報告して止まる。
今回の補助スクリプトは個体専用なので、この文章だけで同じ書き込み環境が自動的にそろうわけではありません。ツールの対応状況とバックアップの確認を、その人の実機でやり直すための依頼です。DevDay Edition向けの公式クイックスタートもありますが、今回使った経路とは分けて読んでください。
今後のゆうあどろっぷ開発は、ソースを直してROMを作り直す
今回のプロジェクトでは、主に次のファイルを編集します。
| ファイル | 変更する内容 |
|---|---|
src/main.c | 画面の切り替え、入力、ゲーム全体の流れ |
src/physics.c | 落下・衝突・合体などの計算 |
src/ui.c | スコア表示などの画面表示 |
src/audio.c・src/audio_player.c | 曲やボイスの切り替え、音声再生 |
src/save.c・src/save_flash.c | 記録の読み書き。変更時は特に保存互換性を確認 |
scripts/generate_assets.py・scripts/generate_audio.py | 元の画像・音声からGB用データを生成 |
手元の開発環境はGBDK 4.5.0、Python 3.12以降、PyBoy 2.8.1、Pillow 12.0.0、FFmpegで構成しています。GBDKはプロジェクト内の .tools/gbdk/、Python環境は .venv/ にあります。元の画像は assets/source/、音声の再生成には隣のWeb版プロジェクトの音源も必要です。
開発環境と素材がそろった今回のフォルダーで、次を実行します。これらはビルドと検証のコマンドで、実機への書き込みは行いません。
# yuua_drop-gbフォルダーで実行
sh scripts/build.sh
sh scripts/test.sh
sh scripts/test_audio.sh
# ブラウザ用のROMプレビュー(音声なし)
.venv/bin/python scripts/preview.py
プレビューのURLは http://127.0.0.1:8766/。Mac上でROMを実行した画面をブラウザへ表示します。これらのスクリプトは今回のプロジェクト固有で、GBDKをインストールするだけで作成されるものではありません。
ビルドすると、2種類の2MiB ROMが出力されます。
| ファイル | 保存方式と用途 |
|---|---|
dist/yuua-drop.gbc | 標準版。MBC5と8KiBのセーブ用SRAMを使う、対応エミュレーターなど向け |
dist/yuua-drop-chromatic.gbc | 手元の付属カートリッジ向け。確認したフラッシュメモリへ記録する専用版 |
MBC5は、カートリッジ内のメモリの読み出し位置などを切り替える仕組みです。SRAMはセーブに使う別の種類のメモリで、今回の専用版が使うフラッシュ保存とは異なります。ファイル名が似ていても、保存方式を確認せず入れ替えないようにします。
ソースを変更したら、ビルド、エミュレーターでの検証、実機確認の順に進めます。カートリッジを更新するときは、その時点の最新スコアを含めて読み出し、保存領域を保護したイメージを書き、読み戻して照合します。以前のバックアップをそのまま使うと、その後に増えた記録を失う可能性があります。
次の機能をCodexに頼むときも、「ゲーム部分を変更し、現在の保存形式と保存領域を維持して検証する」と伝えるつもりです。手元で遊べたROMだけでなく、ソース・元素材・使用したツールの版・バックアップをそろえて残しておくと、その続きから開発できます。

