AmanoJyaku 184 Posted August 18, 2020 Is there a list of the files modified by TSLRCM? There are errors in the NCS files, and I'd like to know if these are errors in the vanilla code or TSLRCM. I already have TSLRCM installed and would like to avoid uninstalling and reinstalling to see what is vanilla and what is modified. For those who don't know, I'm working on an NCS decompiler. If these are errors in the vanilla code then I *may* ignore them and assume they work the way BioWare intended. (Even though it's wrong. I'll spare everyone the details since they only make sense to a programmer.) But if it's TSLRCM we may need an update, and I don't want to be the one to have to do it. 🤣 One file in particular is k_contain_unlock.ncs. I've found two separate errors: one misinterprets the type of the input data, the second is a logic error. Neither of these are game-breaking in this file, but they may produce unintended results if they are present in other files. On the positive side, I may be able to finish this by the end of September! 🎆🎉 1 Quote Share this post Link to post Share on other sites
Kexikus 995 Posted August 18, 2020 Where did you find the file? If it's in the Override and you only have TSLRCM installed, then it's from TSLRCM. If it's in a .mod, you can compare it to the version in the corresponding .rim and see if there are any differences. If there are, then again it's from TSLRCM. In all other cases it's a vanilla file. Quote Share this post Link to post Share on other sites
DarthParametric 3,782 Posted August 18, 2020 Except for 401DXN (Dxun landing site) and 702KOR (Korriban academy), which directly overwrites the vanilla RIMs. Quote Share this post Link to post Share on other sites
AmanoJyaku 184 Posted August 18, 2020 6 hours ago, Kexikus said: Where did you find the file? I don't remember, it was back in March that I created a directory with every K1/K2/TSLRCM NCS file I've seen (over 2,400). I think it's from the vanilla BIF, but that's why I'm asking. DeNCS was able to decompile k_contain_unlock.ncs. But it threw the byte-code mismatch warning, which confirms there is something odd in the NCS. Believe it or not, that's worse than not being able to decompile at all! Quote Share this post Link to post Share on other sites
Kexikus 995 Posted August 18, 2020 In that case I suggest you redownload TSLRCM and check whether you can find the file in there. I doubt that anyone has a database of TSLRCM edits by file Quote Share this post Link to post Share on other sites
JCarter426 1,214 Posted August 18, 2020 I don't see k_contain_unlock in my clean copy of TSLRCM. However, it includes k_inc_treas_k2, which TSLRCM does edit, so it seems like TSLRCM should edit k_contain_unlock as well. k_inc_treas_k2 has a recursive function so any script that includes it will trip up DeNCS. Lots of other scripts have this problem like OnSpawn scripts (k_def_spawn01, k_def_spn_t_drd, k_def_spn_t_jedi, etc) and merchant scripts (a_stock_geeda, a_stock, tienn, a_stock_geg, etc). 1 Quote Share this post Link to post Share on other sites
AmanoJyaku 184 Posted August 18, 2020 @JCarter426 Thanks! The script k_contain_unlock.ncs is in scripts.bif. I don't know what the game does with BIFs, so I don't know if it ever calls that script directly. (Honestly, I never wanted to know how the game did anything. Damn you for asking for help, DrMcCoy! I haven't played this game in months because I've been coding this!!! 🤣) Edit: Also, k_inc_treas_k2 is an include. If it has been modified, then the files that depend on it are modified. For example, k_contain_unlock.ncs. So, maybe the bif is different in TSLRCM from the vanilla. On the subject of recursion, I don't see any reason why recursion should trip up decompilation. My code currently doesn't have a problem with them, not sure why DeNCS does... Then again, my code doesn't have a problem with globals initialized via functions, either. Yet another reason to replace DeNCS. Quote Share this post Link to post Share on other sites
JCarter426 1,214 Posted August 18, 2020 2 hours ago, AmanoJyaku said: Also, k_inc_treas_k2 is an include. If it has been modified, then the files that depend on it are modified. For example, k_contain_unlock.ncs. So, maybe the bif is different in TSLRCM from the vanilla. Yeah, that's why I don't get why I don't see it here. Might be an oversight. If you're looking at the one in scripts.bif, though, that's the original. TSLRCM doesn't edit the BIFF archives directly. I don't think there was even a tool to do so at the time of release. 2 hours ago, AmanoJyaku said: On the subject of recursion, I don't see any reason why recursion should trip up decompilation. My code currently doesn't have a problem with them, not sure why DeNCS does... Then again, my code doesn't have a problem with globals initialized via functions, either. Yet another reason to replace DeNCS. I was just reiterating the problem according to DrMcCoy. But if your new DeNCS can deal with that, that would be very interesting. Are you able to decompile any of the other scripts that include k_inc_treas_k2 that I mentioned? 1 Quote Share this post Link to post Share on other sites
AmanoJyaku 184 Posted August 19, 2020 3 hours ago, JCarter426 said: I was just reiterating the problem according to DrMcCoy. But if your new DeNCS can deal with that, that would be very interesting. Are you able to decompile any of the other scripts that include k_inc_treas_k2 that I mentioned? I don't want to promise anything as I'm testing various ways to reassemble control structures consistently. I am working with k_contain_unlock.ncs, which includes k_inc_treas_k2.nss. Currently, I can detect and reassemble: switch statements if statements if-else statements for loops while loops recursive functions I don't see do-while loops in K2 files, and only one file in K1 has it: k_inc_treasure.nss. I created this topic because of an issue I detected in the logic of sequence points. It doesn't conform to the C99 standard, yet I'm certain it should. I could fix this, but that would require altering every single script in the game. I don't want to, for obvious reasons. But, I may have to. Once I figure out a solution, my to-do list includes: do-while statements detection of vectors (I have a solution, I just haven't coded it yet) detection of structs continue statements break statements I think I know why DrMcCoy's decompiler fails on recursion, and I don't think DeNCS has the same issue since it was able to decompile k_contain_unlock.ncs. My decompiler takes a different approach than what DrMcCoy described, which is due to the fact that I never read DrMcCoy's notes until I had a working solution. 😜 Quote Share this post Link to post Share on other sites
JCarter426 1,214 Posted August 19, 2020 Oh, that's interesting. BioWare started development for Neverwinter Nights and started writing NWScript in 1999 (you can even see this date in nwscript.nss), so it wouldn't surprise me if they were using some older or non-standard implementation of C for it that KOTOR inherited. Quote Share this post Link to post Share on other sites
AmanoJyaku 184 Posted August 19, 2020 @JCarter426 The behavior was standard from the very first version of ANSI C in 1989. I named C99 since the standard draft may have been available when BioWare started NWN. The devs probably read "The C Programming Language" by Brian Kernighan and Dennis Ritchie. The book is clear for experience programmers, but a little ambiguous for novices. I think that's what happened. That, or someone was just sloppy. Ah, well. Fixing this is a problem for a later date. I need to finish the decompiler first! Quote Share this post Link to post Share on other sites
JCarter426 1,214 Posted August 25, 2020 I remember DrMcCoy saying something about some non-standard implementation before. Something to do with how NWScript doesn't initialize variables correctly in some fringe cases with weird scope resolution. Not sure where it was though. Quote Share this post Link to post Share on other sites
AmanoJyaku 184 Posted August 25, 2020 @JCarter426 Nah, that's not it. The problem I ran into is logical OR. //Contrived example int Index{ 0 }; if (true || ++Index) std::cout << "Index " << Index << '\n'; The output should be "0", because ++Index should not be evaluated. Yet, according to the NCS bytecode ++Index is always evaluated. //Code snippet from k_contain_unlock, included from k_inc_treas_k2 //First expression in logical OR //sModule == "851NIH" 2993 CPTOPSP -4 4 3001 CONSTS 6 851NIH 3011 EQUALOO 3013 CPTOPSP -4 4 3021 JZ 3041 //Code to execute if expression evaluates to true 3027 CPTOPSP -4 4 3035 JZ 3061 //Why the heck are we evaluating the next epression if the previous expression is true??? // || sModule == "852NIH" 3041 CPTOPSP -8 4 3049 CONSTS 6 852NIH 3059 EQUALOO 3061 LOGORII If this pattern exists in all files, then all files are "wrong". Quote Share this post Link to post Share on other sites
JCarter426 1,214 Posted August 25, 2020 Oh yes, I've read that some version of the compiler does not evaluate with short-circuit logic for or. Not sure if it's limited to one version or common to all of them, and as far as I've read it evaluates logical and correctly, though. I ran a test with the following and I did indeed get the wrong result. void main() { int n = 0; if( TRUE || ++n ) SendMessageToPC(GetFirstPC(), IntToString(n)); } short_circuit_test.zip 1 Quote Share this post Link to post Share on other sites
AmanoJyaku 184 Posted August 25, 2020 @JCarter426 Sigh... This means I have to check every script that has logical OR. The snippet from k_contain_unlock is fine since it doesn't change anything, but any script that looks like the short circuit test is guaranteed to do the wrong thing. Whether or not that breaks the game remains to be seen... I knew I should have stuck with stupid weapon and armor mods! 😂 Quote Share this post Link to post Share on other sites
JCarter426 1,214 Posted August 25, 2020 We're talking about a game with code like this: int StartingConditional() { int iResult; iResult = ((GetGlobalNumber("MAN_PLANET_PLOT") < 3) && (GetGlobalNumber("MAN_RANDOM") == (1 || 2))); if (iResult) SetGlobalNumber("MAN_RANDOM", d8()); return iResult; } I can almost guarantee that it'll break the game somewhere. Quote Share this post Link to post Share on other sites
AmanoJyaku 184 Posted August 27, 2020 @JCarter426 This is what happens when you hire college kids to write professional software... Anyway, I think I figured out the problem that caused me to create this topic. This is going suspiciously well... 🤔 Quote Share this post Link to post Share on other sites