魔王いっぺいのブログ -7ページ目

魔王いっぺいのブログ

ゲーム、漫画、AIなど、自分の趣味から考察まで、幅広く残していく。Youtubeチャンネルの補完的役割

擬似スクリプト言語の進捗です。


cコマンドを実装しました。下のサンプルでは、a、b、culctestの順に他のスクリプトを呼び出しています。



呼び出し先のスクリプトはこんな感じ。




また、特殊文字d(ダイスロール)を実装しました。下のサンプルコマンドではダイスロールの結果を変数に格納して表示します。



ボタンを押下する毎に各スクリプトの結果が表示され、最後にダイスロールテスト用のスクリプトの結果が表示されました。



【今回苦労したこと】

スクリプト間で制御を渡すところは一工夫いりました。


呼び出し元のスクリプトの状態を保留して呼び出し先のスクリプトを進めます。そして、呼び出し先の処理が終わったところで、元のスクリプトに制御を戻して自動で次に進むようにしなければなりません。


これだけならそこまで難しくはないのですが、呼び出し先のスクリプトがまだ完了していない状態でキー入力待ちになった場合も一旦呼び出し元に制御が戻ってくるので、その辺りをうまく動作させる必要がありました。入れ子で動く各スクリプトが状態を崩さずに、キチンと制御を渡せるようにしなければなりません。


スクリプト終端付近の制御にも手間取りました。色々なバグと格闘した末に何とか動きました。ちゃんと動いた時はちょっとした感動です。これでスクリプトを機能毎に分割して組み立てることが出来ます。


【次回の予定】

スクリプトに引数を与えて戻り値を返してもらうところまであと一息。cと対をなすrtnコマンドを実装予定です。そして、ifコマンドを実装すればスクリプトの自由度が一気に上がります。



毎回楽しみつつ作っています。

ようやく文字列表示や簡単な変数操作が出来るようになった、産まれたての赤ん坊のような擬似スクリプト言語。


しかし、目指したい方向性というか、全体像は何となく見えてきました。そこで今後実装したいコマンドを一覧に並べました。



全てのコマンドが実装できたら、この擬似スクリプト言語を使って本格的にゲームを実装することが可能になります。これだけあれば、コマンドベースの大抵のものは作れるはずです。


また、特殊文字もまとめました。



この特殊文字はコマンドの引数にも使えますので、スクリプトの組み立てが楽になります。特殊文字自体はグローバル関数を追加することで増やせます。


(例)rnd[10](0〜9の乱数)


既にダイスロール関数で乱数を生成できるようにしているので、この例の優先度はあまり高くないですが、頻繁に使う便利機能があれば加えたいです。


【今回の成果】

前回からの進捗です。


変数操作コマンドを改良しました。前回は「a+b」のように2項目と演算子のみのシンプルな計算式しかありませんでしたが、今回は「a=b+c」のように一行で処理できる項目数を増やしました。


改良版のサンプルスクリプトはこちら



変数の初期化と演算を同時に実行できるようにしたことで、前回の半分のステップ数で同じ結果が得られます。



また、ローカル変数にも対応しました。今後、ローカル変数はvコマンドを、グローバル変数はgコマンドを使って操作することにします。


元々コマンドと引数はカンマ区切りにしていましたが、文字列にカンマを使う頻度を考慮してパイプ区切りに変えました。この副産物として、スクリプトの可読性が少し上がりました。


【今回苦戦したこと】

スクリプトのローカル変数に対応しようとしたとき、正規表現の変換用に使っている無名関数からアクセスできないという問題にぶち当たりました。Javascriptのスコープ関連はもう少し勉強が必要ですが、複数埋め込まれる可能性のある特殊文字を変換するには正規表現が大変便利な為、無名関数からもローカル変数にアクセスできるようにしたかったのです。


対応として、実行中のスクリプトをグローバル変数に格納しておき、共通関数からローカル変数にアクセスできるようにしました。


【雑感】

