subnautica-ii-deep-synergy-multiplayer-mod

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Subnautica II Deep Synergy Multiplayer Mod

《Subnautica 2》Deep Synergy多人模组

Skill by ara.so — Devtools Skills collection.
ara.so开发的技能——Devtools Skills合集。

Overview

概述

The Deep Synergy Multiplayer Mod transforms Subnautica 2 into a synchronized cooperative experience using the BepInEx modding framework. It implements deterministic session synchronization (DSS), adaptive dynamic scaling (ADS), and peer-to-peer connectivity via WebRTC for seamless multiplayer gameplay.
Key Architecture:
  • BepInEx Plugin - Hooks into Unity IL2CPP runtime without modifying game files
  • Decentralized Session Management - No central servers; uses NAT punch-through
  • Merkle Tree Inventory - Blockchain-inspired state verification across peers
  • Adaptive Scaling - Creature spawns and resource availability adjust to player count
Deep Synergy多人模组借助BepInEx模组框架,将《Subnautica 2》转变为同步合作体验。它实现了确定性会话同步(DSS)、自适应动态缩放(ADS),并通过WebRTC实现点对点连接,带来流畅的多人游戏体验。
核心架构:
  • BepInEx插件 - 无需修改游戏文件,即可挂钩Unity IL2CPP运行时
  • 去中心化会话管理 - 无需中央服务器;采用NAT穿透技术
  • Merkle Tree库存系统 - 受区块链启发的跨节点状态验证机制
  • 自适应缩放 - 生物生成数量和资源可用性会根据玩家人数调整

Installation

安装

Prerequisites

前置条件

  1. Subnautica 2 installed (Steam/GOG)
  2. BepInEx 6.0.x for IL2CPP Unity games
  1. 已安装《Subnautica 2》(Steam/GOG版本)
  2. 适用于IL2CPP Unity游戏的BepInEx 6.0.x

Step-by-Step Installation

分步安装

bash
undefined
bash
undefined

1. Install BepInEx 6.0.x

1. 安装BepInEx 6.0.x

Extract to Subnautica 2 game directory

解压至《Subnautica 2》游戏目录

2. Download Deep Synergy Mod

2. 下载Deep Synergy模组

3. Extract mod files

3. 解压模组文件

Place contents into: <Game Directory>/BepInEx/plugins/

将内容放置于:<游戏目录>/BepInEx/plugins/

4. Verify structure

4. 验证目录结构

<Game Directory>/ ├── BepInEx/ │ ├── plugins/ │ │ ├── DeepSynergy.dll │ │ ├── SyncEngine.dll │ │ └── NetworkCore.dll │ └── config/ │ └── synergy_profile.json
undefined
<游戏 Directory>/ ├── BepInEx/ │ ├── plugins/ │ │ ├── DeepSynergy.dll │ │ ├── SyncEngine.dll │ │ └── NetworkCore.dll │ └── config/ │ └── synergy_profile.json
undefined

Verify Installation

验证安装

Launch Subnautica 2. Check BepInEx console for:
[Info   :BepInEx] Deep Synergy Multiplayer Mod v2.1.0 loaded
[Info   :DeepSynergy] Session Manager initialized
[Info   :DeepSynergy] State Synchronizer ready
启动《Subnautica 2》。查看BepInEx控制台,确认出现以下内容:
[Info   :BepInEx] Deep Synergy Multiplayer Mod v2.1.0 loaded
[Info   :DeepSynergy] Session Manager initialized
[Info   :DeepSynergy] State Synchronizer ready

Configuration

配置

Profile Configuration File

配置文件

Create/edit
BepInEx/config/synergy_profile.json
:
json
{
  "session_name": "Ocean Explorers",
  "max_players": 4,
  "difficulty_scale": "adaptive",
  "resource_multiplier": 1.5,
  "oxygen_consumption": 0.85,
  "creature_spawn_divider": 2,
  "enable_pvp": false,
  "friendly_fire": false,
  "shared_blueprints": true,
  "ping_locations_shared": true,
  "time_of_day_sync": "all",
  "voice_chat_integration": "discord_rpc",
  "network": {
    "port_range": "7777-7787",
    "timeout_seconds": 30,
    "max_latency_ms": 200
  },
  "api_integration": {
    "openai": {
      "enabled": false,
      "role": "narrator",
      "api_key_env": "OPENAI_API_KEY"
    },
    "claude": {
      "enabled": false,
      "role": "lore_engine",
      "api_key_env": "ANTHROPIC_API_KEY"
    }
  }
}
创建/编辑
BepInEx/config/synergy_profile.json
json
{
  "session_name": "Ocean Explorers",
  "max_players": 4,
  "difficulty_scale": "adaptive",
  "resource_multiplier": 1.5,
  "oxygen_consumption": 0.85,
  "creature_spawn_divider": 2,
  "enable_pvp": false,
  "friendly_fire": false,
  "shared_blueprints": true,
  "ping_locations_shared": true,
  "time_of_day_sync": "all",
  "voice_chat_integration": "discord_rpc",
  "network": {
    "port_range": "7777-7787",
    "timeout_seconds": 30,
    "max_latency_ms": 200
  },
  "api_integration": {
    "openai": {
      "enabled": false,
      "role": "narrator",
      "api_key_env": "OPENAI_API_KEY"
    },
    "claude": {
      "enabled": false,
      "role": "lore_engine",
      "api_key_env": "ANTHROPIC_API_KEY"
    }
  }
}

Configuration Fields

配置字段说明

FieldTypeDescription
session_name
stringDisplay name for hosted session
max_players
intMaximum concurrent players (2-8)
difficulty_scale
enum
adaptive
,
fixed
,
manual
resource_multiplier
floatMultiplier for harvestable resources (0.5-3.0)
oxygen_consumption
floatOxygen drain rate (0.5-1.5, lower = slower)
creature_spawn_divider
intDivide creature spawn rates (2 = half)
shared_blueprints
boolAll players share blueprint unlocks
ping_locations_shared
boolMap pings visible to all players
字段类型描述
session_name
字符串托管会话的显示名称
max_players
整数最大同时在线玩家数(2-8)
difficulty_scale
枚举值
adaptive
(自适应)、
fixed
(固定)、
manual
(手动)
resource_multiplier
浮点数可采集资源的倍率(0.5-3.0)
oxygen_consumption
浮点数氧气消耗速率(0.5-1.5,数值越低消耗越慢)
creature_spawn_divider
整数生物生成速率除数(2表示生成数量减半)
shared_blueprints
布尔值所有玩家共享蓝图解锁进度
ping_locations_shared
布尔值地图标记对所有玩家可见

Locale Configuration

本地化配置

Add to
synergy_profile.json
:
json
{
  "locale": "en_US",
  "locale_override": true
}
Supported:
en_US
,
zh_CN
,
ja_JP
,
de_DE
,
fr_FR
,
pt_BR
,
ru_RU
,
es_ES
,
ko_KR
synergy_profile.json
中添加以下内容:
json
{
  "locale": "en_US",
  "locale_override": true
}
支持的语言:
en_US
zh_CN
ja_JP
de_DE
fr_FR
pt_BR
ru_RU
es_ES
ko_KR

In-Game Commands

游戏内命令

Access via BepInEx console (F5 by default):
通过BepInEx控制台访问(默认快捷键F5):

Session Management

会话管理

bash
undefined
bash
undefined

Start hosting a session

开始托管会话

/start_server
/start_server

Output: Server created: session code = 9B2A-4C7D-E8F1

输出:Server created: session code = 9B2A-4C7D-E8F1

Join existing session

加入现有会话

/join_session 9B2A-4C7D-E8F1
/join_session 9B2A-4C7D-E8F1

