-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Some fixes and features to make it easier to access data #5
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi! Thank you very much for submitting a PR! I like the changes you're proposing, however I can see an issue with setting the string encoding. The way it is now, whenever zenkit._native.load
is called with an encoding, it will change the encoding for all strings loaded by the library. This is unexpected behaviour, I'd think.
I propose instead, to add a function for setting the encoding globally and then applying ot to all string encoding and decoding performed by the library (e.g. a zenkit.set_string_encoding
function). This should then also replace the hardcoded "windows-1252"
in all str.encode
calls (you don't need to do that right now, but that'd be the plan).
2847c83
to
6d02807
Compare
What's the "real" functional difference between DaedalusScript and DaedalusVm? The latter is a subclass, and the Would it be possible to detect if a symbol is a function parameter inside the DLL, other than the The Same goes to other aspects, like the Lastly, it seems that DaedalusVm requires registering externals, even the defaults from Gothic. Why can't ZenKit provide them with the DLL, is there some licensing issue? |
The difference between Daedalus instances are runtime-initialized objects, meaning they have to be explicitly initialized by the engine by running some Daedalus code. That's the job of the VM. So no, Getting the parameters of a Daedalus function isn't as simple as checking for a Caching is something I haven't considered yet, because there are many cases in ZenKit where caching is the wrong answer. In those examples specifically though, I think caving would be a valid strategy, because the script itself is immutable. A generator could be great too. Externals are not registered by ZenKit, because most of them have something to do with game engine stuff, which ZenKit is not concerned with. Of course, things like |
Hello again, I wish you a belated happy new year ^^ However, there is some bug, which is possibly there in 1.3.0 or I'm missing something about memory management and DAT file access. "$INSTANCE_HELP": {
"crashed": "Init Failed - NPC is None"
},
"BDT_10030_ADDON_BUDDLER": {
"crashed": "exception: access violation reading 0x000000474E49525C"
},
"BDT_10031_ADDON_WACHE": {
"dialogues": {
"DIA_ADDON_BDT_10031_WACHE_HI": "Alles klar?"
},
"id": 10031,
"instance_name": "BDT_10031_ADDON_WACHE",
"name": "Wache",
"routines": [
"START"
]
}, As you can see there are NPC Instances, which crash during initialization (OSError), I think this happens with Info Instances as well, but if that happens I skip them without any logging. The worst part is that, the output of my script changes every time, I mean the amount of Sometimes, but not always, the script also shows this Traceback: $ python script.py
Exception ignored in: <function DaedalusScript.__del__ at 0x000002203C8216C0>
Traceback (most recent call last):
File "...\DecDat-Zenkitpy_project\venv\Lib\site-packages\zenkit\daedalus_script.py", line 277, in __del__
self._deleter()
File "...\DecDat-Zenkitpy_project\venv\Lib\site-packages\zenkit\daedalus_vm.py", line 203, in _deleter
DLL.ZkDaedalusVm_del(self._handle)
OSError: exception: access violation reading 0xFFFFFFFFFFFFFFFF Sometimes, but not always, when I enable the Debug LogLevel, I get different errors;
there can be also no errors in the Terminal, and Here is the script.zip, it expects an exported Any advice how could I debug it? I was thinking of setting externals to lessen the burden of the |
Next day of investigation about the random crashes. I've added some externals and started getting this error
I don't really understand where the recursion is, but looking at the Traceback it's related to the Exception ignored on calling ctypes callback function <function DaedalusVm._register_external.<locals>.<lambda> at 0x0000015599AF8540>:
Traceback (most recent call last):
File "...\zenkit\daedalus_vm.py", line 198, in <lambda>
fptr = DaedalusVmExternalCallback(lambda _, __: cb())
File "...\zenkit\daedalus_vm.py", line 177, in _wrapper
vals = [self.pop(arg) for arg in reversed(args)][::-1]
File "...\zenkit\daedalus_vm.py", line 109, in pop
return self.pop_instance()
File "...\zenkit\daedalus_vm.py", line 133, in pop_instance
return DaedalusInstance.from_native(handle)
File "...\zenkit\daedalus\base.py", line 60, in from_native
typ = DaedalusInstanceType(DLL.ZkDaedalusInstance_getType(handle))
RecursionError: maximum recursion depth exceeded
Traceback (most recent call last):
File "...\script.py", line 178, in <module>
main()
File "...\script.py", line 62, in main
if can_skip_symbol(vm_sym):
File "...\script.py", line 50, in can_skip_symbol
return sym.is_member or sym.type not in (DaedalusDataType.INSTANCE, DaedalusDataType.FUNCTION)
File "...\zenkit\daedalus_script.py", line 180, in type
return DaedalusDataType(DLL.ZkDaedalusSymbol_getType(self._handle))
RecursionError: maximum recursion depth exceeded Worst part is that I still get random results, sometimes there is no |
Hm I do see a crash with G2 NotR with your first script, so there's probably a bug here. I'll hopefully have time to investigate a bit on the weekend. In the mean time, the only good way to debug this is to add debug prints in the C/C++ source, then recompile the native library, since the crash happens in C-land, inside |
Okay @kamilkrzyskow, I did find at least one issue which, if fixed, seems to resolve your problem. Before calling You could, for example, add that check to this: if class_sym and vm_sym.is_const:
... There is a bug with externals still though, which causes the program to crash when an incorrect parameter is taken. I've fixed that in GothicKit/ZenKitCAPI@2a1b554 and d9fedd0 :) |
Thanks a lot for the fix 🫶 ! Also sorry for this blunder 😞 over the many iterations of random errors I've seen some As for other observations I've had from my shenanigans:
So with this, the dialogue and routine (script above needed a small fix) extraction solution is superior to my previous DecDat -> Regex/Text extraction method, and less buggy 🥳 I was thinking about simplifying So I'm getting closer to being happy with this PR, thanks again ✌️ |
I was at first confused but I think I understand now. The way you implemented Generally, you should not use the
You can write your own logger if you like. Just use |
I like the sound of that, instantiation-aware instances 🤩 I like how you have solutions already in the making to the issues I face 😆
That's why there is the protection with
Thanks, I've written one for debugging the class Container:
logger_messages = dict()
def main():
# Setup logger
vm_sym_name = "*"
def logger_callback(lvl: LogLevel, name: str, message: str):
count = Container.logger_messages.get(message, 0)
if count == 0:
nonlocal vm_sym_name
print(lvl.name, name, vm_sym_name, message, sep=" - ")
Container.logger_messages[message] = count + 1
set_logger(LogLevel.DEBUG, logger_callback)
# ...
for vm_sym in vm.symbols:
vm_sym_name = vm_sym.name
# ... |
Small progress with the externals, as I use 1 in my next extraction project. My bug came from reading the parameters from the DecDat extraction header comment.
Where it says |
I've add |
I fat fingered the enter key on title and it created an empty PR 🙄
Anyway, I always wanted to be able to access script data from Python, there is PyDecDat but it doesn't support Ikarus/Lego extended scripts, and iirc was rather slow.
So for now I typically used DecDat and parsed the
.d
file with Python to extract data.When I saw this project I was happy that I don't have to parse the
.d
myself 😄...or so I thought.Turned out there are some kinks to be straightened out, so I will fix them along the way.
Edits for maintainers are enabled, so if you want to adjust some things, then go ahead ✌️
My goal is not to create another DecDat, or so I think for now 🤔
My goal is to easily extract data, and cross-connected it afterwards in my external scripts.
Example of previously extracted data about dialogues of an NPC together with their possible routines: