VGS-Zeroリリースから1年の振り返り

以下の記事で VGS-Zero を紹介してから1年ほど経過したので、機能面とビジネス面の視点で振り返ってみました。

https://qiita.com/suzukiplan/items/8a740b593816ef9ef565

# 機能面での振り返り

現時点（2025.02）の VGS-Zero は version 1.19.1 です。

version 1.0.0 (2024.01) からの変更内容（[CHANGELOG.md](https://github.com/suzukiplan/vgszero/blob/master/CHANGELOG.md) ）を全部眺めて、私の主観で「大きな変更」だと思う項目として、以下の 5 項目をピックアップしました。

1. GPIO ジョイパッド対応（version 1.3.0）
1. 2MB 拡張RAM対応（version 1.9.0）
1. NSF 再生対応（version 1.11.0）
1. vgsasm (Z80アセンブラ) 組み込み（version 1.14.0）
1. ユーザ定義I/O対応（version 1.19.0）

## 1. GPIO ジョイパッド対応

これについては Qiita で別途記事にしています。

https://qiita.com/suzukiplan/items/385983d84e28659f0f43

現在主流なジョイパッドの種類としては次のものがあるようです。

- XINPUT (Windows や XBOX)
- DualShock (PS4), DualSense (PS5)
- NitendoSwitch
- GameController Framework / MFi (macOS や iOS)

HID の USB ジョイパッドが過去のものになりつつあり入手が困難だと分かったので、RaspberryPi Zero 2W の 8 本の GPIO (+ 1 本の GND) に直接ボタンを接続した入力もサポートしてみることにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2161417/cea38c31-bfd4-e47c-cef2-3e41dd0ee914.png)

上図のピンアサインで、セイミツ工業のボタンやスティックなどを接続することができます。

詳しくは以下の note で解説しています。

https://note.com/suzukiplan/n/ncccafb305eae

Arduino 経由でスーパーファミコンのコントローラを繋げている方もいらっしゃいました。

https://x.com/honda_ken/status/1758672984364253582

現行のゲーム機は USB や Bluetooth などの一定（数ミリ秒ぐらい？）の遅延を許容した入力方式を採用しているので、「入力レスポンス」の一点に限れば VGS-Zero が現行ゲーム機に勝利しているともいえます。

ただし、60fpsで動作するゲームの場合、1フレームあたり約16.667msぐらい（120fpsでもその半分）の猶予時間があるので、数ミリ秒オーダーの遅延は実質「遅延無し」と言えるため、実用的にはあまり意味はありません :sweat_smile: 

RaspberryPi Zero 2W だと USB のオーバーヘッドが結構キツイのか、操作性の向上を知覚できるレベルで実感できましたが、正確なレスポンス値の検証を行った訳ではないので、もしかするとこれは単なるプラシーボ効果かもしれません。

> _恐らくショット上限を超えているであろう粗悪な金型で作られていそうな Aliexpress で買った HID ジョイパッドではなく、セイミツ工業の品質が高い部品を使っていることによる差かも?_

実のところ、入力レスポンス云々よりも HID や XINPUT など、コロコロ規格が変わる **USB ゲームコントローラの仕様に振り回されない** ということが、VGS-Zero にとって最大のメリットかもしれません。

GPIO ジョイパッドの対応により、少なくとも VGS-Zero は USB ジョイパッドや USB の規格に振り回される必要がなくなりました。

この類の **サードパーティーへの依存度を下げるエンハンス** は、VGS-Zero にとって大きな意義のあるものだと私は考えます。


## 2. 拡張RAM (2MB)

1年前に「16KB もメモリがあればへーきへーき！」というノリで記事を書いていた記憶がある（あの頃は若かった?）のですが、やはり足りないということで **2MB の拡張 RAM** を追加しました。

VGS-Zero のメモリ番地（64KB）は 8KB 区切り 8 ページのレイアウト構造になっています。

| Page | Address | Type | Usage |
|:-:|:-:|:-:|:-|
|0|0x0000 ~ 0x1FFF | ROM | Program Bank 0 (switchable) |
|1|0x2000 ~ 0x3FFF | ROM | Program Bank 1 (switchable) |
|2|0x4000 ~ 0x5FFF | ROM | Program Bank 2 (switchable) |
|3|0x6000 ~ 0x7FFF | ROM | Program Bank 3 (switchable) |
|4|0x8000 ~ 0x9FFF | RAM | VRAM-1 |
|5|0xA000 ~ 0xBFFF | RAM | **VRAM-2** |
|6|0xC000 ~ 0xDFFF | RAM | RAM-1 |
|7|0xE000 ~ 0xFFFF | RAM | RAM-2 |

