subnautica-2-deep-synergy-multiplayer-mod

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Subnautica 2: Deep Synergy Multiplayer Mod

《深海迷航2》:Deep Synergy 多人模组

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

Overview

概述

Deep Synergy is a BepInEx plugin that transforms Subnautica 2 into a synchronized cooperative multiplayer experience. It implements deterministic session synchronization, adaptive difficulty scaling, shared inventory management, and peer-to-peer networking without requiring central servers.
Key Architecture:
  • BepInEx 6.0.x IL2CPP runtime hooks
  • WebRTC peer-to-peer data channels with NAT punch-through
  • Merkle tree inventory state verification
  • Decentralized session migration on host disconnect
  • Optional OpenAI/Claude API integration for dynamic narration
Deep Synergy是一款BepInEx插件,可将《深海迷航2》转变为同步的合作多人体验。它实现了确定性会话同步、自适应难度缩放、共享库存管理,以及无需中央服务器的点对点网络功能。
核心架构:
  • BepInEx 6.0.x IL2CPP运行时钩子
  • WebRTC 带NAT穿透的点对点数据通道
  • Merkle树 库存状态验证
  • 主机断开时的去中心化会话迁移
  • 可选的OpenAI/Claude API集成,用于动态叙事

Installation

安装

Prerequisites

前置要求

  1. Subnautica 2 installed via Steam/GOG
  2. BepInEx 6.0.x for Unity IL2CPP games
  1. 通过Steam/GOG安装**《深海迷航2》**
  2. 适用于Unity IL2CPP游戏的BepInEx 6.0.x

Steps

步骤

bash
undefined
bash
undefined

1. Install BepInEx (Windows example)

1. Install BepInEx (Windows example)

Download BepInEx_x64_6.x.x.zip from https://github.com/BepInEx/BepInEx/releases

Download BepInEx_x64_6.x.x.zip from https://github.com/BepInEx/BepInEx/releases

Extract to Subnautica 2 game directory

Extract to Subnautica 2 game directory

2. Download Deep Synergy mod

2. Download Deep Synergy mod

Extract to: <Game>/BepInEx/plugins/DeepSynergy/

Extract to: <Game>/BepInEx/plugins/DeepSynergy/

3. Verify structure

3. Verify structure

<GameDirectory>/ ├── BepInEx/ │ ├── config/ │ │ └── synergy_profile.json │ └── plugins/ │ └── DeepSynergy/ │ ├── DeepSynergy.dll │ └── localizations/ ├── Subnautica2.exe └── doorstop_config.ini
undefined
<GameDirectory>/ ├── BepInEx/ │ ├── config/ │ │ └── synergy_profile.json │ └── plugins/ │ └── DeepSynergy/ │ ├── DeepSynergy.dll │ └── localizations/ ├── Subnautica2.exe └── doorstop_config.ini
undefined

Linux/Steam Deck

Linux/Steam Deck

bash
undefined
bash
undefined

Set launch options in Steam

Set launch options in Steam

WINEDLLOVERRIDES="winhttp=n,b" %command%
WINEDLLOVERRIDES="winhttp=n,b" %command%

Or use Proton with BepInEx autoloader

Or use Proton with BepInEx autoloader

proton run Subnautica2.exe
undefined
proton run Subnautica2.exe
undefined

Configuration

配置

Session Profile (
BepInEx/config/synergy_profile.json
)

会话配置文件 (
BepInEx/config/synergy_profile.json
)

json
{
  "session_name": "Ocean Explorers",
  "max_players": 4,
  "difficulty_scale": "adaptive",
  "resource_multiplier": 1.0,
  "oxygen_consumption": 1.0,
  "creature_spawn_divider": 1,
  "enable_pvp": false,
  "friendly_fire": false,
  "shared_blueprints": true,
  "ping_locations_shared": true,
  "time_of_day_sync": "host",
  "voice_chat_integration": "none",
  "locale": "auto",
  "api_integration": {
    "openai": {
      "enabled": false,
      "api_key_env": "OPENAI_API_KEY",
      "role": "narrator"
    },
    "claude": {
      "enabled": false,
      "api_key_env": "ANTHROPIC_API_KEY",
      "role": "lore_engine"
    }
  },
  "network": {
    "port_range_start": 7777,
    "port_range_end": 7787,
    "enable_upnp": true,
    "max_latency_ms": 200,
    "packet_retry_limit": 5
  },
  "session_persistence": {
    "auto_save_interval_seconds": 300,
    "backup_count": 3,
    "save_path": "BepInEx/saves/"
  }
}
Key Fields:
  • difficulty_scale
    :
    "static"
    |
    "adaptive"
    (scales with player count)
  • resource_multiplier
    : Float multiplier for resource nodes (1.5 = 50% more)
  • oxygen_consumption
    : Fraction of normal drain (0.8 = 20% slower)
  • creature_spawn_divider
    : Reduces spawns (2 = half creatures)
  • time_of_day_sync
    :
    "all"
    (vote-based) |
    "host"
    |
    "disabled"