改めて、正規表現の威力に驚いています。特殊文字の変換や計算式の解析に大活躍です。正規表現のお陰で多少複雑な文字列操作も短いコードで実装できています。


あと、コマンドをオブジェクト化しておいて正解でした。所謂Factoryパターンを採用したのですが、仮想マシンの心臓部分は思った以上にスッキリしています。


個々のコマンドの処理内容を各コマンドクラスに委譲することでスクリプトクラス本体はローカル変数の管理や分岐、ループ、他スクリプト呼び出しといったコアな処理に集中することができます。そして、コマンド毎に処理が分割されることで実装単位が小さくなり、バグや作り直しの影響範囲も狭まりました。


複雑なことをやろうと思ったら、一気に全部を作るのは無理です。処理を分解して少しずつ組み立てていく。これがオブジェクト指向の本領ですね。


「擬似スクリプト言語を実行する仮想マシンをJavascriptで実装する」という試みも、初めは途方もない作業のように思えましたが、一歩一歩進めるうちに何となく形が見えてきました。


まだまだ先は長いですが、夢は膨らみます。

擬似スクリプト言語制作、本日の成果です。


今回は変数を色々と計算できるようにしました。


テスト用のスクリプトがこちら



vコマンドに演算子(=,+,-,*,/,%,&)が追加されています。各コマンドでやっているのは以下の処理です。


変数a 文字列を代入

変数b 1+2 (加算)

変数c b × 5 (乗算)

変数d c を2で割った商 (除算)

変数e dを3で割った余り (剰余)

さらに文字列「gold」を結合


テスト結果がこちら



計算式の文字列を読み込ませ、正規表現で解析します。解析結果は以下のような基本パターンになります。


「A」「演算子」「B」


この3つのパラメータを計算ロジックに渡して、計算結果をAに代入するのです。


以下のコマンドのように格納先の変数名を変数で指定することも可能です。


v,hoge=HP

v,v[hoge]=100 (変数HPに100を代入する)


また、計算系の処理はボタンを押下しなくても自動でスクリプトを読み進めるようにしました。


【次のステップ】

①ローカル変数も扱えるようにする

②スクリプト間で引数、戻り値をやりとりできるようにする

③分岐処理を加える


①は比較的簡単に実装できそうです。②と③も少し工夫すれば何とかなりそう。


これらのステップが終わったら、スクリプトを使って本格的な処理体系を作ることが出来るようになります。

擬似スクリプト言語作成の続きです。


今回は変数の入力と表示機能を実装しました。テスト用のスクリプトこちら



vコマンドで変数aと変数bに値を代入します。

tコマンドでv[変数名]を指定すると、変数の中身に変換して表示してくれます。



正規表現と変換機能を利用しました。最初は「undefined」が表示されて困りましたが、変換用の無名関数にreturn文を入れていなかったのが原因でした。


【次の課題】

テキスト表示以外のコマンドはボタンを押下しなくてもスクリプトが進むようにする


スクリプト単位でローカル変数を保持、操作できるようにする


変数の代入だけでなく、四則演算も出来るようにする


条件分岐を実装する


亀の歩みで進化させていきます。

テキストベースのゲームを作成中です。


今回はスクリプトを読み込ませて実行する仮想マシンを作成しました。スクリプトはCSV形式で、こんな感じです。



「t」はテキスト表示コマンドを表します。スマホから編集しやすいように、コマンド名はなるべく短縮します。


「c」コマンドで別スクリプトを呼べるようにする予定です。スクリプトを適度な単位で切り分けて構造化できるようになります。


【前回の課題】

外出先から接続できない。→ネットワークの都合上、使えるポートが限られていました。割り当てられたポート番号を使うことでエラーが解消されました。


ゲームのステート管理をどうやるか。→画面上でグローバル変数を持てることが分かり、あっさり解決しました。


【今回格闘したこと】

コマンドやスクリプトをオブジェクト化して、コマンドの種類が増えた時にもコードがスッキリするようにしました。


スクリプトから別スクリプトを呼ぶことを考え、親スクリプトが子スクリプトを保持するマトリョーシカ構造にしました。再起的に処理させることで、コードがスッキリします。


