TOUMEI MAHJONG 透明麻雀
- JavaScript (vanilla)
- Node.js
- WebSocket
- CSS 3D Transform
- Blender
- Figma
- Render
OVERVIEW
プロジェクト概要
課題
麻雀には100年以上の歴史があり、役も点数も数えきれないほど検討されてきた。 それでも「手牌は非公開情報」という前提だけは動いていない。 誰も思いつかなかったからではなく、物理の牌では仕方がなかったのだと思う。 透明な牌を用意して実際に打ってみても、牌は読みづらい。 通常牌と透明牌の比率を、卓ごとに好きなように変えることもできない。
目的
画面の上なら、その制約は消える。 見える牌の枚数はただの数値なので、遊ぶ人が卓ごとに0〜4枚から選べばいい。 読みづらさのほうは、卓の3Dと牌の質感を作り込むことで解く。 100年動かなかった定数を、プレイヤーが握れる変数にする——それが作りたかったもの。 役・符・点数・鳴きは通常の麻雀のままなので、覚えた知識はそのまま使える。
PROCESS
制作プロセス
-
RULE
役・符・点数・鳴き・流局の裁定を1つの仕様書に正本化。点数計算はユニットテストで固めた。
-
SERVER
Node.js + WebSocket のサーバー権威型で実装。牌山・配牌・和了判定・CPU思考はすべてサーバー側。
-
UI
Figma で画面を設計し、卓は CSS の 3D Transform で構築。牌は6面体で厚みも透明感も CSS で表現。
-
ASSET
雀卓と牌を Blender で組み、卓の上での見え方を見ながら質感を調整。牌は111枚を一括生成。
-
TEST
E2E 15本と型チェック(JSDoc + TypeScript)で回帰を止める。ルールを触るたびに全部通す。
-
DEPLOY
Render にブループリントでデプロイ。push するだけで公開版が更新される。
GALLERY
成果物ギャラリー
RETROSPECTIVE
振り返り・工夫した点
CHEATING IS A DESIGN PROBLEM
「見える牌」がルールの中心にあるゲームなので、 見えてはいけない牌が漏れないことを構造で保証した。 他家の不透明牌の種類は、そもそもクライアントへ送っていない。 サーバーの1関数だけが「誰に何を見せるか」を決める唯一の境界で、 ブラウザ側は開発者ツールを開いても知りようがない。
ROUGHNESS MAKES IT GLASS
見える牌が主役なので、質感で手を抜くと企画ごと安っぽくなる。 雀卓と牌を Blender で組み、卓に置いた状態で見え方を確かめながら詰めた。 透明牌はプリンシプル BSDF の Roughness を通常牌の 0.34 から 0.05 へ落とし、 コートを上げてガラスの締まりを出している。 ノイズバンプを足すとハイライトが割れて「曇った氷」になり、 かえって透明感が落ちたので、平滑面と面取りだけで通した。
ANYONE CAN JOIN
誘われた側に負担をかけないことを優先した。 ルームを作ると QR が出て、読み取った人はそのままゲストとして席に着ける。 インストールもアカウント登録もいらない。空席は CPU が埋めるので人数も揃えなくていい。 画面はスマートフォンからPCまで同じレイアウトが伸縮する作りにして、 同じ部屋にいる人とも、遠くにいる人とも同じ手順で遊べるようにした。
ONE RULE ENGINE
和了判定と点数計算はブラウザと Node.js の両方から読める形で書いた。 サーバーの判定と、手元に出る待ち牌表示が同じコードで動くので、 二重実装によるズレが起きない。ルールを直す場所も常に1か所で済む。
MEASURE, DON'T GUESS
「iPhone 16 Pro Max だけ手牌が45%大きい」という報告。 原因は小画面用の条件が横持ちの 956×440 に 6px 差で外れ、 px の下限値が効いていたこと。推測せずに実測したら 43.2px → 31.2px と他機種に揃った。1行の修正だった。
CACHE COST A DAY
差し替えたはずの素材が最大1日ふるいまま出ていた。 しかも CSS の背景画像は、ファイル名に付けたバージョン番号では破れない。 静的配信をETag + no-cache(=キャッシュしてよいが使う前に必ず確認する)へ変更して根治。 一致すれば 304 が返るだけなので、転送量はほぼ増えない。
WRITE DOWN WHAT YOU COULDN'T FIX
Apple 端末だけ他家の立ち牌が平らに見える問題は、まだ直せていない。 代わりに何を潰して何が残ったかを消去法で全部記録し、 回避策まで書いて残した。直せなかったことを隠すより、 次に触る人(自分を含む)が同じ道を辿らずに済むほうが価値がある。
LIVE
公開版で遊ぶ
最初に開くときだけ、起動に30〜60秒かかります。 画面が白いまま止まって見えても、リロードせずそのままお待ちください (無料ホスティングのため、しばらくアクセスがないとサーバーが休止します。一度起きればあとはすぐ開きます)。 ログインもインストールも不要で、開いたその場から CPU 戦が始められます。 スマートフォン・タブレットは横向きでお使いください。