json
{
  "session_name": "Ocean Explorers",
  "max_players": 4,
  "difficulty_scale": "adaptive",
  "resource_multiplier": 1.0,
  "oxygen_consumption": 1.0,
  "creature_spawn_divider": 1,
  "enable_pvp": false,
  "friendly_fire": false,
  "shared_blueprints": true,
  "ping_locations_shared": true,
  "time_of_day_sync": "host",
  "voice_chat_integration": "none",
  "locale": "auto",
  "api_integration": {
    "openai": {
      "enabled": false,
      "api_key_env": "OPENAI_API_KEY",
      "role": "narrator"
    },
    "claude": {
      "enabled": false,
      "api_key_env": "ANTHROPIC_API_KEY",
      "role": "lore_engine"
    }
  },
  "network": {
    "port_range_start": 7777,
    "port_range_end": 7787,
    "enable_upnp": true,
    "max_latency_ms": 200,
    "packet_retry_limit": 5
  },
  "session_persistence": {
    "auto_save_interval_seconds": 300,
    "backup_count": 3,
    "save_path": "BepInEx/saves/"
  }
}
关键字段:
  • difficulty_scale
    :
    "static"
    |
    "adaptive"
    (随玩家数量缩放)
  • resource_multiplier
    : 资源节点的浮点乘数(1.5 = 增加50%)
  • oxygen_consumption
    : 正常消耗的比例(0.8 = 减慢20%)
  • creature_spawn_divider
    : 减少生物生成数量(2 = 生物数量减半)
  • time_of_day_sync
    :
    "all"
    (投票制) |
    "host"
    |
    "disabled"

Network Configuration

网络配置

json
{
  "network": {
    "transport": "webrtc",
    "stun_servers": [
      "stun:stun.l.google.com:19302",
      "stun:stun1.l.google.com:19302"
    ],
    "enable_relay": true,
    "bandwidth_limit_kbps": 512
  }
}
json
{
  "network": {
    "transport": "webrtc",
    "stun_servers": [
      "stun:stun.l.google.com:19302",
      "stun:stun1.l.google.com:19302"
    ],
    "enable_relay": true,
    "bandwidth_limit_kbps": 512
  }
}

In-Game Console Commands

游戏内控制台命令

Access via BepInEx console (F12 by default):
bash
undefined
通过BepInEx控制台访问(默认F12):
bash
undefined

Session Management

Session Management

/start_server [session_name] # Create new session /join_session <code> # Join with session code (format: XXXX-YYYY-ZZZZ) /leave_session # Gracefully disconnect /session_info # Display current session details
/start_server [session_name] # Create new session /join_session <code> # Join with session code (format: XXXX-YYYY-ZZZZ) /leave_session # Gracefully disconnect /session_info # Display current session details

Synchronization

Synchronization

/synergy_status # Show sync health, latency, peers /force_sync # Trigger manual state reconciliation /inventory_verify # Check Merkle tree integrity
/synergy_status # Show sync health, latency, peers /force_sync # Trigger manual state reconciliation /inventory_verify # Check Merkle tree integrity

Scaling & Debug

Scaling & Debug

/synergy_scale <multiplier> # Adjust difficulty (1.0-3.0) /toggle_debug_overlay # Show network stats overlay /seed_override <number> # Force world seed for all clients
/synergy_scale <multiplier> # Adjust difficulty (1.0-3.0) /toggle_debug_overlay # Show network stats overlay /seed_override <number> # Force world seed for all clients

AI Integration (if enabled)

AI Integration (if enabled)

/api_narrate "<event_description>" # Trigger OpenAI/Claude narration /api_status # Check API connection health
undefined
/api_narrate "<event_description>" # Trigger OpenAI/Claude narration /api_status # Check API connection health
undefined