上記のページ 5 (VRAM-2) はキャラクタパターンテーブルですが、VGS-Zero ではキャラクタパターンを ROM バンク番号で指定する DPM (Direct Pattern Mapping) という機能があり、DPM を用いることで VRAM-2 は通常の RAM と同じような用途で使用できる特徴があります。

つまり、VGS-Zero の実質的な RAM サイズは 24KB ということになりますが、このページ 5 をバンク切り替えに対応することで 256 x 8KB (2MB) の拡張 RAM を実装しました。

また、version 1.18.0 でバンク切り替え無しで 1 byte づつ拡張 RAM へアクセスできる I/O を追加しています。

```z80
; 入力
LD HL, 0x1FFF     ; 読み込みアドレスを HL に設定(※上位3ビットはマスクされる)
LD B, 123         ; 読み込むバンク番号を B に設定
IN A, (0xDC)      ; exram[123] の 0x1FFF 番地を A に読み込む
```

```z80
; 出力
LD HL, 0x1FFF     ; 書き込みアドレスを HL に設定(※上位3ビットはマスクされる)
LD B, 123         ; 書き込むバンク番号を B に設定
LD A, 0xCC        ; 書き込む値を A に設定
OUT (0xDC), A     ; exram[123] の 0x1FFF 番地に A を書き込む
```

これにより拡張RAMのアドレス空間（21bits）に **バンク切り替え無し** でアクセスできます。

この機能は、私が現在開発中の最新のVGS-Zero用ゲームソフト「Battle AirForce」でリプレイデータを保存したり再生する機能実装で必要だったので追加しました。

https://store.steampowered.com/app/3476490/Battle_AirForce/

Battle AirForce では、Steam の Remote Cloud Storage 機能と連携することで、世界Top16（グローバルリーダーボード上位16位）のプレイヤーのリプレイを再生することができます。

リプレイデータは、ゲームプレイ時のフレーム（1/60秒）ごとのキー入力を保存したものなので、1秒の動画で 60 bytes、1分で 3,600 bytes、1時間で 216,000 bytes (約211KB) もの膨大なメモリを必要としますが、2MB のメモリがあれば余裕をもってリプレイデータを記録することができます。

## 3. NSF 再生対応

NSF とはファミコンのサウンドデータフォーマットです。

FamiStudio という DAW に感動して入れてみました。

https://famistudio.org/

ただ、正直これは失敗だったと思っています。

というのも NSF というのは純粋なサウンドデータではなく、RP2A03 の音声再生プログラムそのものなので、音楽を再生するために裏でファミコンのエミュレータ相当のものを動かす必要があります。

PPUが不要なので軽いですが、それでも結構なオーバーヘッドです。

幸い、VGS-Zeroのもともとのサウンド機能はもの凄く軽かった（具体的には RaspberryPi Pico でも余裕で動作するレベルだった）ので、サウンドを処理する CPU に比較的余力が多く、RaspberryPi Zero 2W であれば問題無く処理できたのですが、コードサイズが無駄に大きくなってしまった感があります。

将来的には NSF ではなく VGM 形式への移行などを考えています。

> 私は結局のところ VGS のサウンドが一番好きなので、そこにリソースを割くモチベーションがあまり高くないという課題もあります。

## 4. vgsasm (Z80アセンブラ) 組み込み

これについても Qiita で別途記事を書いています。

https://qiita.com/suzukiplan/items/dc44601e5faa23412866

VGS-Zero は当初「C言語でゲームが創れる」という点にフォーカスして売り込みましたが、Battle Marine を C言語 で開発してみて SDCC の課題が色々と見えてきました。

まず、SDCC は性能を優先した最適化をしていないので、それほど速く（≒コードサイズが小さく）ありません。

それだけならまだ良いのですが、コンパイルの時間が物凄く長いです。

私が開発に使っているメインマシン（2013 年モデルの MacBook Air）では、Battle Marine のクリーンビルドにだいたい 5分 ぐらい時間が掛かります。

