diff --git a/server/states/ExploringState.js b/server/states/ExploringState.js index 4d452ef..9a69daf 100644 --- a/server/states/ExploringState.js +++ b/server/states/ExploringState.js @@ -26,47 +26,60 @@ export class ExploringState extends BaseState { console.log(`[${this.turtle.id}] Starting exploration`); while (!this.cancelled) { - // Safety checks - const fuel = await this.checkFuel(); - if (fuel !== 'unlimited' && fuel < this.minFuel) { - const refueled = await this.tryRefuel(); - if (!refueled) { - this.turtle.setState('goHome', { reason: 'low_fuel' }); + try { + // Safety checks + const fuel = await this.checkFuel(); + if (fuel !== 'unlimited' && fuel < this.minFuel) { + const refueled = await this.tryRefuel(); + if (!refueled) { + this.turtle.setState('goHome', { reason: 'low_fuel' }); + return; + } + } + + // Check distance + if (this._isTooFar()) { + this.turtle.setState('goHome', { reason: 'too_far' }); return; } + + // Check inventory + const isFull = await this.isInventoryFull(); + if (isFull) { + this.turtle.setState('goHome', { reason: 'inventory_full', returnState: 'exploring' }); + return; + } + + // Mark position + const pos = this.turtle.position; + if (pos) { + this.visitedPositions.add(`${pos.x},${pos.y},${pos.z}`); + } + + // Comprehensive scan + const scanResult = await this.scanSurroundings(); + if (scanResult) { + this.blocksDiscovered += Object.keys(scanResult).length; + } + + // Mine any valuable ores we find + yield* this._checkAndMineOres(); + + // Exploration movement + yield* this._exploreStep(); + + } catch (error) { + const isTimeout = error.message?.includes('timed out'); + if (isTimeout) { + console.warn(`[${this.turtle.id}] Exploration exec timeout, will retry next iteration`); + // Wait longer before retrying after a timeout + await this._sleep(3000); + } else { + // Non-timeout errors still propagate + throw error; + } } - // Check distance - if (this._isTooFar()) { - this.turtle.setState('goHome', { reason: 'too_far' }); - return; - } - - // Check inventory - const isFull = await this.isInventoryFull(); - if (isFull) { - this.turtle.setState('goHome', { reason: 'inventory_full', returnState: 'exploring' }); - return; - } - - // Mark position - const pos = this.turtle.position; - if (pos) { - this.visitedPositions.add(`${pos.x},${pos.y},${pos.z}`); - } - - // Comprehensive scan - const scanResult = await this.scanSurroundings(); - if (scanResult) { - this.blocksDiscovered += Object.keys(scanResult).length; - } - - // Mine any valuable ores we find - yield* this._checkAndMineOres(); - - // Exploration movement - yield* this._exploreStep(); - yield; await this._sleep(300); }