Code Examples

代码示例

Plugin Hook (for mod developers extending functionality)

插件钩子(供模组开发者扩展功能)

csharp
using BepInEx;
using DeepSynergy.API;
using HarmonyLib;

namespace MySubnauticaAddon
{
    [BepInPlugin("com.example.addon", "My Synergy Addon", "1.0.0")]
    [BepInDependency("com.deepsynergy.multiplayer")]
    public class AddonPlugin : BaseUnityPlugin
    {
        private void Awake()
        {
            // Subscribe to session events
            SynergySessionManager.OnSessionCreated += OnSessionStart;
            SynergySessionManager.OnPlayerJoined += OnPeerConnect;
            
            // Hook into inventory sync
            SynergyInventory.RegisterCustomItemHandler(
                "CustomItem_ID",
                SerializeCustomItem,
                DeserializeCustomItem
            );
            
            Logger.LogInfo("Addon loaded successfully");
        }
        
        private void OnSessionStart(SessionContext ctx)
        {
            Logger.LogInfo($"Session {ctx.SessionCode} started with {ctx.MaxPlayers} slots");
        }
        
        private void OnPeerConnect(PeerInfo peer)
        {
            // Broadcast custom welcome message
            SynergyNetwork.SendToClient(peer.ClientId, new CustomWelcomePacket
            {
                Message = "Welcome to the enhanced session!"
            });
        }
        
        private byte[] SerializeCustomItem(object item)
        {
            // Custom serialization logic
            return System.Text.Encoding.UTF8.GetBytes(item.ToString());
        }
        
        private object DeserializeCustomItem(byte[] data)
        {
            return System.Text.Encoding.UTF8.GetString(data);
        }
    }
}
csharp
using BepInEx;
using DeepSynergy.API;
using HarmonyLib;

namespace MySubnauticaAddon
{
    [BepInPlugin("com.example.addon", "My Synergy Addon", "1.0.0")]
    [BepInDependency("com.deepsynergy.multiplayer")]
    public class AddonPlugin : BaseUnityPlugin
    {
        private void Awake()
        {
            // Subscribe to session events
            SynergySessionManager.OnSessionCreated += OnSessionStart;
            SynergySessionManager.OnPlayerJoined += OnPeerConnect;
            
            // Hook into inventory sync
            SynergyInventory.RegisterCustomItemHandler(
                "CustomItem_ID",
                SerializeCustomItem,
                DeserializeCustomItem
            );
            
            Logger.LogInfo("Addon loaded successfully");
        }
        
        private void OnSessionStart(SessionContext ctx)
        {
            Logger.LogInfo($"Session {ctx.SessionCode} started with {ctx.MaxPlayers} slots");
        }
        
        private void OnPeerConnect(PeerInfo peer)
        {
            // Broadcast custom welcome message
            SynergyNetwork.SendToClient(peer.ClientId, new CustomWelcomePacket
            {
                Message = "Welcome to the enhanced session!"
            });
        }
        
        private byte[] SerializeCustomItem(object item)
        {
            // Custom serialization logic
            return System.Text.Encoding.UTF8.GetBytes(item.ToString());
        }
        
        private object DeserializeCustomItem(byte[] data)
        {
            return System.Text.Encoding.UTF8.GetString(data);
        }
    }
}

Custom Packet Handler

自定义数据包处理器

csharp
using DeepSynergy.Networking;

public class CustomDataPacket : INetworkPacket
{
    public string CustomData { get; set; }
    
    public void Serialize(BinaryWriter writer)
    {
        writer.Write(CustomData ?? "");
    }
    
    public void Deserialize(BinaryReader reader)
    {
        CustomData = reader.ReadString();
    }
}

// Register in Awake()
SynergyNetwork.RegisterPacketHandler<CustomDataPacket>(HandleCustomPacket);

private void HandleCustomPacket(CustomDataPacket packet, PeerInfo sender)
{
    Logger.LogInfo($"Received from {sender.Username}: {packet.CustomData}");
}

// Send packet
SynergyNetwork.BroadcastToAll(new CustomDataPacket 
{ 
    CustomData = "Hello from client!" 
});
csharp
using DeepSynergy.Networking;

public class CustomDataPacket : INetworkPacket
{
    public string CustomData { get; set; }
    
    public void Serialize(BinaryWriter writer)
    {
        writer.Write(CustomData ?? "");
    }
    
