diff --git a/.vscode/launch.json b/.vscode/launch.json
index 528044c45..b85377ba2 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -14,7 +14,7 @@
             "windows": {
               "type": "cppvsdbg",
               "program": "${workspaceFolder}/build/Debug/stratagus-dbg.exe",
-              "args": ["-W", "-p", "-a", "-d", "${workspaceFolder}\\..\\data.${input:game}"],
+              "args": ["-W", "-i", "-p", "-P", "${input:port}", "-a", "-d", "${workspaceFolder}\\..\\data.${input:game}"],
               "environment": [
                 {"name": "PATH", "value": "${workspaceFolder}\\..\\dependencies\\bin;${env:PATH}"},
                 {"name": "OMP_WAIT_POLICY", "value": "passive"}
@@ -23,7 +23,7 @@
             },
             "stopAtEntry": false,
             "cwd": "${workspaceFolder}/../${input:game}",
-        }
+        },
     ],
     "inputs": [
         {
@@ -37,5 +37,11 @@
           ],
           "default": "wargus"
         },
+        {
+          "type": "promptString",
+          "id": "port",
+          "description": "Network port?",
+          "default": "6600"
+        }
     ]
 }
diff --git a/src/action/action_resource.cpp b/src/action/action_resource.cpp
index a1e735788..4d69479cc 100644
--- a/src/action/action_resource.cpp
+++ b/src/action/action_resource.cpp
@@ -221,6 +221,8 @@ COrder_Resource::~COrder_Resource()
 		worker->DeAssignWorkerFromMine(*mine);
 	}
 
+	Depot = NULL;
+
 	CUnit *goal = this->GetGoal();
 	if (goal) {
 		// If mining decrease the active count on the resource.
@@ -908,10 +910,19 @@ int COrder_Resource::StopGathering(CUnit &unit)
 
 	// Find and send to resource deposit.
 	CUnit *depot = FindDeposit(unit, 1000, unit.CurrentResource);
+	// There's a bug in the traversal that leads to workers "sometimes" not finding their way to the old depot.
+	// timfel: of course, maybe it's actually nice that workers drop out towards their last depot...
+	if (!depot && (!(resinfo.HarvestFromOutside || resinfo.TerrainHarvester)) && Depot && Depot->IsAlive()) {
+		CUnit *depot = FindDeposit(unit, 1000, unit.CurrentResource);
+		Assert(unit.Container);
+		DropOutNearest(unit, Depot->tilePos + Depot->Type->GetHalfTileSize(), source);
+	}
+	Depot = depot;
 	if (!depot || !unit.ResourcesHeld || this->Finished) {
 		if (!(resinfo.HarvestFromOutside || resinfo.TerrainHarvester)) {
-			Assert(unit.Container);
-			DropOutOnSide(unit, LookingW, source);
+			if (unit.Container) {
+				DropOutOnSide(unit, LookingW, source);
+			}
 		}
 		CUnit *mine = this->Resource.Mine;
 
@@ -921,13 +932,15 @@ int COrder_Resource::StopGathering(CUnit &unit)
 		}
 
 		DebugPrint("%d: Worker %d report: Can't find a resource [%d] deposit.\n"
-				   _C_ unit.Player->Index _C_ UnitNumber(unit) _C_ unit.CurrentResource);
+				_C_ unit.Player->Index _C_ UnitNumber(unit) _C_ unit.CurrentResource);
 		this->Finished = true;
 		return 0;
 	} else {
 		if (!(resinfo.HarvestFromOutside || resinfo.TerrainHarvester)) {
-			Assert(unit.Container);
-			DropOutNearest(unit, depot->tilePos + depot->Type->GetHalfTileSize(), source);
+			if (unit.Container) {
+				// may have dropped out above
+				DropOutNearest(unit, depot->tilePos + depot->Type->GetHalfTileSize(), source);
+			}
 		}
 		UnitGotoGoal(unit, depot, SUB_MOVE_TO_DEPOT);
 	}