Disconnect from session

断开会话连接

/disconnect
/disconnect

View session status

查看会话状态

/synergy_status
/synergy_status

Output:

输出:

Connected peers: 3/4

Connected peers: 3/4

State sync: 100% complete

State sync: 100% complete

Inventory hash: 0xFA342B1E

Inventory hash: 0xFA342B1E

Average latency: 45ms

Average latency: 45ms

undefined
undefined

Runtime Configuration

运行时配置

bash
undefined
bash
undefined

Adjust difficulty scaling (temporary)

临时调整难度缩放

/synergy_scale 1.5
/synergy_scale 1.5

Force world seed synchronization

强制同步世界种子

/seed_override 8251
/seed_override 8251

Toggle PvP (host only)

切换PvP模式(仅房主可用)

/pvp_toggle
/pvp_toggle

Kick player by index (host only)

根据索引踢出玩家(仅房主可用)

/kick_player 2
undefined
/kick_player 2
undefined

AI Integration Commands

AI集成命令

bash
undefined
bash
undefined

Trigger narrative generation (requires OpenAI API)

触发叙事生成(需OpenAI API)

/api_narrate "exploring the deep sea trench"
/api_narrate "exploring the deep sea trench"

Generate creature biology log (requires Claude API)

生成生物生态日志(需Claude API)

/lore_creature "Shadow Leviathan"
/lore_creature "Shadow Leviathan"

Get contextual hint

获取上下文提示

/narrator_hint
undefined
/narrator_hint
undefined

Code Examples

代码示例

Programmatic Session Control

程序化会话控制

If extending the mod via BepInEx plugins:
csharp
using DeepSynergy.Core;
using BepInEx;
using UnityEngine;

[BepInPlugin("com.yourmod.extension", "Session Extension", "1.0.0")]
public class SessionExtension : BaseUnityPlugin
{
    private SessionManager sessionManager;
    
    void Awake()
    {
        // Get Deep Synergy session manager
        sessionManager = SessionManager.Instance;
        
        // Subscribe to session events
        sessionManager.OnPlayerJoined += HandlePlayerJoined;
        sessionManager.OnStateSync += HandleStateSync;
    }
    
    void HandlePlayerJoined(PlayerInfo player)
    {
        Logger.LogInfo($"Player {player.DisplayName} joined");
        
        // Access session configuration
        var config = sessionManager.Config;
        if (config.SharedBlueprints)
        {
            SyncBlueprintsToPlayer(player);
        }
    }
    
    void HandleStateSync(SyncEvent syncEvent)
    {
        // Process synchronized state updates
        if (syncEvent.Type == SyncType.Inventory)
        {
            VerifyInventoryIntegrity(syncEvent.MerkleHash);
        }
    }
    
    void SyncBlueprintsToPlayer(PlayerInfo player)
    {
        var blueprints = BlueprintManager.GetUnlockedBlueprints();
        sessionManager.SendToPlayer(player.Id, blueprints);
    }
    
    void VerifyInventoryIntegrity(string merkleHash)
    {
        var localHash = InventoryHasher.ComputeMerkleRoot();
        if (localHash != merkleHash)
        {
            Logger.LogWarning("Inventory desync detected, requesting full sync");
            sessionManager.RequestFullSync();
        }
    }
}
如果通过BepInEx插件扩展该模组:
csharp
using DeepSynergy.Core;
using BepInEx;
using UnityEngine;

[BepInPlugin("com.yourmod.extension", "Session Extension", "1.0.0")]
public class SessionExtension : BaseUnityPlugin
{
    private SessionManager sessionManager;
    
    void Awake()
    {
        // 获取Deep Synergy会话管理器
        sessionManager = SessionManager.Instance;
        
        // 订阅会话事件
        sessionManager.OnPlayerJoined += HandlePlayerJoined;
        sessionManager.OnStateSync += HandleStateSync;
    }
    
    void HandlePlayerJoined(PlayerInfo player)
    {
        Logger.LogInfo($"Player {player.DisplayName} joined");
        
        // 访问会话配置
        var config = sessionManager.Config;
        if (config.SharedBlueprints)
        {
            SyncBlueprintsToPlayer(player);
        }
    }
    
    void HandleStateSync(SyncEvent syncEvent)
    {
        // 处理同步状态更新
        if (syncEvent.Type == SyncType.Inventory)
        {
            VerifyInventoryIntegrity(syncEvent.MerkleHash);
        }
    }
    
    void SyncBlueprintsToPlayer(PlayerInfo player)
    {
        var blueprints = BlueprintManager.GetUnlockedBlueprints();
        sessionManager.SendToPlayer(player.Id, blueprints);
    }
    
    void VerifyInventoryIntegrity(string merkleHash)
    {
        var localHash = InventoryHasher.ComputeMerkleRoot();
        if (localHash != merkleHash)
        {
            Logger.LogWarning("Inventory desync detected, requesting full sync");
            sessionManager.RequestFullSync();
        }
    }
}

Custom Scaling Logic

自定义缩放逻辑

csharp
using DeepSynergy.Scaling;

public class CustomScalingRule : IScalingRule
{
    public void ApplyScaling(int playerCount)
    {
        var config = SessionManager.Instance.Config;
        
        // Custom resource scaling
        float resourceScale = config.ResourceMultiplier * Mathf.Sqrt(playerCount);
        ResourceSpawner.SetGlobalMultiplier(resourceScale);
        
        // Creature spawn reduction
        int spawnDivider = config.CreatureSpawnDivider * playerCount;
        CreatureManager.SetSpawnRateDivider(spawnDivider);
        
        // Oxygen efficiency boost
        float oxygenMod = config.OxygenConsumption / Mathf.Log(playerCount + 1);
        PlayerOxygenSystem.SetConsumptionRate(oxygenMod);
    }
}

// Register custom rule
ScalingEngine.RegisterRule(new CustomScalingRule());
csharp
using DeepSynergy.Scaling;

public class CustomScalingRule : IScalingRule
{
    public void ApplyScaling(int playerCount)
    {
        var config = SessionManager.Instance.Config;
        
        // 自定义资源缩放
        float resourceScale = config.ResourceMultiplier * Mathf.Sqrt(playerCount);
        ResourceSpawner.SetGlobalMultiplier(resourceScale);
        
        // 生物生成数量减少
        int spawnDivider = config.CreatureSpawnDivider * playerCount;
        CreatureManager.SetSpawnRateDivider(spawnDivider);
        
        // 氧气效率提升
        float oxygenMod = config.OxygenConsumption / Mathf.Log(playerCount + 1);
        PlayerOxygenSystem.SetConsumptionRate(oxygenMod);
    }
}

// 注册自定义规则
ScalingEngine.RegisterRule(new CustomScalingRule());

Inventory Synchronization Hook

库存同步钩子

csharp
using DeepSynergy.Sync;

public class InventorySyncHook : MonoBehaviour
{
    void OnItemPickup(Item item)
    {
        // Create sync event
        var syncData = new InventorySyncData
        {
            PlayerId = LocalPlayer.Id,
            ItemId = item.TechType,
            Quantity = 1,
            Timestamp = NetworkTime.CurrentTime
        };
        
        // Broadcast to peers
        StateSynchronizer.BroadcastEvent(syncData);
    }
    
    void OnItemCraft(TechType techType)
    {
        if (SessionManager.Instance.Config.SharedBlueprints)
        {
            // Unlock for all players
            var unlockData = new BlueprintUnlockData
            {
                TechType = techType,
                UnlockedBy = LocalPlayer.Id
            };
            
            StateSynchronizer.BroadcastUnlock(unlockData);
        }
    }
}
csharp
using DeepSynergy.Sync;

