Index: binaries/data/mods/public/simulation/data/pathfinder.xml
===================================================================
--- binaries/data/mods/public/simulation/data/pathfinder.xml	(revision 9634)
+++ binaries/data/mods/public/simulation/data/pathfinder.xml	(working copy)
@@ -1,6 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Pathfinder>
 
+  <!--
+    Previously all move commands during a turn were
+    queued up and processed asynchronously at the start
+    of the next turn.  Now we are processing queued up 
+    events several times duing the turn.  This improves
+    responsiveness and units move more smoothly especially.
+    when in formation.  There is still a call at the 
+    beginning of a turn to process all outstanding moves - 
+    this will handle any moves above the MaxSameTurnMoves 
+    threshold.  
+    
+    TODO - The moves processed at the beginning of the 
+    turn do not count against the maximum moves per turn 
+    currently.  The thinking is that this will eventually 
+    happen in another thread.  Either way this probably 
+    will require some adjustment and rethinking.
+  -->
+  <MaxSameTurnMoves>16</MaxSameTurnMoves>
+  
   <PassabilityClasses>
 
     <!-- Unit pathfinding classes: -->
Index: binaries/system/Collada.dll
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: binaries/system/pyrogenesis.exe
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: binaries/system/pyrogenesis.pdb
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: source/simulation2/components/CCmpPathfinder.cpp
===================================================================
--- source/simulation2/components/CCmpPathfinder.cpp	(revision 9634)
+++ source/simulation2/components/CCmpPathfinder.cpp	(working copy)
@@ -58,7 +58,10 @@
 	CParamNode externalParamNode;
 	CParamNode::LoadXML(externalParamNode, L"simulation/data/pathfinder.xml");
 
+	const CParamNode pathingSettings = externalParamNode.GetChild("Pathfinder");
+	m_MaxSameTurnMoves = pathingSettings.GetChild("MaxSameTurnMoves").ToInt();
 
+
 	const CParamNode::ChildrenMap& passClasses = externalParamNode.GetChild("Pathfinder").GetChild("PassabilityClasses").GetChildren();
 	for (CParamNode::ChildrenMap::const_iterator it = passClasses.begin(); it != passClasses.end(); ++it)
 	{
@@ -199,7 +202,12 @@
 		m_TerrainDirty = true;
 		break;
 	}
+	case MT_TurnStart:
+	{
+		m_SameTurnMovesCount = 0;
+		break;
 	}
+	}
 }
 
 void CCmpPathfinder::RenderSubmit(SceneCollector& collector)
@@ -435,6 +443,12 @@
 	// TODO: this computation should be done incrementally, spread
 	// across multiple frames (or even multiple turns)
 
+	ProcessLongRequests(longRequests);
+	ProcessShortRequests(shortRequests);
+}
+
+void CCmpPathfinder::ProcessLongRequests(const std::vector<AsyncLongPathRequest>& longRequests)
+{
 	for (size_t i = 0; i < longRequests.size(); ++i)
 	{
 		const AsyncLongPathRequest& req = longRequests[i];
@@ -443,7 +457,10 @@
 		CMessagePathResult msg(req.ticket, path);
 		GetSimContext().GetComponentManager().PostMessage(req.notify, msg);
 	}
+}
 
+void CCmpPathfinder::ProcessShortRequests(const std::vector<AsyncShortPathRequest>& shortRequests)
+{
 	for (size_t i = 0; i < shortRequests.size(); ++i)
 	{
 		const AsyncShortPathRequest& req = shortRequests[i];
@@ -454,3 +471,63 @@
 		GetSimContext().GetComponentManager().PostMessage(req.notify, msg);
 	}
 }
