調べてみた · · 17分で読めます

Kortress Beach制作記:一緒に座って歌を聴く夜の海をつくるまで

この記事の目次
  1. 海辺では何ができるのか
  2. 一緒に座って歩く場面に、昔の記憶を込めた
  3. 手をつなぐと、手首のずれが先に見えてくる
  4. 地面は波が届いてから濡れる必要があった
  5. 導火線に火がつく瞬間も場面の一部だ
  6. スパークラーで描く線をキャラクターの手までつないだ
  7. 同じ音楽が座っている時間をつなぐ
  8. 他の人にも今の海辺が見える必要がある
  9. きれいな場面にたどり着くまでの操作も整えている
  10. 実際に訪れて、続きも読む
  11. 実装と撮影の基準

한국어 · English · 日本語 · 简体中文

夜の海を一緒に眺め、手に持った花火に火をつけ、同じ歌を聴く空間をつくりたかった。 Kortress Beachの出発点は、山寺だった。 多くを話さなくても、他の人と同じ空間で過ごせることに着想を得た。 その考えを、自分のサイトのキャラクターと記憶の中の場面に置き換えたのがBeachだ。

最初は、山寺のように素朴でかわいいキャラクターを別につくって登場させようかと考えた。 最終的には、Kortressのマスコットであるコシ(Korsh)を使うことにした。 Kortressで使っていたKorshを、Beachにも登場させた。 親密で落ち着いた雰囲気をつくり、キャラクターの見た目に幅を持たせたくて、女性のKorshも追加した。 女性のKorshの名前は、まだ決めていない。

現在のバージョンで並んで座るKorshたち。2026年11月4日にローカルシミュレーションモードで撮影した。一緒に映る相手はコンピューターキャラクター。

現在のバージョンで並んで座るKorshたち。2026年11月4日にローカルシミュレーションモードで撮影した。一緒に映る相手はコンピューターキャラクター。

女性Korshの外観を比較していた開発案。当時の検討用Blenderレンダーであり、現在選べるキャラクターの一覧ではない。

女性Korshの外観を比較していた開発案。当時の検討用Blenderレンダーであり、現在選べるキャラクターの一覧ではない。

この記事は、機能を紹介しながら、その場面の裏で何を修正したかも記録する制作記だ。 コードは、2026年11月4日の0280637コミットを基準に確認した。 新たに撮影した現在の画面と、保管していた開発中の動画を区別して掲載している。 動画に出てくるMinaはテスト相手のニックネームであり、女性のKorshの名前ではない。

着想を得た空間が気になったら、山寺で見た言葉のないインタラクションを先に読んでもらってもよい。

19秒で見る:一緒に歩く・座る・花火 — 撮影用に演出したローカルシーンの紹介映像

海辺では何ができるのか

Kortress Beachに入ると、ニックネームとキャラクターを選ぶ。 その後は海辺を歩き回ったり、道具を選んで花火に火をつけたりできる。 一人で周囲を眺めてもよいし、他の人に一緒にする行動を提案してもよい。

現在の道具メニューには、何も持たない状態のほかに5種類がある。 手に持つスパークラーと連発花火、地面に置く噴出花火と破裂する連発花火、大きな花形の連発花火だ。 手元で光る花火と、遠い空へ上がる花火では、眺める距離から違ってくる。 道具の種類によって、手に持ったり地面に置いたりする過程も変わる。

したいこと画面上の行動一緒に見たい部分
海辺を見て回る移動し、画面を回したり拡大・縮小したりするキャラクターと水平線の距離
小さな花火に火をつけるスパークラーや手持ちの連発花火を選んで点火する手と道具の先端の動き
地面に花火を置く噴出花火・連発花火を配置して点火する道具の間隔、点火の姿勢、発射方向
光で書くスパークラーの描画画面で直接線を描く入力した線とキャラクターの腕のつながり
一緒に過ごす相手に並んで座る・手をつないで歩く行動を提案する承諾後の距離と視線
同じ歌を聴く音楽を一緒に聴く機能でYouTubeの音楽を共有する座る・歩く行動と音楽を同時に続けること

デスクトップではWASDや方向キーで動き、ドラッグで視点を回す。 ホイールは距離の調整、Shiftは走る操作、Spaceはジャンプに使う。 Fは状況に応じて配置や点火に使う。 最初はショートカットを覚えるより、画面に出る道具名と行動ボタンをたどるほうが分かりやすい。 モバイルには、専用の移動パッドとジャンプボタンを用意した。

一緒に座って歩く場面に、昔の記憶を込めた

並んで座る、一緒に歩く、同じ歌を聴く機能には、昔の記憶が入っている。 花火が休んでいる間も一緒に座っていられ、座りながら同じ音楽を聴けるようにした。 Beachで親密な雰囲気をつくりたいという思いは、キャラクターの見た目だけでなく、こうした行動にもつながった。

