Streaming WoW State via Addon → Python Memory Bridge
I’ve been experimenting with building a WoW → external bridge that lets an addon stream structured JSON out of the client, and a separate Python tool that attaches to WoW’s memory space to capture and parse that data.
It’s not a finished product, but it gives a clear idea of the approach and hopefully sparks ideas for other developers.
What it does
- The addon encodes game state (spells, talents, target data, player buffs, nearby enemies, etc.) into JSON wrapped between BRIDGESTART| … |BRIDGEEND.
- A hidden frame inside the addon continuously updates this payload at ~0.1s ticks.
- On the outside, the Python script scans WoW’s memory space for those bridge strings, tracks sequence numbers, and extracts the most recent full JSON block.
- Once an anchor is found, the tool keeps up with live updates and prints the payload in real time, so you can consume it with other tools, log it, or feed it into analytics/rotation helpers.
Example Payload
Here’s a minimal snippet of what the extracted bridge data looks like when read from memory:
Code:
BRIDGESTART|{
"sid":"0B07AB1471951812",
"seq":"00000017",
"target":{"name":"Training Dummy","health":1000,"healthMax":1000},
"enemies":{"melee":1,"ranged":0},
"playerAuras":[{"id":5277,"name":"Evasion","remaining":9.999}]
}|BRIDGEEND
Memory Regions
The scanner looks through committed, readable private/mapped regions (`MEM_COMMIT` + `MEM_PRIVATE` / `MEM_MAPPED`) with protections like:
- PAGE_READWRITE
- PAGE_WRITECOPY
- PAGE_EXECUTE_READWRITE
- PAGE_EXECUTE_WRITECOPY
It avoids PAGE_NOACCESS and PAGE_GUARD, skipping over irrelevant regions. Once a candidate anchor is discovered, it narrows down by tracking pointer references so you don’t need to full-scan every cycle.
Main Difficulty: The Anchor
The hardest part right now is reliably sticking to the anchor address where the JSON buffer starts.
- Anchors can shift around after reloads, zoning, or memory churn.
- I’m using candidate managers and pointer watchers to re-acquire when it goes stale, but it’s not bulletproof.
- I’m sure there are more robust techniques (better pointer chasing, signatures, or alternative anchoring strategies), but I don’t have time to dig deeper right now.
If anyone has ideas on more stable anchor acquisition or smarter region scanning, please shout! That’s the biggest weak point at the moment.
PS: You better off calculating buff remaining time externally, apparently calculating every buff at every tick adds load to this! I kept the code in just for the reference.
GJ.png
DATAPY.png