+
+void CCmpPathfinder::ProcessSameTurnMoves()
+{
+	u32 moveCount;
+
+	if (m_AsyncLongPathRequests.size() > 0)
+	{
+		// Figure out how many moves we can do this time
+		moveCount = m_MaxSameTurnMoves - m_SameTurnMovesCount;
+	
+		if (moveCount <= 0)
+			return;
+
+		// Copy the long request elements we are going to process into a new array
+		std::vector<AsyncLongPathRequest> longRequests;
+		if (m_AsyncLongPathRequests.size() <= moveCount)
+		{
+			m_AsyncLongPathRequests.swap(longRequests);
+			moveCount = longRequests.size();
+		}
+		else
+		{
+			longRequests.resize(moveCount);
+			copy(m_AsyncLongPathRequests.begin(), m_AsyncLongPathRequests.begin() + moveCount, longRequests.begin());
+			m_AsyncLongPathRequests.erase(m_AsyncLongPathRequests.begin(), m_AsyncLongPathRequests.begin() + moveCount);
+		}
+
+		ProcessLongRequests(longRequests);
+
+		m_SameTurnMovesCount += moveCount;
+	}
+	
+	if (m_AsyncShortPathRequests.size() > 0)
+	{
+		// Figure out how many moves we can do now
+		moveCount = m_MaxSameTurnMoves - m_SameTurnMovesCount;
+
+		if (moveCount <= 0)
+			return;
+
+		// Copy the short request elements we are going to process into a new array
+		std::vector<AsyncShortPathRequest> shortRequests;
+		if (m_AsyncShortPathRequests.size() <= moveCount)
+		{
+			m_AsyncShortPathRequests.swap(shortRequests);
+			moveCount = shortRequests.size();
+		}
+		else
+		{
+			shortRequests.resize(moveCount);
+			copy(m_AsyncShortPathRequests.begin(), m_AsyncShortPathRequests.begin() + moveCount, shortRequests.begin());
+			m_AsyncShortPathRequests.erase(m_AsyncShortPathRequests.begin(), m_AsyncShortPathRequests.begin() + moveCount);
+		}
+
+		ProcessShortRequests(shortRequests);
+
+		m_SameTurnMovesCount += moveCount;
+	}
+}
+
Index: source/simulation2/components/CCmpPathfinder_Common.h
===================================================================
--- source/simulation2/components/CCmpPathfinder_Common.h	(revision 9634)
+++ source/simulation2/components/CCmpPathfinder_Common.h	(working copy)
@@ -161,6 +161,7 @@
 		componentManager.SubscribeToMessageType(MT_Update);
 		componentManager.SubscribeToMessageType(MT_RenderSubmit); // for debug overlays
 		componentManager.SubscribeToMessageType(MT_TerrainChanged);
+		componentManager.SubscribeToMessageType(MT_TurnStart);
 	}
 
 	DEFAULT_COMPONENT_ALLOCATOR(Pathfinder)
@@ -187,8 +188,14 @@
 	Grid<TerrainTile>* m_Grid; // terrain/passability information
 	Grid<u8>* m_ObstructionGrid; // cached obstruction information (TODO: we shouldn't bother storing this, it's redundant with LSBs of m_Grid)
 	bool m_TerrainDirty; // indicates if m_Grid has been updated since terrain changed
+	
+	// For responsiveness we will procees some moves in the same turn they were generated in
+	
+	u16 m_MaxSameTurnMoves; // max number of moves that can be created and processed in the same turn
+	u16 m_SameTurnMovesCount; // current number of same turn moves we have processed this turn
 
 	// Debugging - output from last pathfind operation:
+
 	PathfindTileGrid* m_DebugGrid;
 	u32 m_DebugSteps;
 	Path* m_DebugPath;
@@ -242,6 +249,12 @@
 
 	virtual void FinishAsyncRequests();
 
+	virtual void ProcessLongRequests(const std::vector<AsyncLongPathRequest>& longRequests);
+	
+	virtual void ProcessShortRequests(const std::vector<AsyncShortPathRequest>& shortRequests);
+
+	virtual void ProcessSameTurnMoves();
+
 	/**
 	 * Returns the tile containing the given position
 	 */
Index: source/simulation2/components/ICmpPathfinder.h
===================================================================
--- source/simulation2/components/ICmpPathfinder.h	(revision 9634)
+++ source/simulation2/components/ICmpPathfinder.h	(working copy)
@@ -159,6 +159,11 @@
 	 */
 	virtual void FinishAsyncRequests() = 0;
 
+	/**
+	 * Process moves during the same turn they were created in to improve responsiveness.
+	 */
+	virtual void ProcessSameTurnMoves() = 0;
+
 	DECLARE_INTERFACE_TYPE(Pathfinder)
 };
 
Index: source/simulation2/Simulation2.cpp
===================================================================
--- source/simulation2/Simulation2.cpp	(revision 9634)
+++ source/simulation2/Simulation2.cpp	(working copy)
@@ -229,6 +229,10 @@
 	if (!cmpCommandQueue.null())
 		cmpCommandQueue->FlushTurn(commands);
 
+	// Process newly generated move commands so the UI feels snappy
+	if (!cmpPathfinder.null())
+		cmpPathfinder->ProcessSameTurnMoves();
+
 	// Send all the update phases
 	{
 		CMessageUpdate msgUpdate(turnLengthFixed);
@@ -238,6 +242,11 @@
 		CMessageUpdate_MotionFormation msgUpdate(turnLengthFixed);
 		m_ComponentManager.BroadcastMessage(msgUpdate);
 	}
+
+	// Process move commands for formations (group proxy)
+	if (!cmpPathfinder.null())
+		cmpPathfinder->ProcessSameTurnMoves();
+
 	{
 		CMessageUpdate_MotionUnit msgUpdate(turnLengthFixed);
 		m_ComponentManager.BroadcastMessage(msgUpdate);
@@ -247,6 +256,11 @@
 		m_ComponentManager.BroadcastMessage(msgUpdate);
 	}
 
+	// Process moves resulting from group proxy movement (unit needs to catch up or realign) and any others
+	if (!cmpPathfinder.null())
+		cmpPathfinder->ProcessSameTurnMoves();
+
+
 	// Clean up any entities destroyed during the simulation update
 	m_ComponentManager.FlushDestroyedComponents();
 