誘いかけてから一緒に座るまで — コンピューターの相手Minaで試した開発中プロトタイプ

動画で見る:互いに見つめる動作 — 開発中のプロトタイプ

一緒にする行動は、相手を選んで提案し、承諾を待つ方式だ。 キャラクターを2体置いて決まったアニメーションを一つ再生すれば終わりそうだが、実際には準備することが多かった。 離れていれば近づく必要があり、それぞれのモデルの準備が終わるタイミングも異なる。 待っている間に取り消したり、接続が切れたりすることもある。 すでに取り消した準備処理が遅れて完了し、新しい状態を上書きしないように防ぐ必要があった。

そのため、コードには要求、接近、準備、実行中の状態と取り消し処理が一緒に入っている。 接近と準備には制限時間を設け、準備完了の信号を再送し、古い非同期処理を除外する。 2人が一緒にいる短い場面も、別々の2画面で同じ順序で成立しなければならない。 ボタンを押してから何も起きていないように見える時間が長いと、その場面にたどり着く前に関心が途切れてしまう。

特に、承諾した瞬間に実際のキャラクターのリグを複製し、手のひらの表面と歩行データを測定していた処理が負担になっていた。 毎回行う必要のない測定を事前計算データに移し、既存のマテリアルと歩行テーブルを再利用した。 モデルや計算方法が変わったときに古いデータがそのまま使われないよう、フィンガープリントも確認する。 ここで短くしたかったのは画面内の行動の長さではなく、行動を始めるために繰り返していた準備処理だった。

この修正と検証の範囲は、リポジトリのdeploy/couple-stability-2026-11-03.mdに記録されている。

手をつなぐと、手首のずれが先に見えてくる

動画で見る:手をつないで歩く — 開発中のプロトタイプ

手をつないで歩く動作では、2体を同じ速度で動かすことより、手が接する形のほうが難しかった。 手の位置を近づけるだけでは、手のひらの向きがずれたり、腕が引っ張られたりする。 それを手首一つの回転で解決しようとすると、皮膚がキャンディーの包み紙のようにねじれる問題が起きる。

現在の実装では、手のひらの中心と向きを基準に接触関係を決め、両方の腕を繰り返し補正する。 腕の長さが足りない姿勢では、接触点も調整する。 手首に回転が集中しないよう、肩と前腕側にねじれを分散する処理もある。 指を握る形と手を組む形も、姿勢の一部として扱っている。

ここで使うIKは、手があるべき位置を決めてから腕の関節を合わせる方法だ。 名前よりも大切なのは結果になる。 体が動き、顔の向きが変わっても、手は相手との関係を保つ必要がある。 静止画では問題のなかった手が、歩き始めると不自然にならないかも一緒に見る必要があった。

互いを見るときの顔の回転や、歩行から停止に移る際のウェイトと速度も、徐々に変えるようにした。 ただし、座る・立ち上がるすべての切り替えが、一つの完成した全身アニメーションでつながる段階ではない。 今整えた部分と、これからさらに自然にする部分を分けておきたい。

現在のバージョンの、互いを見る機能。ローカルシミュレーションのコンピューターキャラクターと撮影した。

現在のバージョンの、互いを見る機能。ローカルシミュレーションのコンピューターキャラクターと撮影した。

地面は波が届いてから濡れる必要があった

海と濡れる地面には、特に気を配った。 水にきらめきを加え、砂を暗くするだけでは、水際らしく見えなかった。 小さな順序がずれるだけでも、波が背景のエフェクトのように感じられた。

実際、コードに残るフィードバックには、先に地面が濡れてから波が入り、順序が逆に見えるという指摘がある。 以前の方式では、新しい波が始まる時点で、その波が後から到達する最終地点まで、先に濡れたものとして扱っていた。 次の波に移るときには、前の跡の形も急に変わっていた。 水より濡れた跡が先行することと、跡が途切れること、2つの問題が重なっていた。

改善前:水際の波の表現 — 開発中のプロトタイプ

改善後:水際の波の表現 — 開発中のプロトタイプ

この2本は開発当時の波の表現を比較する資料であり、以下の現在の濡れ処理だけを切り分けて検証した対照実験ではない。

現在は、今回の波が実際に到達した最大地点だけを記録する。 同時に、直前の波が残した端の位置と模様、水が引いた時刻も別々に記憶する。 新しい波が始まったからといって、前の跡まで新しい模様には変えない。 前の波の跡はそれ自身の時間に従って乾き、次の波は実際に入ってきた範囲だけに新しい跡をつくる。