diff --git a/src/action/actions.cpp b/src/action/actions.cpp
index 6881e62c0..7d97e94a6 100644
--- a/src/action/actions.cpp
+++ b/src/action/actions.cpp
@@ -77,6 +77,14 @@
 #include "unit_manager.h"
 #include "unittype.h"
 
+#ifdef USE_STACKTRACE
+#include <stdexcept>
+#include <stacktrace/call_stack.hpp>
+#include <stacktrace/stack_exception.hpp>
+#else
+#include "st_backtrace.h"
+#endif
+
 /*----------------------------------------------------------------------------
 --  Variables
 ----------------------------------------------------------------------------*/
@@ -483,11 +491,38 @@ static void DumpUnitInfo(CUnit &unit)
 	}
 
 	fprintf(logf, "%lu: ", GameCycle);
-	fprintf(logf, "%d %s %d P%d Refs %d: %X %d,%d %d,%d\n",
+
+	const char *currentAction;
+	switch (!unit.Orders.empty() ? unit.CurrentAction() : -1) {
+		case -1: currentAction = "No Orders"; break;
+		case UnitActionNone: currentAction = "None"; break;
+		case UnitActionStill: currentAction = "Still"; break;      
+		case UnitActionStandGround: currentAction = "StandGround"; break;
+		case UnitActionFollow: currentAction = "Follow"; break;     
+		case UnitActionDefend: currentAction = "Defend"; break;     
+		case UnitActionMove: currentAction = "Move"; break;       
+		case UnitActionAttack: currentAction = "Attack"; break;     
+		case UnitActionAttackGround: currentAction = "AttackGround"; break;
+		case UnitActionDie: currentAction = "Die"; break;        
+		case UnitActionSpellCast: currentAction = "SpellCast"; break;  
+		case UnitActionTrain: currentAction = "Train"; break;      
+		case UnitActionUpgradeTo: currentAction = "UpgradeTo"; break;  
+		case UnitActionResearch: currentAction = "Research"; break;   
+		case UnitActionBuilt: currentAction = "Built"; break;      
+		case UnitActionBoard: currentAction = "Board"; break;      
+		case UnitActionUnload: currentAction = "Unload"; break;     
+		case UnitActionPatrol: currentAction = "Patrol"; break;     
+		case UnitActionBuild: currentAction = "Build"; break;      
+		case UnitActionExplore: currentAction = "Explore"; break;    
+		case UnitActionRepair: currentAction = "Repair"; break;     
+		case UnitActionResource: currentAction = "Resource"; break;
+		case UnitActionTransformInto: currentAction = "TransformInto"; break;
+	}
+
+	fprintf(logf, "%d %s %s P%d Refs %d: Seed %X Hash %X %d@%d %d@%d\n",
 			UnitNumber(unit), unit.Type ? unit.Type->Ident.c_str() : "unit-killed",
-			!unit.Orders.empty() ? unit.CurrentAction() : -1,
-			unit.Player ? unit.Player->Index : -1, unit.Refs, SyncRandSeed,
-			unit.tilePos.x, unit.tilePos.y, unit.IX, unit.IY);
+			currentAction, unit.Player ? unit.Player->Index : -1, unit.Refs,
+			SyncRandSeed, SyncHash, unit.tilePos.x, unit.tilePos.y, unit.IX, unit.IY);
 #if 0
 	SaveUnit(unit, logf);
 #endif
@@ -532,10 +567,18 @@ static void UnitActionsEachCycle(UNITP_ITERATOR begin, UNITP_ITERATOR end)
 		if (EnableUnitDebug) {
 			DumpUnitInfo(unit);
 		}
+
 		// Calculate some hash.
 		SyncHash = (SyncHash << 5) | (SyncHash >> 27);
 		SyncHash ^= unit.Orders.empty() == false ? unit.CurrentAction() << 18 : 0;
 		SyncHash ^= unit.Refs << 3;
