16 KiB
DayZ Memory C++ Overlay
A Windows C++20 DMA reader for DayZ using VolkDMA backend. Reads game memory in real-time and streams data to two frontends: an overlay ESP (DirectX 11 + ImGui) and a web radar (HTTP + SSE).
Use only on authorized systems. The web server runs plain HTTP — protect with a password before exposing beyond localhost.
Features
Memory & Reading:
- DMA-backed memory access (VolkDMA)
- Runtime signature scanning + static offsets
- Auto-reconnect on process/session drop
- High-frequency camera reads
- Efficient batched entity scanning
Overlay (DirectX 11 + ImGui):
- Player/zombie/animal/vehicle/loot ESP
- Player skeletons with interpolation
- Health bars, held weapons, worn items
- Configurable draw distances
- Ballistic aim dot (weapon velocity + drag)
- Bullet trail visualization
- Lumin menu with live config save
Web Radar (HTTP + SSE):
- Real-time map with pan/zoom
- Entity filters + player list
- Bullet path visualization
- Server-sent events for live updates
- Map tiles (512x512 PNG cache)
- Optional Caddy proxy for static hosting
- CORS support
Requirements
Build:
- Windows x64
- Visual Studio 2022 (MSVC toolchain)
- Windows SDK (DirectX 11)
- CMake 3.20+
- Git
- Internet (first configure only, to fetch dependencies)
VolkDMA:
Must be at this location (or update VOLKDMA_ROOT in CMakeLists.txt):
../dayz-dma/dma-dayz-cpp-master/VolkDMA/
Auto-fetched:
- nlohmann/json 3.11.3
- spdlog 1.14.1
- cpp-httplib 0.18.1
- stb
Vendored in external/lumin/: ImGui, Lumin framework, FreeType
Repository Layout
.
|-- CMakeLists.txt
|-- Caddyfile
|-- config/
| |-- config.cfg
| `-- item_filters.json
|-- external/lumin/
|-- maps/ # optional, git-ignored map PNGs
|-- src/
| |-- Core/ # shared runtime models
| |-- Memory/ # VolkDMA/VMM access wrapper
| |-- Overlay/ # DirectX/ImGui overlay and menu bridge
| |-- Readers/ # entity, item, bullet, scoreboard readers
| |-- Resolvers/ # world/local player/network metadata resolvers
| |-- Runtime/ # service loop and snapshot orchestration
| |-- SigScanner/ # signature scanner
| `-- Web/ # web radar server, snapshots, maps, bullet cache
`-- webroot/ # browser radar UI
Build output is normally placed under build/<config>/. Post-build steps copy runtime DLLs, config/, webroot/, maps/, and icon font assets next to the executable.
Quick Start
From a Developer PowerShell or a shell with MSVC available:
cmake -S . -B build -G "Visual Studio 17 2022" -A x64
cmake --build build --config Release
Run from the output directory so relative paths resolve to the copied assets:
cd .\build\Release
.\dayz-memory-cpp.exe
Typical launch flow:
- Start DayZ and join a server.
- Start
dayz-memory-cpp.exe. - Watch the console or
logs/dayz-memory.logfor attach/status messages. - Press
INSERTto open or close the overlay menu. - Open
http://localhost:7777for the web radar.
Running From an IDE
Use the dayz-memory-cpp CMake target.
Recommended debug/run settings:
- Generator/platform: x64 MSVC.
- Working directory:
$<TARGET_FILE_DIR:dayz-memory-cpp>or the concrete output folder such asbuild/Debug. - Configuration:
Releasefor normal use,Debugfor development.
Running from the repository root can work for some files, but the executable also needs the copied DLLs and data directories. The output directory is the least surprising working directory.
Runtime Controls
Keys:
INSERT— toggle menuCtrl+Cin console — shutdown
Menu Tabs:
Aim— ballistics, bullet trailsVisuals— ESP toggles, draw distancesLoot— item filters (fromconfig/item_filters.json)Info— status, entity counts, DMA throughput, web radar URLsConfig— resolution/render overrides, save settings, exit
Configuration
Two config files (both in working directory, copied at build):
config/config.cfg— INI format, runtime reader settings (refresh intervals, batch sizes)config/overlay.json— JSON, overlay/web UI settings (auto-created/updated by menu)
config/config.cfg
The parser accepts key = value lines and ignores # comments. Missing keys keep the code defaults.
Supported runtime keys:
| Key | Default if omitted | Purpose |
|---|---|---|
processName |
DayZ_x64.exe |
Target process name. |
useMemoryMap |
true |
Enables VolkDMA memory map usage. |
networkMetadataRefreshMs |
30000 |
Server name/version/map refresh interval. |
scoreboardRefreshMs |
30000 |
Scoreboard refresh interval. |
nearEntityRefreshMs |
20 |
Near entity list refresh interval. |
farEntityRefreshMs |
50 |
Far entity list refresh interval. |
slowEntityRefreshMs |
100 |
Slow entity list refresh interval. |
bulletRefreshMs |
50 |
Bullet table refresh interval. |
itemRefreshMs |
200 |
Item scan refresh interval. |
playersRefreshMs |
16 |
Player projection/update interval. |
boneRefreshMs |
4 |
Bone scatter refresh interval. |
liveLoopIdleMs |
1 |
Main loop idle sleep. Lower is more responsive and more CPU-heavy. |
reconnectThreshold |
5 |
Consecutive failures before reconnect. |
reconnectGracePeriodMs |
5000 |
Delay after session loss before reconnect. |
farEntityBatchSize |
64 |
Far entity batch size per tick. |
slowEntityBatchSize |
64 |
Slow entity batch size per tick. |
itemBatchSize |
64 |
Item batch size per tick. |
bonePlayerMaxDist |
500.0 |
Max player distance for skeleton reads. |
boneZombieMaxDist |
250.0 |
Max infected distance for skeleton reads. |
vmmRefreshMs |
30000 |
VMMDLL cache refresh cadence. |
itemSpatialFilterRadius |
300.0 |
Max item distance from local player published to overlay/web. |
The checked-in file intentionally keeps conservative refresh rates. Reduce intervals only when you have enough DMA/CPU headroom.
config/overlay.json
If the file does not exist, defaults from OverlayConfig are used. Saving from the menu creates it.
Example:
{
"showPlayers": true,
"showAnimals": true,
"showZombies": true,
"showItems": true,
"showBox": true,
"showSkeleton": true,
"showHeadDot": false,
"showCorpses": false,
"showWeapon": true,
"showHealthBar": true,
"showHealthNumber": false,
"playerMaxDist": 1000.0,
"animalMaxDist": 1000.0,
"zombieMaxDist": 500.0,
"itemMaxDist": 200.0,
"overlayWidth": 0,
"overlayHeight": 0,
"renderWidth": 0,
"renderHeight": 0,
"stretchToFill": true,
"webBindAddress": "0.0.0.0",
"webPort": 7777,
"webPassword": ""
}
Resolution notes:
overlayWidthandoverlayHeightshould be the monitor resolution.renderWidthandrenderHeightshould be the resolution DayZ actually renders at.- Leave render dimensions at
0when the game render resolution matches the monitor. - Set
stretchToFilltofalseif the game is letterboxed or pillarboxed instead of stretched.
config/item_filters.json
Loot categories are data-driven. Each top-level key is a category and can match by:
NameTypeNameConfigNameModelName
Values may be a string or an array of strings. Matching is case-insensitive substring matching after normalization.
Example:
{
"isWeapon": {
"desc": "Weapons",
"Color": "#f43f5e",
"TypeName": "weapon"
},
"isFood": {
"desc": "Food and drinks",
"Color": "#22c55e",
"ModelName": ["\\food\\", "\\drinks\\"]
}
}
If item_filters.json is missing, ItemFilterCatalog writes a default file.
Web Radar
When the app starts, it launches an HTTP server using settings from config/overlay.json.
Default URL:
http://localhost:7777
LAN access:
http://<overlay-pc-ip>:7777
The overlay Info tab lists detected local URLs.
Authentication
Set webPassword in config/overlay.json before exposing the radar beyond localhost:
{
"webPassword": "change-me"
}
Remote clients append the password as a query parameter:
http://<host>:7777/?password=change-me
Loopback requests are allowed without a password. An empty password disables password checks.
API Endpoints
| Endpoint | Description |
|---|---|
/ |
Serves webroot/index.html. |
/api/bootstrap |
Initial map/filter/server metadata. |
/api/state |
Latest full JSON state for polling clients. |
/events |
Server-sent events stream for live updates. |
/tile |
Serves 512x512 map tiles. |
/map-image |
Serves the full map image when available. |
/api/debug |
Debug information for paths and runtime state. |
Cross-origin GET and OPTIONS requests are supported so the UI can be hosted separately from the C++ backend.
Static Hosting With Caddy
The included Caddyfile serves webroot/ on port 8080 and proxies API/data endpoints to the C++ backend on 7777.
From the repository root:
caddy run
Open:
http://localhost:8080
This mode keeps browser requests same-origin on :8080 while Caddy proxies /api/*, /tile, /map-image, and /events to the backend.
Static Host With server= Parameter
The web UI can also be hosted somewhere else and pointed at the backend:
http://static-host/index.html?server=http://192.168.1.25:7777&password=change-me
The server value is stripped of a trailing slash in webroot/app.js.
Map Images
Map PNGs are loaded from:
maps/<map-id>.png
The folder is resolved relative to the executable directory. The repository maps/ directory is git-ignored because map images are large/user-supplied.
Supported map IDs:
| File | Map |
|---|---|
chernarusplus.png |
ChernarusPlus |
livonia.png |
Livonia / Enoch |
namalsk.png |
Namalsk |
banov.png |
Banov |
deadfall.png |
Deadfall |
deerisle.png |
Deer Isle |
esseker.png |
Esseker |
lux.png |
Lux |
sakhal.png |
Sakhal |
takistan.png |
Takistan |
alteria.png |
Alteria |
Runtime disk files take priority. CMake can also embed map PNGs that exist under repository maps/ at configure time. Re-run CMake after adding new map images if you want them embedded into the executable.
The tile server cuts maps into 512x512 PNG tiles and caches encoded tile bytes in memory after first request.
Architecture
Startup (main.cpp):
- Create logs, init spdlog
- Load
config/config.cfg→RuntimeConfig - Load
config/overlay.json→OverlayConfig - Start
WebRadarServer,DayZRuntimeService - Create overlay, enter DX11 render loop
Memory (VmmAccessor):
- Wraps VolkDMA/VMM access
- Finds + attaches to
DayZ_x64.exe - Typed/raw/string/scatter reads
- Tracks DMA throughput
Runtime Service (DayZRuntimeService):
- Main loop: wait for process, resolve base objects
- Refresh entity lists at configured intervals
- Read players, bullets, items, bones
- Publish
RuntimeUpdatesnapshot to overlay + web
Readers/Resolvers:
BaseObjectResolver— world/network ptrsLocalPlayerResolver,NetworkMetadataReaderNearEntityListReader,FarEntityListReader,SlowEntityListReaderItemListReader,BulletTableReader,ClientScoreboardReaderEntityCategoryProjector— raw ents → typed listsItemFilterCatalog— loot categorization
Offsets & Signatures:
Offsets.h— static known offsetsRuntimeOffsets.h— runtime-resolved addressesSigScanner.cpp— module pattern scanning- After DayZ updates: check these first if data is wrong
Overlay (DirectX 11 + ImGui):
OverlayWindow— Win32 window, DX device, font atlasGameOverlay— ESP rendering, projection, trails, ballisticsMenuBridge→external/lumin/framework/gui.cpp(menu layout)
Web Radar:
WebRadarServer— HTTP routes, SSE, auth, CORSWebSnapshotService—RuntimeUpdate→ JSONBulletTrackCache— bullet historyMapTileService— tile generation + PNG cachewebroot/— browser UI
Logs
Logs are written to:
logs/dayz-memory.log
The file sink logs at trace level and is truncated on each run. The console sink defaults to info level.
Useful messages to look for:
- Process attach and reconnect events.
- Signature scan results.
- Base object/session readiness.
- Skeleton loss diagnostics.
- Ammo chain diagnostics for ballistic prediction.
- Periodic live heartbeat with player/zombie counts.
Build Notes
- The project is Windows-only and intentionally fails CMake configure on non-Windows platforms.
- The target is
dayz-memory-cpp. - C++ standard is C++20.
- MSVC builds with
/W4,/permissive-,/utf-8, and warnings not treated as errors. NOMINMAX,IMGUI_ENABLE_FREETYPE, andIMGUI_DEFINE_MATH_OPERATORSare set for the target.- Runtime DLLs are copied from
${VOLKDMA_ROOT}/dllsafter build. webroot/,config/,maps/, and Lumin icon fonts are copied after build.
Troubleshooting
CMake can't find VolkDMA
- Check:
../dayz-dma/dma-dayz-cpp-master/VolkDMA/exists - If elsewhere, set
VOLKDMA_ROOTin CMakeLists.txt
Dependency fetch fails
- First configure needs internet (GitHub FetchContent)
- Check network/proxy; use pre-cached deps if offline
Exit code 0xC0000135 (DLL missing)
- Verify these exist next to exe:
vmm.dll,leechcore.dll,FTD3XX.dll - Rebuild or copy from
${VOLKDMA_ROOT}/dlls
Overlay ESP misaligned
- Open
Configtab, set:overlayWidth/overlayHeight= monitor resolutionrenderWidth/renderHeight= game render resolution (if different)stretchToFill= match your GPU scaling
Web radar blank
- Check
Infotab: attached + connected? - Browser URL correct (host/port)?
webPasswordmatches?password=param?webBindAddressnot127.0.0.1for remote?- Firewall allows port?
Map background missing
- Place PNG:
maps/<map-id>.png(e.g.,maps/chernarusplus.png) - To embed: add to repo
maps/, re-run CMake, rebuild
Caddy serves 404s
- Run
caddy runfrom repo root, or fixrootpath in Caddyfile
Port in use
- Change
webPortinconfig/overlay.json, restart - If using Caddy, also update upstream port
Attach OK but data wrong
- DayZ offsets/signatures may be stale post-update
- Check:
Offsets.h,SigScanner.cpp,logs/dayz-memory.log
Development Workflow
Add a memory field:
- Add offset to
Offsets.hor scanner logic - Read in appropriate resolver/reader
- Add to
Models.h/RuntimeUpdateif cross-module - Publish to overlay or web
- Add diagnostics for fragile chains
Add overlay option:
OverlayConfigstruct +Config.cppload/save- Add to
GameOverlayclass - Sync in
GameOverlay::SyncConfig() - Expose via
MenuBridge - Add control in
external/lumin/framework/gui.cpp - Use in draw path
Add web radar field:
- Add to runtime model
- Serialize in
WebSnapshotService - Consume in
webroot/app.js - Style in
webroot/style.css - Update bootstrap data if needed
Known Limitations
- Windows-only
- Offsets/signatures must match current DayZ build
- Web server is HTTP only (use Caddy/proxy for TLS)
- Web auth is query-param password, not full session system
- Map recognition depends on server metadata + alias table
- Browser map images need correctly named PNGs (or embed at build)
- Overlay accuracy depends on monitor/render resolution config
Third-Party Code
Vendored/fetched components — check licenses before redistribution:
- ImGui, FreeType (under
external/lumin/) - Lumin framework, nlohmann/json, spdlog, cpp-httplib, stb
- VolkDMA + VMM/LeechCore (sibling checkout)