    public void Deserialize(BinaryReader reader)
    {
        CustomData = reader.ReadString();
    }
}

// Register in Awake()
SynergyNetwork.RegisterPacketHandler<CustomDataPacket>(HandleCustomPacket);

private void HandleCustomPacket(CustomDataPacket packet, PeerInfo sender)
{
    Logger.LogInfo($"Received from {sender.Username}: {packet.CustomData}");
}

// Send packet
SynergyNetwork.BroadcastToAll(new CustomDataPacket 
{ 
    CustomData = "Hello from client!" 
});

AI Integration Example

AI集成示例

csharp
using DeepSynergy.AI;
using System.Threading.Tasks;

public async Task GenerateNarrativeLog(string playerAction)
{
    if (!SynergyAI.IsEnabled(AIProvider.OpenAI))
        return;
    
    var prompt = $"Generate a 2-sentence survival log entry for: {playerAction}";
    
    var response = await SynergyAI.QueryOpenAI(new AIRequest
    {
        Prompt = prompt,
        MaxTokens = 100,
        Temperature = 0.7f,
        ApiKeyEnvVar = "OPENAI_API_KEY"
    });
    
    if (response.Success)
    {
        // Display in PDA journal
        SynergyUI.ShowNotification(response.Text, NotificationType.Journal);
    }
}

// Usage
await GenerateNarrativeLog("Built a multipurpose room at 200m depth");
csharp
using DeepSynergy.AI;
using System.Threading.Tasks;

public async Task GenerateNarrativeLog(string playerAction)
{
    if (!SynergyAI.IsEnabled(AIProvider.OpenAI))
        return;
    
    var prompt = $"Generate a 2-sentence survival log entry for: {playerAction}";
    
    var response = await SynergyAI.QueryOpenAI(new AIRequest
    {
        Prompt = prompt,
        MaxTokens = 100,
        Temperature = 0.7f,
        ApiKeyEnvVar = "OPENAI_API_KEY"
    });
    
    if (response.Success)
    {
        // Display in PDA journal
        SynergyUI.ShowNotification(response.Text, NotificationType.Journal);
    }
}

// Usage
await GenerateNarrativeLog("Built a multipurpose room at 200m depth");

Session Persistence Hook

会话持久化钩子

csharp
using DeepSynergy.Persistence;

public void SaveCustomSessionData()
{
    var sessionData = new SessionSaveData
    {
        CustomFields = new Dictionary<string, object>
        {
            ["custom_marker_count"] = 42,
            ["team_base_name"] = "Arctic Outpost"
        }
    };
    
    SynergyPersistence.SaveSession(sessionData);
}

public void LoadCustomSessionData()
{
    var loaded = SynergyPersistence.LoadSession();
    
    if (loaded.CustomFields.TryGetValue("team_base_name", out var baseName))
    {
        Logger.LogInfo($"Restored base name: {baseName}");
    }
}
csharp
using DeepSynergy.Persistence;

public void SaveCustomSessionData()
{
    var sessionData = new SessionSaveData
    {
        CustomFields = new Dictionary<string, object>
        {
            ["custom_marker_count"] = 42,
            ["team_base_name"] = "Arctic Outpost"
        }
    };
    
    SynergyPersistence.SaveSession(sessionData);
}

public void LoadCustomSessionData()
{
    var loaded = SynergyPersistence.LoadSession();
    
    if (loaded.CustomFields.TryGetValue("team_base_name", out var baseName))
    {
        Logger.LogInfo($"Restored base name: {baseName}");
    }
}

Common Patterns

常见模式

Hosting a Session Programmatically

以编程方式托管会话

csharp
var sessionConfig = new SessionConfig
{
    Name = "Research Team Alpha",
    MaxPlayers = 3,
    Password = "optional_password",
    IsPublic = false,
    DifficultyScale = DifficultyScaleMode.Adaptive
};

var sessionCode = SynergySessionManager.CreateSession(sessionConfig);
Logger.LogInfo($"Session code: {sessionCode}"); // Share with friends
csharp
var sessionConfig = new SessionConfig
{
    Name = "Research Team Alpha",
    MaxPlayers = 3,
    Password = "optional_password",
    IsPublic = false,
    DifficultyScale = DifficultyScaleMode.Adaptive
};

var sessionCode = SynergySessionManager.CreateSession(sessionConfig);
Logger.LogInfo($"Session code: {sessionCode}"); // Share with friends