public class InventorySyncHook : MonoBehaviour
{
    void OnItemPickup(Item item)
    {
        // 创建同步事件
        var syncData = new InventorySyncData
        {
            PlayerId = LocalPlayer.Id,
            ItemId = item.TechType,
            Quantity = 1,
            Timestamp = NetworkTime.CurrentTime
        };
        
        // 广播至所有节点
        StateSynchronizer.BroadcastEvent(syncData);
    }
    
    void OnItemCraft(TechType techType)
    {
        if (SessionManager.Instance.Config.SharedBlueprints)
        {
            // 为所有玩家解锁蓝图
            var unlockData = new BlueprintUnlockData
            {
                TechType = techType,
                UnlockedBy = LocalPlayer.Id
            };
            
            StateSynchronizer.BroadcastUnlock(unlockData);
        }
    }
}

Common Patterns

常见模式

Host Migration on Disconnect

房主断开时的迁移逻辑

csharp
void OnHostDisconnect()
{
    if (SessionManager.Instance.IsHost)
    {
        // Current host is disconnecting, migrate session
        var nextHost = SessionManager.Instance.GetNextEligibleHost();
        
        if (nextHost != null)
        {
            Logger.LogInfo($"Migrating host to {nextHost.DisplayName}");
            SessionManager.Instance.MigrateHostTo(nextHost.Id);
            
            // Transfer session state
            var sessionState = SessionStateSerializer.Capture();
            SessionManager.Instance.SendStateSnapshot(nextHost.Id, sessionState);
        }
        else
        {
            Logger.LogWarning("No eligible host for migration, ending session");
            SessionManager.Instance.EndSession();
        }
    }
}
csharp
void OnHostDisconnect()
{
    if (SessionManager.Instance.IsHost)
    {
        // 当前房主即将断开,迁移会话控制权
        var nextHost = SessionManager.Instance.GetNextEligibleHost();
        
        if (nextHost != null)
        {
            Logger.LogInfo($"Migrating host to {nextHost.DisplayName}");
            SessionManager.Instance.MigrateHostTo(nextHost.Id);
            
            // 传输会话状态
            var sessionState = SessionStateSerializer.Capture();
            SessionManager.Instance.SendStateSnapshot(nextHost.Id, sessionState);
        }
        else
        {
            Logger.LogWarning("No eligible host for migration, ending session");
            SessionManager.Instance.EndSession();
        }
    }
}

Conflict Resolution

冲突解决

csharp
void ResolveInventoryConflict(InventoryConflict conflict)
{
    // Timestamp-based authority
    var localTimestamp = conflict.LocalEvent.Timestamp;
    var remoteTimestamp = conflict.RemoteEvent.Timestamp;
    
    if (remoteTimestamp > localTimestamp)
    {
        // Remote event is newer, apply it
        ApplyInventoryEvent(conflict.RemoteEvent);
    }
    else if (remoteTimestamp < localTimestamp)
    {
        // Local event is newer, broadcast to override
        StateSynchronizer.BroadcastEvent(conflict.LocalEvent, priority: true);
    }
    else
    {
        // Exact tie, use player ID as tiebreaker
        if (conflict.RemoteEvent.PlayerId > conflict.LocalEvent.PlayerId)
        {
            ApplyInventoryEvent(conflict.RemoteEvent);
        }
    }
}
csharp
void ResolveInventoryConflict(InventoryConflict conflict)
{
    // 基于时间戳的权限判定
    var localTimestamp = conflict.LocalEvent.Timestamp;
    var remoteTimestamp = conflict.RemoteEvent.Timestamp;
    
    if (remoteTimestamp > localTimestamp)
    {
        // 远程事件更新,应用该事件
        ApplyInventoryEvent(conflict.RemoteEvent);
    }
    else if (remoteTimestamp < localTimestamp)
    {
        // 本地事件更新,广播以覆盖远程
        StateSynchronizer.BroadcastEvent(conflict.LocalEvent, priority: true);
    }
    else
    {
        // 时间戳完全相同,使用玩家ID作为决胜条件
        if (conflict.RemoteEvent.PlayerId > conflict.LocalEvent.PlayerId)
        {
            ApplyInventoryEvent(conflict.RemoteEvent);
        }
    }
}

