diff --git a/TODO.md b/TODO.md index b3e3486..d2b286c 100644 --- a/TODO.md +++ b/TODO.md @@ -32,6 +32,7 @@ Character sheet Battle ------ +* Fix stats only filling for one fleet * Add a voluntary retreat option * Toggle bar/text display in power section of action bar * Show a cooldown indicator on move action icon, if the simulation would cause the engine to overheat @@ -67,6 +68,7 @@ Ships models and actions Artificial Intelligence ----------------------- +* If web worker is not responsive, or produces only errors, it should be disabled for the session * Produce interesting "angle" areas * Evaluate active effects * Account for luck diff --git a/out/aiworker.js b/out/aiworker.js index 84d9c64..985c6ce 100644 --- a/out/aiworker.js +++ b/out/aiworker.js @@ -19,5 +19,5 @@ onmessage = function (e) { debug("[AI Worker] Send", maneuver); postMessage(serializer.serialize(maneuver)); return maneuver.apply(battle); - }).catch(postMessage).then(close); + }).catch(postMessage); } diff --git a/src/core/ai/AIDuel.ts b/src/core/ai/AIDuel.ts index 9eef8a7..f4a1d82 100644 --- a/src/core/ai/AIDuel.ts +++ b/src/core/ai/AIDuel.ts @@ -97,7 +97,7 @@ module TK.SpaceTac { } else { this.update(-1); } - this.scheduled = Timer.global.schedule(100, () => this.next()); + this.scheduled = Timer.global.schedule(50, () => this.next()); } /** diff --git a/src/core/ai/AIWorker.ts b/src/core/ai/AIWorker.ts index 0c2ea24..d818fdb 100644 --- a/src/core/ai/AIWorker.ts +++ b/src/core/ai/AIWorker.ts @@ -1,4 +1,20 @@ module TK.SpaceTac { + /** + * Initialize the background worker, if possible + */ + function initializeWorker(): Worker | null { + if (typeof window != "undefined" && (window).Worker) { + try { + return new Worker('aiworker.js'); // TODO not hard-coded + } catch { + console.error("Could not initialize AI web worker"); + return null; + } + } else { + return null; + } + } + /** * AI processing, either in the current process or in a web worker */ @@ -6,6 +22,7 @@ module TK.SpaceTac { private battle: Battle; private ship: Ship; private debug: boolean; + private static worker = initializeWorker(); constructor(battle: Battle, debug = false) { this.battle = battle; @@ -27,8 +44,13 @@ module TK.SpaceTac { * Process AI in a webworker if possible, else do the work in the render thread */ async processAuto(feedback: AIFeedback): Promise { - if (!this.debug && (window).Worker) { - await this.processInWorker(feedback); + if (!this.debug && AIWorker.worker) { + try { + await this.processInWorker(AIWorker.worker, feedback); + } catch (err) { + console.error("Web worker error, falling back to main thread", err); + await this.processHere(feedback); + } } else { await this.processHere(feedback); } @@ -37,14 +59,10 @@ module TK.SpaceTac { /** * Process AI in a webworker */ - async processInWorker(feedback: AIFeedback): Promise { - let worker = new Worker('aiworker.js'); // TODO not hard-coded + async processInWorker(worker: Worker, feedback: AIFeedback): Promise { let serializer = new Serializer(TK.SpaceTac); let promise = new Promise((resolve, reject) => { - worker.onerror = (error) => { - worker.terminate(); - reject(error); - }; + worker.onerror = reject; worker.onmessage = (message) => { let maneuver = serializer.unserialize(message.data); if (maneuver instanceof Maneuver) { @@ -56,7 +74,6 @@ module TK.SpaceTac { resolve(); } } else { - worker.terminate(); reject("Received something that is not a Maneuver"); } };