diff --git a/src/network/commands.cpp b/src/network/commands.cpp
new file mode 100644
index 000000000..cf3912125
--- /dev/null
+++ b/src/network/commands.cpp
@@ -0,0 +1,682 @@
+//   ___________		     _________		      _____  __
+//   \_	  _____/______   ____   ____ \_   ___ \____________ _/ ____\/  |_
+//    |    __) \_  __ \_/ __ \_/ __ \/    \  \/\_  __ \__  \\   __\\   __\ 
+//    |     \   |  | \/\  ___/\  ___/\     \____|  | \// __ \|  |   |  |
+//    \___  /   |__|    \___  >\___  >\______  /|__|  (____  /__|   |__|
+//	  \/		    \/	   \/	     \/		   \/
+//  ______________________                           ______________________
+//			  T H E   W A R   B E G I N S
+//	   FreeCraft - A free fantasy real time strategy game engine
+//
+/**@name commands.c	-	Global command handler - network support. */
+//
+//	(c) Copyright 2000 by Lutz Sammer
+//
+//	$Id$
+
+//@{
+
+//----------------------------------------------------------------------------
+//	Includes
+//----------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <time.h>
+
+#include "freecraft.h"
+#include "unit.h"
+#include "map.h"
+#include "actions.h"
+#include "player.h"
+#include "network.h"
+
+//----------------------------------------------------------------------------
+//	Declaration
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+//	Variables
+//----------------------------------------------------------------------------
+
+global int CommandLogEnabled;		/// True if command log is on
+
+//----------------------------------------------------------------------------
+//	Log commands
+//----------------------------------------------------------------------------
+
+/**@name log */
+//@{
+
+/**
+**	Log commands into file.
+**
+**	This could later be used to recover, crashed games.
+**
+**	@param name	Command name (move,attack,...).
+**	@param unit	Unit that receive the command.
+**	@param flag	Append command or flush old commands.
+**	@param position	Flag X,Y contains position or value or nothing.
+**	@param x	optional X map position.
+**	@param y	optional y map position.
+**	@param dest	optional destination unit.
+**	@param type	optional command argument (unit-type,...).
+*/
+local void CommandLog(const char* name,const Unit* unit,int flag,
+	int position,unsigned x,unsigned y,const Unit* dest,const char* value)
+{
+    static FILE* logf;
+
+    if( !CommandLogEnabled ) {
+	return;
+    }
+
+    if( !logf ) {
+	time_t now;
+
+	logf=fopen("command.log","wb");
+	if( !logf ) {
+	    return;
+	}
+	fprintf(logf,";;; Log file generated by FreeCraft Version "
+		VERSION "\n");
+	time(&now);
+	fprintf(logf,";;;\tDate: %s",ctime(&now));
+	fprintf(logf,";;;\tMap: %s\n\n",TheMap.Description);
+    }
+    fprintf(logf,"(log %d 'U%Zd '%s '%s",
+	    FrameCounter,UnitNumber(unit),name,
+	    flag ? "flush" : "append");
+    switch( position ) {
+	case 1:
+	    fprintf(logf," (%d %d)",x,y);
+	    break;
+	case 2:
+	    fprintf(logf," %d",x);
+    }
+    if( dest ) {
+	fprintf(logf," 'U%Zd",UnitNumber(unit));
+    }
+    if( value ) {
+	fprintf(logf," '%s",value);
+    }
+    fprintf(logf,")\n");
+    fflush(logf);
+}
+
+//@}
+
+//----------------------------------------------------------------------------
+//	Send game commands, maybe over the network.
+//----------------------------------------------------------------------------
+
+/**@name send */
+//@{
+
+/**
+**	Send command: Unit stop.
+**
+**	@param unit	pointer to unit.
+*/
+global void SendCommandStopUnit(Unit* unit)
+{
+    CommandLog("stop",unit,1,0,0,0,NoUnitP,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandStopUnit(unit);
+    } else {
+	NetworkSendCommand(MessageCommandStop,unit,0,0,NoUnitP,0,1);
+    }
+}
+
+/**
+**	Send command: Unit stand ground.
+**
+**	@param unit	pointer to unit.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandStandGround(Unit* unit,int flush)
+{
+    CommandLog("stand-ground",unit,flush,0,0,0,NoUnitP,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandStandGround(unit,flush);
+    } else {
+	NetworkSendCommand(MessageCommandStand,unit,0,0,NoUnitP,0,flush);
+    }
+}
+
+/**
+**	Send command: Follow unit to position.
+**
+**	@param unit	pointer to unit.
+**	@param x	X map tile position to move to.
+**	@param y	Y map tile position to move to.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandFollow(Unit* unit,Unit* dest,int flush)
+{
+    CommandLog("move",unit,flush,0,0,0,dest,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandFollow(unit,dest,flush);
+    } else {
+	NetworkSendCommand(MessageCommandFollow,unit,0,0,dest,0,flush);
+    }
+}
+
+/**
+**	Send command: Move unit to position.
+**
+**	@param unit	pointer to unit.
+**	@param x	X map tile position to move to.
+**	@param y	Y map tile position to move to.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandMove(Unit* unit,int x,int y,int flush)
+{
+    CommandLog("move",unit,flush,1,x,y,NoUnitP,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandMove(unit,x,y,flush);
+    } else {
+	NetworkSendCommand(MessageCommandMove,unit,x,y,NoUnitP,0,flush);
+    }
+}
+
+/**
+**	Send command: Unit repair.
+**
+**	@param unit	pointer to unit.
+**	@param x	X map tile position to repair.
+**	@param y	Y map tile position to repair.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandRepair(Unit* unit,int x,int y,Unit* dest,int flush)
+{
+    CommandLog("repair",unit,flush,1,x,y,dest,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandRepair(unit,x,y,dest,flush);
+    } else {
+	NetworkSendCommand(MessageCommandRepair,unit,x,y,dest,0,flush);
+    }
+}
+
+/**
+**	Send command: Unit attack unit or at position.
+**
+**	@param unit	pointer to unit.
+**	@param x	X map tile position to attack.
+**	@param y	Y map tile position to attack.
+**	@param attack	or !=NoUnitP unit to be attacked.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandAttack(Unit* unit,int x,int y,Unit* attack,int flush)
+{
+    CommandLog("attack",unit,flush,1,x,y,attack,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandAttack(unit,x,y,attack,flush);
+    } else {
+	NetworkSendCommand(MessageCommandAttack,unit,x,y,attack,0,flush);
+    }
+}
+
+/**
+**	Send command: Unit attack ground.
+**
+**	@param unit	pointer to unit.
+**	@param x	X map tile position to fire on.
+**	@param y	Y map tile position to fire on.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandAttackGround(Unit* unit,int x,int y,int flush)
+{
+    CommandLog("attack-ground",unit,flush,1,x,y,NoUnitP,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandAttackGround(unit,x,y,flush);
+    } else {
+	NetworkSendCommand(MessageCommandGround,unit,x,y,NoUnitP,0,flush);
+    }
+}
+
+/**
+**	Send command: Unit patrol between current and position.
+**
+**	@param unit	pointer to unit.
+**	@param x	X map tile position to patrol between.
+**	@param y	Y map tile position to patrol between.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandPatrol(Unit* unit,int x,int y,int flush)
+{
+    CommandLog("patrol",unit,flush,1,x,y,NoUnitP,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandPatrolUnit(unit,x,y,flush);
+    } else {
+	NetworkSendCommand(MessageCommandPatrol,unit,x,y,NoUnitP,0,flush);
+    }
+}
+
+/**
+**	Send command: Unit board unit.
+**
+**	@param unit	pointer to unit.
+**	@param dest	Destination to be boarded.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandBoard(Unit* unit,int x,int y,Unit* dest,int flush)
+{
+    CommandLog("board",unit,flush,1,x,y,dest,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandBoard(unit,dest,flush);
+    } else {
+	NetworkSendCommand(MessageCommandBoard,unit,x,y,dest,0,flush);
+    }
+}
+
+/**
+**	Send command: Unit unload unit.
+**
+**	@param unit	pointer to unit.
+**	@param x	X map tile position of unload.
+**	@param y	Y map tile position of unload.
+**	@param what	Passagier to be unloaded.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandUnload(Unit* unit,int x,int y,Unit* what,int flush)
+{
+    CommandLog("unload",unit,flush,1,x,y,what,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandUnload(unit,x,y,what,flush);
+    } else {
+	NetworkSendCommand(MessageCommandUnload,unit,x,y,what,0,flush);
+    }
+}
+
+/**
+**	Send command: Unit builds building at position.
+**
+**	@param unit	pointer to unit.
+**	@param x	X map tile position of construction.
+**	@param y	Y map tile position of construction.
+**	@param what	pointer to unit-type of the building.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandBuildBuilding(Unit* unit,int x,int y
+	,UnitType* what,int flush)
+{
+    CommandLog("build",unit,flush,1,x,y,NULL,what->Ident);
+    if( NetworkFildes==-1 ) {
+	CommandBuildBuilding(unit,x,y,what,flush);
+    } else {
+	NetworkSendCommand(MessageCommandBuild,unit,x,y,NoUnitP,what,flush);
+    }
+}
+
+/**
+**	Send command: Cancel this building construction.
+**
+**	@param unit	pointer to unit.
+*/
+global void SendCommandCancelBuilding(Unit* unit,Unit* worker)
+{
+    // FIXME: currently unit and worker are same?
+    CommandLog("cancel-build",unit,1,0,0,0,worker,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandCancelBuilding(unit,worker);
+    } else {
+	NetworkSendCommand(MessageCommandCancelBuild,unit,0,0,worker,0,1);
+    }
+}
+
+/**
+**	Send command: Unit harvest wood.
+**
+**	@param unit	pointer to unit.
+**	@param x	X map tile position where to harvest.
+**	@param y	Y map tile position where to harvest.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandHarvest(Unit* unit,int x,int y,int flush)
+{
+    CommandLog("harvest",unit,flush,1,x,y,NoUnitP,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandHarvest(unit,x,y,flush);
+    } else {
+	NetworkSendCommand(MessageCommandHarvest,unit,x,y,NoUnitP,0,flush);
+    }
+}
+
+/**
+**	Send command: Unit mine gold.
+**
+**	@param unit	pointer to unit.
+**	@param dest	pointer to destination (gold-mine).
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandMineGold(Unit* unit,Unit* dest,int flush)
+{
+    CommandLog("mine",unit,flush,0,0,0,dest,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandMineGold(unit,dest,flush);
+    } else {
+	NetworkSendCommand(MessageCommandMine,unit,0,0,dest,0,flush);
+    }
+}
+
+/**
+**	Send command: Unit haul oil.
+**
+**	@param unit	pointer to unit.
+**	@param dest	pointer to destination (oil-platform).
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandHaulOil(Unit* unit,Unit* dest,int flush)
+{
+    CommandLog("haul",unit,flush,0,0,0,dest,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandHaulOil(unit,dest,flush);
+    } else {
+	NetworkSendCommand(MessageCommandHaul,unit,0,0,dest,0,flush);
+    }
+}
+
+/**
+**	Send command: Unit return goods.
+**
+**	@param unit	pointer to unit.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandReturnGoods(Unit* unit,int flush)
+{
+    CommandLog("return",unit,flush,0,0,0,NoUnitP,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandReturnGoods(unit,flush);
+    } else {
+	NetworkSendCommand(MessageCommandReturn,unit,0,0,NoUnitP,0,flush);
+    }
+}
+
+/**
+**	Send command: Building/unit train new unit.
+**
+**	@param unit	pointer to unit.
+**	@param what	pointer to unit-type of the unit to be trained.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandTrainUnit(Unit* unit,UnitType* what,int flush)
+{
+    CommandLog("train",unit,flush,0,0,0,NULL,what->Ident);
+    if( NetworkFildes==-1 ) {
+	CommandTrainUnit(unit,what,flush);
+    } else {
+	NetworkSendCommand(MessageCommandTrain,unit,0,0,NoUnitP,what,flush);
+    }
+}
+
+/**
+**	Send command: Cancel training.
+**
+**	@param unit	pointer to unit.
+*/
+global void SendCommandCancelTraining(Unit* unit,int slot)
+{
+    CommandLog("cancel-train",unit,1,2,slot,0,NoUnitP,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandCancelTraining(unit,slot);
+    } else {
+	NetworkSendCommand(MessageCommandCancelTrain,unit,slot,0,NoUnitP,0,1);
+    }
+}
+
+/**
+**	Send command: Building starts upgrading to.
+**
+**	@param unit	pointer to unit.
+**	@param what	pointer to unit-type of the unit upgrade.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandUpgradeTo(Unit* unit,UnitType* what,int flush)
+{
+    CommandLog("upgrade-to",unit,flush,0,0,0,NULL,what->Ident);
+    if( NetworkFildes==-1 ) {
+	CommandUpgradeTo(unit,what,flush);
+    } else {
+	NetworkSendCommand(MessageCommandUpgrade,unit,0,0,NoUnitP,what,flush);
+    }
+}
+
+/**
+**	Send command: Cancel building upgrading to.
+**
+**	@param unit	pointer to unit.
+*/
+global void SendCommandCancelUpgradeTo(Unit* unit)
+{
+    CommandLog("cancel-upgrade-to",unit,1,0,0,0,NoUnitP,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandCancelUpgradeTo(unit);
+    } else {
+	NetworkSendCommand(MessageCommandCancelUpgrade,unit
+		,0,0,NoUnitP,NULL,1);
+    }
+}
+
+/**
+**	Send command: Building/unit research.
+**
+**	@param unit	pointer to unit.
+**	@param what	research-type of the research.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandResearch(Unit* unit,Upgrade* what,int flush)
+{
+    CommandLog("research",unit,flush,0,0,0,NULL,what->Ident);
+    if( NetworkFildes==-1 ) {
+	CommandResearch(unit,what,flush);
+    } else {
+	NetworkSendCommand(MessageCommandResearch,unit
+		,what-Upgrades,0,NoUnitP,0,flush);
+    }
+}
+
+/**
+**	Send command: Cancel Building/unit research.
+**
+**	@param unit	pointer to unit.
+*/
+global void SendCommandCancelResearch(Unit* unit)
+{
+    CommandLog("cancel-research",unit,1,0,0,0,NoUnitP,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandCancelResearch(unit);
+    } else {
+	NetworkSendCommand(MessageCommandCancelResearch,unit
+		,0,0,NoUnitP,0,1);
+    }
+}
+
+/**
+**	Send command: Unit demolish at position.
+**
+**	@param unit	pointer to unit.
+**	@param x	X map tile position where to demolish.
+**	@param y	Y map tile position where to demolish.
+**	@param attack	or !=NoUnitP unit to be demolished.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandDemolish(Unit* unit,int x,int y,Unit* attack,int flush)
+{
+    CommandLog("demolish",unit,flush,1,x,y,attack,NULL);
+    if( NetworkFildes==-1 ) {
+	CommandDemolish(unit,x,y,attack,flush);
+    } else {
+	NetworkSendCommand(MessageCommandDemolish,unit,x,y,attack,0,flush);
+    }
+}
+
+/**
+**	Send command: Unit spell cast on position/unit.
+**
+**	@param unit	pointer to unit.
+**	@param x	X map tile position where to cast spell.
+**	@param y	Y map tile position where to cast spell.
+**	@param attack	Cast spell on unit (if exist).
+**	@param spellid  Spell type id.
+**	@param flush	Flag flush all pending commands.
+*/
+global void SendCommandSpellCast(Unit* unit,int x,int y,Unit* dest,int spellid,int flush)
+{
+    CommandLog("spell-cast",unit,flush,1,x,y,dest,NULL); //FIXME: vladi: spellid?
+    if( NetworkFildes==-1 ) {
+	CommandSpellCast(unit,x,y,dest,spellid,flush);
+    } else {
+	NetworkSendCommand(MessageCommandSpellCast+spellid,unit,x,y,dest,0,flush);
+    }
+}
+
+//@}
+
+
+/**@name parse */
+//@{
+
+/**
+**	Parse a command (from network).
+**
+**	@param Type	Network message type
+**	@param Unum	Unit number (slot) that receive the command.
+**	@param x	optional X map position.
+**	@param y	optional y map position.
+**	@param Dest	optional destination unit.
+*/
+global void ParseCommand(unsigned short Type,UnitRef Unum,unsigned short x,unsigned short y,UnitRef Dest)
+{
+    Unit *unit, *dest;
+    int id, status;
+
+    DebugLevel3Fn(" %d frame %d\n", Type, FrameCounter);
+
+    unit=UnitSlots[Unum];
+    DebugCheck( !unit );
+    if( unit->Destroyed ) {
+	DebugLevel0Fn(" destroyed unit skipping %Zd\n"
+		,UnitNumber(unit));
+	return;
+    }
+
+    status=(Type&0x80)>>7;
+
+    // Note: destroyed destination unit is handled by the action routines.
+
+    switch( Type&0x7F ) {
+	case MessageSync:
+	    return;
+	case MessageQuit:
+	    return;
+	case MessageCommandStop:
+	    CommandStopUnit(unit);
+	    break;
+	case MessageCommandStand:
+	    CommandStandGround(unit,status);
+	    break;
+	case MessageCommandMove:
+	    CommandMove(unit,x,y,status);
+	    break;
+	case MessageCommandAttack:
+	    dest=NoUnitP;
+	    DebugLevel3Fn(" %x\n",Dest);
+	    if( Dest!=(unsigned short)0xFFFF ) {
+		dest=UnitSlots[Dest];
+		DebugCheck( !dest );
+	    }
+	    CommandAttack(unit,x,y,dest,status);
+	    break;
+	case MessageCommandGround:
+	    CommandAttackGround(unit,x,y,status);
+	    break;
+	case MessageCommandPatrol:
+	    CommandPatrolUnit(unit,x,y,status);
+	    break;
+	case MessageCommandBoard:
+	    dest=NoUnitP;
+	    if( Dest!=(unsigned short)0xFFFF ) {
+		dest=UnitSlots[Dest];
+		DebugCheck( !dest );
+	    }
+	    CommandBoard(unit,dest,status);
+	    break;
+	case MessageCommandUnload:
+	    dest=NoUnitP;
+	    if( Dest!=(unsigned short)0xFFFF ) {
+		dest=UnitSlots[Dest];
+		DebugCheck( !dest );
+	    }
+	    CommandUnload(unit,x,y,dest,status);
+	    break;
+	case MessageCommandBuild:
+	    CommandBuildBuilding(unit,x,y
+		    ,UnitTypes+Dest,status);
+	    break;
+	case MessageCommandCancelBuild:
+	    // dest is the worker building the unit...
+	    dest=NoUnitP;
+	    if( Dest!=(unsigned short)0xFFFF ) {
+		dest=UnitSlots[Dest];
+		DebugCheck( !dest );
+	    }
+	    CommandCancelBuilding(unit,dest);
+	    break;
+	case MessageCommandHarvest:
+	    CommandHarvest(unit,x,y,status);
+	    break;
+	case MessageCommandMine:
+	    dest=NoUnitP;
+	    if( Dest!=(unsigned short)0xFFFF ) {
+		dest=UnitSlots[Dest];
+		DebugCheck( !dest );
+	    }
+	    CommandMineGold(unit,dest,status);
+	    break;
+ 	case MessageCommandHaul:
+	    dest=NoUnitP;
+	    if( Dest!=(unsigned short)0xFFFF ) {
+		dest=UnitSlots[Dest];
+		DebugCheck( !dest );
+	    }
+	    CommandHaulOil(unit,dest,status);
+	    break;
+ 	case MessageCommandReturn:
+	    CommandReturnGoods(unit,status);
+	    break;
+ 	case MessageCommandTrain:
+	    CommandTrainUnit(unit,UnitTypes+Dest,status);
+	    break;
+	case MessageCommandCancelTrain:
+	    // FIXME: cancel slot?
+	    CommandCancelTraining(unit,0);
+	    break;
+ 	case MessageCommandUpgrade:
+	    CommandUpgradeTo(unit,UnitTypes+Dest,status);
+	    break;
+ 	case MessageCommandResearch:
+	    CommandResearch(unit,Upgrades+x,status);
+	    break;
+	case MessageCommandDemolish:
+	    dest=NoUnitP;
+	    if( Dest!=(unsigned short)0xFFFF ) {
+		dest=UnitSlots[Dest];
+		DebugCheck( !dest );
+	    }
+	    CommandDemolish(unit,x,y,dest,status);
+	    break;
+	default:
+	    id = (Type&0x7f) - MessageCommandSpellCast;
+	    dest=NoUnitP;
+	    if( Dest!=(unsigned short)0xFFFF ) {
+		dest=UnitSlots[Dest];
+		DebugCheck( !dest );
+	    }
+	    CommandSpellCast(unit,x,y,dest,id,status);
+	    break;
+    }
+}
+
+//@}
+
+//@}