Skip to content
watamario15 edited this page Jan 20, 2023 · 1 revision

プロジェクト構造

│  .eslintignore : ESLint の除外ファイル
│  .eslintrc.cjs : ESLint の設定ファイル
│  .gitignore : Git の除外ファイル
│  .npmrc : NPM の設定ファイル
│  .prettierignore : Prettier の除外ファイル
│  .prettierrc : Prettier の設定ファイル
│  README.md : 説明書
│  game.png : ゲーム進行の概要 (説明書用)
│  index.js : サーバスクリプト (Node.js 実行用)
│  package-lock.json : NPM のアレ
│  package.json : NPM のアレ
│  result.png : ゲーム画面 (説明書用)
│  socketIoHandler.js : Socket.IO のハンドラ (サーバのメイン処理)
│  svelte.config.js : Svelte の設定ファイル
│  tsconfig.json : TypeScript の設定ファイル
│  vite.config.ts : Vite の設定ファイル
│
├─src : ソースコード
│  │  app.d.ts : 初期ファイル
│  │  app.html : ベース HTML
│  │
│  ├─lib : 共通ファイル群
│  │      ogiri.type.ts : アプリ内型定義
│  │
│  └─routes : 「ルート」群
│          +layout.svelte : レイアウト (global.css を読み込む)
│          +page.svelte : ページ (状態に合わせて以下の画面を出し分ける)
│          Answer.svelte : お題・回答画面
│          global.css : グローバルスタイル
│          Result.svelte : 結果画面
│          Title.svelte : タイトル画面
│          WaitingRoom.svelte : 待機室
│
└─static : そのままビルド成果に含められるファイル群
        favicon.png : Favicon

ページとしては最上位の +page.svelte のみである。このページ内で状態遷移を行い、各画面に相当するコンポーネントを表示する。データの受け渡しには、「+page.svelte -> 各コンポーネント」方向では property (props)、「各コンポーネント -> +page.svelte」方向では createEventDispatcher で生成される dispatcher を用いる。

サーバスクリプトは、基本的に socketIoHandler.js に記述する。これは vite.config.tsindex.js が参照しており、デバッグビルド npm run dev では前者、リリースビルド npm run build + node index.js では後者が使用される。index.js に直接実装するとデバッグ時に hot-reload が使えない。参考: SvelteKit with SocketIO in Production

通信内容

参加時 (join, クライアント -> サーバ)

{
  "username": "<user name>"
}

参加時 (join, サーバ -> クライアント)

{
  "result": "OK", // or "NG"
  "reason": null, // "Duplicate user name." or "No room is currently open."
  "members": [
    {
      "username": "<user name>"
    },
    ...
  ]
}

参加者更新 (members, サーバ -> クライアント)

{
  "members": [
    {
      "username": "<user name>"
    },
    ...
  ]
}

ゲーム開始 (start, 押したクライアント -> サーバ)

メッセージなし

ターン開始 (game, サーバ -> 各クライアント)

{
  "answerer": "<user name>",
  "turn": 1, // odd for theme, even for answer
  "question": null // 一人目のためnull,二人目以降は前回の解答
}

回答 (answer, 回答クライアント -> サーバ)

{
  "username": "<user name>",
  "answer": "<answer>"
}

結果 (result, サーバ -> 全クライアント)

{
  "answers": [
    {
      "username": "<user name>",
      "answer": "<answer>"
    },
    ...
  ]
}

Static 版

参考: SvelteKitアプリケーションをGitHub Pagesにデプロイする

GitHub Pages のような静的サイトホスティングサービスでも動作するように設定を変更し、オンラインプレイ関連の機能をごっそり消し飛ばしたローカルプレイ専用バージョン。この特性上、static 版である static ブランチを本流に merge することはなく、独立した存在として扱う。ただし、本流に加えた変更を static 版にも反映させるために、本流を static ブランチに merge することはある。この場合、static 版にとって不要な変更が入らないように慎重に行う必要がある。

static ブランチは push に対して GitHub Actions が走り、gh-pages ブランチにビルド成果をデプロイするように設定されている (build.yml)。なので、基本的に gh-pages ブランチを開発で触ることはない。

余談だが、参考サイトは static 版作成作業の前日に公開された記事のようで、何か運命のようなものを感じた。

Branching policy

極短期開発となるため、かなり柔軟に運用する。厳格なレビューなどを行うつもりもない。

  • main : 動作する最新のコードベース。npm run lint が通り、かつ regression がなければ勝手にぶち込んで OK。
  • static : Static 版 (前述) における main 相当のブランチ。
  • gh-pages : GitHub Pages デプロイ (前述)。
  • その他 : 作業途中を含む開発ブランチ。致命的なバグを含んでいたりコンパイルすら通らなかったりしても構わない。