API Integration Example

API集成示例

csharp
using System.Net.Http;
using Newtonsoft.Json;

public class NarrativeEngine
{
    private static readonly HttpClient client = new HttpClient();
    
    public async Task<string> GenerateNarrative(string context)
    {
        var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY");
        if (string.IsNullOrEmpty(apiKey))
        {
            Logger.LogWarning("OPENAI_API_KEY not set");
            return null;
        }
        
        client.DefaultRequestHeaders.Authorization = 
            new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", apiKey);
        
        var request = new
        {
            model = "gpt-4",
            messages = new[]
            {
                new { role = "system", content = "You are a narrative generator for Subnautica 2 multiplayer sessions." },
                new { role = "user", content = $"Generate a journal entry: {context}" }
            },
            max_tokens = 150
        };
        
        var response = await client.PostAsync(
            "https://api.openai.com/v1/chat/completions",
            new StringContent(JsonConvert.SerializeObject(request), System.Text.Encoding.UTF8, "application/json")
        );
        
        var result = JsonConvert.DeserializeObject<dynamic>(
            await response.Content.ReadAsStringAsync()
        );
        
        return result.choices[0].message.content;
    }
}
csharp
using System.Net.Http;
using Newtonsoft.Json;

public class NarrativeEngine
{
    private static readonly HttpClient client = new HttpClient();
    
    public async Task<string> GenerateNarrative(string context)
    {
        var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY");
        if (string.IsNullOrEmpty(apiKey))
        {
            Logger.LogWarning("OPENAI_API_KEY not set");
            return null;
        }
        
        client.DefaultRequestHeaders.Authorization = 
            new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", apiKey);
        
        var request = new
        {
            model = "gpt-4",
            messages = new[]
            {
                new { role = "system", content = "You are a narrative generator for Subnautica 2 multiplayer sessions." },
                new { role = "user", content = $"Generate a journal entry: {context}" }
            },
            max_tokens = 150
        };
        
        var response = await client.PostAsync(
            "https://api.openai.com/v1/chat/completions",
            new StringContent(JsonConvert.SerializeObject(request), System.Text.Encoding.UTF8, "application/json")
        );
        
        var result = JsonConvert.DeserializeObject<dynamic>(
            await response.Content.ReadAsStringAsync()
        );
        
        return result.choices[0].message.content;
    }
}

Troubleshooting

故障排除

Session Connection Failures

会话连接失败

Problem: Cannot join session, timeout errors
Solutions:
  1. Verify firewall allows UDP ports
    7777-7787
  2. Check NAT type:
    Strict
    NAT requires manual port forwarding
  3. Increase timeout in config:
    json
    "network": {
      "timeout_seconds": 60
    }
Diagnostic command:
bash
/network_diagnostics
问题: 无法加入会话,出现超时错误
解决方案:
  1. 验证防火墙允许UDP端口
    7777-7787
    通过
  2. 检查NAT类型:
    Strict
    (严格)NAT需要手动端口转发
  3. 在配置中增加超时时间:
    json
    "network": {
      "timeout_seconds": 60
    }
诊断命令:
bash
/network_diagnostics

Shows: NAT type, port status, peer connectivity

显示:NAT类型、端口状态、节点连接性

undefined
undefined

Inventory Desynchronization

库存不同步

Problem: Players see different inventory states
Solutions:
  1. Force full resync:
    /synergy_resync inventory
  2. Check network latency:
    /synergy_status
  3. Verify Merkle hash integrity:
    csharp
    var localHash = InventoryHasher.ComputeMerkleRoot();
    Logger.LogInfo($"Local inventory hash: {localHash}");