Joining via Code

通过代码加入会话

csharp
var joinResult = await SynergySessionManager.JoinSessionAsync("9B2A-4C7D-E8F1");

if (joinResult.Success)
{
    Logger.LogInfo($"Connected to {joinResult.SessionName}");
}
else
{
    Logger.LogError($"Join failed: {joinResult.ErrorMessage}");
}
csharp
var joinResult = await SynergySessionManager.JoinSessionAsync("9B2A-4C7D-E8F1");

if (joinResult.Success)
{
    Logger.LogInfo($"Connected to {joinResult.SessionName}");
}
else
{
    Logger.LogError($"Join failed: {joinResult.ErrorMessage}");
}

Inventory Sync Verification

库存同步验证

csharp
// Check if local inventory matches peer consensus
var syncStatus = SynergyInventory.VerifyIntegrity();

if (!syncStatus.IsValid)
{
    Logger.LogWarning($"Inventory desync detected: {syncStatus.ConflictCount} conflicts");
    
    // Trigger reconciliation
    SynergyInventory.ForceReconciliation();
}
csharp
// Check if local inventory matches peer consensus
var syncStatus = SynergyInventory.VerifyIntegrity();

if (!syncStatus.IsValid)
{
    Logger.LogWarning($"Inventory desync detected: {syncStatus.ConflictCount} conflicts");
    
    // Trigger reconciliation
    SynergyInventory.ForceReconciliation();
}

Adaptive Difficulty Adjustment

自适应难度调整

csharp
// Automatically adjusts when players join/leave
SynergySessionManager.OnPlayerCountChanged += (count) =>
{
    float creatureMultiplier = Mathf.Lerp(1.0f, 1.8f, count / 4.0f);
    float resourceMultiplier = 1.0f + (count - 1) * 0.15f;
    
    SynergyScaling.SetCreatureSpawnRate(creatureMultiplier);
    SynergyScaling.SetResourceMultiplier(resourceMultiplier);
};
csharp
// Automatically adjusts when players join/leave
SynergySessionManager.OnPlayerCountChanged += (count) =>
{
    float creatureMultiplier = Mathf.Lerp(1.0f, 1.8f, count / 4.0f);
    float resourceMultiplier = 1.0f + (count - 1) * 0.15f;
    
    SynergyScaling.SetCreatureSpawnRate(creatureMultiplier);
    SynergyScaling.SetResourceMultiplier(resourceMultiplier);
};

Troubleshooting

故障排查

Session Code Not Generated

会话代码未生成

Symptom:
/start_server
returns "Failed to create session"
Solutions:
bash
undefined
症状:
/start_server
返回 "Failed to create session"
解决方案:
bash
undefined

Check port availability

Check port availability

netstat -an | grep 7777
netstat -an | grep 7777

Enable UPnP in router settings or manually forward ports 7777-7787

Enable UPnP in router settings or manually forward ports 7777-7787

Try manual port specification

Try manual port specification

/start_server "MySession" --port 7780
/start_server "MySession" --port 7780

Check BepInEx log

Check BepInEx log

tail -f BepInEx/LogOutput.log | grep "DeepSynergy"
undefined
tail -f BepInEx/LogOutput.log | grep "DeepSynergy"
undefined

Connection Timeout on Join

加入时连接超时

Symptom: "Session not found" or timeout after 30s
Solutions:
json
// Increase timeout in config
{
  "network": {
    "connection_timeout_seconds": 60,
    "enable_relay": true,
    "force_relay": false  // Try setting to true if direct connection fails
  }
}
Check NAT type:
bash
undefined
症状: "Session not found" 或30秒后超时
解决方案:
json
// Increase timeout in config
{
  "network": {
    "connection_timeout_seconds": 60,
    "enable_relay": true,
    "force_relay": false  // Try setting to true if direct connection fails
  }
}
检查NAT类型:
bash
undefined

Use test utility

Use test utility

/network_diagnostics
/network_diagnostics

Expected output:

Expected output:

NAT Type: Moderate (Full Cone)

NAT Type: Moderate (Full Cone)

UPnP: Enabled

UPnP: Enabled

Direct Connectivity: Yes

Direct Connectivity: Yes

undefined
undefined

Inventory Desync

库存不同步

Symptom: Items appear in one client but not others
Solutions:
csharp
// Force full state resync
SynergyInventory.RequestFullSync();

