Skip to content

Frequently Asked Questions ​


Getting Started ​

Q: What do I need to start modding DayZ? ​

A: You need Steam, DayZ (retail copy), DayZ Tools (free on Steam under Tools), and a text editor (VS Code recommended). No programming experience is strictly required — start with Chapter 8.1: Your First Mod. DayZ Tools includes Object Builder, Addon Builder, TexView2, and the Workbench IDE.

Q: What programming language does DayZ use? ​

A: DayZ uses Enforce Script, a proprietary language by Bohemia Interactive. It has C-like syntax similar to C#, but with its own rules and limitations (no ternary operator, no try/catch, no lambdas). See Part 1: Enforce Script for a complete language guide.

Q: How do I set up the P: drive? ​

A: Open DayZ Tools from Steam, click "Workdrive" or "Setup Workdrive" to mount the P: drive. This creates a virtual drive pointing to your modding workspace where the engine looks for source files during development. You can also use subst P: "C:\Your\Path" from the command line. See Chapter 4.5.

Q: Can I test my mod without a dedicated server? ​

A: Yes. Launch DayZ with the -filePatching parameter and your mod loaded. For quick testing, use a Listen Server (host from the in-game menu). For production testing, always verify on a dedicated server too, as some code paths differ. See Chapter 8.1.

Q: Where do I find vanilla DayZ script files to study? ​

A: After mounting the P: drive via DayZ Tools, vanilla scripts are at P:\DZ\scripts\ organized by layer (3_Game, 4_World, 5_Mission). These are the authoritative reference for every engine class, method, and event. Also see the Cheat Sheet and API Quick Reference.


Common Errors and Fixes ​

Q: My mod loads but nothing happens. No errors in the log. ​

A: Most likely your config.cpp has an incorrect requiredAddons[] entry, so your scripts load too early or not at all. Verify that each addon name in requiredAddons matches an existing CfgPatches class name exactly (case-sensitive). Check the script log at %localappdata%/DayZ/ for silent warnings. See Chapter 2.2.

Q: I get "Cannot find variable" or "Undefined variable" errors. ​

A: This usually means you are referencing a class or variable from a higher script layer. Lower layers (3_Game) cannot see types defined in higher layers (4_World, 5_Mission). Move your class definition to the correct layer, or use typename reflection for loose coupling. See Chapter 2.1.

Q: Why does JsonFileLoader<T>.JsonLoadFile() not return my data? ​

A: JsonLoadFile() returns void, not the loaded object -- and it is deprecated in the vanilla source. You must pre-allocate your object and pass it as a reference parameter: ref MyConfig cfg = new MyConfig(); JsonFileLoader<MyConfig>.JsonLoadFile(path, cfg);. Assigning the return value gives you null. It also cannot tell you it failed: it does nothing when the file is missing or cannot be opened, and a parse failure only reaches the RPT through ErrorEx (3_game/tools/jsonfileloader.c:129). Prefer the non-deprecated JsonFileLoader<T>.LoadFile(path, out data, out errorMessage) (:7), which returns bool and hands you the error. See Chapter 6.8 and Error Handling.

Q: My RPC is sent but never received on the other side. ​

A: Check these common causes: (1) The RPC ID does not match between sender and receiver. (2) You are sending from client but listening on client (or server-to-server). (3) You forgot to register the RPC handler in OnRPC() or your custom handler. (4) The target entity is null or not network-synced. See Chapter 6.9 and Chapter 7.3.

Q: I get "Error: Member already defined" in an else-if block. ​

A: Enforce Script does not allow variable redeclaration in sibling else if blocks within the same scope. Declare the variable once before the if chain, or use separate scopes with braces. See Chapter 1.12.

Q: My UI layout shows nothing / widgets are invisible. ​

A: Common causes: (1) Widget has zero size — check that width/height are set correctly (no negative values). (2) The widget is not Show(true). (3) Text color alpha is 0 (fully transparent). (4) The layout path in CreateWidgets() is wrong (no error is thrown, it just returns null). See Chapter 3.3.

Q: My mod causes a crash on server startup. ​

A: Check for: (1) Calling client-only methods (GetGame().GetPlayer(), UI code) on the server. (2) null reference in OnInit or OnMissionStart before the world is ready. (3) Infinite recursion in a modded class override that forgot to call super. Always add guard clauses since there is no try/catch. See Chapter 1.11.

Q: Are \\ and \" usable in Enforce Script string literals? ​

A: Yes. Bohemia's Enforce Script syntax page lists \n, \r, \t, \\ and \" as the supported escape sequences, and vanilla uses both freely — "DZ\\plants" in 3_game/objectspawner.c:4, "\\" as a literal backslash in 3_game/tools/keystouielements.c:89, and string.Format("Cannot open file \"%1\" for reading", filename) in 3_game/tools/jsonfileloader.c:14. An older version of this FAQ said the parser rejected them; that was wrong.

Forward slashes are still the right choice for engine resource paths — a convention, not a parser limit. Vanilla's particle registry even warns about \ in a registered path under DIAG_DEVELOPER (3_game/particles/particlelist.c:391-393). If you are hitting a parse error around a string, look for an unterminated literal or a multiline call rather than the escapes. See Chapter 1.12.