问题: 玩家看到的库存状态不一致
解决方案:
  1. 强制完全重新同步:
    /synergy_resync inventory
  2. 检查网络延迟:
    /synergy_status
  3. 验证Merkle哈希完整性:
    csharp
    var localHash = InventoryHasher.ComputeMerkleRoot();
    Logger.LogInfo($"Local inventory hash: {localHash}");

High CPU Usage

CPU占用过高

Problem: Performance degradation with multiple players
Solutions:
  1. Reduce
    creature_spawn_divider
    in config
  2. Disable API integrations if enabled
  3. Lower
    max_players
    count
  4. Adjust sync frequency in
    BepInEx/config/DeepSynergy.cfg
    :
    ini
    [Synchronization]
    StateUpdateHz = 10  # Lower from default 20
问题: 多玩家情况下性能下降
解决方案:
  1. 在配置中减小
    creature_spawn_divider
    的值
  2. 禁用已启用的API集成
  3. 降低
    max_players
    的数量
  4. BepInEx/config/DeepSynergy.cfg
    中调整同步频率:
    ini
    [Synchronization]
    StateUpdateHz = 10  # 从默认20降低

BepInEx Load Errors

BepInEx加载错误

Problem: Mod not loading, missing dependencies
Check:
bash
undefined
问题: 模组未加载,缺少依赖项
检查:
bash
undefined

View BepInEx log

查看BepInEx日志

<Game Directory>/BepInEx/LogOutput.log
<游戏目录>/BepInEx/LogOutput.log

Common issues:

常见问题:

- Missing BepInEx.IL2CPP.dll

- 缺少BepInEx.IL2CPP.dll

- Incompatible Unity version

- Unity版本不兼容

- Conflicting plugins

- 插件冲突


**Solution:**
1. Reinstall BepInEx 6.0.x IL2CPP variant
2. Remove conflicting mods from `plugins/` folder
3. Verify game version matches mod compatibility (check release notes)

**解决方案:**
1. 重新安装适用于IL2CPP的BepInEx 6.0.x版本
2. 移除`plugins/`文件夹中的冲突模组
3. 验证游戏版本与模组兼容性(查看发布说明)

Session Code Invalid

会话代码无效

Problem: "Invalid session code" when joining
Solutions:
  1. Verify code format:
    XXXX-XXXX-XXXX
    (12 hex characters)
  2. Check host is still running:
    /synergy_status
    on host
  3. Ensure matching mod versions across all players
  4. Regenerate session:
    /restart_server
    on host
问题: 加入时提示“无效会话代码”
解决方案:
  1. 验证代码格式:
    XXXX-XXXX-XXXX
    (12位十六进制字符)
  2. 检查房主是否仍在运行:在房主端执行
    /synergy_status
  3. 确保所有玩家使用相同版本的模组
  4. 重新生成会话:在房主端执行
    /restart_server

API Integration Not Working

API集成无法工作

Problem: Narrative/lore generation fails
Check:
  1. Environment variables set:
    bash
    echo $OPENAI_API_KEY
    echo $ANTHROPIC_API_KEY
  2. API enabled in config:
    json
    "api_integration": {
      "openai": { "enabled": true }
    }
  3. Network connectivity to API endpoints
  4. Check BepInEx console for API error messages
问题: 叙事/生态生成失败
检查:
  1. 环境变量已设置:
    bash
    echo $OPENAI_API_KEY
    echo $ANTHROPIC_API_KEY
  2. 配置中已启用API:
    json
    "api_integration": {
      "openai": { "enabled": true }
    }
  3. 网络可连接至API端点
  4. 查看BepInEx控制台中的API错误信息

Performance Optimization

性能优化

Recommended Settings for 4+ Players

4人及以上玩家推荐设置