この流れを順に書くと、こうなる。

  1. 白い波が水際に近づく。
  2. 水が届いた範囲まで濡れた領域を広げる。
  3. 水は引くが、濡れた跡は残す。
  4. 残った跡の暗さと光沢を、時間とともに弱める。
  5. 次の波が来ても、まだ残っている前の跡を一緒に計算する。

濡れ具合はexp(-age/9)の形で弱める。 9秒後に突然完全に乾くタイマーではなく、時間とともに徐々に弱まる減衰だ。 この値が砂の色、光沢、空の反射、花火の光への反応につながる。 何がどれくらいきらめくかより先に、なぜその場所がまだ濡れているかを説明できるようにしたわけだ。

波が入り、引いていくタイミングは、打ち寄せる音にも合わせている。 沖の白い線、水際に入ってくる線、後に残る泡には、それぞれ違う役割がある。 完全な流体シミュレーションをつくったわけではない。 目に見える跡と耳に聞こえる音が同じ波を指すように、手続き的に演出した海だ。

この修正は、風景の説得力が一つのフレームだけでなく、場面のつながりからも生まれる例になっている。 前の場面の結果が、次の場面に残る必要がある。 濡れた砂では、その記憶が短く残る波の跡だった。

導火線に火がつく瞬間も場面の一部だ

花火の道具のリアルさにも力を入れた。 ボタンを押すと、キャラクターが道具を扱って火をつける過程を見せる。 手に持つ道具と地面に置いた道具では、点火する姿勢から違う必要がある。

点火動作を見る — 手を伸ばして道具に火をつける開発中のプロトタイプ

現在のコードでは、手持ちの道具と地面の道具で、点火位置に届くまでの時間と動作全体の時間を別にしている。 地面の道具に火をつけるときは、キャラクターが体の向きを変え、姿勢を低くする。 このとき上半身をかがめるだけでは、足まで一緒にずれるように見えることがある。 そのため、足の位置と向きを保存し、脚の関節を補正して足を元の場所に置くようにした。

右手に持つ点火棒は、その先端が導火線に届くよう、腕を改めて合わせる。 点火が終わったら、元の保持姿勢に戻る時間も設けている。 大切なのは花火の明るさだけでなく、手、棒の先、導火線が同じ出来事を示すことだ。 火がついているのに手が別の場所を向いていたら、道具を使った感覚が弱くなる。

初期のデスクトップ版ツール配置UIの前後比較。選択・位置のプレビュー・配置を確認した画面で、キャラクターとUIは現在の版とは異なる。

初期のデスクトップ版ツール配置UIの前後比較。選択・位置のプレビュー・配置を確認した画面で、キャラクターとUIは現在の版とは異なる。

道具ごとに、効果の性格も分けた。 スパークラーは手元で続く光を、噴出花火は地面から噴き上がる火花を見せる。 連発花火と大きな花形の花火には、発射と破裂の順序がある。 この区別は、あらゆる火薬の物理を正確に再現したという意味ではない。 どこに置き、どう火をつけ、どんな光が出るかを、画面の中で納得できるようにする作業だ。

現在のバージョンで、手に持ったスパークラーが顔と周囲を照らす。ローカルシミュレーションで近い角度から撮影した。

現在のバージョンで、手に持ったスパークラーが顔と周囲を照らす。ローカルシミュレーションで近い角度から撮影した。

花火を打ち上げる方向を決める操作も別に比較した。下の開発映像では、画面上の目標点を動かす方式と、それ以前の入力方式を並べて確認している。

打ち上げ方向を決める操作の前後比較 — 開発中プロトタイプ。キャラクターとUIは現在と異なる

スパークラーで描く線をキャラクターの手までつないだ

光で文字を書く — 開発中の座標マッピング比較動画

スパークラーで文字を書く機能は、画面にテキストを入力して表示する機能とは異なる。 利用者が直接描いた線を、キャラクターの持つ道具の軌跡につなぐ。 上の動画は開発中に入力と腕の動きを合わせていた比較画面であり、現在のUIは全画面キャンバスを使っている。

マウスや指が動く場所は平面の画面だが、キャラクターの手は立体空間にある。 画面座標をそのまま広い空間に変換すると、手が届かない点が生まれる。 キャラクターの腕の長さ、道具の向き、文字を書く平面の大きさを、一緒に決める必要があった。

現在は入力座標をキャンバス基準で正規化してから、腕が届く描画空間へ移す。 入力面積を広げることと、キャラクターの動きを大きくすることは同じではない。 小さな画面でも描きやすくしながら、場面の中では手を無理に伸ばさないようにする必要がある。 全画面の描画UIに変えたのも、この入力体験を整理する過程だった。

読む側には線を描く短い動作でも、制作時には画面入力とキャラクターの体を一緒に扱う必要がある機能だった。 花火の軌跡は、手に持つ道具の動きにつながっている。