+
+		if (EnableUnitDebug) {
+			fprintf(stderr, "GameCycle: %lud, new SyncHash: %x (unit: %d:%s, order: %d, refs: %d)\n", GameCycle, SyncHash,
+								UnitNumber(unit), unit.Type->Ident.c_str(), unit.Orders.empty() ? -1 : unit.CurrentAction(), unit.Refs);
+			print_backtrace(8);
+			fflush(stderr);
+		}
 	}
 }
 
diff --git a/src/ai/ai.cpp b/src/ai/ai.cpp
index 72aac91a6..274e25d36 100644
--- a/src/ai/ai.cpp
+++ b/src/ai/ai.cpp
@@ -926,7 +926,7 @@ void AiCanNotMove(CUnit &unit)
 	const int gh = unit.pathFinderData->input.GetGoalSize().y;
 
 	AiPlayer = unit.Player->Ai;
-	if (PlaceReachable(unit, goalPos, gw, gh, 0, 255)) {
+	if (PlaceReachable(unit, goalPos, gw, gh, 0, 255, false)) {
 		// Path probably closed by unit here
 		AiMoveUnitInTheWay(unit);
 	}
diff --git a/src/include/pathfinder.h b/src/include/pathfinder.h
index cb1071f3e..1bdcb86e9 100644
--- a/src/include/pathfinder.h
+++ b/src/include/pathfinder.h
@@ -219,13 +219,13 @@ extern void FreePathfinder();
 /// Returns the next element of the path
 extern int NextPathElement(CUnit &unit, short int *xdp, short int *ydp);
 /// Return path length to unit 'dst'.
-extern int UnitReachable(const CUnit &src, const CUnit &dst, int range);
+extern int UnitReachable(const CUnit &src, const CUnit &dst, int range, bool from_outside_container);
 /// Return path length to unit 'dst' or error code.
 extern int CalcPathLengthToUnit(const CUnit &src, const CUnit &dst,
 						  const int minrange, const int range);
 /// Can the unit 'src' reach the place x,y
 extern int PlaceReachable(const CUnit &src, const Vec2i &pos, int w, int h,
-						  int minrange, int maxrange);
+						  int minrange, int maxrange, bool from_outside_container);
 
 //
 // in astar.cpp
