 		; Progressing?
 		if (mod(t, progressCheckDelay) = 0) {
 			if (!locateImage(imgProgression) and gameMode != "FARMING") {
-				if (zone > estimatedAscendLevel) {
-					triggerAscension("Stuck at high level boss")
-					break
+				if (++bossFailCounter < 2) {
+					showDebugSplash("Try boss one more time...")
+					setProgressionMode()
 				} else {
-					startFarming()
+					if (zone > estimatedAscendLevel) {
+						triggerAscension("Stuck at high level boss")
+						break
+					} else {
+						startFarming()
+					}
 				}
 			}
 		}

	local progressCheckDelay := 10

	local t := 0
	local elapsedTime := 0

	local comboDelay := skillCombo[1]
	comboIndex := 2


timeBetweenZones(z1, z2) {
	global
	local currentTime := getTime()
	local z1time := zoneTime.HasKey(z1) ? zoneTime[z1] : currentTime
	local z2time := zoneTime.HasKey(z2) ? zoneTime[z2] : currentTime
	return abs(z1time - z2time)
}

storeZoneTime() {
	global
	local cz := getCurrentZone()
	if (cz > 0) {
		local pz := cz - 1
		local currentTime := getTime()

		if (!zoneTime.HasKey(pz)) {
			zoneTime[pz] := currentTime
		}
		if (!zoneTime.HasKey(cz)) {
			zoneTime[cz] := currentTime
			; Reached a new non-boss zone?
			if (gameMode != "PROGRESSING" and mod(cz, 5) > 0 and zoneTime.MaxIndex() > 1) {
				; Yup!
				setGameMode("PROGRESSING")
			}
			bossFailCounter := 0
		}
	}
}

logZoneData(zStart, zEnd, zInterval) {
	global
	local startZone := zStart < zoneTime.MinIndex() ? zoneTime.MinIndex() : zStart
	local endZone := zEnd > zoneTime.MaxIndex() ? zoneTime.MaxIndex() : zEnd
	local intervals := ceil((endZone - startZone) / zInterval)

	local zone := startZone