キーボードの1や2を押下してもボタン押下と同じアクションをするようにしました。


【考えないといけないこと】

分岐処理をどうやって実現するか。何となくイメージは湧いてるけど、実際に仮想マシンを動かせるようにするには、それなりに考えないといけないです。


プログラミング言語でいうif文の部分なんですが、スクリプト内でif文が入れ子になってもちゃんと動作する仕組みが必要です。スクリプトの呼び出し関係は再起処理を使って実現できるのですが、スクリプト内のif文の状態をどう管理するか、うーん悩ましい・・・。


if文の入れ子を許さない(例えば分岐する時は必ず別スクリプトを呼び出す)とかにすると、実装難易度は比較的下がります。昔のRPGツクールも分岐処理はシンプルでした。


変数の持たせ方も悩ましいです。RPGツクールのように全部グローバル変数にしちゃえば楽なのですが、スクリプト内のローカル変数があったほうが、後々便利なんですよね。ゲームが大きくなればなるほど、変数管理は煩雑になってくるので。


ちょっと考えますが、とりあえず最初は簡単なものを完成させることを目標にしたほうがよさそうですね。

ブラウザゲーム作成2日目です。


phina.jsの学習コストやモチベと相談して、よりシンプルな構成でスタートすることにしました。


【画面レイアウト】

HTMLとCSSで定義しました。やりたいことをググるとすぐサンプルコードが手に入ります。打った結果がすぐに見れるのも嬉しい。(←これ大事)


しばらく格闘した結果がこちら


それらしいゲーム画面が出来ました。非常にシンプルなUIなので、テキストエリアとボタンの描画周りは全てCSSの属性指定で済みました。ネットでフリーフォントを拾ってきて、レトロな雰囲気を演出しています。


内部処理はjavascriptで書いていきます。コーディングしやすくする為、よく使う共通機能はutil.jsに定義して、使い回すことにしました。


テキスト表示処理はこんな感じ


画面読み込み時に呼ばれる処理で、サンプル文を表示させています。


ここから、ボタン押下時に呼ばれる処理でゲームを動かしたいのですが、どんな仕組みにすればコーディングが楽に済むか、思案中です。


【ここまでに格闘した主な内容】

・解決済み

Safariがキャッシュを記憶してしまい、更新内容が画面に反映されない→HTMLヘッダでキャッシュさせない設定


ページ全体に指定したつもりの書式がテキストエリアやボタンに反映されない→CSSに個別設定を追加


ボタンをダブルタップすると画面が拡大されてしまう→CSSで動作制御


・未解決の問題

家の外からインターネット経由でアクセスすると504エラーでタイムアウトしてしまう


家のWifi経由だとURL指定でも表示されるのですが、Apacheのタイムアウト設定あたり?


【今後の課題】

ゲームを進行するには必ずステート管理が必要だが、ボタンキックで動かす場合、ゲームの進行状況をどんな形で保持するべきか。


シナリオデータをどんな形で保存するか。データを読み込ませて動かすにはRPGツクールのような仮想マシンが必要だが、どんな作りにするか。特に条件分岐やイベント呼び出しの仕組みをどうやって実装するか。


チマチマと育てていく感じが楽しいです。


Chaotic Journey


に触発され、ブラウザゲームを作ってみることにしました。テーマは「スマホで開発」です。


第一日目にやったこと


サーバ構築

マイクラサーバーとしてはスペック不足になってしまった10年前のミニPC。こいつを再利用して、 Ubuntu上にApacheを導入しました。マイクラ同様、ルーターの設定をいじってポートを公開すれば、世界中どこからでもアクセスできるWebサーバーの完成です。


スマホからサーバ上のファイルをいじれるよう、SFTP環境を設定しました。※セキュリティ面は要注意



phina.jsの導入方法を調べて、とりあえず真っ黒なスクリーンを表示するところまで完了。


開発環境はあっさり整いました。