diff --git a/src/include/st_backtrace.h b/src/include/st_backtrace.h
index 8e4709007..1dd4ec7b8 100644
--- a/src/include/st_backtrace.h
+++ b/src/include/st_backtrace.h
@@ -16,13 +16,12 @@ inline void print_backtrace(int sz = 100) {
 
 #elif defined(USE_WIN32)
 
-#if 1 // the below would mean we give up XP support
 #include "windows.h"
 #include "winbase.h"
 #include "dbghelp.h"
 #include "process.h"
 
-inline void print_backtrace(void) {
+inline void print_backtrace(int sz = 100) {
     unsigned int i;
     void *stack[100];
     unsigned short frames;
@@ -34,7 +33,7 @@ inline void print_backtrace(void) {
 
     process = GetCurrentProcess();
     SymInitialize(process, NULL, TRUE);
-    frames = CaptureStackBackTrace(0, 100, stack, NULL);
+    frames = CaptureStackBackTrace(0, sz, stack, NULL);
     fprintf(stderr, "backtrace returned %d addresses\n", frames);
     symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1);
     symbol->MaxNameLen = 1024;
@@ -58,17 +57,12 @@ inline void print_backtrace(void) {
     }
     free(symbol);
 }
-#else
-inline void print_backtrace(void) {
-}
-#endif
 
 #else
 
-inline void print_backtrace(void) {
+inline void print_backtrace(int sz = 100) {
 }
 
 #endif
 
-
 #endif
diff --git a/src/include/tile.h b/src/include/tile.h
index ff9aee7c7..1166689ce 100644
--- a/src/include/tile.h
+++ b/src/include/tile.h
@@ -227,6 +227,9 @@ public:
 	unsigned char getCost() const { return cost; }
 	unsigned int getFlag() const { return Flags; }
 	void setGraphicTile(unsigned int tile) { this->tile = tile; }
+#ifdef DEBUG
+	int64_t lastAStarCost;    /// debugging pathfinder
+#endif
 private:
 #ifdef DEBUG
 	unsigned int tilesetTile;  /// tileset tile number
diff --git a/src/map/map_draw.cpp b/src/map/map_draw.cpp
index a58508db4..61b5b25e6 100644
--- a/src/map/map_draw.cpp
+++ b/src/map/map_draw.cpp
@@ -286,6 +286,38 @@ void CViewport::DrawMapBackgroundInViewport() const
 				tile = mf.playerInfo.SeenTile;
 			}
 			Map.TileGraphic->DrawFrameClip(tile, dx, dy);
+#if 0
+			int64_t cost = mf.lastAStarCost;
+			int32_t alpha;
+			// we use the msb as marker, but only consider the lower 32-bits as numeric value
+			if (cost != 0) {
+				if (cost == -1) {
+					// non traversible tiles always start full red
+					alpha = -60;
+				} else if (cost > 0) {
+					// msb not set means this has not been scaled
+					// scale cost to be between 1 and 60
+					cost <<= 3;
+					if (cost > 60) {
+						cost = 60;
+					}
+					alpha = static_cast<int32_t>(cost);
+				} else {
+					// consider only low 32-bits of already scaled value
+					alpha = static_cast<int32_t>(cost);
+				}
+			}
+			if (alpha > 0) {
+				Video.FillTransRectangleClip(ColorGreen, dx, dy,
+								 dx + Map.TileGraphic->getWidth(), dy + dx + Map.TileGraphic->getWidth(), alpha * 200 / 60);
+				alpha--;
+			} else if (alpha < 0) {
+				Video.FillTransRectangleClip(ColorRed, dx, dy,
+								 dx + Map.TileGraphic->getWidth(), dy + dx + Map.TileGraphic->getWidth(), -alpha * 200 / 60);
+				alpha++;
+			}
+			const_cast<CMapField &>(mf).lastAStarCost = alpha | ((uint64_t)1 << 63);
+#endif
 			++sx;
 			dx += PixelTileSize.x;
 		}
diff --git a/src/map/map_fog.cpp b/src/map/map_fog.cpp
index c3879b3a7..8c30e2ce2 100644
--- a/src/map/map_fog.cpp
+++ b/src/map/map_fog.cpp
@@ -51,6 +51,13 @@
 #include "video.h"
 #include "../video/intern_video.h"
 
+#ifdef USE_STACKTRACE
+#include <stdexcept>
+#include <stacktrace/call_stack.hpp>
+#include <stacktrace/stack_exception.hpp>
+#else
+#include "st_backtrace.h"
+#endif
 
 /*----------------------------------------------------------------------------
 --  Variables
@@ -205,6 +212,7 @@ void MapMarkTileSight(const CPlayer &player, const unsigned int index)
 {
 	CMapField &mf = *Map.Field(index);
 	unsigned short *v = &(mf.playerInfo.Visible[player.Index]);
+
 	if (*v == 0 || *v == 1) { // Unexplored or unseen
 		// When there is no fog only unexplored tiles are marked.
 		if (!Map.NoFogOfWar || *v == 0) {
@@ -214,10 +222,25 @@ void MapMarkTileSight(const CPlayer &player, const unsigned int index)
 		if (mf.playerInfo.IsTeamVisible(*ThisPlayer)) {
 			Map.MarkSeenTile(mf);
 		}
-		return;
+	} else {
+		Assert(*v != 65535);
+		++*v;
 	}
-	Assert(*v != 65535);
-	++*v;
+#if 0
+	if (EnableDebugPrint) {
+		fprintf(stderr, "Mapsight: GameCycle: %lud, SyncHash before: %x", GameCycle, SyncHash);
+	}
+	// Calculate some hash.
+	SyncHash = (SyncHash << 5) | (SyncHash >> 27);
+	SyncHash ^= (*v << 16) | *v;
+
+	if (EnableDebugPrint) {
+		fprintf(stderr, ", after: %x (mapfield: %d, player: %d, sight: %d)\n", SyncHash,
+							index, player.Index, *v);
+		print_backtrace(8);
+		fflush(stderr);
+	}
+#endif
 }
 
 void MapMarkTileSight(const CPlayer &player, const Vec2i &pos)
diff --git a/src/network/network.cpp b/src/network/network.cpp
index 4ac34d613..4519b93dc 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -250,6 +250,8 @@
 //  Declaration
 //----------------------------------------------------------------------------
 
+extern int SaveGame(const std::string &filename); /// Save game
+
 /**
 **  Network command input/output queue.
 */
@@ -298,8 +300,8 @@ CUDPSocket NetworkFildes;                  /// Network file descriptor
 static unsigned long NetworkLastFrame[PlayerMax]; /// Last frame received packet
 static unsigned long NetworkLastCycle[PlayerMax]; /// Last cycle received packet
 
-static int NetworkSyncSeeds[256];          /// Network sync seeds.
-static int NetworkSyncHashs[256];          /// Network sync hashs.
+static unsigned int NetworkSyncSeeds[256];          /// Network sync seeds.
+static unsigned int NetworkSyncHashs[256];          /// Network sync hashs.
 static CNetworkCommandQueue NetworkIn[256][PlayerMax][MaxNetworkCommands]; /// Per-player network packet input queue
 static std::deque<CNetworkCommandQueue> CommandsIn;    /// Network command input queue
 static std::deque<CNetworkCommandQueue> MsgCommandsIn; /// Network message input queue
@@ -917,8 +919,8 @@ static void NetworkExecCommand_Sync(const CNetworkCommandQueue &ncq)
 	CNetworkCommandSync nc;
 	nc.Deserialize(&ncq.Data[0]);
 	const unsigned long gameNetCycle = GameCycle;
-	const int syncSeed = nc.syncSeed;
-	const int syncHash = nc.syncHash;
+	const unsigned int syncSeed = nc.syncSeed;
+	const unsigned int syncHash = nc.syncHash;
 
 	if (syncSeed != NetworkSyncSeeds[gameNetCycle & 0xFF]
 		|| syncHash != NetworkSyncHashs[gameNetCycle & 0xFF]) {
@@ -929,10 +931,20 @@ static void NetworkExecCommand_Sync(const CNetworkCommandQueue &ncq)
 			// only print this message circa every 5 seconds...
 			SetMessage("%s", _("Network out of sync"));
 			gameInSync = false;
+			SetGamePaused(true);
+
+			time_t now;
+			time(&now);
+			std::string savefile = "desync_savegame_";
+			savefile += std::to_string(ThisPlayer->Index);
+			savefile += "_";
+			savefile += std::to_string((intmax_t)now);
+			savefile += ".sav";
+			SaveGame(savefile);
 		}
-		DebugPrint("\nNetwork out of sync %x!=%x! %d!=%d! Cycle %lu\n\n" _C_
+		DebugPrint("\nNetwork out of sync seed: %X!=%X , hash: %X!=%X Cycle %lu\n\n" _C_
 				   syncSeed _C_ NetworkSyncSeeds[gameNetCycle & 0xFF] _C_
-				   syncHash _C_ NetworkSyncHashs[gameNetCycle & 0xFF] _C_ GameCycle);
+				   syncHash _C_ NetworkSyncHashs[gameNetCycle & 0xFF] _C_ GameCycle);	
 	} else {
 		gameInSync = true;
 	}