> サブ機の 2024 年モデルの MacBook Air (M3搭載) ならもうちょっと早くビルドできるかも?

Steam 版 Battle Marine を完成させた後、ゲームギア版の Battle Marine を z88dk の z80asm で開発してみたところ「フルアセンブリ言語の開発も悪くない」と思えるようになったので、VGS-Zero でも新作を z80asm で開発しようとしたのですが色々と上手くいかず、「結局何が問題なのか」と考えた結果 **「z80asmには構造体が無いからゲームが開発し難い」** という結論に至りました。

ただし、構造体を扱える Z80 アセンブリ言語は私が知る限り存在しなかったので自作しました。

https://github.com/suzukiplan/vgsasm

また、vgsasm には Visual Studio Code で扱える専用のエクステンションもあるので、アセンブリ言語なのに構造体のメンバ変数サジェスト表示などに対応しています。

https://github.com/suzukiplan/vgsasm-extension

現代的!

## 5. ユーザ定義I/O対応

Battle Marine を開発した時は、セーブデータを保存する時のコールバック内で数値の変化をチェックしてSteamのアチーブメントアンロックやリーダーボード登録をしていました。しかし、Battle AirForceの開発でアチーブメントの種類を増やしたり、リプレイのダウンロード機能を実装しようとしたところ、INとOUTでネイティブプログラムとの入出力できる機能が欲しくなり作りました。

これがあれば何でもできてしまいますね。

例えば、センサーの情報を読み取って連携すること（IoT的なこと）もできます。

> IoT 的なことであれば普通に M5Stack 等を使って μPython でプログラムを書いた方が楽だし、何やかや RaspberryPi Zero は消費電力が高い（実用的に難がある）ので、VGS-Zero を IoT 用途でプッシュするつもりはありませんが、DS や Wii の頃のような方向性の体感ゲーム機のようなものを VGS-Zero でも開発できるようになったとも言えるかも？（そっち方面には疎いのでよく分かりませんが...）


ユーザ定義I/Oを使えばインターネット通信処理との連携が容易にできるので、VGS-Zeroでソーシャルゲームを作ることも可能かもしれません。（Battle AirForceのリプレイ共有機能もある意味ソーシャルゲーム的な要素）

# ビジネス面での振り返り

1年前の記事でも書いてますが、Battle Marine には「3,000 本売る」という中々無謀な KPI を設定しているので、それについても振り返ってみたいと思います。

今のところ「3,000本とか無理だろjk」という売り上げ本数です :sweat_smile:

Steam のざっくりとした売り上げ本数は レビュー数 x 100本 みたいな話をよく聞きますが概ね合ってますね。

Battle Marine は初動こそ想定以上に売れたのですが、今では1日1～2本売れれば御の字という感じです。Steam の場合、季節セールやテーマ別セールというものがあり、そこに参加して割引販売をして伸ばしていくことが定石ですが、これについては意図的に一度も参加しないようにしていたので、初動以降の伸びが悪かったことは概ね想定通りです。

> 将来に渡り季節セールに参加しないという訳ではないです。売り上げが伸びるなら参加した方が良いとも思っていますが、私はデジタルコンテンツの値引き販売というものに対して若干の疑問（抵抗？）があります。デジタルコンテンツは腐らないし在庫コストも殆ど掛からないので何故値引きをするのかと。そのため初年度は意図的に参加せずに様子見をしていましたが、Steamではやっぱり値引きが必須なのかなぁ～と思いつつあります。（定価は敢えて割高に設定しておき、リリースセールや季節セールで値引き販売してセールスを伸ばす手法が多分Steamにおけるベストな価格戦略です）

想定外だったのは、Steamでゲームを販売するには1本あたり＄100 (¥15,000) のAppクレジットというものを購入する必要がある（※これは＄1,000売り上げれば返金される）のですが、Appクレジット分の売り上げを想定よりも早く回収できたことです。

一定の知名度があるコンテンツなら話は別ですが、Steamで完全に無名な私（個人製作）の同人ソフトでもちゃんと売れるのか...と。

Battle Marine の販売を経験したことで、Steamで売り上げを伸ばすための売り方 みたいなものが何となく見えてきた気がするので、次作（Battle AirForce）ではその点を踏まえた販売戦略を練りました。

