How does tostring, concat and using the object directly have different results?

126 Views Asked by At

I'm using an version of Lua 5.1 in a game called Kingdoms of Amalur. This is havocscript but afaik, havocscript is lua. Now there is a custom type called ui64 that the game has and a custom package that injects a hook that I added to the game.

If I do the following:

module("playerdodge_hook", package.seeall)

function save_to_file(filename, data)
    if io then
        io.output(filename)
        io.write(data)
        io.flush()
    end
end

function dodge_hook()
    local x = SIMTYPE_ID("longbow_unique11a")
    save_to_file("type", type(x))
    save_to_file("directly", x)
    save_to_file("tostring", tostring(x))
    save_to_file("concat", "" .. x)
end

The output of the files are the following: type

ui64

Directly

Sin

tostring

0

concat (does not exist)

I am no expert in Lua, but i'm trying to understand how this works. As I would like to be able to print debug information and save this externally.

Edit: Short answer is the game's engine used a proprietary override the io write method.

Amalur has different types, and the ui64 is actually a pointer to some memory inaccessible to lua/havok script, but the library allows manipulation. And basically when a ui64 is passed in raw to write calls the localization for the Type or Actor or whatever the internal object represented.

had an altered version of io library that when it received an ui64 would interrogate the

1

There are 1 best solutions below

0
On

First, I want to say that I could not use actual io.write as io is not loaded into the engine but I have a similar method that I can use to write text to an ini entry, however, every time I call the write method it overrides the content of my personal entry regardless of if I change the key.

The basic gist of the issue is that the game Kingdoms of Amalur havok engine has a custom write/(and pretty much any other way to display text) routine.

The ui64 data type is more or less a pointer to an object that exists in havok or c. However, the engine offers an api that can take these pointers and call various routines.

Passing the ui64 to the write method would make the game invoke into it's localization tables and output the localized name to the screen for this particular Type. Thus longbow_unique11a is Sin.

Since my goal was to try to get the actual localized name and dump them all plus other data, I came up with a workaround.

Essentially, the game allows you to name crafted items, and when it does so it populates the name with a default entry and so some by decompiling some methods I was able to come up a routine to build my string like so::

function dump_item_names(tbl)
    local callback = function(text, canceled)
        op = {}
        for i = 1,#tbl do
           local actor = tbl[i]
           local typeId = get_hex_of_raw_id(actor)
           WINDOW.populate_edit_box(name_win.m_editbox, actor)
           local name = WINDOW.get_editbox_text(name_win.m_editbox)
           op[#op + 1] = typeId .. ',' .. name
        end
        save_to_file("items.txt", table.concat(op,'\n'))
    end
    name_win.launch(SL(357894144), tbl[1], true, 100, callback, false)
end

So yeah, not really a lua problem so much as a havok problem and me not understanding a foreign game engine that I'm hacking.