diff --git a/src/pathfinder/astar.cpp b/src/pathfinder/astar.cpp
index 996bbca12..5cbd52c3c 100644
--- a/src/pathfinder/astar.cpp
+++ b/src/pathfinder/astar.cpp
@@ -534,12 +534,18 @@ static int CostMoveToCallBack_Default(unsigned int index, const CUnit &unit)
 			if (flag && (AStarKnowUnseenTerrain || mf->playerInfo.IsExplored(*unit.Player))) {
 				if (flag & ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit)) {
 					// we can't cross fixed units and other unpassable things
+#ifdef DEBUG
+					const_cast<CMapField *>(mf)->lastAStarCost = -1;
+#endif
 					return -1;
 				}
 				CUnit *goal = mf->UnitCache.find(unit_finder);
 				if (!goal) {
 					// Shouldn't happen, mask says there is something on this tile
 					Assert(0);
+#ifdef DEBUG
+					const_cast<CMapField *>(mf)->lastAStarCost = -1;
+#endif
 					return -1;
 				}
 				if (goal->Moving)  {
@@ -549,6 +555,9 @@ static int CostMoveToCallBack_Default(unsigned int index, const CUnit &unit)
 					// for non moving unit Always Fail unless goal is unit, or unit can attack the target
 					if (&unit != goal) {
 						if (GetAStarFixedEnemyUnitsUnpassable() == true) {
+#ifdef DEBUG
+							const_cast<CMapField *>(mf)->lastAStarCost = -1;
+#endif
 							return -1;
 						}
 						if (goal->Player->IsEnemy(unit) && unit.IsAgressive() && CanTarget(*unit.Type, *goal->Type)
@@ -556,6 +565,9 @@ static int CostMoveToCallBack_Default(unsigned int index, const CUnit &unit)
 								cost += 2 * AStarMovingUnitCrossingCost;
 						} else {
 						// FIXME: Need support for moving a fixed unit to add cost
+#ifdef DEBUG
+							const_cast<CMapField *>(mf)->lastAStarCost = -1;
+#endif
 							return -1;
 						}
 						//cost += AStarFixedUnitCrossingCost;
@@ -569,6 +581,9 @@ static int CostMoveToCallBack_Default(unsigned int index, const CUnit &unit)
 			}
 			// Add tile movement cost
 			cost += mf->getCost();
+#ifdef DEBUG
+			const_cast<CMapField *>(mf)->lastAStarCost = cost;
+#endif
 			++mf;
 		} while (--i);
 		index += AStarMapWidth;