Architecture Decisions ​

Q: What is the 5-layer script hierarchy and why does it matter? ​

A: DayZ scripts compile in five numbered layers: 1_Core, 2_GameLib, 3_Game, 4_World, 5_Mission. Each layer can only reference types from the same or lower-numbered layers. This enforces architectural boundaries — put shared enums and constants in 3_Game, entity logic in 4_World, and UI/mission hooks in 5_Mission. See Chapter 2.1.

Q: Should I use modded class or create new classes? ​

A: Use modded class when you need to change or extend existing vanilla behavior (adding a method to PlayerBase, hooking into MissionServer). Create new classes for self-contained systems that do not need to override anything. Modded classes chain automatically — always call super to avoid breaking other mods. See Chapter 1.4.

Q: How should I organize client vs. server code? ​

A: Use #ifdef SERVER and #ifndef SERVER preprocessor guards for code that must only run on one side. For larger mods, split into separate PBOs: a client mod (UI, rendering, local effects) and a server mod (spawning, logic, persistence). This prevents leaking server logic to clients. See Chapter 2.5 and Chapter 6.9.

Q: When should I use a Singleton vs. a Module/Plugin? ​

A: Use a Module (registered with the vanilla PluginManager or a framework module manager — see Chapter 7.2) when you need lifecycle management (OnInit, OnUpdate, OnMissionFinish). Use a standalone Singleton for stateless utility services that just need global access. Modules are preferred for anything with state or cleanup needs. See Chapter 7.1 and Chapter 7.2.

Q: How do I safely store per-player data that survives server restarts? ​

A: Save JSON files to the server's $profile: directory using JsonFileLoader. Use the player's Steam UID (from PlayerIdentity.GetId()) as the filename. Load on player connect, save on disconnect and periodically. Always handle missing/corrupted files gracefully with guard clauses. See Chapter 7.4 and Chapter 6.8.


Publishing and Distribution ​

Q: How do I pack my mod into a PBO? ​

A: Use Addon Builder (from DayZ Tools) or third-party tools like PBO Manager. Point it at your mod's source folder, set the correct prefix (matching your config.cpp addon prefix), and build. The output .pbo file goes into your mod's Addons/ folder. See Chapter 4.6.

Q: How do I sign my mod for server use? ​

A: Generate a keypair with DayZ Tools' DSSignFile or DSCreateKey: this produces a .biprivatekey and .bikey. Sign each PBO with the private key (creates .bisign files next to each PBO). Distribute the .bikey to server admins for their keys/ folder. Never share your .biprivatekey. See Chapter 4.6.

Q: How do I publish to the Steam Workshop? ​

A: Use the DayZ Tools Publisher or the Steam Workshop uploader. You need a mod.cpp file in your mod root defining the name, author, and description. The publisher uploads your packed PBOs, and Steam assigns a Workshop ID. Update by re-publishing from the same account. See Chapter 2.3 and Chapter 8.7.

Q: Can my mod require other mods as dependencies? ​

A: Yes. In config.cpp, add the dependency mod's CfgPatches class name to your requiredAddons[] array. In mod.cpp, there is no formal dependency system — document required mods in your Workshop description. Players must subscribe to and load all required mods. See Chapter 2.2.


Advanced Topics ​

Q: How do I create custom player actions (interactions)? ​

A: Extend ActionBase (or a subclass like ActionInteractBase), define CreateConditionComponents() for preconditions, override OnStart/OnExecute/OnEnd for logic, and register it in SetActions() on the target entity. Actions support continuous (hold) and instant (click) modes. See Chapter 6.12.

Q: How does the damage system work for custom items? ​

A: Define a DamageSystem class in your item's config.cpp with DamageZones (named regions) and ArmorType values. Each zone tracks its own health. Override EEHitBy() and EEKilled() in script for custom damage reactions. The engine maps model Fire Geometry components to zone names. See Chapter 6.1.

Q: How can I add custom keybindings to my mod? ​

A: Create an inputs.xml file defining your input actions with default key assignments. Register them in script via GetUApi().RegisterInput(). Query state with GetUApi().GetInputByName("your_action").LocalPress(). Add localized names in your stringtable.csv. See Chapter 5.2 and Chapter 6.13.

Q: How do I make my mod compatible with other mods? ​

A: Follow these principles: (1) Always call super in modded class overrides. (2) Use unique class names with a mod prefix (e.g., MyMod_Manager). (3) Use unique RPC IDs. (4) Do not override vanilla methods without calling super. (5) Use #ifdef to detect optional dependencies. (6) Test with popular mod combinations (CF, Expansion, etc.). See Chapter 7.2.

Q: How do I optimize my mod for server performance? ​

A: Key strategies: (1) Avoid per-frame (OnUpdate) logic — use timers or event-driven design. (2) Cache references instead of calling GetGame().GetPlayer() repeatedly. (3) Use GetGame().IsServer() / GetGame().IsClient() guards to skip unnecessary code. (4) Profile with int start = TickCount(0); benchmarks. (5) Limit network traffic — batch RPCs and use Net Sync Variables for frequent small updates. See Chapter 7.7.


Have a question not covered here? Open an issue on the repository.

Released under CC BY-SA 4.0 | Code examples under MIT License