オンライン舞星

https://github.com/Gypsophila1912/MaiStar

CSS

JavaScript

Node.js

HTML

オンラインマイスター!

ぎぷそ

Maaakia

いぶき

推しアイデア

ボードゲームの舞星をオンライン化!

作った背景

ボドゲの舞星が面白かったからオンラインでみんなとできるようにしたかったから

推し技術

和を追求して「なでしこ」という言語を使用

プロジェクト詳細

ゲーム概要

ボードゲーム「舞星」をオンラインゲーム化!

舞星・雅 🌸

花柳界を舞台にした、3人用オンライン対戦カードゲーム


概要

舞星・雅は、花柳界をテーマにした戦略系カードゲームです。
プレイヤーはそれぞれ一人の舞妓を率い、客を招いて座敷を賑わせ、最も多くの金子を稼いだ者が勝利します。


テーマ関連

舞星界隈に新たな風を起こす! 芸者に新たな技を持たせてゲームに波風を起こして既存の舞星とは違った体験に

ゲームの特徴

  • 3人のオンラインマルチプレイ
  • 舞妓ごとに異なる固有能力と3ラウンドを通して1度しか使えない固有の「技」
  • 客カードの特殊効果によるゲーム進行と連鎖や強カードをうまく使った逆転劇

ゲームの流れ

ラウンド開始 → 手札配布 ↓ 各プレイヤーが順番にアクションを実行 ├─ 座敷 : 手札から客カードを出して収入を得る ├─ 宣伝 : 宣伝カードを出して評判を上げる └─ 紹介 : 手札を交換する ↓ ラウンド終了条件を満たしたら得点計算 ↓ 3ラウンド終了後、最多金子のプレイヤーが勝利!

技術スタック

image

日本語プログラミング言語「なでしこ3」をフロント・バック両方に採用した意欲作です。

Socket通信 + API連携

今回のアーキテクチャは以下

フロント(なでしこ3) ↓ Socket.io Socketサーバー(Node.js) ↓ HTTP POST APIサーバー(なでしこ3) ↓ レスポンス Socketサーバー ↓ emit フロント

・リアルタイム通信 → Socket.io ・ゲームロジック → APIサーバー(なでしこ3) ・状態管理 → API側で一元管理

socket.io採用理由 当初は、なでしこ3のWebSocketプラグインを使う予定でしたが、リアルタイム対戦ゲームを作るには機能が不足していると感じました。

特に、イベントベースでの処理分岐やルーム管理、再接続対応などをすべて自前で実装する必要があり、実装コストや保守性に課題がありました。

そこで、これらの機能が標準で揃っているSocket.ioを採用しました。 結果として、通信はSocket.io、ゲームロジックはなでしこ3のAPIに分離することで、シンプルで扱いやすい構成にしてます

裏のコードはこんな感じ

image 普段のコードが日本語で処理を書いている形です もし➡if    ここまで。➡ } 鍵括弧の閉じる「 } 」一つでいいのに「ここまで。」って書かないといけないです 無駄に長いですね

なでしこはコードを記述するとjsに変換されて動くっていう形になっています 基本はフロントエンドを記述したりプログラムの動きの勉強のために使われたりする言語ですがNode.jsを動かせたりプラグインでexpressを扱えたりなでしこで書いたコードをAPI形式の形にして通信側に渡したりすることができて今回バックエンドも主になでしこで記述しています

なでしこが日本語の特殊な言語なため普段起きないエラーが起きて苦労というか時間がとられてたりしましたimage

これは「の」がなでしこによって助詞判定されて「く」が単語扱いされているような状態になっている 自分(いぶき)英語大っ嫌いなんですけど日本語が嫌いになりそうでした

なでしこがいつどこで引っかかって動かなくなるのか/なっているのかわからない都合上ゲームの処理とデータはテストしてました 以下テスト関係のプルリク投げたときのやつ https://github.com/Gypsophila1912/MaiStar/pull/8 テスト関係のフォルダ https://github.com/Gypsophila1912/MaiStar/tree/main/tests

以下テストコード実行ログ テストでは各動作自体は全部通っている状態 image image image ちゃんとたたけば全カード動いてくれる はず

画面

ホーム画面 image ルーム入室 image 合流画面 image 対戦画面 image 舞妓が朧だから開幕2ドローが反映されて手札が多くなってます

客の能力発動の例 image 以下長い細かいゲームルール Topa'zの一番最後に新しく追加してる能力とか書いてます 我こそはまいすたーまいすたーだという人は是非読んで下さい

ゲームルール

ゲーム開始時に12種類の舞妓が各プレイヤーにランダムに割り振られます

各舞妓は赤・青・緑の3色の評判値を持っています。 三色はそれぞれ赤:芸事 青:接客 緑:教養となっています 客カードを出すには、そのカードの色に対応する評判値が条件値以上である必要があります。

例:赤の客カードの条件が4の場合、自分の赤の評判が4以上必要

評判は「宣伝」を行うことで上げられます。宣伝カードの色に応じた評判が上がります。