diff --git a/src/pathfinder/pathfinder.cpp b/src/pathfinder/pathfinder.cpp
index 46f47df25..a229396c2 100644
--- a/src/pathfinder/pathfinder.cpp
+++ b/src/pathfinder/pathfinder.cpp
@@ -183,33 +183,68 @@ void FreePathfinder()
 **
 **  @return          Distance to place.
 */
-int PlaceReachable(const CUnit &src, const Vec2i &goalPos, int w, int h, int minrange, int range)
+int PlaceReachable(const CUnit &src, const Vec2i &goalPos, int w, int h, int minrange, int range, bool from_outside_container)
 {
 	SetAStarFixedEnemyUnitsUnpassable(true); /// change Path Finder setting to don't count tiles with enemy units as passable
-	int i = AStarFindPath(src.tilePos, goalPos, w, h,
-						  src.Type->TileWidth, src.Type->TileHeight,
-						  minrange, range, NULL, 0, src);
+	int i;
+	Vec2i srcTilePos = src.tilePos;
+	int srcTW = src.Type->TileWidth;
+	int srcTH = src.Type->TileHeight;
+	if (!from_outside_container || !src.Container) {
+		i = AStarFindPath(srcTilePos, goalPos, w, h,
+						  srcTW, srcTH,
+						  minrange, range, nullptr, 0, src);
+	} else {
+		const CUnit *first_container = GetFirstContainer(src);
+
+        const Vec2i offset(1, 1);
+		int containerW = first_container->Type->TileWidth;
+		int containerH = first_container->Type->TileHeight;
+		Vec2i containerTilePos = first_container->tilePos;
+		// check top and bottom rows and left and right columns around the container
+		for (int x = -1; x <= containerW; x++) {
+			for (int y = -1; y <= containerH; y++) {
+				if (x >= 0 && x < containerW && y >= 0 && y < containerH) {
+					// inside the container, no need to check
+					continue;
+				}
+				Vec2i tile_pos = containerTilePos + Vec2i(x, y);
+				if (!Map.Info.IsPointOnMap(tile_pos)) {
+					continue;
+				}
+				if (!CanMoveToMask(tile_pos, src.Type->MovementMask)) {
+					//ignore tiles to which the unit cannot be dropped from its container
+					continue;
+				}
+
+				i = AStarFindPath(tile_pos, goalPos, w, h,
+					srcTW, srcTH,
+					minrange, range, nullptr, 0, src);
+
+				switch (i) {
+					case PF_FAILED:
+					case PF_UNREACHABLE:
+					case PF_WAIT:
+						continue;
+				}
+				goto finished;
+			}
+		}
+	}
+finished:
 	SetAStarFixedEnemyUnitsUnpassable(false); /// restore Path Finder setting
 	switch (i) {
 		case PF_FAILED:
 		case PF_UNREACHABLE:
-			i = 0;
-			break;
+		case PF_WAIT:
+			return 0;
 		case PF_REACHED:
 			/* since most of this function usage check return value as bool
-			 * then reached state should be track as true value */
-			i = 1;
-			break;
-		case PF_WAIT:
-			Assert(0);
-			i = 0;
-			break;
-		case PF_MOVE:
-			break;
+			* then reached state should be track as true value */
+			return std::max(i, 1);
 		default:
-			break;
+			return i;
 	}
-	return i;
 }
 
 /**
@@ -221,14 +256,14 @@ int PlaceReachable(const CUnit &src, const Vec2i &goalPos, int w, int h, int min
 **
 **  @return       Distance to place.
 */
