philmasterplus
Active member
Update: This was not a JavaScript issue, but a problem with the ASH function itself. See reply #4 and below.
As such, I have renamed the thread title (previously "JavaScript: putShop() bug due to typing issues").
TL; DR: When calling
JavaScript's type system does not distinguish integers and floating-point numbers. Because of this, calling ASH functions (including KoLmafia's library functions) from JavaScript can lead to surprising behavior.
For example,
(I used a variable for demonstration purposes. In reality, any non-trivial expression will trigger the bug.)
In the last example, the error message is printed from line 828 of
Fortunately, this issue can be worked around by wrapping the quantity with
There may be more typing issues like this, but this one could be particularly damaging.
Edit: It seems that the ASH function
As such, I have renamed the thread title (previously "JavaScript: putShop() bug due to typing issues").
TL; DR: When calling
putShop()
, be sure to wrap the item quantity argument with toInt()
.JavaScript's type system does not distinguish integers and floating-point numbers. Because of this, calling ASH functions (including KoLmafia's library functions) from JavaScript can lead to surprising behavior.
For example,
putShop()
will behave inconsistently if you pass a computed (i.e. non-literal) value as the item quantity:
JavaScript:
// Passing a literal 1 as the quantity
putShop(0, 0, 1, Item.get('spices'));
// Works as intended
// Passing a variable as the quantity
let qty = 1;
putShop(0, 0, qty, Item.get('spices'));
// KoLmafia prints "Adding spices to the store...", but does not actually transfer any items
// Passing a variable as the quantity, but batched
batchOpen();
putShop(0, 0, qty, Item.get('spices'));
batchClose();
// KoLmafia transfers ALL of your spices to the store
// It also prints something like "4621819117588971520 is out of range, returning 0"
(I used a variable for demonstration purposes. In reality, any non-trivial expression will trigger the bug.)
In the last example, the error message is printed from line 828 of
StringUtilities.java
. I traced this back to line 4240 of RuntimeLibrary.java
, which reads the contentLong
field from the Value object. This issue might be solvable if we called intValue()
here instead, but I haven't tested this idea.Fortunately, this issue can be worked around by wrapping the quantity with
toInt()
, which seems to "sanitize" the quantity to an integer:
JavaScript:
// Puts 1 spices in the store
putShop(0, 0, toInt(qty), Item.get('spices'));
// Puts 1 spices in the store
batchOpen();
putShop(0, 0, toInt(qty), Item.get('spices'));
batchClose();
There may be more typing issues like this, but this one could be particularly damaging.
Edit: It seems that the ASH function
put_shop()
does not reject floating numbers for the quantity, either:
Code:
put_shop(0, 0, 1.5, $item[ spices ]);
// Prints "Adding spices to store..." and returns true, but does not transfer any items
Last edited: