| name | subnautica-ii-coop-deep-synergy-mod |
| description | BepInEx multiplayer mod for Subnautica 2 enabling synchronized co-op survival with deterministic session architecture |
| triggers | ["how do I set up Subnautica 2 multiplayer mod","configure Deep Synergy mod for co-op","install BepInEx mod for Subnautica 2","troubleshoot Subnautica multiplayer sync issues","create co-op session in Subnautica 2","customize Deep Synergy session parameters","integrate AI narration with Subnautica mod","fix session desync in Subnautica co-op"] |
Subnautica II Deep Synergy Co-op Mod
Skill by ara.so — Devtools Skills collection.
Overview
The Deep Synergy Multiplayer Mod transforms Subnautica 2 into a synchronized cooperative experience using BepInEx framework. It implements deterministic session synchronization (DSS) where game state, inventory, base-building, and creature AI are shared across clients without central servers.
Key Architecture:
- Peer-to-peer WebRTC connectivity with NAT punch-through
- Blockchain-inspired Merkle tree inventory verification
- Hot-reloadable BepInEx plugin modules
- Adaptive dynamic scaling based on player count
- Optional AI narrative integration (OpenAI/Claude APIs)
Installation
Prerequisites
- Subnautica 2 installed via Steam/GOG
- BepInEx 6.0.x IL2CPP version for Unity games
Setup Steps
Subnautica2/
├── BepInEx/
│ ├── config/
│ │ └── synergy_profile.json
│ ├── core/
│ └── plugins/
│ └── DeepSynergy/
│ ├── DeepSynergy.dll
│ ├── SessionManager.dll
│ └── StateSynchronizer.dll
└── Subnautica2.exe
First Launch
[Info : BepInEx] BepInEx 6.0.0-pre.1 - Subnautica2
[Info : DeepSynergy] Deep Synergy Mod v1.0 loaded
[Info : DeepSynergy] Multiplayer hooks initialized
Configuration
Session Profile (synergy_profile.json)
Create or edit BepInEx/config/synergy_profile.json:
{
"session_name": "DeepDiveSquad",
"max_players": 4,
"difficulty_scale": "adaptive",
"resource_multiplier": 1.5,
"oxygen_consumption": 0.85,
"creature_spawn_divider": 1.5,
"enable_pvp": false,
"friendly_fire": false,
"shared_blueprints": true,
"ping_locations_shared": true,
"time_of_day_sync": "host",
"voice_chat_integration": "discord_rpc",
"network": {
"port_range":
Configuration Fields
| Field | Type | Description |
|---|
resource_multiplier | float | Scales harvestable resources (1.5 = 50% more) |
oxygen_consumption | float | Oxygen drain modifier (0.85 = 15% slower) |
creature_spawn_divider | float | Reduces creature counts (1.5 = 33% fewer) |
difficulty_scale | string | "fixed", "adaptive", or "manual" |
tick_rate | int | State sync updates per second |
state_hash_interval_ms | int | Inventory verification interval |
Console Commands
Access via BepInEx console (F12 by default):
Session Management
/start_server
/join_session 9B2A-4C7D-E8F1
/synergy_status
/leave_session
Session Scaling
/synergy_scale 1.8
/seed_override 8251
/synergy_reset
AI Integration
/api_narrate "discovering the precursor facility"
/api_lore creature_reaper_001
Code Integration Patterns
Plugin Development Hook
For extending the mod with custom BepInEx plugins:
using BepInEx;
using BepInEx.IL2CPP;
using DeepSynergy.Core;
using DeepSynergy.Sync;
namespace MyCustomExtension
{
[BepInPlugin("com.myname.custommod", "Custom Synergy Extension", "1.0.0")]
[BepInDependency("com.deepsynergy.core", BepInDependency.DependencyFlags.HardDependency)]
public class CustomSynergyPlugin : BasePlugin
{
public override void Load()
{
SessionManager.OnSessionStarted += OnSessionStart;
StateSynchronizer.OnInventorySync += OnInventoryUpdated;
Log.LogInfo("Custom extension loaded");
}
private void OnSessionStart(SessionContext context)
{
Log.LogInfo($"Session {context.SessionCode} started with {context.PlayerCount} players");
if (context.PlayerCount >= 3)
{
context.ApplyDifficultyModifier(1.2f);
}
}
private void OnInventoryUpdated(InventoryState state)
{
var merkleRoot = state.ComputeMerkleRoot();
Log.LogInfo($"Inventory hash: ");
}
}
}
Custom Session Event Listener
using DeepSynergy.Events;
using UnityEngine;
public class BaseConstructionSyncer : MonoBehaviour
{
void Start()
{
ConstructionSync.OnBasePiecePlaced += HandlePiecePlaced;
ConstructionSync.OnBasePieceRemoved += HandlePieceRemoved;
}
void HandlePiecePlaced(ConstructionPiece piece, ulong playerId)
{
var syncPacket = new SyncPacket
{
Type = SyncType.ConstructionAdd,
Timestamp = NetworkTime.CurrentTimestamp(),
PlayerId = playerId,
Data = piece.Serialize()
};
SessionManager.Broadcast(syncPacket);
}
void HandlePieceRemoved(Vector3 position, ulong playerId)
{
var syncPacket = new SyncPacket
{
Type = SyncType.ConstructionRemove,
Timestamp = NetworkTime.CurrentTimestamp(),
PlayerId = playerId,
Data = position.Serialize()
};
SessionManager.Broadcast(syncPacket);
}
}
AI Narration Integration
using DeepSynergy.AI;
using System.Threading.Tasks;
public class NarrativeController
{
private AIIntegrationService aiService;
public async Task GenerateDiscoveryNarrative(string eventDescription)
{
if (!aiService.IsEnabled("openai")) return;
var prompt = $@"
Context: Multiplayer Subnautica 2 session
Event: {eventDescription}
Generate a 2-3 sentence journal entry from the player's perspective.
";
var narrative = await aiService.CallOpenAI(
model: "gpt-4",
prompt: prompt,
maxTokens: 150,
temperature: 0.7f
);
PDAManager.AddJournalEntry(narrative);
}
public async Task<string> GenerateSpeciesDescription(string creatureId)
{
if (!aiService.IsEnabled("claude")) return null;
var prompt = $@"
Generate a fictional marine biology report for creature ID: {creatureId}
Include: Classification, behavior patterns, threat level, ecosystem role
Format: Scientific database entry style
";
return await aiService.CallClaude(
model: "claude-3-sonnet-20240229",
prompt: prompt,
maxTokens:
);
}
}
Common Usage Patterns
Hosting a Session
/start_server
/join_session A7B3-9D2E-F1C4
Debugging Sync Issues
/synergy_status
/synergy_resync inventory
/synergy_dump_state
/synergy_verify_integrity
Performance Tuning
{
"sync_settings": {
"tick_rate": 15,
"state_hash_interval_ms": 750,
"inventory_verify_frequency": 10
},
"network": {
"max_latency_ms": 300,
"packet_loss_tolerance": 0.08
}
}
Troubleshooting
"Session Code Invalid" Error
Cause: Mismatched mod versions or network timeout
/synergy_version
/synergy_ping <host_ip>
/start_server --port 7777
Inventory Desynchronization
Symptoms: Items appear duplicated or missing
/synergy_reconcile_state
/synergy_verify_integrity
/synergy_rollback_checkpoint
Creature AI Conflicts
Symptoms: Creatures behave erratically or freeze
{
"sync_settings": {
"ai_state_interval_ms": 200
}
}
/synergy_debug_ai creature_stalker_032
High Latency/Packet Loss
/synergy_netstat
/synergy_tickrate 12
/synergy_compression lz4
API Integration Failures
OpenAI/Claude not responding:
echo $OPENAI_API_KEY
echo $ANTHROPIC_API_KEY
/api_test openai
/api_test claude
tail -f BepInEx/LogOutput.log | grep API
Session Migration After Host Disconnect
Automatic recovery:
/synergy_status
/synergy_migrate_host <peer_id>
Advanced Configuration
Custom Difficulty Profiles
{
"difficulty_profiles": {
"casual": {
"resource_multiplier": 2.0,
"oxygen_consumption": 0.6,
"creature_spawn_divider": 2.5,
"damage_taken_multiplier": 0.7
},
"hardcore": {
"resource_multiplier": 0.8,
"oxygen_consumption": 1.3,
"creature_spawn_divider": 0.7,
"damage_taken_multiplier": 1.5,
"permadeath": true
}
},
"active_profile": "casual"
}
Locale-Specific Settings
{
"locale": "ja-JP",
"localization_override": {
"console_commands": "ja-JP",
"ui_elements": "ja-JP",
"api_prompts": "en-US"
}
}
WebRTC Configuration
{
"network": {
"webrtc": {
"ice_servers": [
"stun:stun.l.google.com:19302",
"stun:stun1.l.google.com:19302"
],
"enable_turn": false,
"turn_server_env": "TURN_SERVER_URL",
"turn_credentials_env": "TURN_CREDENTIALS"
}
}
}
Best Practices
- Always backup saves before using multiplayer sessions
- Match mod versions across all players to prevent sync issues
- Use adaptive scaling for dynamic player counts
- Set realistic latency tolerances based on geographic distances
- Enable AI features sparingly to avoid API rate limits
- Monitor console logs during first session for configuration errors
- Use checkpoint systems via
/synergy_checkpoint every 15-20 minutes
Environment Variables
export OPENAI_API_KEY="sk-..."
export ANTHROPIC_API_KEY="sk-ant-..."
export TURN_SERVER_URL="turn:turnserver.example.com:3478"
export TURN_CREDENTIALS="username:password"