-int UnitReachable(const CUnit &src, const CUnit &dst, int range)
+int UnitReachable(const CUnit &src, const CUnit &dst, int range, bool from_outside_container)
 {
 	//  Find a path to the goal.
 	if (src.Type->Building) {
 		return 0;
 	}
 	const int depth = PlaceReachable(src, dst.tilePos,
-									 dst.Type->TileWidth, dst.Type->TileHeight, 0, range);
+									 dst.Type->TileWidth, dst.Type->TileHeight, 0, range, from_outside_container);
 	if (depth <= 0) {
 		return 0;
 	}
diff --git a/src/stratagus/util.cpp b/src/stratagus/util.cpp
index 26c632d5d..3ec394514 100644
--- a/src/stratagus/util.cpp
+++ b/src/stratagus/util.cpp
@@ -87,7 +87,7 @@ int SyncRand()
 	
 	if (EnableDebugPrint) {
 		fprintf(stderr, "GameCycle: %lud, seed: %x, Sync rand: %d\n", GameCycle, SyncRandSeed, val);
-		print_backtrace();
+		print_backtrace(8);
 		fflush(stderr);
 	}
 	return val;
diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp
index cf7125c78..84eb4d0ad 100644
--- a/src/unit/unit.cpp
+++ b/src/unit/unit.cpp
@@ -430,43 +430,45 @@ void CUnit::Init()
 	pathFinderData = new PathFinderData;
 	pathFinderData->input.SetUnit(*this);
 
+	Frame = 0;
 	Colors = -1;
+	memset(IndividualUpgrades, 0, sizeof(IndividualUpgrades));
 	IX = 0;
 	IY = 0;
-	Frame = 0;
 	Direction = 0;
+	CurrentResource = 0;
+	ResourcesHeld = 0;
 	DamagedType = ANIMATIONS_DEATHTYPES;
 	Attacked = 0;
+	Summoned = 0;
+	Blink = 0;
+	Moving = 0;
+	ReCast = 0;
+	AutoRepair = 0;
 	Burning = 0;
 	Destroyed = 0;
 	Removed = 0;
 	Selected = 0;
-	TeamSelected = 0;
 	Constructed = 0;
 	Active = 0;
 	Boarded = 0;
+	CacheLock = 0;
+	Waiting = 0;
+	MineLow = 0;
+	TeamSelected = 0;
 	RescuedFrom = NULL;
 	memset(VisCount, 0, sizeof(VisCount));
 	memset(&Seen, 0, sizeof(Seen));
 	delete Variable;
 	Variable = NULL;
 	TTL = 0;
-	Threshold = 0;
-	UnderAttack = 0;
 	GroupId = 0;
 	LastGroup = 0;
-	ResourcesHeld = 0;
 	Wait = 0;