同じ音楽が座っている時間をつなぐ

音楽を一緒に聴くUI — 開発中のプロトタイプ・無音録画

同じ歌を一緒に聴く機能にも、昔の記憶を込めた。 そのため、音楽を始めるときに、座る・歩く行動を先に終えなくてもよいようにした。 すでに一緒に座ったり歩いたりしている相手に、音楽を追加できる。 コードでも既存の同行動作を維持し、その中に音楽の状態をつないでいる。

音楽にはYouTubeの再生を利用する。 要求した側が基準の再生時刻を定期的に送り、受け取る側は送信後に経過した時間を考慮する。 再生位置が2秒より大きくずれたら、その位置へ移動させる。 2つの画面がまったく同じオーディオクロックで動くわけではなく、互いのバッファリング状態まで共有してはいない。

外部動画の埋め込み制限や、ブラウザーの自動再生ポリシーも影響する。 ブロックされたときはエラーを伝え、自動再生されなければ手動で再生するよう案内する経路がある。

上の動画は、テスト相手を使った共有UIの実演だ。実際の2人によるネットワーク再生の検証動画とは区別している。

他の人にも今の海辺が見える必要がある

一人で見る花火と、他の人と一緒に見る花火では、実装すべき問題が違う。 後から入った人にも、すでに地面に置かれている道具が見える必要がある。 誰かが火をつけたら、他の画面でもその道具に火がついた状態でなければならない。 座っている人の手が、観察者には違う姿勢に見える問題にも対処する必要がある。

Beachは、すべての火花の粒子の座標を送り続ける方式にはしていない。 道具の種類、位置、進行状態、時間といった情報を分けて送り、各画面で効果を構成する。 速く変化する手持ちの道具、キャラクターの移動、比較的長く残る地面の道具で、送信周期も分けている。 地面の道具は一覧全体を送り直して欠けた状態を合わせ、空の一覧も送って古い道具を消す。

一緒に行動するキャラクターの姿勢も、行動名を共有するだけでは終わらせなかった。 アニメーションと関節補正を適用した後の実際の姿勢、指を握る形まで送信・復元する処理がある。 誰かが「座っている」という事実と、今どんな姿勢で座っているかは、別の情報だったからだ。

接続や後からの入場を復旧する仕組みは入れたが、すべての途切れがなくなったという意味ではない。 現在の部屋の定員のような設定値も、実際に複数の機器で快適に動くという性能測定とは異なる。

きれいな場面にたどり着くまでの操作も整えている

最近の変更には、走る動作、ジャンプ、入場案内、モバイル操作の改善が含まれる。 走る動作は、歩行の再生速度だけを上げる方式から、専用のRunアニメーションに変えた。 既存のリグとアニメーションを維持しながら走行データを追加し、実際の靴や手の形状を測定して動きを確認した。 その後も、腕と手首、歩幅のタイミングを再調整した記録が続いている。

2人のKorshの走る動作を確認する開発プレビュー

海辺でのプレイ映像ではなく、2人のKorshの走行アニメーションを確認していた開発プレビュー。

モバイルでは、見えない移動判定領域が見えているパッドより広く、視点を回そうとしてキャラクターが動くことがあった。 移動領域と親指が届く位置を整理し、画面端と道具バーも一緒に考慮した。 小さな画面でボタンが重ならないことの確認と、実際のスマートフォンの発熱・フレームの確認は、別に見る必要がある。

入場過程でも、キャラクターの準備が終わる前に操作が始まらないようにした。 長く待つときやエラーが起きたときは状態を知らせ、再試行できるようにした。 入場後には移動方法を案内する。 海辺で何をすればよいか分からない状態や、画面が止まったように見える待ち時間も、制作で解決すべき部分だった。

次に点検する項目も、こうした小さな途切れだ。 初めて来た人が動き方を理解できるか、提案後に待つ理由が分かるか、2人が行動を終えるとき不自然ではないかが基準になる。 手をつないで音楽を聴く機能があっても、その場面までの過程が難しければ、意図は十分に伝わらない。

山寺から得た着想は、BeachでKorsh、海、花火、音楽へとつながった。 私が力を注いだのは、一緒にいる時間がぎこちなくならないよう、小さな動作と痕跡をつなぐことだった。

実際に訪れて、続きも読む

実装と撮影の基準

実装の説明は、Beachリポジトリのweb/index.html、ネットワークコード、2026年11月3〜4日の変更記録、同行動作の安定化報告書を照合した。 現在の画面は、2026年11月4日に公開デプロイ版のローカルシミュレーションで撮影した。 開発動画は別途保管していたプロトタイプ資料であり、実際の訪問者や運用性能の証拠としては使っていない。 詳しい根拠とメディア原本の一覧は、執筆用の調査報告書に別途保管している。

1 / 1