ブログネタ
【公式】現在○○を制作中! に参加中!
公式のブログネタに制作中!というお題があったので、昨年から作り続けている PC-8001mk2 用のゲーム制作の進捗状況について、簡単に説明していきたいと思います。このゲームはひみつをときあかす要素もあったりあるので、そういう謎部分には殆ど触れないように説明していきますので、それはご了承ください。現在の完成度は40%ぐらいとなっています。


  • 最初はサウンドから
プログラムの制作に取り掛かったのは 2023年8月からとなります。それまでは PC-6001mk2 対応で制作を進めていたのですが、実行速度が足りないことが分かり頓挫して、新たに開発を始めたのが PC-8001mk2 向けのゲームとなっています。PC-6001mk2 向けのはいきなり大容量を使う前提での開発を行ったため、データの取り回しにかなりの負担がかかってしまいまして。ただでさえ非力な PC-6001mk2 ではキャラが立体的にマップを歩くだけで、かなり CPU を消費してしまいまして…
PC-6001開発頓挫
少し意気消沈してたところに、PC-8001 で作成してた Newシティヒーローのソースコードを見てたら、BEEP音源ドライバを作りたくなって、いろいろ皆さんに質問して聞きながら作ったのが、再開発スタートのきっかけとなります。つまり、ゲーム制作の再開でなく、単純にドライバを作ったら、そのままの流れでゲームを作りなったというヤツですね。
ConvBeep
この BEEP音源ドライバとコンバータの作成は 2023年9月17日まで開発を進めていました。このドライバですが、完成度が低いので、近々再作成を試みようと思っています。もう少しまともに音階が出てほしいですし、もう少し軽くなって欲しいのですが、完成するかどうかは分かりません…


  • ゲームを作るにはデザインが必要だが…
さて、折角 BEEPドライバを作ったのだから、やっぱりゲームに活かしたいと。PC-6001mk2 で作ろうと思ってたゲームデザインのうち、無謀だった4方向に自由に移動しての広大なマップという仕様は打ち切り、ギャラクシアンのような普通のシューティングゲームのように、マップ固定で出現する敵を撃破するタイプにしようと思った訳です。

ただ、やっぱり絵が必要で。PC-8001mk2 は 320x200 ドットと解像度的には普通なのですが、色が固定3色+任意1色という変態仕様。任意色を青にして RGB 発色可能な状態から、タイリングでっていうワザもあるにはあるのですが、敵キャラの基本サイズが 16x16 という小さいサイズでは、タイリングなんて出来なかったりします。

なんかないかなーって思っていろいろ見てたら、目についたのが 1-Bit Rogue というゲーム。スキップモアさんがリリースしているタイトルなのですが、ローレゾ前提で、かつ、色が付いてもデジタル8色。同時に使われている色も少ないので、ちょっと改良すれば割とそのまま使えそう。何より、基本デザインが素晴らしくて惚れちゃいました。そこでユウラボさんに、この画像データを使用させてもらえませんかと連絡したところ、即座に快諾いただきました。ありがたい!
1-Bit Rogue
        1-Bit Rogue (C)2016 SKIPMORE

そして、 1-Bit Rogue だけではデータが足りないので、細かくドットを打ってくれそうな人に連絡を入れたところ、針鼠屋さんが担当するよーと快諾していただきまして。これで、グラフィックデザインの問題は解決して、正式にゲーム制作を始めることにしました。
※ 新発売の謎肉だけの商品。謎肉をコレでもかと堪能できます。自分で炒飯に入れてもよし、サラダにトッピングしても良し。そのまま齧ると新食感!

  • 基本システムの構築
比較的 CPU が高速と言われる PC-8001mk2 とはいえ、高速というより他の兄弟(PC-8001 とか PC-6001mk2 とか)が遅すぎるだけで、普通に Z80 でほぼクロック通りの 4MHz が出てるだけです。いや、実際には 3.7MHz 程度だったかと思います。そのため、最初に描画周りを徹底的にリファインしてサブルーチンを作っていきました。