-	Blink = 0;
-	Moving = 0;
-	ReCast = 0;
-	CacheLock = 0;
-	Summoned = 0;
-	Waiting = 0;
-	MineLow = 0;
+	Threshold = 0;
+	UnderAttack = 0;
 	memset(&Anim, 0, sizeof(Anim));
 	memset(&WaitBackup, 0, sizeof(WaitBackup));
-	CurrentResource = 0;
 	Orders.clear();
 	delete SavedOrder;
 	SavedOrder = NULL;
@@ -478,9 +480,7 @@ void CUnit::Init()
 	AutoCastSpell = NULL;
 	delete SpellCoolDownTimers;
 	SpellCoolDownTimers = NULL;
-	AutoRepair = 0;
 	Goal = NULL;
-	memset(IndividualUpgrades, 0, sizeof(IndividualUpgrades));
 }
 
 CUnit::~CUnit() {
@@ -2984,7 +2984,7 @@ static void HitUnit_AttackBack(CUnit &attacker, CUnit &target)
 			COrder_Attack &order = dynamic_cast<COrder_Attack &>(*target.CurrentOrder());
 			if (order.IsAutoTargeting() || target.Player->AiEnabled) {
 				if (attacker.IsVisibleAsGoal(*target.Player)) {
-					if (UnitReachable(target, attacker, target.Stats->Variables[ATTACKRANGE_INDEX].Max)) {
+					if (UnitReachable(target, attacker, target.Stats->Variables[ATTACKRANGE_INDEX].Max, false)) {
 						target.UnderAttack = underAttack; /// allow target to ignore non aggressive targets while searching attacker
 						order.OfferNewTarget(target, &attacker);
 					}
@@ -3018,7 +3018,7 @@ static void HitUnit_AttackBack(CUnit &attacker, CUnit &target)
 			const Vec2i posToAttack = (attacker.IsVisibleAsGoal(*target.Player)) 
 									? attacker.tilePos 
 									: GetRndPosInDirection(target.tilePos, attacker.tilePos, false, target.Type->ReactRangeComputer, 2);
-			if (!PlaceReachable(target, posToAttack, 1, 1, 0, target.Stats->Variables[ATTACKRANGE_INDEX].Max)) {
+			if (!PlaceReachable(target, posToAttack, 1, 1, 0, target.Stats->Variables[ATTACKRANGE_INDEX].Max, false)) {
 				return;
 			}
 			COrder *savedOrder = NULL;
diff --git a/src/unit/unit_find.cpp b/src/unit/unit_find.cpp
index 5cae1a2e8..b8b41e985 100644
--- a/src/unit/unit_find.cpp
+++ b/src/unit/unit_find.cpp
@@ -213,14 +213,8 @@ class BestDepotFinder
 					return;
 				}
 
-				// calck real travel distance
-				if (worker->Container != nullptr) {
-					UnmarkUnitFieldFlags(*first_container);
-				}
-				const int travel_distance = UnitReachable(*worker, *dest, 1);
-				if (worker->Container != nullptr) {
-					MarkUnitFieldFlags(*first_container);
-				}
+				// calc real travel distance
+				const int travel_distance = UnitReachable(*worker, *dest, 1, worker->Container != nullptr);
 				//
 				// Take this depot?
 				//
@@ -730,7 +724,7 @@ private:
 		// Unit in range ?
 		const int d = attacker->MapDistanceTo(*dest);
 
-		if (d > attackrange && !UnitReachable(*attacker, *dest, attackrange)) {
+		if (d > attackrange && !UnitReachable(*attacker, *dest, attackrange, false)) {
 			return INT_MAX;
 		}
 
@@ -934,7 +928,7 @@ public:
 
 				int attackrange = attacker->Stats->Variables[ATTACKRANGE_INDEX].Max;
 				if (d <= attackrange ||
-					(d <= range && UnitReachable(*attacker, *dest, attackrange))) {
+					(d <= range && UnitReachable(*attacker, *dest, attackrange, false))) {
 					++enemy_count;
 				} else {
 					dest->CacheLock = 1;