手番の流れ

  1. 技の使用(任意):基本行動の前にのみ使用可能(3ラウンド通した各ゲーム1回)
  2. 基本行動:以下から1つ選んで実行
    • 座敷:手札から条件を満たす客カードを1枚出す
    • 宣伝:手札から1枚を宣伝カードとして使い評判を上げる(山札から1枚引いた後に宣伝カードを選ぶ)
    • 紹介:手札を最大2枚捨てて同枚数引く
  3. 予約客の使用(任意):条件を満たしていれば予約客を座敷に出せる

予約客

  • ゲーム開始時に手札から1枚を非公開で予約客としてセットする
  • 自分のターンにいつでも条件を満たしていれば客として出せる
  • 条件を満たしていない場合は手札に戻り、山札から1枚ペナルティドロー

ラウンド終了条件

以下のいずれかを満たすとラウンドが終了します。

  • 条件A:いずれかのプレイヤーの手札が0枚かつ予約客がない状態になった
  • 条件B:いずれかのプレイヤーの座敷の客が5枚以上になった
  • 条件C:山札が0枚になった

条件Aでラウンドが終了した場合、そのプレイヤーはボーナスを獲得します (ラウンド1・2:+5点、ラウンド3:+10点)

条件A以外の場合は、最後の1周が終わってからラウンド終了となります。

得点計算

得点 = 座敷の客の収入合計 - 手札ペナルティ

手札ペナルティ:残った手札枚数に応じて減点

  • 1枚:-1点
  • 2枚:-3点(1+2)
  • 3枚:-6点(1+2+3)
  • N枚:-(1+2+...+N)点

得点が0未満の場合は0点として扱います。

基本的には客の効果を有効活用し、手札がすべてなくなった人が出たらラウンド終了となり、その時に場に出ていた客に応じて金子を稼げます

3ラウンドを通して一番金子を稼いだ人が勝利となります

予約客…ゲーム開始時に1枚非公開で手札から予約客を置きます 予約客は条件を満たしていれば自分のターンでいつでも客として出すことができます

プレイ方法

  1. URLにアクセスしてニックネームを入力
  2. 部屋を作る → 合言葉を仲間に共有
  3. 仲間は 部屋に入る → 合言葉を入力して入室
  4. ホストが ゲームスタート を押してゲーム開始!

各カード能力一覧

赤・青・緑/客カード(各色2枚)

image

赤・青・緑/客カード(各色1枚)

image

無色客カード(各1枚)

image

条件タイプについて

  • 同色: カードと同じ色の評判値で判定
  • any: 赤・青・緑のうち最大値で判定
  • 手札反応: 条件なし・手札から発動する特殊カード

舞妓カード

常時発動効果

image

技(スキル)

image

技使用条件

  • 技は基本行動の前にのみ使用可能(各手番1回)
  • M07は4ターン目以降かつ自分の得点が全員最低の場合のみ使用可能

初期手札枚数

image

朧は能力が反映され各ラウンド+2枚ドロー状態から開始します

おまけ

うぇいぶこーでぃんぐ

image

舞妓の技名と能力、できるだけストーリーと性能に嚙み合わせながら考えたから供養 使用可能なのはゲーム3ラウンドを通して一回 skillName➡技名 skillDescription➡性能

朝霧・夕霧 "skillName": 明日は明日の風が吹く "skillDescription": "手札をすべて捨て同じ枚数引く(勝利条件は満たさない) 鈴音 "skillName":うら若き音 "skillDescription": 宣伝をさらに一回行う 夏海 "skillName":富める夏 "skillDescription":山札から五枚引いて2枚公開で手札に加えて最大三枚手札を捨てる 紅葉 "skillName": 才能の秋風 "skillDescription":他プレイヤー1人が場に出している赤い客カード1枚を自分の客として移動させる(登場時効果は発動しない) 初代舞星 "skillName": 舞星への道 "skillDescription":全員はカードを二枚先に捨て二枚引く 春風 "skillName":春一番 "skillDescription":5コスト以下のカードを色と評判に関係なく客に加える。その客の効果は発動する 雪 "skillName":儚き笑み "skillDescription":4ターン目以降に発動可能。自分の才能合計点が全員最低なら他全員の最新の客を1人捨て、手札から2枚無条件に客として出す(登場時能力使用可能) 朧 "skillName":真の実力 "skillDescription":自分以外全員2ドロー。自分は7コスト以下のカードを無条件で客として出す(客の効果は発動する) へのろいど "skillName": "機械仕掛けの熱", "skillDescription":山札から大名を手札に加える。なければ異人、なければくのいち。それもなければ手札1枚捨てる。その後3回宣伝を行う 葛葉 "skillName":隣の芝生 "skillDescription": その手番の間すべての評判を+4する 沙羅 "skillName":異風堂々 "skillDescription":自分を含め全員の最新の評判を捨て札にする。その後自分は二回宣伝 明星 "skillName": "明けの明星", "skillDescription":手札のすべてのカードのコスト条件(必要評判)を-2として扱う(0未満にはならない)

おまけ

芸者は全部で12人で全キャラ作りました。 image マーキアの苦戦した点は、 ・全キャラのデザイン考えたのに芸者の画像が手札に全く表示されないとこ... ・発表ぎりぎりに、行動記録のログが、ニックネームと対応できました!!!(重複表示があるので、改善します。) 全体の感想として、AIの考えるデザインに感動と癒しをもらっていました。 シャドバとかのDCGってすげぇなーってまた思いました

ぎぷそ

@Gypsophila1912