画面に絵が出なければ何も分からないままですから、C# で PNG データを PC-8001mk2 形式のバイナリデータに変換するコンバータを作りました。重ね合わせをするマスクデータ付きだとか、バイナリの出力方向を指定するだとか、画像内で複数のキャラが存在する場合は1キャラ辺りの横幅を指定する等のオプションが指定できるようにしました。
CG80mk2.exe
この変換データを画面に出したのが 9月23日です。凡そ1週間で画面に画像が出るようにはなりました…が、これはまずは PC-8001mk2 の GVRAM 構造の理解が目的で、実行速度的にはあまり褒められたものではありませんでした😓


  • プレイヤーの移動処理
画面に絵が出たので、続いてはプレイヤーの移動処理を作成し始めます。プレイヤーだけは 16x24 と少し大きめのサイズとしました(実際には縦23ドット)。そのほうが見た目が良いためですが、そのため消して描いてと処理するとかなりちらつきそうです。また、実行速度的にも不利だなと思ったので、プレイヤーは描画と同時に移動差分消去も行うという特殊専用処理としました。例えば、下に移動した場合は、頭の上の部分の高さ 4ドットだけ消去するという処理です。
プレイヤー
また、リアルタイムで背景と重ね合わせ処理を実行すると、やはり処理能力的に厳しいことも分かってきました。そこで、基本色のタイリング背景とゲームが始まる前に事前に重ね合わせを実行しておき、ゲーム中ではその背景をマージしたプレイヤー画像をマップに直描きする事にしました。キャラが小さいので、余白サイズはかなり小さいです。その小さいサイズのために重ね合わせを実行するぐらいなら、背景と溶け込みやすいパターンでマージ済みのプレイヤー画像を、まんま直接描くだけとしたほうが処理速度は全然高速なはずです。
スライム
重ね合わせはしていないがし
このようなプレイヤーだけ特別な処理を作っていたため、プレイヤー移動がある程度動き始めたのは 10月5日までかかっています。
※一見普通のハサミですが、閉じてる状態でちょっとだけ刃先が出せるんです。そこを使って段ボールを開けると、中の商品に傷がつきにくいというアイディア商品です。カッターだと切り過ぎちゃうことありますよね?

  • ステージマップの描画
マップはまともにデータを保持すると、メモリをバカスカ消費してしまいます。今回はマップに関しては(一部を除いて)見た目だけの問題になっていますから、自動生成とか感簡易表示にしてしまおうと考えました。Stage-1 / 2 は草原ステージです。マップエディタで作る場合でも、殆ど自動生成で配置してしまうので、そのアルゴリズムと同等の処理を Z80 で書いてしまえと。結果、コードサイズはそれりの大きさになりましたが、データは数バイトから数十バイしか使わない描画処理が出来ました。
Stage-3
Stage-3 / 4 は森林です。重ね合わせも必要なので、流石にコードだけでは厳しいなあと、拙作の Magic.MapEditor を使って、マップの配置を作ってみました。最初は樹木の配置の数だけ、データを必要としていたりのですが、どうせ森林はある程度の塊でドンドンと配置していくだけだからと、ある程度の塊単位での配置としました。結果、ちゃんとしたマップ配置データなのに、データサイズは 73バイトに抑えることが出来ました。
Stage-4
Stage-4 は Stage-3 のデータにさらに上書きとすることで、データサイズを半減させました。この辺りのマップデータの省メモリ技術は、Newシティヒーロー作成時に確立していたりします。マップの制作は、今も続いています。新しいステージに開発が入るたびに、マップデータの構造を考えていってます。


  • AILZ80ASM の進化
