Project Plateau
Project Plateau: four glass plates, one living valley, and the road back to camp.
翻訳待ち
No updates detected yet. GitHub releases will appear here.
割り箸ゲーム+能力カードの2人対戦ブラウザゲーム
Loading the full README.
Read the full README ↗2人対戦のブラウザゲーム。相手の両手をアウトにしたら勝ち。
遊ぶ: https://finstgame.github.io/
部屋を作って6文字のコードを相手に送るか、リンクを開いてもらえば始まります。 インストール不要。1台を回して遊ぶモードもあります。
ホーム画面に追加すると、アドレスバーの無い全画面で起動します(PWA)。 電波が無くてもCPU戦と1台版は遊べます。
浮遊する闘技場で、魔法陣の上に光るクリスタルが浮かびます。クリスタルの個数が本数を表し、自分は緑・相手はピンクで表示します。クリスタルや魔法陣を選んで対戦できます。相手の本数表示は盤面の上部に配置しています。隕石の落下、召喚の魔法陣、カウンターの反射など、能力カード全20種の3D演出を搭載。上部のボタンから2D表示にも切り替えられます。
assets/vendor/ に同梱。ライセンスは同フォルダにあります。npm start(Node.js)、テストは npm test、ランダムな対局を大量に回して盤の壊れ方を探すのは npm run fuzz(1台の対局は node tests/fuzz.mjs 対局数 種、2台をつないだオンライン対戦は node tests/fuzz-online.mjs 対局数 種。後者は通信の遅れを入れて2台の盤がずれないかを見る)。46件のルール・描画連携・リソース解放・オフライン文書分離のテストを含みます。ロビーの「はじめての人はチュートリアル」(または ?go=tutorial)で、CPUとの決まった流れの1試合を遊びながら操作を覚えます。
構える → 攻撃してアウトにする → 分配 → 防御カード(シールド)→ 能力カード(倍返指)で勝つ、の10段。
いまの段で求めている操作だけを受け付け、違う操作は案内をゆらして止めます。勝ってもCPU戦の勝利数(スキン解放)には数えません。
一度終えるかスキップすると、ロビーの表示が「チュートリアルをもう一度」に変わります(finst_tut_done)。
ロビーのスキンショップで、自分の駒(3D盤で本数を表す駒)の形を変えられます。色はプレイヤー色のままです。
CPU戦の勝利数で解放します。全15種:指0勝(標準。CPUの駒も指)・クリスタル1・しずく2・炎3・ハート5・星7・雷10・キューブ12・剣15・三日月20・桜25・盾30・牙40・ダイヤ50・王冠75。勝利数は端末に保存します(finst_cpu_wins)。
オンライン対戦では相手にも自分のスキンが見えます。形は arena3d.js の PIECES、一覧と解放条件は index.html の SKINS。
自分の番にできるのは、次のどれか1つ。
| タッチ | 自分の手で相手の手をタップ。自分の本数が相手に足される |
| 分配 | 両手の合計を組み替える。0の手も復活できる。同じ配分・左右の入れ替えだけは不可 |
| カード | 手札から1枚使う |
能力カードはモードで決めた範囲から3枚。各1回きりです。自分の番を手札なしで終えると、次の自分の番に1枚だけランダムに配られます(何度でも)。略奪で相手の番に取られた場合は、自分の番を1回手札なしで過ごしてから配られます。相手の手札は見えません。
| モード | 種類 | 5の扱い |
|---|---|---|
| イージー | 10種 | 5以上でアウト。効果が一目でわかるものだけ |
| ハード | 20種 | 5以上でアウト。全カード |
| テクニカル | 20種 | ちょうど5でアウト(超えたら余り)。全カード |
「防御割り込み」のカードは相手に攻撃されたときに使い、15秒で自動パスになります。
| ファイル | 中身 |
|---|---|
index.html | 本体(フレームワークなしの素のHTML/CSS/JS) |
finst-phase1.html | カードなしの初期版 |
manifest.webmanifest | ホーム画面に置くための定義 |
sw.js | オフライン用のサービスワーカー |
supabase/schema.sql | オンライン対戦用のテーブル・RLS・Realtime設定 |
supabase/matchmaking.sql | 野良マッチ(待ち行列) |
supabase/rating.sql | レートとランク分け。schema → matchmaking → rating の順に実行する |
アップデート2.0で一時停止中(遊ぶ人が増えるまで)。index.html の RATING_ON を true に戻すと再開します。
データベース側の関数とテーブルは残してあります。
ランダム対戦だけレートが動きます(友達との部屋は動かない)。1200から始まり、 近いレートの人から順に当たります。相手が見つからないときは待つほど許容レート差が 広がり、最後はだれとでも当たります。
| レート | ランク |
|---|---|
| 1800〜 | マスター |
| 1600〜 | ダイヤ |
| 1400〜 | プラチナ |
| 1200〜 | ゴールド |
| 1000〜 | シルバー |
| 〜999 | ブロンズ |
計算はすべてデータベース側(report_result)で行います。クライアントが言えるのは
「この部屋を集計してくれ」だけで、勝敗は関数が共有盤面(matches.state)を読んで決めます。
負けた側が「勝った」と送っても通りません。決着していない盤面や、負けた側の手が
残っている盤面も弾きます。1部屋につき1回しか記録しません。
残る穴は、共有盤面そのものを書き換えられることです(クライアントが state を書く構成のため)。
そこまで塞ぐには、手の正しさを検証する審判を Edge Functions に置き、
matches への書き込みを service_role だけに限る必要があります。
Supabase Realtime で対戦状態を同期しています。静的サイトなのでサーバー側の審判が存在せず、 クライアントが状態を書き込む構成です。理屈上チートは可能で、ルームコードを知っていれば 誰でもその対戦を読み書きできます。友達内で遊ぶ前提の割り切りです。