なお、Battle Marine は Steam で販売した後にゲームギアへ移植してパッケージ販売する という多分世界初の試みを実施してみたのですが、それについての Steam での売り上げ本数への貢献はほぼ無かった感触です。客層が全然違うので当然かもしれません。しかし、ゲームギアに移植したことで、4gamer さんに記事で取り上げて頂いたり、Battle Marine をキッカケに Steam を初めて触ってみたという方も居たので、大変だったけどやって良かったです。

もちろん、ゲームギアへの移植はメインのマーケティング戦略ではありません。

私が考えたマーケティング戦略は、**Battle Marineとふわっとした関連性のある新作を出し続けることで結果的に Battle Marine の売り上げ本数を 3,000 本に到達させる** というものです。

例えば、今では大人気の東方Projectも最初（靈異伝）から大人気だった訳ではなく、（続編やシリーズではないが）何となく関連性のある新作「東方なにがし」を創り続けることで IP 価値を向上させてきたものと思われるので、それに倣って Battle Marine と Battle AirForce を世界観のレベルで何となく関連性がある形にしてます。（ゲーム内容は全然違いますが）

何とも気が遠くなりそうな作戦ですが、私が考えた限り **KPI を達成するために再現性がある唯一の手段** がそれだったので仕方がありません。

東方Projectですら、界隈（狭い世間）で注目が集まったのは恐らく2003年の東方妖々夢（第7作）あたりで、一般（広い世間）で注目を集めたのはニコニコ動画が流行った2008〜2009年頃（第11作〜第12作）だと思われるので、まだまだ先は長くなるものと想定しています。

短い期間（上場企業なら四半期毎）で成果が求められる大手企業とは異なり、短期間の数値に捉われる必要がないので、じっくりねっとり気長にやっていこうという所存です。

投資の世界で利益を最大化するための再現性が高い手法は、「長期・分散・積立」みたいな話をよく聞きますがそれに近いかもしれません。短期投資で勝つには潤沢な資本が必要なので個人が大手ヘッジファンドに勝つことはほぼ不可能ですが、ヘッジファンドには半年なり四半期ごとに利益や損失を確定させなければならない縛りがあるので、長期を前提とした戦略で戦えば個人でもヘッジファンドに勝つことができると言われています。

地道に「コンテンツ資産」を積み立てて、将来的に「Battleなにがし」の第12弾あたりが登場する頃には、ゲームギア版Battle Marineに東方旧作（PC-98版）のように数百万円の値段がついていると良いなぁ...と。中古販売でどれほど高額で取引されようとも私には1円も入りませんが、仮にそうなったら面白そうかなと。

**東方旧作に相当する製品ポートフォリオ** が欲しかったという事が、ゲームギア移植の制作を引き受けた最大の理由だったことは秘密です。

---

もう一点、1年前と状況が変わったこととしては白色申告から青色申告へ切り替えました。

