Skip to main content

Dunia.dll — Command-Line Parsing and Full Flag List

Verified via reverse engineering

See the overview for binary identification.

Traced from RunGame (0x10006510) down through InitDuniaEngine (0x10004900) and its callees, fully decompiled and read. Two independent parsing mechanisms exist:

  1. Ad-hoc strstr(cmdline, "-flagname") checks scattered across several functions — presence-only flags, or (via the helper FUN_1003f7f0(cmdline, "-flagname", &outBuf)) flags that also capture the following token as a value.
  2. A generic -key value tokenizer, ParseGamerProfileArgs (0x10661950) — walks the whole command line splitting on -/space and stuffing every pair into a "GamerProfile" property-bag object via FUN_106616e0(profile, key, value). Any -key value pair is accepted generically; the flags below are just the ones with confirmed, dedicated consumers reading back out of that bag (or checked directly via strstr).

Call graph, top to bottom:

RunGame (0x10006510)
strstr(cmdline, "-openautomate") -> FUN_10005fa0 (QA automation loop, separate from normal play)
else: InitDuniaEngine(hInstance, 0, 0, cmdline, ...)
ParseGameConfigFlags(cmdline) [0x10662c70]
...
DispatchLaunchMode(cmdline) [0x10663d40]
-> ParseLoadSaveArgs [0x10661f50, "-load"]
-> ParseWorldAndBenchmarkArgs [0x10662f90, "-benchmark"/"-world"/"-map"/spawn*]
-> DispatchNetworkMode [0x10663af0, "-host"/"-client"/"-join"/"-wait"]
-> ParseOnlineSessionArgs [0x10662440, "-login" etc.]
-> ParseJoinArgs [0x10662b40, "-join <ip>"]
-> (editorpc / default paths, not further split out)

Window / bootstrap flags (checked directly in InitDuniaEngine, before engine subsystems init)

FlagEffect
-borderlessBorderless window
-dedicatedDedicated-server mode; combined with -norender skips window/render init entirely
-norenderNo rendering (only takes the headless branch together with -dedicated)
-editorpcRemote-editor/PC connection mode — routes into DispatchLaunchMode's editorpc branch (FUN_10661b40, not further explored)
-xpos <n> / -ypos <n>Window position (only read when not -host/-client)
-host / -clientPresence checked here to build a window-title suffix; real network handling happens later in DispatchNetworkMode
-d3dmtsSets a D3D multithread-safety flag (DAT_10f92043 = 1)
-3dplatform <d3d10a|d3d10|d3d9>Forces the render backend

Config toggles (ParseGameConfigFlags, 0x10662c70 — runs once at the very start of InitDuniaEngine)

FlagEffect
-cmdfile <path>Load additional arguments from a file, recursively re-parsed (FUN_10661cf0)
-logFile <path>Parsed but non-functional in retail — see below
-nomouseDisable mouse
-noexmouseDisable "extended" mouse (raw input?)
-nopadDisable gamepad
-nobfBoolean toggle, name unexplored — likely a netcode/"battlefield" layer disable
-nocompileDisable shader (or script) compilation
-norenderAlso read here (duplicate of the bootstrap check above)
-runscriptindebugRun Lua scripts in debug mode
-zombieaiBoolean AI toggle, name unexplored — plausibly a simplified/dumb-AI debug mode
-usearchivecache / -noarchivecacheForce-enable/disable the packed-archive read cache

World / spawn / save (ParseWorldAndBenchmarkArgs 0x10662f90, ParseLoadSaveArgs 0x10661f50 — reached via DispatchLaunchMode)

FlagEffect
-world <name> / -map <name>Load directly into a level, skipping the main menu
-spawn <name>Spawn at a named spawn point
-spawnpos <x,y,z>Spawn at an explicit position
-spawnangle <yaw,pitch,roll>Spawn with an explicit orientation (values scaled by a deg→rad-style constant DAT_10e0eed8)
-load <savename>Load a specific save game directly (walks PersistenceDB, reads back a "PlayerPos" property afterward — see savegame)
-bfname <name>Session/"battlefield" display name (also read again in the online-session parser)

Benchmark harness (ParseWorldAndBenchmarkArgs, entered whenever -benchmark is present)

