0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

原神型オープンワールドRPGのマルチ同期を低コストで実装する設計テンプレ

0
Last updated at Posted at 2026-03-05

近年のライブ型オープンワールドRPG(例:原神)では、

  • ストーリーは基本ソロ進行
  • 宝箱や探索は個別管理
  • マルチでは世界が部分同期

という設計が一般的です。

しかし構造を分解すると、

技術的に同期が難しいのではなく
「永続状態を持ちすぎている」ことが問題

本記事では、

体験を損なわず、開発コストを抑えた同期フラグシステムの最小構成テンプレ

を提示します。


設計原則

原則1:世界は1本線にする

int story_progress_id;

永続分岐を持たない

NPCの生死フラグを持たない

世界状態はprogressから導出

bool isNpcVisible(int progress_id) {
    return progress_id >= 3020;
}

保存しない。導出する。

原則2:宝箱は「点」でなく「面」で持つ

❌ NG(フラグ爆発)

bool chest_100234_opened;
bool chest_100235_opened;

✅ 推奨(エリア単位ビットマスク)

struct RegionChestData {
    uint64_t bitmask[2]; // 128個まで
};
  • エリア単位管理
  • ONのみ(OFFに戻さない)
  • データサイズ固定

原則3:存在と取得を分離せよ(重要)

宝箱同期で最も多いバグ:

マルチ後に宝箱が復活する問題

原因は
「存在」と「取得」を同一視していること。

🔹 宝箱の存在(セッション依存)

if (host_region_bitmask[target_bit] == 0)
    spawn_chest();

→ ホスト基準

🔹 宝箱の取得(プレイヤー依存)

if (player_region_bitmask[target_bit] == 0)
    allow_loot();
else
    disable_loot();

→ 個人基準

なぜ復活しないのか?

  • ビットはONのみ
  • OFFに戻らない
  • 永続データはプレイヤー単位

セッション終了後は
自分のbitmaskから世界を再構築するだけ。

クラス設計(最小構成)

永続層(保存対象)

story_progress_id
region_bitmask[]
boss_kill_time[]

以上のみ。

セッション層(揮発)

SessionWorld
visible_objects

セッションシーケンス

1. 参加

PlayerA  Server : Join
Server   : buildFrom(host.progress)

2. 宝箱インタラクト

PlayerA  Server : ChestInteract(region, bit)

Server:
    if A.bitmask == 0:
        giveReward()
        setBit(A)

セッション世界は変更しない。

3.セッション終了

PlayerA:
    world = rebuildFrom(A.PlayerWorldData)

宝箱は復活しない。

「参加者未取得宝箱」問題

ケース:

  • ホスト:開封済み
  • 参加者:未取得

解決策は3パターン。

A:取得不可(低コスト)

仕様:
ホストが開封済みなら不可。

B:個別可視(推奨)

if (player.bitmask == 0)
    showChestToPlayerOnly();
  • 未取得者にだけ表示
  • UX自然
  • 永続増加なし

C:完全個別インスタンス(高コスト)

MMO型。今回は不要。

ワールドボス管理

撃破フラグを持たない。

int64_t boss_last_kill_time;
if (now - boss_last_kill_time > respawn_time)
    spawn();

データ肥大対策

  • NPC状態は保存しない
  • ワールドはprogressから導出
  • 宝箱はビット圧縮
  • ボスはタイムスタンプ

保存は最小限。

セーブ改竄対策(最低限)

  • bitmaskはサーバー保持

  • 報酬判定は必ずサーバー側

  • クライアントは参照のみ

この設計のメリット

✔ 管理フラグの増殖を防ぐ
✔ QAコストを抑えられる
✔ ライブ拡張に強い
✔ データサイズが固定化できる

適用可能なゲーム

✔ 直線型ライブRPG
✔ 分岐が少ない探索型
✔ ホスト制マルチ

✖ 分岐型ADV
✖ 大規模MMO

結論

同期が難しいのではない。

永続状態を持ちすぎていることが問題。

保存は最小限に。
あとは導出する。

それだけで
原神型ライブRPGの同期はテンプレ化できる。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?