I'm trying to create a userscript that runs another person's Istrolid AI library. But when I run it, I get:
ERROR: Execution of script 'New Userscript' failed! Interpolator is not defined
My userscript looks like this:
// ==UserScript==
// @name New Userscript
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match www.istrolid.com
// @grant none
// @require https://rawgit.com/Rio6/Istrolid-js-ai/master/r26Ai.js
// ==/UserScript==
console.log(r26Ai);
Several issues, big to small:
That library is only valid on game pages (which is where Interpolator
is defined).
The @match
directive is improper and needs to be set to just those game pages.
The game takes some time to load and initialize -- at least a second.
That library is poorly written and will crash if it's loaded before then.
Which means that @require
can't be used for that library. For now, use script injection instead.
You will need to use a timer (last resort) or event (Best option) or strategic node (second best option) to tell when to inject the script. Finding an event (if it exists), or strategic node is a bit of an art and page specific. That's beyond scope here, so a timer is used in the sample code below.
The other directives, especially the @name
should be set to sensible values or omitted.
Putting it all together, this script will get you to the next step (which is beyond the scope of this question):
// ==UserScript==
// @name Istrolid.com, use Istrolid Javascript AI API
// @version 0.2
// @match *://www.istrolid.com/game.html*
// @grant none
// ==/UserScript==
/*-- Wait for game to load. Try to find an event or node that signals
this, instead of one or two timers.
*/
var sfStrtTmr = setInterval ( () => {
if (typeof Interpolator === "function") {
clearInterval (sfStrtTmr);
setTimeout (loadPoorScript, 1111);
}
}, 333);
function loadPoorScript () {
var newNode = document.createElement ('script');
newNode.onload = runScriptMain;
newNode.src = "https://rawgit.com/Rio6/Istrolid-js-ai/master/r26Ai.js";
document.body.appendChild (newNode);
}
function runScriptMain () {
// ALL OF YOUR CODE GOES HERE.
console.log ("r26Ai: ",r26Ai);
}
Important: Note that Interpolator
is a page specific function, unique to that site, that we use here as indicator that (a) we're running on an appropriate page and (b) it's time to start checking for game load.