FlagEffect
-benchmark <playback|record|sectors|spawnpoints|path>Selects benchmark sub-mode. Any other value (without -benchmarkinputname also present) is a hard usage error: "Invalid parameters for -benchmark. Ex; -benchmark {playback|record|sectors|spawnpoints|path} -world worldname -map mapname"
-benchmarkinputname <name>Alternate trigger accepted instead of -benchmark playback
-benchmarkloop <n>Loop count for the benchmark (default 1)
-benchmarkfixedframerateForce a fixed frame rate during the benchmark
-benchmarkdisableaiDisable AI during the benchmark (also pokes an engine flags int, +0x20 = 0xfff7)
-benchmarkid <id>Numeric benchmark ID

Networking (DispatchNetworkMode 0x10663af0 → ParseOnlineSessionArgs 0x10662440 / ParseJoinArgs 0x10662b40)

-host, -client, -join, and -wait all route into DispatchNetworkMode, which always calls ParseOnlineSessionArgs — and that function hard-aborts if -login is absent ("Invalid parameters for -host, missing (-login)"), regardless of which of the four triggered entry.

FlagEffect
-hostLaunch as server (requires -login)
-clientLaunch as a network client (also requires -login, same gate)
-join <ip>Connect to a specific server IP; validated with inet_addr — invalid/missing IP produces the exact usage strings "Trying to launch an online client with an invalid ip (-join xxx.xx.xx.xx)" / "...but ip is missing..."
-waitWait-for-connection mode, otherwise same gating as -host/-join
-login <name>Required Ubi.com/Agora login name
-password <pw>Login password
-keyonline <key>Likely a CD-key/license token for online auth
-sessionuid <uid>Numeric session ID (parsed with _strtoui64)
-team / -ctf / -vipSelects game mode constant
-online / -lanNetwork scope (-online = Agora-backed online, code 2; default/-lan = 3)
-noagoraForces non-Agora networking; combined with -online is a hard error: "Cannot launch an online game (-online) without using Agora (-noagora was detected)"
-rankedMarks the session ranked
-dedicatedAlso read here, marks the session as a dedicated server for the online layer specifically

Misc, read in DispatchLaunchMode itself before branching

FlagEffect
-exec <file>Execute a console/Lua command file at boot
-notrackingDisables the telemetry/tracking client

QA automation path (-openautomate, handled entirely separately by FUN_10005fa0)

If -openautomate is present, RunGame skips the normal game loop entirely and enters a numeric-command dispatch loop (FUN_10299a00 returns a case 0–6, dispatching to FUN_10006710/FUN_10008620/FUN_10007050/FUN_100075a0/FUN_100065b0/FUN_10006600) — an internal QA/automation harness, not reachable through normal -flag parsing. None of these 6 handlers have been examined.

-logFile appears dead in the retail build

Live-tested (.\FarCry2.exe -logFile C:\path\engine.log): no file is created. Traced why in ParseGameConfigFlags and its caller InitDuniaEngine:

  • The flag is genuinely parsed — FUN_1003f7f0(cmdline, "-logFile", param_1 + 0x13) captures the path into a dedicated std::string field of the config object ParseGameConfigFlags constructs (called twice, redundantly — a harmless duplicate). That config object is constructed directly on InitDuniaEngine's own stack frame (confirmed via disassembly — the three boolean fields immediately after it, nomouse/noexmouse/nopad, are read back at fixed stack offsets and drive DAT_10fd42c0..c2, so the frame layout is confirmed, not guessed). The logfile string sits at this+0x4c in that frame.
  • Full disassembly of InitDuniaEngine was read end to end looking for any read of that this+0x4c stack slot after the parse — none exists. No CreateFileA/fopen/log-write call anywhere in the function takes that buffer as an argument.
  • The RTTI-derived class list does contain a CLog, but its mangled RTTI name is .?AVCLog@MassiveAdClient3@@ — it belongs to the third-party MassiveAdClient3 in-game-advertising SDK linked into this DLL, not an engine logging facility. No other Log-named class or function exists in the binary.
  • Consistent with the independently-sourced community finding that Far Cry 2 retail has no in-game dev console — debug/dev-facing instrumentation reads as compiled-out or stubbed for the shipped build, not merely hidden behind a flag.

Conclusion: -logFile's value is captured and then goes nowhere within the boot path — vestigial parsing left over from a development build whose actual log sink was stripped for retail, not a flag the user is invoking wrong. Not proven for the entire 20MB DLL (this traced one function's disassembly exhaustively, not every one of the ~90k functions in the binary), but no plausible consumer turned up anywhere reachable from boot.

Unknowns

  • The exact semantics of -nobf and -zombieai — booleans read but never named beyond their flag string.
  • What -client does differently from -join given both share the same ParseOnlineSessionArgs gate.
  • The -editorpc handler FUN_10661b40 itself.