ブラウザゲームなので、電車の移動中にスマホからチョコチョコ開発して、テストプレイすることも可能です。

Javascriptのゲーム開発はむかーし迷路ゲームを作って以来です。とりあえず簡単なコマンドベースのミニゲームにしようと思います。

Chaotic Journey


Chaotic Journeyというフリーゲームを最近プレイしました。夢現にもレビューを書きましたが、学ぶべきことが多かったのでブログにもまとめます。



【徹底したミニマル化】

このゲームにモンスターのグラフィックはありません。また、ダンジョンマップもありません。その辺りは全てテキストベースで語られます。フィールドらしきマップは、常に自分の周囲9マスがランダム生成されるというものです。アイテム、装備品のストック、従者は全て同じインベントリ内で管理されます。これらが全て一つの画面レイアウトに収まっています。


主な基本操作は以下


①フィールドでの上下左右移動

②1〜6の選択肢ボタン(選択内容はテキスト表示)

③インベントリ、装備品のアイコン選択


ゲーム内で進行するダンジョン探索、イベントや戦闘は全て、画面の大部分を占めるコマンドライン上に文章で表現されます。


【拘りポイントへの注力】

グラフィック・アニメーション周りや画面遷移を極限まで削った代わりに、このゲームには細かい機能がたくさん実装されています。


①多種多様なクラス(職業)

②装備品の製造、強化、ランダムエンチャント

③多様なランダムイベント

④豊富なアイテム


TRPGで体験したくなるようなイベントはほぼ全て実装されており、見た目はシンプルですが奥が深いです。戦闘には士気の要素があり、戦闘で士気が大幅に下がったモンスター集団は撤退します。


【個人制作で完成させる為に】

削減された工程

①固定マップ・シナリオ作成

②グラフィック演出・画面デザイン


代わりに得たもの

①リプレイ性

②拡張性


個人制作は時間もリソースも限られています。全てに手を広げると、完成させるのは困難です。なので、何に注力して何を捨てるのか、選択する必要があります。


ローグライク形式を選択すると、シナリオ作成コストを削減し、自由度の高さ、リプレイ性の高さを得ることができますが、その代償として相当量のプログラム実装が求められます。


フリーゲームに一本道のRPGが多いのは、このランダム要素の実装コストが高いからです。見た目やシナリオを拘りたい創作者は、ランダム要素の実装まで手が回せません。欲張って全部に手を伸ばせば、エターなります。能力の問題ではなく、単純に体力と時間の問題です。


このゲームはローグライクの面白さを追求するため、フィールドマップを完全ランダム生成とし、かつ生成されたマップを記憶しないという大胆な割り切りをしました。普通の発想ではなかなか出来ない英断です。


マインクラフトは探索を進めると、ワールドデータがどんどん膨らみます。生成されたマップデータを記憶して、プレイヤーが戻ってきた時にいつでも読み込めるようにしておくためです。無限大に広がるランダム世界では、膨らむワールドデータをどう管理するかという問題に向き合わねばなりません。


ですが、「生成されたマップは9マス以上記憶しない」としておけば、データの書き込み、読み込み領域を固定化することができます。通り過ぎたマップのデータは捨てて上書きしてしまうことで考慮すべき点が減り、マップ自動生成の実装コストを抑えることが出来ます。


それでいて、プレイヤーが体験できる世界の広さは無限大なのですから、この割り切りは作者プレイヤー双方にとってお得な取引なのです。


どこまで削ってよいか、この線引きのセンスは、どこまでプレイヤー心理を熟知しているかにかかっています。ランダム生成された世界を楽しむローグライクでは、特定の場所に戻れないことは致命的な欠陥ではないと判断できたのです。


「モンスターのグラフィックを無くす」といった割り切りも一般的な制作者心理では怖いものですが、ローグライクの醍醐味を熟知している作者なら「面白くしてみせる!」と踏み込めるのです。実際、バトルは色々な要素が絡んで楽しめる内容になっています。