json
{
  "max_players": 4,
  "creature_spawn_divider": 3,
  "resource_multiplier": 2.0,
  "network": {
    "state_update_hz": 10,
    "position_update_hz": 20,
    "inventory_sync_batch": true
  },
  "optimization": {
    "async_state_processing": true,
    "threaded_merkle_computation": true,
    "delta_compression": true
  }
}
json
{
  "max_players": 4,
  "creature_spawn_divider": 3,
  "resource_multiplier": 2.0,
  "network": {
    "state_update_hz": 10,
    "position_update_hz": 20,
    "inventory_sync_batch": true
  },
  "optimization": {
    "async_state_processing": true,
    "threaded_merkle_computation": true,
    "delta_compression": true
  }
}

Monitoring Performance

性能监控

csharp
void Update()
{
    var perfStats = SessionManager.Instance.GetPerformanceStats();
    
    if (perfStats.AverageLatency > 150)
    {
        Logger.LogWarning($"High latency detected: {perfStats.AverageLatency}ms");
    }
    
    if (perfStats.PacketLossRate > 0.05)
    {
        Logger.LogWarning($"Packet loss: {perfStats.PacketLossRate * 100}%");
    }
}
csharp
void Update()
{
    var perfStats = SessionManager.Instance.GetPerformanceStats();
    
    if (perfStats.AverageLatency > 150)
    {
        Logger.LogWarning($"High latency detected: {perfStats.AverageLatency}ms");
    }
    
    if (perfStats.PacketLossRate > 0.05)
    {
        Logger.LogWarning($"Packet loss: {perfStats.PacketLossRate * 100}%");
    }
}

Advanced Usage

高级用法

Custom Session Events

自定义会话事件

csharp
using DeepSynergy.Events;

// Define custom event
public class BaseConstructedEvent : ISyncEvent
{
    public string PlayerId { get; set; }
    public Vector3 Position { get; set; }
    public string BasePartType { get; set; }
    public long Timestamp { get; set; }
}

// Broadcast custom event
void OnBasePartPlaced(BasePartType type, Vector3 position)
{
    var evt = new BaseConstructedEvent
    {
        PlayerId = LocalPlayer.Id,
        Position = position,
        BasePartType = type.ToString(),
        Timestamp = NetworkTime.CurrentTime
    };
    
    StateSynchronizer.BroadcastCustomEvent(evt);
}

// Handle custom event
void OnCustomEventReceived(ISyncEvent evt)
{
    if (evt is BaseConstructedEvent baseEvt)
    {
        Logger.LogInfo($"Player {baseEvt.PlayerId} built {baseEvt.BasePartType}");
    }
}
This skill covers the essential knowledge needed to install, configure, use, and troubleshoot the Deep Synergy Multiplayer Mod for Subnautica 2 using BepInEx.
csharp
using DeepSynergy.Events;

// 定义自定义事件
public class BaseConstructedEvent : ISyncEvent
{
    public string PlayerId { get; set; }
    public Vector3 Position { get; set; }
    public string BasePartType { get; set; }
    public long Timestamp { get; set; }
}

// 广播自定义事件
void OnBasePartPlaced(BasePartType type, Vector3 position)
{
    var evt = new BaseConstructedEvent
    {
        PlayerId = LocalPlayer.Id,
        Position = position,
        BasePartType = type.ToString(),
        Timestamp = NetworkTime.CurrentTime
    };
    
    StateSynchronizer.BroadcastCustomEvent(evt);
}

// 处理自定义事件
void OnCustomEventReceived(ISyncEvent evt)
{
    if (evt is BaseConstructedEvent baseEvt)
    {
        Logger.LogInfo($"Player {baseEvt.PlayerId} built {baseEvt.BasePartType}");
    }
}
本技能涵盖了使用BepInEx安装、配置、使用和排查《Subnautica 2》Deep Synergy多人模组所需的核心知识。