Anyone knows the memory structure of Arcanum?

Discussion in 'Modding and Scripting Support' started by Canyon, Nov 7, 2023.

Remove all ads!
Support Terra-Arcanum:

PayPal - The safer, easier way to pay online!
  1. Canyon

    Canyon New Member

    Likes Received:
    Nov 5, 2023
    Is there anyone out there that knows how the memory is structured in Arcanum? Or has a good knowledge of Cheat Engine?


    Basically I would like to know things like the location (coordinates) of the player, the name of the NPC that is currently speaking with the player, the current map name etc.

    Skip to the bottom of this post for more details about these question. If you're interested in how I approach the improvement of the games I play, read on...


    I'm not really a modder but I'm usually looking at ways how I can improve the user interface of the games I'm playing and most of the time that means remapping keys AND THE MOUSE: I hate clicking and holding down the mouse all the time!

    Autohotkey is my tool of choice

    I remap the left, right mouse buttons to A and D and I remap a lot of other shortcuts as well. Very easy, all in a simple text macro script.

    But what if there is no hotkey for something I do regularly, like clicking the Sort button in the Inventory screens? Wouldn't it be great if I could press a hotkey to click that button? What I do in that case is create a simple macro in AutoHotkey that will click at the sort button when I press the hotkey, S for example.

    s::click 450,310


    This is very easy to achieve in most games but there are games where the mouse coordinates are HIDDEN. The standard (Windows) API calls to set and retrieve the mouse position don't work. Arcanum is such a game...

    I hit the same problem when playing the great game Inquisitor and I managed to find the coordinates in memory for that game using Cheat Engine. With AutoHotkey I wrote functions to read and set the mouse position. This worked in Arcanum too:

    mem.write(baseAddress + 0x000FF3D0, x, "Uint", 0x0)
    mem.write(baseAddress + 0x000FF4F0, y, "Uint", 0x0)


    So I can click on the Sort button if I press the S key but what if I hit S when the Inventory is closed and we're in the game area? We get an unwanted click! What I usually do in games is this: I identify the current screen (Inventory, Maps, Main Menu, Game Area etc) by looking at colors of a few pixels, like taking a fingerprint. Then I can have the macro only click on that Sort button location in the Inventory screen.

    This works in most games but there are games where the pixel colors are HIDDEN. Arcanum is such a game... It didn't surprise me that it doesn't work because Arcanum doesn't allow me to use a tool like Fraps or SnagIt to make a screenshot, I only get black screens. Some games are like that...


    Did I overcome this problem? Yes. First I wrote a macro that took a screenshot with Arcanum's F12 key, then (in the background) the macro would read the pixel colors from the bmp file. This worked but it was a little slow so I tried to find the bitmap in memory instead using Cheat Engine and I found it! Unfortunately I couldn't find the correct pointer address but I had a workaround to scan the memory for a unique color (in the top HUD) and that lead me to the screen location in memory. Now I can easily script hotkeys for various interface elements in a variety of screens.


    What about being able to press numpad 1,2,3,4 and 5 to pick your choice in a conversation? Easy after all the work I've done above:

    if isDlg("Talking")
    arcTextChoice(1) ; Talking Line 1

    The first line is the hotkey. The second line will use the pixel color technique to tell you the talking dialog is active and the third line will use the mouse coordinate technique to click the correct response.


    That's great but it's a pity Arcanum doesn't have a history log like some games do, wouldn't you say? Hmmmm....maybe I can do something about it, couldn't I...

    Yes I can! I built a macro that would write tiny bitmaps containing the balloon text and the chosen response to a 'bitmap log'. This log is viewed/updated on the secondary monitor while I am having a conversation and it looks like this:


    This was not easy, especially the floating balloons. I had to come up with a clever routine to find the balloon on the screen by analysing a lot of pixels. Unfortunately it's quite slow to do this - even in memory - so having a conversation while logging was tedious. That's why I made a queue to handle this: during the conversation I let the macro write a 'trigger' and then I had a background script that would pick up these triggers and produce these text balloons and responses. This worked way better! Responsive conversations and the certainty that I could reread everything afterwards because the queue was ensuring the conversation was fully saved...


    Using the same technique it was easy to get the quest and rumour pieces from the logbook. Whenever I press a shortcut key when a page in the logbook is opened the macro will write all the snippets from that page to the same bitmap queue:


    I also added the NPC that the player was having the conversation with to the log:



    But when I arrived in Tarant I hit a snag...the shouting paper boys are also producing text balloons so that 'clever' routine was not so clever. There's no way I can separate these shouting balloons from the conversations...what to do?


    I started analyzing the memory with Cheat Engine and I found the conversation balloon! And it seems to be pretty static at offset 0x26DB30. Also, the available conversation choices are in the same memory region. This allowed me to write a macro that writes all the balloons and responses to a simple text file everytime a conversation takes place! Opening the text file in an editor that is able to do 'polling' (that is jumping to the end of the file as new lines are added to the file) I now had a working history log on my secondary monitor:


    Having it in a textfile means I can do a simple text search in the full conversation history of my playthrough! That's great.


    Unfortunately I cannot find the NPC that is talking to the player in memory. Neither can I find the logbook entries with the active quests and the rumours that I've heard so far. Also, what is my current location? The name of the Map? If I can find all these things I could build a better Quest handling system for Arcanum, maybe even a universal tool...

    To sum it up, this is what I would like read from memory:
    - CURRENT LOCATION: Preferably the coordinates that are shown in the Map screen but the ones that are shown if you press X using Troika's original Cheat Mode would do too.
    - CURRENT MAP NAME: Shrouded Hills, Tarant, Dernholm etc.
    - CONVERSATION NPC NAME: Preferably the full name that you see after the conversation (because at the start the name is not always displayed). I can find the names in memory but that's probably within the table that contains all the names. I want to find the structure with the current NPC that is participating in the conversation.
    - QUESTS AND RUMOURS: Same as with the NPC: I can find the text of all these but where is the table with active quests and collected rumours?

    If there is anyone that can point me in the right direction, this would be appreciated!
    Last edited: Nov 7, 2023
  2. Oracle

    Oracle Member

    Likes Received:
    Sep 25, 2006
    Forum may be a bit dead, well quite dead actually XD maybe you can try asking on terras Discord?
Our Host!