テキストベースの独特な世界感を支えているのは、実はグラフィックです。レトロ調に統一された画面がその説得力を全て請け負っています。当時はハードウェアの限界で、どうしても世界を記号化せざるを得なかった。でもそれが逆にプレイヤーに想像の余地を与えて、脳内で楽しめるようになっていた。昔はこういうゲームが普通だったんだ。プレイヤーはそのレトロな世界を受け入れ、浸るのです。


最後に作者視点での大きなメリットを挙げて終わります。拡張性です。全体がテキストベースのランダムイベントで成り立っているシステムですから、新しい要素も比較的追加しやすい作りになっています。所謂マイクロサービスに近い作り方が出来ます。


例えば、このゲームにはカジノという独自のサブルーチンを追加して、ランダムイベントの候補として加えることでアップデートが可能です。


グラフィックは不要です。コアなロジックを用意してあげれば、文章表現でスロットゲームも実装できます。プレイヤーの脳内補完を利用したコマンドベースならではの強みです。


ベースを固めてから少しずつ育てられるゲーム基盤は、リプレイ性の高いローグライクの特権であり、一話完結してしまう一本道RPGでは中々こうはいきません。アジャイル的に作れるというのは、体力的にもモチベ的にも、実は個人制作では大事な要素なのではないかと、最近思うようになりました。


この拡張性を可能にする土台作りには相当な労力がいったと思います。リリースにこぎつけられたのは、ひとえに作者さんの情熱があったからだと思います。


このゲームには色んな意味で、刺激と希望を与えられました。私自身、純粋にプレイヤーとして何時間も楽しんでいますが、制作者視点でも得るものが大きい作品です。私がこの作品を知るきっかけとなったYoutube動画のコメントに集約されるのですが、本当に「つくりが美しい」です。



興味を持たれた方はぜひ覗いてみて下さい。

少し前から始めた自宅サーバーで遊ぶマイクラシリーズ。今日はPC的なお話を。


マイクラ専用サーバとしてミニPCを買いました。お値段は24,000円。CPUはIntelのN100、メモリ12GBです。いわゆるローエンドモデルですが、4〜5人で遊んでいる分には全く支障ありません。低負荷時の消費電力は2〜3W程度で、24時間稼働でもそこまで電気代はかかりません。


クライアント用のミニPCも新規調達しました。こちらはゲーム配信用なので、性能を少し欲張って65,000円。CPUはAMDのRyzen 6800Uで、32GBのメモリ、1TBのSSDです。内臓GPUはRadeon 680mを搭載しており、シェーダーを入れてもぬるぬる動きます。


このCPUは2023年時点で最高クラスの電力効率を誇ります。フルHD、60FPS設定でゲーム配信するとフル稼働になりますが、25W程度しか消費しませんし、発熱が少ない分、冷却ファンも割と静かです。


マイクラ配信にはアナーキー鯖時代からの知り合いがよく登場します。日本からamoさん、Rahanさん、イギリスからForteanSlipさん、フィンランドからはPK_Ripperさん。それぞれ、村の周りに様々な建物や装置を作っています。


たまに荒らしも出現します。何度か酷く荒らされて、ワールドデータのバックアップ戻しも発動しました。


サーバーは公開されていますので、気が向いたら覗きに来て下さい。

ipeiworld.clear-net.jp:53599




マインクラフト、EearthMCの日記です。


サハラ砂漠の緑化は地道に続いています。



衛星写真からもはっきりと見えますね。

四国くらいの広さになったでしょうか。



ワタクシがログイン出来るタイミングがあまり無かったのですが、裏でRahanさんがコツコツと広げていました。


活動拠点もお洒落なツリーハウスに変身。


拠点周辺には田園風景が広がり、ニンジン畑にはウサギが集まっています。


ウサギの革を大量に集めて本棚の数を増やし、ついにシルクタッチのエンチャントが出来るようになりました。シャベルの効率性も上がり、ポーション無しでも土ブロックをサクサク掘れます。


好きな場所に草ブロックを置けるようになり、砂漠の緑地化が進みました。


少しずつですが、これからも土を撒いて木を植えようと思います。