Feature - Implemented Combat filter functions in JavaScript

Obeliks

Member
I started working with the JavaScript Runtime, and I couldn't figure out how to use adventure() with a custom combat filter function defined in the same script. The function is never found, and thus always returns void. (Shouldn't it throw an error if the requested function is not found? Ash seems to do that from looking at the code, but the wiki for adventure() says otherwise)

So I dug around the code a bit, and it seems that the JavascriptRuntime always searches the topLevelScope for exported functions. However, the functions exported by the main module are not merged into the global context, and are thus lost after the top-level execution.

I tried this change, and now I can use locally defined functions as combat filter functions.

Can anybody with some knowledge of the Javascript runtime give me a hint if this is the right way to go, or am I missing something?

Is there any good use case for looking up the function name in the top level scope (here)?

I also had a problem that run_combat always returns void, because the engine state is always EXIT (perhaps because of the filter function :)). I tried to re-set the engine state during non-top-level executions, but without much success. Any ideas?
 

gausie

D̰͕̝͚̤̥̙̐̇̑͗̒e͍͔͎͈͔ͥ̉̔̅́̈l̠̪̜͓̲ͧ̍̈́͛v̻̾ͤe͗̃ͥ̐̊ͬp̔͒ͪ
Staff member
I think I'm going to "fix" this by special casing those functions in the JavascriptRuntime to be able to take functions as params
 

Obeliks

Member
That sounds like an ideal Implementation from the frontend side.
But you still need to "remember" those functions for the invocation somewhere (or refactor quite some stuff to be able to pass functions from and to the runtime), right?
 

gausie

D̰͕̝͚̤̥̙̐̇̑͗̒e͍͔͎͈͔ͥ̉̔̅́̈l̠̪̜͓̲ͧ̍̈́͛v̻̾ͤe͗̃ͥ̐̊ͬp̔͒ͪ
Staff member
I will look into it, or you can if you like!
 

gausie

D̰͕̝͚̤̥̙̐̇̑͗̒e͍͔͎͈͔ͥ̉̔̅́̈l̠̪̜͓̲ͧ̍̈́͛v̻̾ͤe͗̃ͥ̐̊ͬp̔͒ͪ
Staff member
@Obeliks This is my proposed approach. I'm waiting on some feedback from @ikzann since he is the expert, but this means that we'll certainly merge something that works!
 

Attachments

  • js_combat_filters.diff
    2.3 KB · Views: 5

Obeliks

Member
Ah, not bad, I didn't think about simply keeping the references in the global scope. Should the cleanup of temporaryName perhaps happen in a finally-block?

I will try the patch in an hour or two...
 

Obeliks

Member
I finally got around testing these, and it doesn't seem to work for me.

I'm basically running this code:

JavaScript:
export function creationCombatHandler(round, opp, text) {
  const macro = generateWeirdeauxMacro(text);
  printHtml(`creationCombatHandler returned: <pre>${macro}</pre>`);
  return `"${macro}"`;
}

export function main() {
  adv1(Mansion, -1, creationCombatHandler);
}

but I get this in the output log:

Code:
Macro override "org.mozilla.javascript.gen.file__C__Users_micro_KoLmafia_scripts_weirdeaux_weirdeaux_a878ef1a_js_16@3e7e47fb" returned void.

and then it calls the CCS, since it couldn't execute the combat filter function.
 

gausie

D̰͕̝͚̤̥̙̐̇̑͗̒e͍͔͎͈͔ͥ̉̔̅́̈l̠̪̜͓̲ͧ̍̈́͛v̻̾ͤe͗̃ͥ̐̊ͬp̔͒ͪ
Staff member
No worries! It's a cool feature that I'm using now too!
 
Top