// Enable verbose logging
SynergyDebug.SetLogLevel(LogLevel.Trace, "Inventory");

// Check Merkle tree hash
var localHash = SynergyInventory.GetStateHash();
var peerHashes = SynergyInventory.GetPeerHashes();

foreach (var peer in peerHashes)
{
    if (peer.Value != localHash)
    {
        Logger.LogWarning($"Hash mismatch with {peer.Key}");
    }
}
症状: 物品在一个客户端显示但其他客户端不显示
解决方案:
csharp
// Force full state resync
SynergyInventory.RequestFullSync();

// Enable verbose logging
SynergyDebug.SetLogLevel(LogLevel.Trace, "Inventory");

// Check Merkle tree hash
var localHash = SynergyInventory.GetStateHash();
var peerHashes = SynergyInventory.GetPeerHashes();

foreach (var peer in peerHashes)
{
    if (peer.Value != localHash)
    {
        Logger.LogWarning($"Hash mismatch with {peer.Key}");
    }
}

Base Building Sync Issues

基地建造同步问题

Symptom: Placed structures invisible to other players
Solutions:
bash
undefined
症状: 放置的结构对其他玩家不可见
解决方案:
bash
undefined

Enable construction event logging

Enable construction event logging

/debug_construction true
/debug_construction true

Verify timestamp authority

Verify timestamp authority

/synergy_status # Check "Time Offset" column (should be <100ms)
/synergy_status # Check "Time Offset" column (should be <100ms)

Manual structure sync

Manual structure sync

/sync_base_structures
undefined
/sync_base_structures
undefined

High Latency/Packet Loss

高延迟/数据包丢失

Symptom: Laggy movement, delayed actions
Solutions:
json
// Reduce bandwidth usage
{
  "network": {
    "tick_rate": 15,  // Default: 30 (lower = less data)
    "compression": "lz4",  // Options: "none", "lz4", "gzip"
    "bandwidth_limit_kbps": 256
  }
}
bash
undefined
症状: 移动卡顿、操作延迟
解决方案:
json
// Reduce bandwidth usage
{
  "network": {
    "tick_rate": 15,  // Default: 30 (lower = less data)
    "compression": "lz4",  // Options: "none", "lz4", "gzip"
    "bandwidth_limit_kbps": 256
  }
}
bash
undefined

Monitor network stats

Monitor network stats

/network_stats
/network_stats

Expected output:

Expected output:

Latency: 45ms (good: <100ms, acceptable: <200ms)

Latency: 45ms (good: <100ms, acceptable: <200ms)

Packet Loss: 0.2% (good: <1%, max: 5%)

Packet Loss: 0.2% (good: <1%, max: 5%)

Bandwidth: 180 KB/s

Bandwidth: 180 KB/s

undefined
undefined

AI Integration Not Responding

AI集成无响应

Symptom:
/api_narrate
returns no output
Solutions:
bash
undefined
症状:
/api_narrate
无输出
解决方案:
bash
undefined

Verify environment variables

Verify environment variables

echo $OPENAI_API_KEY echo $ANTHROPIC_API_KEY
echo $OPENAI_API_KEY echo $ANTHROPIC_API_KEY

Check API status

Check API status

/api_status
/api_status

Test connection

Test connection

/api_narrate "test connection"
/api_narrate "test connection"

Enable debug logging

Enable debug logging

/debug_ai true

**Check logs for errors:**
[DeepSynergy.AI] Rate limit exceeded (429) - retry in 30s [DeepSynergy.AI] Invalid API key (401) [DeepSynergy.AI] Network timeout after 15s
undefined
/debug_ai true

**检查日志中的错误:**
[DeepSynergy.AI] Rate limit exceeded (429) - retry in 30s [DeepSynergy.AI] Invalid API key (401) [DeepSynergy.AI] Network timeout after 15s
undefined

Session Migration Failure

会话迁移失败

Symptom: "Host disconnected - migration failed"
Solutions:
json
// Enable redundant session state
{
  "session_persistence": {
    "enable_migration": true,
    "migration_timeout_seconds": 30,
    "require_consensus": true,  // All clients must agree on new host
    "backup_host_priority": ["peer_with_best_connection", "peer_with_lowest_latency"]
  }
}
bash
undefined
症状: "Host disconnected - migration failed"
解决方案:
json
// Enable redundant session state
{
  "session_persistence": {
    "enable_migration": true,
    "migration_timeout_seconds": 30,
    "require_consensus": true,  // All clients must agree on new host
    "backup_host_priority": ["peer_with_best_connection", "peer_with_lowest_latency"]
  }
}
bash
undefined