そういえば私が書いた Qiita の記事で一番伸びているのは何故か [確定申告関連の記事](https://qiita.com/suzukiplan/items/cbd8e5efaeb150dc6c0b) なので、念のためそのことについても触れておきます。

> Qiita は技術の記事を書く場所だと思うのですが :thinking: 

GooglePlayで有料販売をするには、組織アカウントにしなければ自宅の住所を晒さなければならなくなったので、組織アカウントに変更するため（DUNS番号を取得するため）にバーチャルオフィスを借りつつ開業届を出して青色申告に切り替えておきました。

青色で一定の要件（措法28の2）を満たせば30万円未満の資産を即時償却できるので、10万円以上30万円未満の設備投資がカジュアルに出来るようになります。

白色だと経費で落とせる設備投資（消耗品）は10万円未満で、10万円以上～20万円未満なら一括償却（3年で減価償却）、20万円以上なら通常の減価償却（パソコンなら種類によって4年〜5年）をする必要があり、とても面倒くさいです。

また、青色なら特別控除で65万円まで非課税になります。

雑所得と違って利益が20万円未満でも確定申告が必要になるのが少し面倒ですが、赤字を3年間繰り越すこともできます。（白色は利益が20万円未満なら確定申告不要なので実質非課税ですが、赤字繰越や損益通算ができません）

つまり、長期戦を見越すなら青色チェンジしない理由がありません。

青色確定申告自体は簡単です。

問題は税務調査ですね。

国税庁は確定申告ではそこまで細かくチェックしていなくて、本格的にチェックされるのは税務調査のタイミングです。税務調査の結果誤りと指摘される（脱税と判定される）と修正申告をしつつ追徴課税することになります。

デジタルコンテンツ系は税務調査に入られる率が高いという話も聞くので少しビクビクしてます。

> 起業障壁が低い ≒ 会計ガバガバ率高め → 追徴ゲットしやすい？

恐らく売り上げ1,000万円（免税事業者の閾値）に漸近しなければ一般調査は無いだろうと思って（高をくくって）いますが、青色なら簡易接触ぐらいはあるだろうという想定で真面目に帳簿を付けています。

特に最近は AI の発達により「臭い確定申告」をピックアップする腕がかなり上がったらしく、追徴件数が伸びているという話もあるので、より正確には「AIに疑われにくい帳簿付け」を心がけています。ディープラーニングは特徴抽出が得意（というよりそれしかできない筈）なので、脱税しているっぽい特徴抽出は彼ら（AI）の十八番です。

> 65万円の特別控除を受けるには複式簿記の帳簿を電子申告する必要があり、所定のフォーマットで電子申告をするということは AI によるチェックが低コストで簡単にできるということかなと想像。

「事業と無関係な経費は載せないこと」が基本中の基本ですが、簡易接触で質問がきそうな項目は予めメモ欄に経費購入したものの具体的な事業活動での使途を記載したり、接待交際関係は証憑として議事録も添付したり、根拠法令を記載したり、特措法関連なら法令番号を記載するなどの基本的なことを心がけています。（そんなんで大丈夫かなと思いつつ）

ちなみに帳簿は Excel から Money Forward Cloud へ移行しました。

freeeとMFCを試用したのですが、MFCのクレジットカードや銀行の取引内容から勘定科目への仕分け入力をAIが半自動でやってくれる機能が便利だったのでMFCを採用しました。MFCの方が月額の料金が安いですし。ただし、AIによる自動仕分けが結構微妙なのであまり油断はできません。例えば、なんでもかんでも雑費にしようとしたりとか。勘定科目の雑費は滅多に使いません。例えば、減価償却が終わった資産を処分する時にその残存簿価（1円）を経費として計上したりとか。経理に不慣れな人が誤って使ってしまいがちなので、AIが誤った学習をしてしまった感じかなと想像してます。税務調査で否認されやすいケースはNGとするとか、AIさんはもう少し高度な学習をして頂きたいところ...

65万円の特別控除を受けるには複式簿記での帳簿付けが必要で、一応私は日商簿記（※何級かは忘れた）を持っていて複式簿記での帳簿の付け方も分かっているつもりですが、あまり自信は無い（経理の実務経験が無い）のでクラウド会計システムへ移行して凡ミスによる追徴発生リスクを下げる狙いです。

ついでに、将来一般調査に当選してしまった時に顧問税理士無し（独力）で是認ゲットできるようにするため、税理士試験のテキストを眺めて軽く税務について勉強しようと思っているのですが中々腰が重いです。簿記論と財務諸表論は会社経営にも役立ちそうなので取っておいても良いかもしれませんが。代行業をやるつもりはないので資格+登録は不要です。_（何より暗記が苦手な私に税理士試験は結構難しそう）_

> 顧問税理士をつけないつもりではないですが、税理士の先生の約半数は税理士試験を受けずに税理士資格を持っている方々（国税庁OB）なので、法律知識や実務スキル面にバラツキがあり、あまり頼りにはできないと思っています。（国税庁の職員時代にどういう職務を担当していたかによると思いますが）
>
> ちなみに、税理士資格試験を受験するには資格要件（日商簿記1級etc）がありますが、会計学の科目（簿記論と財務諸表論）は令和5年から無資格でも受験可能になりました。（[参考](https://www.nta.go.jp/taxes/zeirishi/zeirishishiken/shikaku/shikaku.htm)）

一般調査をするにも簡易接触をするにも、役人の人件費が掛かり、役人の人件費＝税金です。つまり、国民の税金を無駄撃ちするケースは可能な限り回避したい筈（そのためのAI）だと考えられます。

国税庁にとって「無駄撃ち」と思われない程度の事業に成長させたいですね。