Index: source/ps/Filesystem.cpp
===================================================================
--- source/ps/Filesystem.cpp	(revision 16116)
+++ source/ps/Filesystem.cpp	(working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 Wildfire Games.
+/* Copyright (C) 2015 Wildfire Games.
  * This file is part of 0 A.D.
  *
  * 0 A.D. is free software: you can redistribute it and/or modify
@@ -46,10 +46,9 @@
 }
 
 // try to skip unnecessary work by ignoring uninteresting notifications.
-static bool CanIgnore(const DirWatchNotification& notification)
+static bool CanIgnore(const OsPath& pathname)
 {
 	// ignore directories
-	const OsPath& pathname = notification.Pathname();
 	if(pathname.IsDirectory())
 		return true;
 
@@ -66,6 +65,25 @@
 	return false;
 }
 
+Status UpdateVFS(OsPath filename)
+{
+	if(!CanIgnore(filename))
+	{
+		VfsPath pathname;
+		RETURN_STATUS_IF_ERR(g_VFS->GetVirtualPath(filename, pathname));
+		RETURN_STATUS_IF_ERR(g_VFS->RemoveFile(pathname));
+		RETURN_STATUS_IF_ERR(g_VFS->RepopulateDirectory(pathname.Parent()/""));
+		
+		// Tell each hotloadable system about this file change:
+		
+		for (size_t j = 0; j < g_ReloadFuncs.size(); ++j)
+			g_ReloadFuncs[j].first(g_ReloadFuncs[j].second, pathname);
+		
+		RETURN_STATUS_IF_ERR(h_reload(g_VFS, pathname));
+	}
+	return INFO::OK;
+}
+
 Status ReloadChangedFiles()
 {
 	PROFILE3("hotload");
@@ -74,24 +92,19 @@
 	RETURN_STATUS_IF_ERR(dir_watch_Poll(notifications));
 	for(size_t i = 0; i < notifications.size(); i++)
 	{
-		if(!CanIgnore(notifications[i]))
-		{
-			VfsPath pathname;
-			RETURN_STATUS_IF_ERR(g_VFS->GetVirtualPath(notifications[i].Pathname(), pathname));
-			RETURN_STATUS_IF_ERR(g_VFS->RemoveFile(pathname));
-			RETURN_STATUS_IF_ERR(g_VFS->RepopulateDirectory(pathname.Parent()/""));
-
-			// Tell each hotloadable system about this file change:
-
-			for (size_t j = 0; j < g_ReloadFuncs.size(); ++j)
-				g_ReloadFuncs[j].first(g_ReloadFuncs[j].second, pathname);
-
-			RETURN_STATUS_IF_ERR(h_reload(g_VFS, pathname));
-		}
+		Status result = UpdateVFS(notifications[i].Pathname());
+		if (result < 0)
+			return result;
 	}
 	return INFO::OK;
 }
 
+void ReloadChangedFilesFromAtlas(std::wstring filename)
+{
+	const OsPath& osPath(filename);
+	UpdateVFS(osPath);
+}
+
 std::wstring GetWstringFromWpath(const fs::wpath& path)
 {
 #if BOOST_FILESYSTEM_VERSION == 3
Index: source/ps/Filesystem.h
===================================================================
--- source/ps/Filesystem.h	(revision 16116)
+++ source/ps/Filesystem.h	(working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 Wildfire Games.
+/* Copyright (C) 2015 Wildfire Games.
  * This file is part of 0 A.D.
  *
  * 0 A.D. is free software: you can redistribute it and/or modify
@@ -54,6 +54,8 @@
  **/
 extern Status ReloadChangedFiles();
 
+extern void ReloadChangedFilesFromAtlas(std::wstring filename);
+
 /**
  * Helper function to handle API differences between Boost Filesystem v2 and v3
  */
Index: source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp
===================================================================
--- source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp	(revision 16116)
+++ source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp	(working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012 Wildfire Games.
+/* Copyright (C) 2015 Wildfire Games.
  * This file is part of 0 A.D.
  *
  * 0 A.D. is free software: you can redistribute it and/or modify
@@ -32,6 +32,7 @@
 #include "wx/config.h"
 #include "wx/debugrpt.h"
 #include "wx/file.h"
+#include <wx/log.h>
 
 // wx and libxml both want to define ATTRIBUTE_PRINTF (with similar
 // meanings), so undef it to avoid a warning
@@ -122,44 +123,6 @@
 	g_ConfigDir = config.GetPath(wxPATH_GET_SEPARATOR);
 }
 
-ATLASDLLIMPEXP void Atlas_StartWindow(const wchar_t* type)
-{
-	// Initialise libxml2
-	// (If we're executed from the game instead, it has the responsibility to initialise libxml2)
-	LIBXML_TEST_VERSION
-	
-	g_InitialWindowType = type;
-#ifdef __WXMSW__
-	wxEntry(g_Module);
-#else
-#ifdef __WXGTK__
-	// Because we do GL calls from a secondary thread, Xlib needs to
-	// be told to support multiple threads safely
-	int status = XInitThreads();
-	if (status == 0)
-	{
-		fprintf(stderr, "Error enabling thread-safety via XInitThreads\n");
-	}
-#endif
-	int argc = 1;
-	char atlas[] = "atlas";
-	char *argv[] = {atlas, NULL};
-#ifndef __WXOSX__
-	wxEntry(argc, argv);
-#else
-	// Fix for OS X init (see http://trac.wildfiregames.com/ticket/2427 )
-	// If we launched from in-game, SDL started NSApplication which will
-	// break some things in wxWidgets
-	wxEntryStart(argc, argv);
-	wxTheApp->OnInit();
-	wxTheApp->OnRun();
-	wxTheApp->OnExit();
-	wxEntryCleanup();
-#endif
-
-#endif
-}
-
 ATLASDLLIMPEXP void Atlas_DisplayError(const wchar_t* text, size_t WXUNUSED(flags))
 {
 	// This is called from the game thread.
@@ -186,7 +149,6 @@
 class AtlasDLLApp : public wxApp
 {
 public:
-
 #ifdef __WXOSX__
 	virtual bool OSXIsGUIApplication()
 	{
@@ -236,7 +198,10 @@
 			// dragging-and-dropping onto the program in Explorer.)
 			Datafile::SetSystemDirectory(argv[0]);
 		}
+		
+		//Disable log for file watcher
 
+		wxLog::SetLogLevel(wxLOG_FatalError);
 		// Display the appropriate window
 		wxFrame* frame;
 		if (g_InitialWindowType == _T("ActorEditor"))
@@ -246,6 +211,7 @@
 		else if (g_InitialWindowType == _T("ScenarioEditor"))
 		{
 			frame = new ScenarioEditor(NULL);
+			m_scenarioEditor = wxDynamicCast(frame, ScenarioEditor);
 		}
 		else
 		{
@@ -279,6 +245,15 @@
 		return true;
 	}
 
+	virtual void OnEventLoopEnter(wxEventLoopBase* WXUNUSED(loop))
+	{
+		if (m_scenarioEditor)
+		{
+			m_scenarioEditor->OnEventLoopEnter();
+			m_scenarioEditor = NULL;
+		}
+	}
+
 #if wxUSE_DEBUGREPORT && USE_WX_FATAL_EXCEPTION_REPORT
 	virtual void OnFatalException()
 	{
@@ -317,7 +292,7 @@
 */
 
 private:
-
+	ScenarioEditor* m_scenarioEditor;
 	bool OpenDirectory(const wxString& dir)
 	{
 		// Open a directory on the filesystem - used so people can find the
@@ -365,3 +340,38 @@
 };
 
 IMPLEMENT_APP_NO_MAIN(AtlasDLLApp);
+
+ATLASDLLIMPEXP void Atlas_StartWindow(const wchar_t* type)
+{
+    // Initialise libxml2
+    // (If we're executed from the game instead, it has the responsibility to initialise libxml2)
+    LIBXML_TEST_VERSION
+    
+    g_InitialWindowType = type;
+#ifdef __WXMSW__
+    wxEntry(g_Module);
+#else
+#ifdef __WXGTK__
+    // Because we do GL calls from a secondary thread, Xlib needs to
+    // be told to support multiple threads safely
+    int status = XInitThreads();
+    if (status == 0)
+    {
+        fprintf(stderr, "Error enabling thread-safety via XInitThreads\n");
+    }
+#endif
+    int argc = 1;
+    char atlas[] = "atlas";
+    char *argv[] = {atlas, NULL};
+#ifndef __WXOSX__
+    wxEntry(argc, argv);
+#else
+    // Fix for OS X init (see http://trac.wildfiregames.com/ticket/2427 )
+    // If we launched from in-game, SDL started NSApplication which will
+    // break some things in wxWidgets
+    wxApp::SetInstance(new AtlasDLLApp());
+    wxEntry(argc, argv);
+#endif
+
+#endif
+}
\ No newline at end of file
Index: source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp
===================================================================
--- source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp	(revision 16116)
+++ source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp	(working copy)
@@ -556,6 +556,34 @@
 	m_Timer.Start(20);
 }
 
+void ScenarioEditor::OnFileSystemEvent(wxFileSystemWatcherEvent &event)
+{
+	wxFileName file = event.GetPath();
+	if (!file.IsDir())
+	{
+		wxString filename = file.GetFullPath();
+		POST_MESSAGE(VFSUpdateFile, (filename.wc_str()));
+	}
+}
+
+ScenarioEditor::~ScenarioEditor()
+{
+	m_watcher->RemoveAll();
+	delete m_watcher;
+}
+
+void ScenarioEditor::OnEventLoopEnter()
+{
+	//start watcher
+	m_watcher = new wxFileSystemWatcher();
+	m_watcher->SetOwner(this);
+	Connect(wxEVT_FSWATCHER, wxFileSystemWatcherEventHandler(ScenarioEditor::OnFileSystemEvent));
+
+	wxString filename = Datafile::GetDataDirectory();
+	const wxFileName fn = wxFileName::DirName(filename);
+	m_watcher->AddTree(fn);
+}
+
 wxToolBar* ScenarioEditor::OnCreateToolBar(long style, wxWindowID id, const wxString& WXUNUSED(name))
 {
 	ToolButtonBar* toolbar = new ToolButtonBar(m_ToolManager, this, &m_SectionLayout, id, style);
Index: source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h
===================================================================
--- source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h	(revision 16116)
+++ source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h	(working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 Wildfire Games.
+/* Copyright (C) 2015 Wildfire Games.
  * This file is part of 0 A.D.
  *
  * 0 A.D. is free software: you can redistribute it and/or modify
@@ -19,6 +19,7 @@
 #define INCLUDED_SCENARIOEDITOR
 
 #include "wx/toolbar.h"
+#include <wx/fswatcher.h>
 
 #include "General/AtlasWindowCommandProc.h"
 #include "General/Observable.h"
@@ -31,6 +32,7 @@
 {
 public:
 	ScenarioEditor(wxWindow* parent);
+	~ScenarioEditor();
 	void OnClose(wxCloseEvent& event);
 	void OnTimer(wxTimerEvent& event);
 	void OnIdle(wxIdleEvent& event);
@@ -59,9 +61,12 @@
 	void OnDumpState(wxCommandEvent& event);
     void OnSelectedObjectsChange(const std::vector<AtlasMessage::ObjectID>& selectedObjects);
 
+	void OnFileSystemEvent(wxFileSystemWatcherEvent &event);
+
     void OnMenuOpen(wxMenuEvent& event);
 
 	bool OpenFile(const wxString& name, const wxString& filename);
+	void OnEventLoopEnter();
 
 	void NotifyOnMapReload();
 
@@ -93,6 +100,8 @@
 
 	wxIcon m_Icon;
 
+	wxFileSystemWatcher* m_watcher;   // file system watcher
+
 	DECLARE_EVENT_TABLE();
 };
 
Index: source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp
===================================================================
--- source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp	(revision 16116)
+++ source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp	(working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 Wildfire Games.
+/* Copyright (C) 2015 Wildfire Games.
  * This file is part of 0 A.D.
  *
  * 0 A.D. is free software: you can redistribute it and/or modify
@@ -36,6 +36,7 @@
 #include "renderer/Renderer.h"
 #include "simulation2/Simulation2.h"
 #include "simulation2/components/ICmpSoundManager.h"
+#include "ps/Filesystem.h"
 
 extern void (*Atlas_GLSwapBuffers)(void* context);
 
@@ -225,4 +226,9 @@
 	in_dispatch_event(&ev);
 }
 
+MESSAGEHANDLER(VFSUpdateFile)
+{
+	ReloadChangedFilesFromAtlas(*msg->filePath);
 }
+
+}
Index: source/tools/atlas/GameInterface/Messages.h
===================================================================
--- source/tools/atlas/GameInterface/Messages.h	(revision 16116)
+++ source/tools/atlas/GameInterface/Messages.h	(working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 Wildfire Games.
+/* Copyright (C) 2015 Wildfire Games.
  * This file is part of 0 A.D.
  *
  * 0 A.D. is free software: you can redistribute it and/or modify
@@ -200,6 +200,10 @@
 		((bool, exists))
 		);
 
+MESSAGE(VFSUpdateFile,
+		((std::wstring, filePath))
+		);
+
 //////////////////////////////////////////////////////////////////////////
 // Messages for player panel