Force manual migration to specific peer

Force manual migration to specific peer

/migrate_host <peer_id>
undefined
/migrate_host <peer_id>
undefined

Performance Optimization

性能优化

json
{
  "performance": {
    "sync_interval_ms": 100,  // Faster = more responsive, higher bandwidth
    "state_compression": true,
    "lazy_sync_non_critical": true,  // Only sync nearby objects
    "cull_distance_multiplier": 1.5,  // Sync range relative to render distance
    "batch_updates": true
  }
}
json
{
  "performance": {
    "sync_interval_ms": 100,  // Faster = more responsive, higher bandwidth
    "state_compression": true,
    "lazy_sync_non_critical": true,  // Only sync nearby objects
    "cull_distance_multiplier": 1.5,  // Sync range relative to render distance
    "batch_updates": true
  }
}

Advanced: Custom Mod Integration

进阶:自定义模组集成

Creating Compatible Plugins

创建兼容插件

csharp
[BepInDependency("com.deepsynergy.multiplayer", BepInDependency.DependencyFlags.HardDependency)]
public class CompatibleMod : BaseUnityPlugin
{
    void Start()
    {
        // Wait for Deep Synergy initialization
        SynergySessionManager.OnInitialized += () =>
        {
            Logger.LogInfo("Deep Synergy ready - registering hooks");
            RegisterCustomSyncHandlers();
        };
    }
    
    void RegisterCustomSyncHandlers()
    {
        // Sync custom mod data
        SynergyAPI.RegisterSyncCallback("MyMod_CustomData", SyncMyModData);
    }
    
    void SyncMyModData(NetworkMessage msg)
    {
        // Handle incoming sync data
    }
}
csharp
[BepInDependency("com.deepsynergy.multiplayer", BepInDependency.DependencyFlags.HardDependency)]
public class CompatibleMod : BaseUnityPlugin
{
    void Start()
    {
        // Wait for Deep Synergy initialization
        SynergySessionManager.OnInitialized += () =>
        {
            Logger.LogInfo("Deep Synergy ready - registering hooks");
            RegisterCustomSyncHandlers();
        };
    }
    
    void RegisterCustomSyncHandlers()
    {
        // Sync custom mod data
        SynergyAPI.RegisterSyncCallback("MyMod_CustomData", SyncMyModData);
    }
    
    void SyncMyModData(NetworkMessage msg)
    {
        // Handle incoming sync data
    }
}

Environment Variables

环境变量

bash
undefined
bash
undefined

Required for AI features

Required for AI features

export OPENAI_API_KEY="sk-..." export ANTHROPIC_API_KEY="sk-ant-..."
export OPENAI_API_KEY="sk-..." export ANTHROPIC_API_KEY="sk-ant-..."

Optional network configuration

Optional network configuration

export SYNERGY_FORCE_PORT=7780 export SYNERGY_DISABLE_UPNP=false export SYNERGY_LOG_LEVEL=INFO # DEBUG, INFO, WARN, ERROR
undefined
export SYNERGY_FORCE_PORT=7780 export SYNERGY_DISABLE_UPNP=false export SYNERGY_LOG_LEVEL=INFO # DEBUG, INFO, WARN, ERROR
undefined

Localization

本地化

json
// BepInEx/config/synergy_profile.json
{
  "locale": "ja",  // "en", "zh", "ja", "de", "fr", "pt", "ru", "es", "ko"
  "custom_translations_path": "BepInEx/localizations/custom/"
}
Custom translation file (
custom/my_lang.json
):
json
{
  "ui.session_created": "セッションが作成されました",
  "ui.player_joined": "{0}が参加しました",
  "error.connection_failed": "接続に失敗しました"
}
json
// BepInEx/config/synergy_profile.json
{
  "locale": "ja",  // "en", "zh", "ja", "de", "fr", "pt", "ru", "es", "ko"
  "custom_translations_path": "BepInEx/localizations/custom/"
}
自定义翻译文件 (
custom/my_lang.json
):
json
{
  "ui.session_created": "セッションが作成されました",
  "ui.player_joined": "{0}が参加しました",
  "error.connection_failed": "接続に失敗しました"
}