10月の開発中にふと気が付きます。使用しているアセンブラ AILZ80ASM に、ネームスペース機能があるんだなと。そこで今回はこのネームスペースをフル活用することにしました。今までだと DrawPlayer とか、DrawMonster などとラベルを付けていましたが、それぞれの処理に [PLAYER] とか [MONS] 等とネームスペース名を定義して、描画なら全部 Draw: というラベル名で共通化しました。ゲームのメインルーチン側から呼び出す際は CALL PLAYER.Draw みたいな記述となります。このおかげでソースコードが格段に読みやすくなりました。
ネームスペース
2024年に入り、テンポラリラベルに対応して頂けたので、早速使いまくっています。このテンポラリラベルとは .@@ と記述するラベルで、そのラベルであれば、何個でも記述することが出来ます。そして、このテンポラリラベルにジャンプする際は、@@F とか @@B と記述します。@@F は下に流れます。@@B が上です。いずれも直近のテンポラリラベルが対象となります。これでいちいち .@0 .@1 .@2 とラベル名を管理する必要がなくなりました。まあ、テンポラリラベルを飛び越えてジャンプは出来ないので、そこは制限ありますが、それでもあるとないとでは大違いでした。
キワモノアイディア商品を作らせたら日本一かもしれないサンコーのおもしろ商品。SDカードって無くしやすいですよね?だったらSDカードリーダーに格納しちゃえば使いたい時にそこにあるし、無くさなくなるし最高じゃね?って作られた気がするデスw

  • ローダーの作成
10月13日、アセンブルしたバイナリファイルのロードが厄介になってきたので、ローダーを作り始めました。大元になったのは、Newシティヒーローのローダーそのままです。ただ、あちらはロード中演出が含まれていたので、それを削除して実装しています。ですが、1200baud ではまともにロードしないことが分かりました。また、後日判明したのですが、ローダーの処理にバグが隠れており、こちらのタイトルではそのバグが表面化してまともに動かないという困った状態になりました。

さらに加えて、私の PC-8001mk2 本体の異常が疑われました。ML で #80mk2 会の面々に協力を仰ぎ、データのロード実行テストをしてもらったところ、全員全く問題なし。私の環境でのみ、ロードエラーで止まってしまうという状態でした。そこで本体のメンテするよーっと仰って頂けた有志に本体をお預けしたところ、異常なしと診断されまして…
実機での動作確認
このロードの問題が解決したのは 2024年の2月までかかってしまいました。結局、プログラム的な問題に加えて、テープの位相問題がロードエラーの原因でした。今では、私のマシンでも問題なくロードが出来るようになっています。

あと、ローダー内部で SDドライブの存在判定を行っています。そのため、パッチを当てることなく、自分自身が SDドライブからロードされた場合は、内部での多段ロードはSDドライブから読み込むように動作します。あと、SDドライブ実装マシンに限っては、ハイスコアランキングはSDカードに保存するようにする予定です。


  • 怪物の移動処理
最初に動かし始めた怪物はスライムです。こやつは方向とかも何も無いので、作るのは簡単…なはずでしたが、実際には、その他の怪物の移動も含めた汎用的な怪物移動システムの構築が必要でした。例えば、ステージにどんな怪物がどんな順番で登場するのかとか、怪物の移動はプレイヤーを縦横で追いかけるのか、ランダムに動くのか、自由曲線なのか等々。
怪物登場テーブル
そこで、怪物の登場はテーブル参照、怪物の基本的な移動はスクリプトで行うことにしました。このスクリプトのプログラム実装にはやや時間がかかり、ある程度形になったのは 11月26日となりました。が、この時は本当にバギーで、少しスクリプトを弄るととたんにバグが出ると言った有り様。ある程度安定したのは翌年 2024年1月26日までかかることになります。

ここには本当に時間がかかりました。正直、作ってても一番つまんない部分ではあります。何しろ、数値的にこのコマンドを発行したらこう変わるというのを、ただひたすら確認しては修正という、地味な作業を数ヶ月続けたわけですから。ただ、これをきっちり作っておかないと、後で後悔すると思って…、いや理解していたので、ここには時間をかけました。
ゲーム画面
この移動スクリプトのお陰で、雑魚キャラの追加は1週間程度で出来ます。いや、1日で出来るんですが、1種類毎に特徴づけしてるので1週間ですね。例えば、緑のスライムはうごうご動くだけですが、赤のスライムはプレイヤーを狙ってたまに分身とばしてくるとか。黒のスライムは分身撒き散らします。こういう特殊処理がしやすいようにも設計してあります。

開発の進捗は下記の場所で適宜報告してます。フォローしてご覧いただければ幸いです。


※ありそでなかなかなかったBT対応3機種マルチペアリング対応の日本語フルキーボードです。海外製品にありがちな「ろ」の位置が正しいデス!しかもキーサイズも普通です!普通であることがこんなに嬉しいなんてw