Repository navigation
Configuration
ModSync has two configuration surfaces:
-
Server
config.jsonc— what the server walks, what to never sync, what reaches a Fika headless install, and which Unity Managed DLLs to push. -
Each install's
<game>/ModSync_Data/Exclusions.jsonc— personal per-install opt-outs (player or headless).
Both files are created on first run with sensible defaults and a comment header you can hand-edit without consulting docs.
The serverside is really the heart of ModSync configuration, here you can pretty extensively customize your server's syncing behavior.
The main place you'll look to configure the server is in SPT/user/mods/Corter-ModSync/config.jsonc.
Note
SPT 4 path layout. The SPT 4 server runs from <gameRoot>/SPT/, not the game root directly.
This means paths to client-side files (BepInEx, Managed, etc.) must use ../ to step up to the game root.
user/mods/ and ModSync.Updater.exe are exceptions — they live under SPT/ and need no prefix.
SPT 3 used plain BepInEx/... because the server ran at the game root.
The syncPaths section is where you'll configure what files to sync and how they should be synced. Below, you'll find the default syncPath value
and a breakdown of what each option does.
Note
Why no user/mods/? Server-side mods stay on the server. Their client-facing components ship as separate BepInEx plugins, which DO sync via the three folders above.
Note
There are two hardcoded syncPaths built into the server mod. They are defined as follows
{
"enabled": true,
"enforced": true,
"silent": true,
"restartRequired": false,
"path": "../ModSync.Updater.exe",
"name": "(Builtin) ModSync Updater"
},
{
"enabled": true,
"enforced": true,
"silent": true,
"restartRequired": true,
"path": "../BepInEx/plugins/Corter-ModSync",
"name": "(Builtin) ModSync Plugin"
}If all you want is to add a new path and keep the default sync behavior, you can simply specify the path as a string.
// Adding a new sync path
{
"syncPaths": [
// ...
"../BepInEx/plugins"
]
}For more control over how files are synced, you can specify an object for the path. Any of the following options can be specified to customize behavior, or they can be omitted to inherit the default value.
-
path(string, required) - What path will be synced by this entry- Path must be relative to the SPT server root (
<gameRoot>/SPT/). BepInEx paths therefore start with../BepInEx/. - These paths can be to folders, recursively including all children, or individual files.
-
Exclusions can be overridden by more specific syncPaths (ie. An exclusion of
../BepInEx/plugins/Hollywood*can be overridden by adding../BepInEx/plugins/HollywoodGraphicsexplicitly as a syncPath) - Globs are not permitted
- Path must be relative to the SPT server root (
-
name(string, optional) Default: value of path - Name shown to clients in F12 sync menu- Allows admins to specify a more user-friendly name for syncPaths such as the name of the mod or things like "client-side mods", "server mods (self-hosting only)".
-
enabled(boolean, optional) Default:true- Will clients sync this path by default- Clients are able to toggle all non-enforced syncPaths individually on their end, this option sets the default state for a given entry
-
"enabled": truemakes a syncPath opt-out, while a value offalsemakes it opt-in. - A value of false does not prevent syncing, it just requires users to check a box before syncing will occur
-
enforced(boolean, optional) Default:false- Will clients be forced to match the server exactly- This changes sync behavior so that clients must strictly match the files present on the server
- Files that are modified or deleted by the client will be redownloaded and files added by clients will be removed
- Enforced syncPaths will override any client side exclusions users have set
Enforced paths can cause issues when files are generated client-side or excluded server-side. Ensure that all files a client needs for mods in enforced paths are either present on the server or added to the exclusions list!
[!WARNING] Never enforce the
../BepInEx/plugins/Fikafolder (or any folder that contains a file you exclude from players).enforcedmakes a client an exact mirror of the server and deletes anything the client has that the server's list doesn't. On a headless client, enforcing a folder re-applies the serverexclusionsto it — which hidesFika.Headless.dllfrom the list — so ModSync then deletes the headless's ownFika.Headless.dllon every sync, breaking the headless. Leave Fika on a non-enforced entry (e.g. the../BepInEx/pluginscatch-all): there theheadlessIncludesallowlist deliversFika.Headless.dllto headless whileexclusionskeeps it from players, and it is never deleted. Enforce individual mods that every client must match — not a whole folder holding a headless-only or player-excluded file. -
restartRequired(boolean, optional) Default:true- Will clients have to restart their game after updating these files- Some files, like server mods, do not require a restart when syncing to the client
- If a user is attempting to sync an update with any files marked
"restartRequired": truewill be required to restartFiles synced with
"restartRequired": trueare downloaded directly into the client's SPT folder, so make sure they won't be in use when the update is applied, otherwise it will fail.
-
silent(boolean, optional) Default:false- Will clients receive a prompt when this path is updated- When this option is
trueand updates are available they will be automatically applied in the background as the game loads - If a user is attempting to sync an update with any files marked
"silent": falsea prompt will be shown with all changes visible - This option plays well with
"restartRequired": falseand updates will be applied in the background while the game loads as usual
- When this option is
Tip
Sync Paths are processed from most specific to most general, so its possible to override settings for some
files in a directory. For instance, to enforce only a subset of ../BepInEx/config.
Recommended pattern: keep the broad folders (../BepInEx/plugins, ../BepInEx/patchers, ../BepInEx/config)
as plain non-enforced catch-alls that set the default rules, then add specific entries only for the mods you
want to lock down. Every file belongs to exactly one syncPath — the most-specific match — so anything you don't
name explicitly falls back to the catch-all. Removing the catch-alls means every mod must be listed individually
and there is no safe default (this is the usual cause of a headless deleting Fika.Headless.dll — see the
warning under enforced above).
The antithesis to the syncPaths setting is exclusions. This section of the config lets you specify files not to sync.
Exclusions can be specified as a list of paths or patterns not to include. You can find the default configuration for this setting below.
{
// ...
"exclusions": [
// SPT Installer files — not mods, they come with the SPT install
"../BepInEx/plugins/spt",
"../BepInEx/patchers/spt-prepatch.dll",
// Fika headless DLL — must never reach regular players
"../BepInEx/plugins/Fika/Fika.Headless.dll",
// Universal per-file opt-out — drop a .nosync or .nosync.txt file
// next to any mod folder/file to skip it
"**/*.nosync",
"**/*.nosync.txt",
// Git repo metadata
"**/.git"
]
}Tip
The .nosync sentinel: drop an empty .nosync or .nosync.txt file inside any mod folder to exclude that mod from sync without editing config.jsonc. Handy for mods that write per-machine state into their own folder — add it to the mod folder on the server and every client will skip that folder automatically.
Tip
If you ever run into a file that changes every time you try to sync, such as a log file or a configuration, it can be easily added here to prevent clients being bombarded by update prompts.
Tip
Excluding from players but still delivering to headless: add the path to exclusions AND to headlessIncludes. Entries in headlessIncludes override exclusions, so headless clients still receive the file while regular players never do. This is the correct pattern for mods like RAID_REVIEW that should only run on headless:
"exclusions": [
"../BepInEx/plugins/RAID_REVIEW.dll" // blocked for regular players
],
"headlessIncludes": [
"../BepInEx/plugins/RAID_REVIEW.dll" // override: headless still receives it
]Tip
Sync Paths can override exclusions if they are more specific. For instance, if you wanted to exclude all files
in the ../BepInEx/plugins/SAIN directory except the plugin itself (don't do this). You could add an exclusion of
../BepInEx/plugins/SAIN and a sync path of ../BepInEx/plugins/SAIN/SAIN.dll
When a Fika headless client connects, ModSync serves it only the plugins explicitly listed in headlessIncludes (scoped to ../BepInEx/plugins only). Patchers and config files pass through to headless unfiltered — only plugins are gated.
An empty list means the headless client receives zero plugins. You must populate this if you run a headless instance.
{
// ...
"headlessIncludes": [
// Fika (Core + Headless.dll both live in this folder) and ModSync itself
"../BepInEx/plugins/Fika",
"../BepInEx/plugins/Corter-ModSync",
// Bot AI — add whatever your headless needs:
// "../BepInEx/plugins/SAIN",
// "../BepInEx/plugins/DrakiaXYZ-BigBrain.dll",
// "../BepInEx/plugins/DrakiaXYZ-Waypoints"
]
}Entries can target a folder or an exact file:
-
../BepInEx/plugins/SAIN— matches the folder and everything inside it. Directory boundary is respected:SAINdoes NOT matchSAINFoo. -
../BepInEx/plugins/DrakiaXYZ-BigBrain.dll— matches just that one DLL. Sibling files in the same folder are not pulled in.
Note
Entries in headlessIncludes override exclusions — if a file appears in both lists it will be sent to headless.
This is intentional: it lets you keep Fika.Headless.dll in exclusions (so regular players never receive it)
while still delivering it to headless clients via headlessIncludes.
Warning
Do not use globs (e.g. *.dll) here. The allowlist exists to be deliberate about what reaches headless — a broad glob
defeats the purpose and can accidentally re-include files you meant to exclude. An allowlist is also much shorter than
its denylist equivalent (~20 entries vs. hundreds of cosmetic mods), and you only have to update it when headless's
mod set changes, not when the player ecosystem moves.
Tip
Watch the commas when you uncomment an example entry. The last active entry has no trailing comma, so add one to it before uncommenting the line below — otherwise you get two values with no separator and malformed JSON:
"headlessIncludes": [
"../BepInEx/plugins/Fika",
"../BepInEx/plugins/Corter-ModSync" // ← add a comma here before uncommenting below
// "../BepInEx/plugins/SAIN"
]Some mods ship Unity assemblies that must be installed into EscapeFromTarkov_Data/Managed/ on every player client. List the filenames (not full paths) of those DLLs here.
{
// ...
"managedIncludes": [
// Example — DynamicMaps ships these Unity assemblies. Replace with your own:
// "Unity.VectorGraphics.dll",
// "Unity.InternalAPIEngineBridge.003.dll"
]
}The server reads from ../EscapeFromTarkov_Data/Managed/ but only serves files you list here. This is intentionally restrictive:
- Docker/Linux server: that folder is a staging area containing only the mod DLLs you placed there — nothing vanilla.
- Windows host-is-also-a-player: that folder contains the full EFT install (169+ Unity DLLs). Without the allowlist, vanilla Unity DLLs would be synced to all clients.
Backup behaviour:
- On install: if the file already exists on the client, the original is backed up as
<filename>.modsync-bakbefore being replaced. - On removal (entry deleted from config, server restarted): if a
.modsync-bakexists, the original is restored automatically. If no backup was made (the file was new — not present in vanilla), it is deleted.
The headless equivalent of managedIncludes. Headless runs the game simulation without the rendering stack, so Managed assemblies are almost never needed there. Leave this empty unless a mod's install instructions specifically say it is required on headless.
{
// ...
"headlessManagedIncludes": []
}-
On the server, populate
headlessIncludesinconfig.jsoncwith the plugins your headless needs. Below is a full working example — adjust to your own mod set:"headlessIncludes": [ // Fika (Core + Headless.dll both live in this folder) and ModSync "../BepInEx/plugins/Fika", "../BepInEx/plugins/Corter-ModSync", // Bot AI + behavior "../BepInEx/plugins/SAIN", "../BepInEx/plugins/DrakiaXYZ-BigBrain.dll", "../BepInEx/plugins/DrakiaXYZ-Waypoints", // Bot gameplay tweaks "../BepInEx/plugins/DontShootTheBus.dll", "../BepInEx/plugins/NerfBotGrenades.dll", "../BepInEx/plugins/Shibdib.SniperBros.dll", // Misc gameplay + raid content "../BepInEx/plugins/acidphantasm-temporaryfixes", "../BepInEx/plugins/BlackDiv", "../BepInEx/plugins/MergeConsumables", "../BepInEx/plugins/RUAFComeHome", "../BepInEx/plugins/tacticaltoaster-untargohome", "../BepInEx/plugins/Terkoiz.FlareEventNotifier.dll", "../BepInEx/plugins/UseItemsFromAnywhere.dll", // Bundle / CRC loader helpers (raid load path) "../BepInEx/plugins/s8_SPT_LoadBundleEvenFaster", "../BepInEx/plugins/s8_SPT_PatchCRC32", // Networking / interop libs "../BepInEx/plugins/Tyfon.UIFixes.dll", "../BepInEx/plugins/Tyfon.UIFixes.Net.dll", // Worn cosmetics visible to other players in raid "../BepInEx/plugins/7Bpencil.WeaponCamoAndStickers", "../BepInEx/plugins/acidphantasm-armbandsforall", // WTT content libs "../BepInEx/plugins/WTT-ArmoryClient", "../BepInEx/plugins/WTT-ClientCommonLib", "../BepInEx/plugins/WTT-ContentBackportClient", "../BepInEx/plugins/WTT-PackNStrap" ]
-
On the headless install — nothing to configure. It detects
Fika.Headless.dllat startup, sends?headless=1to the server, and gets only the allowlisted plugins back.Exclusions.jsoncstays at its empty default.
When in doubt about whether a particular mod is safe on headless, check the Fika wiki or ask in the Fika Discord.
Clients are also given a few powerful tools for customizing how sync works for them. Plenty of clients will want to customize their config with tweaks to all sorts of client-side plugins.
Be sure to familiarize yourself with how syncing works if you run into any edge cases, but by and large the following tools are all you should need to make sure you can keep all your tricked out configs as a client.
If you are playing SPT with any mods, you are likely already familiar with the BepInEx Configuration Manager. ModSync makes use of this excellent system to expose client-side configuration. Clients can access the menu with F12 by default and scroll to where they see ModSync in the list.
-
Delete Removed Files(boolean) Default:true- Will files that get deleted on the server be automatically removed- Enforced sync paths will have their files removed regardless of what the client sets this to
- To understand how removed files are determined, review how syncing works
-
Synced Paths(list) - What syncPaths from the server will the client sync- Clients can toggle on and off any non-enforced paths
- This might be good if server admins want to allow clients to download optional mods only when they want them
Lives at <game>/ModSync_Data/Exclusions.jsonc on each install. Created on first run with an empty array and a comment header explaining the format.
One-line mental model: "files I don't want ModSync to install or keep installed on this machine."
For each path or glob you list:
| How the file got onto this install | What happens on next sync |
|---|---|
| ModSync installed it on a previous sync | Deleted locally |
| You never had it | Stays absent — not downloaded |
| You copied it in by hand (ModSync never installed it) | Stays — ModSync only touches files it installed |
This is an uninstall + don't-reinstall list, not a "freeze locally" list. Add something you currently have, and ModSync will remove it on the next sync (assuming ModSync had installed it in the first place).
- Player install: use this for personal opt-outs — visual mods you don't want, hotkey mods that conflict with yours, etc. Typically just a handful of entries per player.
-
Headless install: usually empty. The server's
headlessIncludesallowlist already controls what reaches headless. Use this file only for per-headless overrides on top of the allowlist (rare).
ModSync ships three of its own files: the plugin, the desktop Updater (ModSync.Updater.exe), and the headless patcher (BepInEx/patchers/Corter-ModSync-Prepatch.dll). By default all three sync to every client — which is harmless, but the Updater is dead weight on headless and the patcher is dead weight on players. If you want leaner installs, you can trim the one each side never runs:
| To remove… | Add this to that install's Exclusions.jsonc
|
|---|---|
| The Updater from a headless client | ModSync.Updater.exe |
| The patcher from a player client | BepInEx/patchers/Corter-ModSync-Prepatch.dll |
ModSync only honours these on the side that doesn't need the file. Each component stays enforced on the side that does: a player can't exclude the Updater, and a headless can't exclude the patcher — the exclusion is silently ignored so you can't break your own apply mechanism. The plugin itself is always enforced everywhere. Leaving all three in place is completely fine; this is purely for a minimal install.
Exclusions.jsonc is read once at game startup. Mid-game edits do nothing until you restart EFT.
[
// Examples — uncomment / edit as needed:
"BepInEx/plugins/NoInsurance.dll",
"BepInEx/plugins/HollywoodGraphics/**",
"BepInEx/config/com.author.somemod.cfg"
]Entries can be:
-
An exact file path —
BepInEx/plugins/SomeMod.dll -
A folder path —
BepInEx/plugins/DynamicMapsmatches the folder and everything inside it -
A glob —
BepInEx/plugins/DynamicMaps/**,BepInEx/config/*.cfg
Paths are written game-root-relative with forward slashes.
-
enforcedsyncpaths bypass local exclusions. If the admin marked a syncpath asenforced: true, the client can't opt out of files inside it. This keepsCorter-ModSync.dllitself uninstall-proof. -
Manually-installed files are immune. ModSync only deletes files it recognises from a previous sync (tracked in
ModSync_Data/PreviousSync.json). If you hand-dropped a file into BepInEx, ModSync won't touch it. - The "X files to remove" confirm appears before anything deletes. If a bad glob is about to delete 20 things, click Cancel and fix the glob.
Tip
If you were using the older Exclusions.json (from v0.12.0 or earlier), ModSync will automatically migrate it to
Exclusions.jsonc on first run. You don't need to do anything manually.
-
Server-only mod (lives in
user/mods/, no BepInEx component)? → Don't list anywhere. ModSync never syncsuser/mods/. -
BepInEx mod every player needs? → It syncs automatically via
syncPaths. No config needed. -
BepInEx mod the headless needs to run raids properly (bot AI, pathfinding, networking, server-driven gameplay)? → Add to
headlessIncludeson the server. -
BepInEx mod that's purely client-facing (HUD, UI overlays, visual effects, item info, hotkeys)? → Don't list anywhere — players get it by default, headless skips it because it's not in
headlessIncludes. -
Mod that ships Unity assemblies into
EscapeFromTarkov_Data/Managed/? → Add the DLL filenames tomanagedIncludes. Place the DLL files in../EscapeFromTarkov_Data/Managed/on the server (a staging folder on Docker, or the existing EFT folder on Windows — the allowlist keeps vanilla files out either way). -
A particular player doesn't want a particular mod? → That player adds it to their own
Exclusions.jsonc. -
Fika.Headless.dll→ already inexclusionsby default. Don't add anywhere else.
Fika is the multiplayer layer ModSync is designed to coexist with.
- Wiki: https://github.com/project-fika/Wiki
- Headless docs: see the Wiki's "Headless" section for the canonical list of which mods are known to work / break on a headless instance.
- Fika-Server-CSharp: https://github.com/project-fika/Fika-Server-CSharp
{ "syncPaths": [ "../BepInEx/plugins", "../BepInEx/patchers", "../BepInEx/config" ], // ... }