diff --git a/Nomyx.cabal b/Nomyx.cabal
--- a/Nomyx.cabal
+++ b/Nomyx.cabal
@@ -1,5 +1,5 @@
 name: Nomyx
-version: 0.3.2
+version: 0.4.0
 cabal-version: >=1.6
 build-type: Simple
 license: BSD3
@@ -11,7 +11,7 @@
              Nomyx is a fabulous and strange game where you have the right to change the rules in the middle of the game!
              Indeed, changing the rules is the goal of the game. Changing a rule is considered as a move. Of course even that could be changed! The original (paper) game: www.nomic.net
 category: game
-Homepage: www.nomyx.net
+Homepage: http://www.nomyx.net
 author: Corentin Dupont
 data-files: static/css/nomyx.css 
             static/nomyx.js
@@ -20,63 +20,57 @@
 extra-source-files: AUTHORS README TODO
  
 executable Nomyx
-    build-depends: Nomyx-Language ==0.3.2,
-                   base <5,
-                   Cabal -any,
-                   DebugTraceHelpers -any,
-                   MissingH -any,
-                   MonadCatchIO-mtl -any,
-                   QuickCheck -any,
-                   Unixutils -any,
-                   binary -any,
-                   bytestring -any,
-                   containers -any,
-                   data-accessor-transformers -any,
-                   data-lens -any,
-                   data-lens-fd -any,
-                   data-lens-template -any,
-                   directory -any,
-                   eprocess -any,
-                   extensible-exceptions -any,
-                   fb -any,
-                   filepath -any,
-                   hdaemonize -any,
-                   hint -any,
-                   hint-server -any,
-                   hscolour -any,
-                   hslogger -any,
-                   ixset -any,
-                   lenses -any,
-                   mime-mail -any,
-                   monad-loops -any,
-                   mtl ==2.*,
-                   mueval -any,
-                   network -any,
-                   process -any,
-                   acid-state -any,
-                   happstack-authenticate -any,
-                   happstack-server ==7.*,
-                   blaze-html ==0.5.*,
-                   blaze-markup -any,
-                   reform -any,
-                   reform-blaze -any,
-                   reform-happstack -any,
-                   web-routes ==0.27.*,
-                   web-routes-happstack ==0.23.*,
-                   web-routes-regular ==0.19.*,
-                   web-routes-th -any,
-                   regular -any,
-                   safe -any,
-                   safecopy -any,
-                   split -any,
-                   stm -any,
-                   syb -any,
-                   template-haskell -any,
-                   text -any,
-                   time -any,
-                   unix -any,
-                   utf8-string -any,
-                   old-locale -any
+    build-depends: Nomyx-Language         == 0.4.0,
+                   DebugTraceHelpers      == 0.12.*,
+                   MissingH               == 1.2.*,
+                   MonadCatchIO-mtl       == 0.3.*,
+                   acid-state             == 0.10.*,
+                   base                   == 4.6.*,
+                   blaze-html             == 0.5.*,
+                   blaze-markup           == 0.5.*,
+                   bytestring             == 0.10.*,
+                   containers             == 0.5.*,
+                   data-lens              == 2.10.*,
+                   data-lens-template     == 2.1.*,
+                   data-lens-fd           == 2.0.*,
+                   directory              == 1.2.*,
+                   either-unwrap          == 1.1.*,
+                   fb                     == 0.14.*,
+                   filepath               == 1.3.*,
+                   happstack-authenticate == 0.10.*,
+                   happstack-server       == 7.1.*,
+                   hint                   == 0.3.*,
+                   hint-server            == 1.2.*,
+                   hscolour               == 1.20.*,
+                   ixset                  == 1.0.*,
+                   mime-mail              == 0.4.*,
+                   mtl                    == 2.1.*,
+                   network                == 2.4.*,
+                   old-locale             == 1.0.*,
+                   reform                 == 0.1.*,
+                   reform-blaze           == 0.1.*,
+                   reform-happstack       == 0.1.*,
+                   safe                   == 0.3.*,
+                   safecopy               == 0.8.*,
+                   split                  == 0.2.*,
+                   stm                    == 2.4.*,
+                   tar                    == 0.4.*,
+                   temporary              == 1.1.*,
+                   template-haskell       == 2.8.*,
+                   text                   == 0.11.*,
+                   time                   == 1.4.*,
+                   -- cross-platform file handling
+                   unix-compat            == 0.4.*,
+                   web-routes             == 0.27.*,
+                   web-routes-happstack   == 0.23.*,
+                   web-routes-regular     == 0.19.*,
+                   web-routes-th          == 0.22.*
+                  
+    if os(windows)
+        Cpp-options: -DWINDOWS
+    else
+        build-depends: unix == 2.6.*
+
     main-is: Main.hs
     buildable: True
     extensions: CPP
diff --git a/TODO b/TODO
--- a/TODO
+++ b/TODO
@@ -2,9 +2,12 @@
 TODO list
 
 Bugs:
-- command line arguments are ignored if there is a save file
 - recurring event are making increasing memory size
+- forbid void names
+- import qualified Data.Map and Control.Category (or hide conflicting functions)
+- display bugs on MacOS (tabs, vertical size)
 
+
 Improvements:
 - make code instructions in the active rules table clickable to access haddock documentation
 - option to read step by step the save file for analysis?
@@ -18,13 +21,26 @@
 - add examples with a game master, a castle..
 - fix facebook
 - vote: include new players, delete leaving players 
-- make settings file with start up rules
+- make settings file with start up rules (?)
 - make/fix deployement: 
    - the interpreter needs GHC to be installed: is that right?
    - the Web application needs to access files from the library (Nomyx-Language)
    - the interpreter needs the library to be installed to read the modules
-- rules should communicate by message passing instead of shared variables
-
+- rules should communicate by message passing instead of shared variable
+- HCI improvements: space player names, bold games
+- display viewer list
+- import qualified uploads (?)
+- 15 characters max for names
+- add a space before buttons (in HTML)
+- some files are accepted when uploaded but cause the game to crash when restarting. Check with GATDs for example. 
+- display vote infos (modalities, date etc.)
+- parameterize the mail sender
+- Short description field is too small
+- variable creation: use the definition (V...) ?
+- put a scroll on long IOs
+- put settings at session level, not multi level
+- a way to overwrite uploads (automatically or with admin intervention)
+- tag the save file with the version
 
 Futur Nomic:
 - ability to analyse rules, proof system
diff --git a/data/static/css/nomyx.css b/data/static/css/nomyx.css
--- a/data/static/css/nomyx.css
+++ b/data/static/css/nomyx.css
@@ -226,7 +226,7 @@
         pointer-events: none;
 }
 
-.view, .join {
+.modalButton {
         background: #606061;
         color: #FFFFFF;
         line-height: 25px;
@@ -272,4 +272,12 @@
 #modalCode {
     overflow: auto;
     height: 60%;
+}
+
+pre {
+    -moz-tab-size:    16;
+    -o-tab-size:      16;
+    -webkit-tab-size: 16;
+    -ms-tab-size:     16;
+    tab-size:         16;
 }
diff --git a/src/Interpret.hs b/src/Interpret.hs
--- a/src/Interpret.hs
+++ b/src/Interpret.hs
@@ -6,52 +6,56 @@
 import Language.Nomyx
 import System.Directory
 import System.FilePath
-import System.Posix.Files
-import System.Posix.Resource
 import Control.Exception as CE
+import Data.Either.Unwrap
+import Utils
+import Data.List
+import Control.Monad
 
-modDir = "modules"
 importList = ["Prelude",
               "Language.Nomyx",
+              "Language.Nomyx.Examples",
               "GHC.Base",
               "Data.Maybe",
               "Data.List",
               "Control.Monad.State",
               "Control.Applicative",
               "Control.Monad.Error",
-              "Data.Map",
+              --"Data.Map",
               "Safe",
               "Data.Typeable",
-              "Control.Category",
+              --"Control.Category",
               "Data.Lens",
               "Control.Arrow"]
               
 -- | the server handle
 startInterpreter :: FilePath -> IO ServerHandle
-startInterpreter dataDir = do
-   h <- start
-   liftIO $ createDirectoryIfMissing True $ dataDir </> modDir
-   ir <- runIn h $ initializeInterpreter dataDir
+startInterpreter saveDir = do
+   sh <- start
+   liftIO $ createDirectoryIfMissing True $ saveDir </> uploadDir
+   ir <- runIn sh $ initializeInterpreter saveDir
    case ir of
       Right r -> do
          putStrLn "Interpreter Loaded"
          return $ Just r
       Left e -> error $ "sHandle: initialization error:\n" ++ show e
-   return h
+   return sh
 
+-- get all uploaded modules from the directory (may be empty)
 getUploadModules :: FilePath -> IO([FilePath])
-getUploadModules dataDir = do
-    all <- getDirectoryContents $ dataDir </> modDir
-    files <- filterM (getFileStatus . (\f -> joinPath [dataDir, modDir, f]) >=> return . isRegularFile) all
-    return $ map (\f -> joinPath [dataDir, modDir, f]) files
-
+getUploadModules saveDir = do
+    files <- getUploadedModules saveDir
+    return $ map (\f -> joinPath [saveDir, uploadDir, f]) files
+
+   
 -- | initializes the interpreter by loading some modules.
 initializeInterpreter :: FilePath -> Interpreter ()
-initializeInterpreter dataDir = do
-   fmods <- liftIO $ getUploadModules dataDir
+initializeInterpreter saveDir = do
+   fmods <- liftIO $ getUploadModules saveDir
+   liftIO $ putStrLn $ "Loading modules: " ++ (concat $ intersperse ", " fmods)
    loadModules fmods
    setTopLevelModules $ map (dropExtension . takeFileName) fmods
-   set [searchPath := [dataDir], languageExtensions := [GADTs, ScopedTypeVariables]] --, installedModulesInScope := False
+   set [searchPath := [saveDir], languageExtensions := [GADTs, ScopedTypeVariables]] --, installedModulesInScope := False
    setImports importList
    return ()
 
@@ -67,41 +71,29 @@
       Right ruleFunc -> return ruleFunc
       Left e -> error $ show e
 
---liftIO $ mapM_ (uncurry setResourceLimit) limits      
-cpuTimeLimitSoft = ResourceLimit 4
-cpuTimeLimitHard = ResourceLimit 5
-
-
-limits :: [(Resource, ResourceLimits)]
-limits = [ (ResourceCPUTime,      ResourceLimits cpuTimeLimitSoft cpuTimeLimitHard)]
-         
-
 -- | check an uploaded file and reload
 loadModule :: FilePath -> FilePath -> ServerHandle -> FilePath -> IO (Either InterpreterError ())
-loadModule tempModName name sh dataDir = do
-    c <- checkModule tempModName sh dataDir
-    case c of
-        Right _ -> do
-            let dest = (dataDir </> modDir </> name)
-            copyFile tempModName dest
-            setFileMode dest (ownerModes + groupModes)
-            runIn sh $ initializeInterpreter dataDir
-            return $ Right ()
-        Left e -> do
-            runIn sh $ initializeInterpreter dataDir
-            return $ Left e
+loadModule tempModName name sh saveDir = do
+    --copy the new module in the upload directory
+    let dest = (saveDir </> uploadDir </> name)
+    copyFile tempModName dest
+    setMode dest
+    inter <- runIn sh $ initializeInterpreter saveDir
+    res <- case inter of
+       Right _ -> return $ Right ()
+       Left e -> do
+          --suppress the faulty module
+          removeFile dest
+          final <- runIn sh $ initializeInterpreter saveDir
+          when (isLeft final) $ putStrLn "Error: reinitialize interpreter failed"
+          return $ Left e
+    return res
 
----- | check if a module is valid. Context will be reset.
-checkModule :: FilePath -> ServerHandle -> FilePath -> IO (Either InterpreterError ())
-checkModule dir sh dataDir = runIn sh $ do
-   fmods <- liftIO $ getUploadModules dataDir
-   liftIO $ putStrLn $ concat $ fmods
-   loadModules (dir:fmods)
 
 showInterpreterError :: InterpreterError -> String
 showInterpreterError (UnknownError s)  = "Unknown Error\n" ++ s
 showInterpreterError (WontCompile ers) = "Won't Compile\n" ++ concatMap (\(GhcError errMsg) -> errMsg ++ "\n") ers
-showInterpreterError (NotAllowed s)    = "Not Allowed\n" ++ s
+showInterpreterError (NotAllowed s)    = "Not Allowed (Probable cause: bad module or file name)\n" ++ s
 showInterpreterError (GhcException s)  = "Ghc Exception\n" ++ s
 
 
diff --git a/src/Mail.hs b/src/Mail.hs
--- a/src/Mail.hs
+++ b/src/Mail.hs
@@ -12,7 +12,7 @@
 import Control.Monad
 import Types
 import Language.Nomyx
-import Language.Nomyx.Game
+import Language.Nomyx.Engine
 import Data.Text(Text, pack)
 import Control.Concurrent
 import Data.Maybe
@@ -23,6 +23,8 @@
 import Text.Blaze.Internal
 import Control.Category
 import Control.Applicative ((<$>))
+import Safe
+import Data.List
 default (Integer, Double, Data.Text.Text)
 
 
@@ -30,7 +32,7 @@
 sendMail to object htmlBody textBody = do
    putStrLn $ "sending a mail to " ++ to
    forkIO $ simpleMail (Address Nothing (pack to))
-                       (Address (Just "Nomyx Game") "Nomyx.Game@gmail.com")
+                       (Address (Just "Nomyx Game") "kau@nomyx.net")
                        (pack object)
                        (B.pack htmlBody)
                        (B.pack textBody)
@@ -67,7 +69,7 @@
 sendMailsNewRule :: Session -> SubmitRule -> PlayerNumber -> IO ()
 sendMailsNewRule s sr pn = when (_sendMails $ _mSettings $ _multi s) $ do
    putStrLn "Sending mails"
-   gn <- fromJust <$> getPlayersGame pn s
+   gn <- fromJustNote "sendMailsNewRule" <$> getPlayersGame pn s
    let sendMailsTo = delete pn (map _playerNumber (_players $ _game gn))
    proposer <- Utils.getPlayerName pn s
    profiles <- mapM (getProfile s) sendMailsTo
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -22,39 +22,31 @@
 import Control.Concurrent
 import Interpret
 import Control.Concurrent.STM
-import qualified System.Posix.Signals as S
-import Control.Monad.CatchIO hiding (catch)
-import Control.Monad.Trans
-import Language.Nomyx.Test as LT
+import Control.Monad.CatchIO (bracket)
+import Language.Nomyx.Engine.Test as LT
 import Data.Maybe
 import Safe
 import Network.BSD
-import System.Posix.Daemonize
 import Types
 import Serialize
 import Paths_Nomyx as PN
 import Paths_Nomyx_Language as PNL
-import System.Directory
+import System.Directory (removeDirectoryRecursive, canonicalizePath, removeFile, doesFileExist)
 import Data.Time.Clock
-import Language.Nomyx hiding (getCurrentTime)
+import Language.Nomyx.Engine
 import Control.Exception as E hiding (bracket)
 import Test
 import Utils
 import Data.Version (showVersion)
-import Control.Category
 import Multi
 import Language.Haskell.Interpreter.Server hiding (start)
 import Data.Acid (openLocalStateFrom)
-import System.FilePath
+import System.FilePath ((</>))
 import Happstack.Auth.Core.Auth (initialAuthState)
 import Data.Acid.Local (createCheckpointAndClose)
 import Happstack.Auth.Core.Profile (initialProfileState)
-import System.Unix.Directory
+import Control.Monad.State
 
-defaultLogFile, profilesDir, modulesDir :: FilePath
-defaultLogFile = "Nomyx.save"
-profilesDir = "profiles"
-modulesDir = "modules"
 
 -- | Entry point of the program.
 main :: IO Bool
@@ -70,39 +62,45 @@
    else do
       putStrLn "Welcome to Nomyx!"
       putStrLn "Type \"Nomyx --help\" for usage options"  
-      case (Daemon `elem` flags) of
-         True -> (daemonize $ start flags) >> return True
-         False -> start flags >> return True
+      start flags
+      return True
 
 start :: [Flag] -> IO ()
 start flags = do
-   serverCommandUsage
    defDataDir <- PN.getDataDir
    defSourceDir <- PNL.getDataDir
    hostName <- getHostName
-   logFilePath <- case (findSaveFile flags) of
-      Just f -> canonicalizePath f
-      Nothing -> PN.getDataFileName defaultLogFile
    let port = read $ fromMaybe "8000" (findPort flags)
    let host = fromMaybe hostName (findHost flags)
    let adminPass = fromMaybe "NXPSD" (findAdminPass flags)
    let sendMail = Mails `elem` flags
+   -- save directory: Nomyx.save and uploaded files
+   saveDir <- case (findTarFile flags) of
+      Just tarFile -> untar tarFile
+      Nothing -> case (findSaveDir flags) of
+         Just f -> canonicalizePath f
+         Nothing -> PN.getDataDir
+   -- data directory: web ressources and profiles
    let dataDir = fromMaybe defDataDir (findDataDir flags)
+   -- source directory: Nomyx-Language files (used only for display in GUI, since this library is statically linked otherwise)
    let sourceDir = fromMaybe defSourceDir (findSourceDir flags)
-   let settings = Settings logFilePath (Network host port) sendMail adminPass dataDir sourceDir
-   --start the haskell interpreter
-   sh <- protectHandlers $ startInterpreter dataDir
+   let settings = Settings (Network host port) sendMail adminPass saveDir dataDir sourceDir
    if Test `elem` flags then do
+      sh <- protectHandlers $ startInterpreter saveDir
       putStrLn $ "\nNomyx Language Tests results:\n" ++ (concatMap (\(a,b) -> a ++ ": " ++ (show b) ++ "\n") LT.tests)
       ts <- playTests sh
       putStrLn $ "\nNomyx Game Tests results:\n" ++ (concatMap (\(a,b) -> a ++ ": " ++ (show b) ++ "\n") ts)
       putStrLn $ "All Tests Pass: " ++ (show $ allTests && (all snd ts))
    else if (DeleteSaveFile `elem` flags) then do
       putStrLn "Deleting save files"
-      (removeRecursiveSafely $ dataDir </> profilesDir)        `catch` (\(e::SomeException)-> putStrLn $ show e)
-      (removeRecursiveSafely $ dataDir </> modulesDir </> "*") `catch` (\(e::SomeException)-> putStrLn $ show e)
-      (removeFile (_logFilePath settings))                     `catch` (\(e::SomeException)-> putStrLn $ show e)
+      let catchExp io = io `catch` (\(e::SomeException)-> putStrLn $ show e)
+      catchExp $ removeDirectoryRecursive $ dataDir </> profilesDir
+      catchExp $ removeDirectoryRecursive $ saveDir </> uploadDir
+      catchExp $ removeFile               $ saveDir </> saveFile
    else do
+      serverCommandUsage
+      --start the haskell interpreter
+      sh <- protectHandlers $ startInterpreter saveDir
       --creating game structures
       multi <- case (findLoadTest flags) of
          Just testName -> loadTestName settings testName sh
@@ -117,13 +115,15 @@
 
 loadMulti :: Settings -> ServerHandle -> IO Multi
 loadMulti set sh = do
-   fileExists <- doesFileExist $ _logFilePath $ set
+   fileExists <- doesFileExist $ getSaveFile set
    multi <- case fileExists of
       True -> do
-         putStrLn $ "Loading game: " ++ (_logFilePath $ set)
+         putStrLn $ "Loading game: " ++ (getSaveFile set)
          Serialize.loadMulti set sh `E.catch`
             (\e -> (putStrLn $ "Error while loading logged events, log file discarded\n" ++ (show (e::ErrorCall))) >> (return $ defaultMulti set))
-      False -> return $ defaultMulti set
+      False -> do
+         let defMulti = defaultMulti set
+         execStateT (newGame' "Default game" (GameDesc "This is the default game." "") 0 sh) defMulti
    return multi
 
 
@@ -152,15 +152,15 @@
           | Test
           | HostName String
           | Port String
-          | LogFile FilePath
-          | Daemon
           | LoadTest String
           | DeleteSaveFile
           | AdminPass String
           | Mails
           | Help
+          | SaveDir FilePath
           | DataDir FilePath
-          | SourceDir FilePath
+          | SourceDir FilePath
+          | TarFile FilePath
        deriving (Show, Eq)
 
 -- | launch options description
@@ -171,15 +171,15 @@
      , Option ['t'] ["tests"]     (NoArg Test)                   "perform routine check"
      , Option ['h'] ["host"]      (ReqArg HostName "Hostname")   "specify host name"
      , Option ['p'] ["port"]      (ReqArg Port "Port")           "specify port"
-     , Option ['r'] ["read"]      (ReqArg LogFile "SaveFile")    "specify save file (default is Nomyx.save)"
      , Option ['n'] ["delete"]    (NoArg DeleteSaveFile)         "delete all save files"
-     , Option ['d'] ["daemon"]    (NoArg Daemon)                 "run in daemon mode"
      , Option ['l'] ["loadtest"]  (ReqArg LoadTest "TestName")   "specify name of test to load"
-     , Option ['a'] ["adminPass"] (ReqArg AdminPass "AdminPass") "specify the admin password"
+     , Option ['a'] ["adminPass"] (ReqArg AdminPass "AdminPass") "specify the admin password (default is NXPSD)"
      , Option ['m'] ["mails"]     (NoArg Mails)                  "send mails (default is no)"
      , Option ['?'] ["help"]      (NoArg Help)                   "display usage options (this screen)"
-     , Option ['f'] ["dataDir"]   (ReqArg DataDir "DataDir")     "set data directory"
-     , Option ['s'] ["sourceDir"] (ReqArg SourceDir "SourceDir") "set source directory"
+     , Option ['r'] ["saveDir"]   (ReqArg SaveDir "SaveDir")     "specify save directory (for Nomyx.save and uploads)"
+     , Option ['f'] ["dataDir"]   (ReqArg DataDir "DataDir")     "specify data directory (for profiles and website files)"
+     , Option ['s'] ["sourceDir"] (ReqArg SourceDir "SourceDir") "specify source directory (for Nomyx-Language files)"
+     , Option ['T'] ["tar"]       (ReqArg TarFile "TarFile")     "specify tar file (containing Nomyx.save and uploads)"
      ]
     
 nomyxOpts :: [String] -> IO ([Flag], [String])
@@ -206,10 +206,10 @@
     isLoadTest (LoadTest a) = Just a
     isLoadTest _ = Nothing
 
-findSaveFile :: [Flag] -> Maybe FilePath
-findSaveFile fs = headMay $ catMaybes $ map isSaveFile fs where
-    isSaveFile (LogFile a) = Just a
-    isSaveFile _ = Nothing
+findSaveDir :: [Flag] -> Maybe FilePath
+findSaveDir fs = headMay $ catMaybes $ map isSaveDir fs where
+    isSaveDir (SaveDir a) = Just a
+    isSaveDir _ = Nothing
 
 findAdminPass :: [Flag] -> Maybe String
 findAdminPass fs = headMay $ catMaybes $ map isAdminPass fs where
@@ -226,32 +226,18 @@
     isSourceDir (SourceDir a) = Just a
     isSourceDir _ = Nothing
 
-helper :: MonadCatchIO m => S.Handler -> S.Signal -> m S.Handler
-helper handler signal = liftIO $ S.installHandler signal handler Nothing
-
-signals :: [S.Signal]
-signals = [ S.sigQUIT
-          , S.sigINT
-          , S.sigHUP
-          , S.sigTERM
-          ]
-
-saveHandlers :: MonadCatchIO m => m [S.Handler]
-saveHandlers = liftIO $ mapM (helper S.Ignore) signals
-
-restoreHandlers :: MonadCatchIO m => [S.Handler] -> m [S.Handler]
-restoreHandlers h  = liftIO . sequence $ zipWith helper h signals
+findTarFile :: [Flag] -> Maybe String
+findTarFile fs = headMay $ catMaybes $ map isTarFile fs where
+    isTarFile (TarFile a) = Just a
+    isTarFile _ = Nothing
 
 
-protectHandlers :: MonadCatchIO m => m a -> m a
-protectHandlers a = bracket saveHandlers restoreHandlers $ const a
-
 triggerTimeEvent :: TVar Session -> UTCTime -> IO()
 triggerTimeEvent tm t = do
     (Session sh m a) <- atomically $ readTVar tm
     m' <- execWithMulti t (Multi.triggerTimeEvent t) m
     atomically $ writeTVar tm (Session sh m' a)
-    save (_mSettings >>>_logFilePath $ m') m'
+    save m'
 
 
 launchTimeEvents :: TVar Session -> IO()
@@ -275,3 +261,4 @@
     bracket (openLocalStateFrom (basePath </> "profile")     initialProfileState)     (createCheckpointAndClose) $ \profile ->
     bracket (openLocalStateFrom (basePath </> "profileData") initialProfileDataState) (createCheckpointAndClose) $ \profileData ->
         f (Profiles auth profile profileData)
+
diff --git a/src/Multi.hs b/src/Multi.hs
--- a/src/Multi.hs
+++ b/src/Multi.hs
@@ -19,7 +19,7 @@
 import Debug.Trace.Helpers
 import Data.Lens
 import Language.Nomyx
-import Language.Nomyx.Game as G
+import Language.Nomyx.Engine as G
 import Control.Category hiding ((.))
 import qualified Data.Acid.Advanced as A (update', query')
 import Quotes (cr)
@@ -35,7 +35,10 @@
 newGame :: GameName -> GameDesc -> PlayerNumber -> StateT Session IO ()
 newGame name desc pn = do
    sh <- access sh
-   focus multi $ do
+   focus multi $ newGame' name desc pn sh
+
+newGame' :: GameName -> GameDesc -> PlayerNumber -> ServerHandle -> StateT Multi IO ()
+newGame' name desc pn sh = do
       gs <- access games
       case null $ filter ((== name) . getL (game >>> gameName)) gs of
          True -> do
@@ -63,7 +66,7 @@
 joinGame game pn = do
    s <- get
    name <- lift $ Utils.getPlayerName pn s
-   inGameDo game $ G.update $ JoinGame pn name
+   inGameDo game $ G.execGameEvent $ JoinGame pn name
    viewGamePlayer game pn
 
 -- | del a game.delGame :: GameName -> StateT Session IO ()
@@ -72,7 +75,7 @@
 
 -- | leave a game.
 leaveGame :: GameName -> PlayerNumber -> StateT Session IO ()
-leaveGame game pn = inGameDo game $ G.update $ LeaveGame pn
+leaveGame game pn = inGameDo game $ G.execGameEvent $ LeaveGame pn
 
 -- | insert a rule in pending rules.
 submitRule :: SubmitRule -> PlayerNumber -> GameName -> ServerHandle -> StateT Session IO ()
@@ -82,11 +85,11 @@
    case mrr of
       Right _ -> do
          tracePN pn $ "proposed rule compiled OK "
-         inGameDo gn $ G.update' (Just $ getRuleFunc sh) (ProposeRuleEv pn sr)
+         inGameDo gn $ G.execGameEvent' (Just $ getRuleFunc sh) (ProposeRuleEv pn sr)
          modifyProfile pn (pLastRule ^= Nothing)
       Left e -> do
          let errorMsg = showInterpreterError e
-         inGameDo gn $ update $ GLog (Just pn) ("Error in submitted rule: " ++ errorMsg)
+         inGameDo gn $ execGameEvent $ GLog (Just pn) ("Error in submitted rule: " ++ errorMsg)
          tracePN pn ("Error in submitted rule: " ++ errorMsg)
          modifyProfile pn (pLastRule ^= Just (sr, errorMsg)) -- keep in memory the last rule proposed by the player to display it in case of error
 
@@ -97,32 +100,32 @@
    case mrr of
       Right _ -> do
          tracePN pn $ "proposed rule compiled OK "
-         inGameDo gn $ update' (Just $ getRuleFunc sh) (SystemAddRule sr)
+         inGameDo gn $ execGameEvent' (Just $ getRuleFunc sh) (SystemAddRule sr)
          modifyProfile pn (pLastRule ^= Nothing)
       Left e -> do
          let errorMsg = showInterpreterError e
-         inGameDo gn $ update $ GLog (Just pn) ("Error in submitted rule: " ++ errorMsg)
+         inGameDo gn $ execGameEvent $ GLog (Just pn) ("Error in submitted rule: " ++ errorMsg)
          tracePN pn ("Error in submitted rule: " ++ errorMsg)
          modifyProfile pn (pLastRule ^= Just (sr, errorMsg))
 
 
 inputResult :: PlayerNumber -> EventNumber -> UInputData -> GameName -> StateT Session IO ()
-inputResult pn en ir gn = inGameDo gn $ update $ InputResult pn en ir
+inputResult pn en ir gn = inGameDo gn $ execGameEvent $ InputResult pn en ir
 
 -- | upload a rule file
 inputUpload :: PlayerNumber -> FilePath -> String -> ServerHandle -> StateT Session IO ()
 inputUpload pn temp mod sh = do
-   dataDir <- access (multi >>> mSettings >>> dataDir)
-   m <- liftIO $ loadModule temp mod sh dataDir
+   saveDir <- access (multi >>> mSettings >>> saveDir)
+   m <- liftIO $ loadModule temp mod sh saveDir
    tracePN pn $ " uploaded " ++ (show mod)
    case m of
       Right _ -> do
-         inPlayersGameDo pn $ update $ GLog (Just pn) ("File loaded: " ++ show temp ++ ", as " ++ show mod ++"\n")
+         inPlayersGameDo pn $ execGameEvent $ GLog (Just pn) ("File loaded: " ++ show temp ++ ", as " ++ show mod ++"\n")
          tracePN pn "upload success"
          modifyProfile pn (pLastUpload ^= UploadSuccess)
       Left e -> do
          let errorMsg = showInterpreterError e
-         inPlayersGameDo pn $ update $ GLog (Just pn) ("Error in file: " ++ show e ++ "\n")
+         inPlayersGameDo pn $ execGameEvent $ GLog (Just pn) ("Error in file: " ++ show e ++ "\n")
          tracePN pn "upload failed"
          modifyProfile pn (pLastUpload ^= UploadFailure (temp, errorMsg))
 
@@ -191,7 +194,7 @@
 
 trig :: UTCTime -> LoggedGame -> IO LoggedGame
 trig t g =  do
-   g' <- execWithGame' t (update $ TimeEvent t) g
+   g' <- execWithGame' t (execGameEvent $ TimeEvent t) g
    evaluate g'
 
 -- | get all events that has not been triggered yet
@@ -216,7 +219,7 @@
 
 initialGame :: ServerHandle -> StateT LoggedGame IO ()
 initialGame sh = mapM_ addR [rVoteUnanimity, rVictory5Rules]
-   where addR r = update' (Just $ getRuleFunc sh) (SystemAddRule r)
+   where addR r = execGameEvent' (Just $ getRuleFunc sh) (SystemAddRule r)
 
 initialLoggedGame :: GameName -> GameDesc -> UTCTime -> ServerHandle -> IO LoggedGame
 initialLoggedGame name desc date sh = do
diff --git a/src/Quotes.hs b/src/Quotes.hs
--- a/src/Quotes.hs
+++ b/src/Quotes.hs
@@ -40,46 +40,3 @@
 
 
 
-
---cr2 :: QuasiQuoter
---cr2 = QuasiQuoter { quoteExp  = quoteRuleFunc2,
---                   quotePat  = undefined,
---                   quoteType = undefined,
---                   quoteDec  = undefined}
---
---quoteRuleFunc2 :: String -> Q TH.Exp
---quoteRuleFunc2 s = do
---   res <- runIO $ runInterpreter $ do
---      setImports importList
---      interpret s (as::RuleFunc)
---   case res of
---      Right f -> [| (s,f) |]
---      Left e -> fail $ show e
-
-
-      --do --[| putParens s |]
---   s_0 <- newName "s"
---   return $ LamE [VarP s_0] (InfixE (Just (LitE (StringL "(")))
---                                    (VarE GHC.Base.++)
---                                    (Just (InfixE (Just (VarE s_0))
---
---
---putParens :: String -> String
---putParens s =  "(" ++ s ++ ",\"" ++ s ++ "\")"
---
---putParens' :: Q TH.Exp -> Q TH.Exp
---putParens' (LitE (StringL s)) = (LitE (StringL s))
-
---t :: (Int, String)
---t = $( [| 1 |] )
---RuleName -> RuleFunc -> RuleCode -> RuleNumber -> String -> Nomex ()
-
----- $( quoteRuleFunc2 "voidRule $ return ()")
---putParens :: String -> IO (String, RuleFunc)
---putParens s = do
---   res <- runIO $ runInterpreter $ do
---      setImports importList
---      interpret s (as::RuleFunc)
---   case res of
---      Right f -> return (s, f)
---      Left  e -> fail $ show e
diff --git a/src/Serialize.hs b/src/Serialize.hs
--- a/src/Serialize.hs
+++ b/src/Serialize.hs
@@ -3,36 +3,34 @@
 
 module Serialize where
 
-import Prelude hiding (log, (.))
+import Prelude hiding (log)
 import Language.Nomyx hiding (getCurrentTime)
-import Language.Nomyx.Game
+import Language.Nomyx.Engine
 import Control.Monad.State
 import Types
-import Control.Category
 import Data.Lens
 import Language.Haskell.Interpreter.Server
 import Interpret
+import Utils
 
-save :: FilePath -> Multi -> IO()
-save fp m = writeFile fp (show m)
+save :: Multi -> IO ()
+save m = writeFile (getSaveFile $ _mSettings m) (show m)
 
 save' :: StateT Multi IO ()
-save' = do
-   lfp <- access (mSettings >>> logFilePath)
-   m <- get
-   lift $ save lfp m
+save' = get >>= lift . save
 
-load :: FilePath -> IO(Multi)
+load :: FilePath -> IO Multi
 load fp = do
    s <- readFile fp
    return $ read s
 
 loadMulti :: Settings -> ServerHandle -> IO Multi
 loadMulti set sh = do
-   m <- load $ _logFilePath set
+   m <- load (getSaveFile set)
    gs' <- mapM (updateLoggedGame $ getRuleFunc sh) $ _games m
    let m' = games `setL` gs' $ m
-   return m'
+   let m'' = mSettings `setL` set $ m'
+   return m''
 
 updateLoggedGame :: (RuleCode -> IO RuleFunc) -> LoggedGame -> IO LoggedGame
 updateLoggedGame f (LoggedGame g log) = getLoggedGame g f log
diff --git a/src/Test.hs b/src/Test.hs
--- a/src/Test.hs
+++ b/src/Test.hs
@@ -22,6 +22,7 @@
 import Multi
 import Language.Haskell.Interpreter.Server (ServerHandle)
 import Language.Nomyx hiding (getCurrentTime)
+import Language.Nomyx.Engine
 import Control.Applicative
 import Control.Exception as E
 import Language.Haskell.TH
@@ -29,11 +30,12 @@
 import System.IO.Unsafe
 import Quotes
 import Data.Lens
+import Data.List
 import Safe
 import Data.Acid.Memory
 import Happstack.Auth.Core.Auth (initialAuthState)
 import Happstack.Auth.Core.Profile (initialProfileState)
-import qualified Language.Nomyx.Game as G
+import qualified Language.Nomyx.Engine as G
 import Control.Arrow ((>>>))
 import Data.Time hiding (getCurrentTime)
 
@@ -60,7 +62,7 @@
 test :: ServerHandle -> StateT Session IO () -> (Multi -> Bool) -> IO Bool
 test sh tes cond = do
    tp <- testProfiles
-   let s = Session sh (defaultMulti (Settings "" defaultNetwork False "" "" "")) tp
+   let s = Session sh (defaultMulti (Settings defaultNetwork False "" "" "" "")) tp
    m' <- loadTest tes s
    (evaluate $ cond m') `E.catch` (\(e::SomeException) -> (putStrLn $ "Exception in test: " ++ show e) >> return False)
 
@@ -139,7 +141,7 @@
 condHelloWorld2Players m = isOutput "hello, world!" m
 
 partialFunction1 :: String
-partialFunction1 = [cr|voidRule $ readVar_ (V "toto1" :: V String)|]
+partialFunction1 = [cr|voidRule $ readMsgVar_ (msgVar "toto1" :: MsgVar String)|]
 
 gamePartialFunction1 :: StateT Session IO ()
 gamePartialFunction1 = submitR partialFunction1
@@ -152,7 +154,7 @@
 partialFunction2 :: String
 partialFunction2 = [cr|voidRule $ do
    t <- getCurrentTime
-   onEventOnce_ (Time $ addUTCTime 5 t) $ const $ readVar_ (V "toto2")|]
+   onEventOnce_ (Time $ addUTCTime 5 t) $ const $ readMsgVar_ (msgVar "toto2")|]
 
 gamePartialFunction2 :: StateT Session IO ()
 gamePartialFunction2 = do
@@ -168,7 +170,7 @@
                          (take 5 $ _lMsg $ headNote "cond3 failed" $ _logs $ G._game $ headNote "cond4 failed" $ _games m) == "Error"
 
 partialFunction3 :: String
-partialFunction3 = [cr|voidRule $ onEvent_ (RuleEv Proposed) $ const $ readVar_ (V "toto3")|]
+partialFunction3 = [cr|voidRule $ onEvent_ (RuleEv Proposed) $ const $ readMsgVar_ (msgVar "toto3")|]
 
 gamePartialFunction3 :: StateT Session IO ()
 gamePartialFunction3 = do
diff --git a/src/Types.hs b/src/Types.hs
--- a/src/Types.hs
+++ b/src/Types.hs
@@ -3,11 +3,11 @@
 
 module Types where
 import Language.Nomyx
+import Language.Nomyx.Engine
 import Data.Typeable
 import Text.Reform.Happstack()
 import Network.BSD
 import Data.Lens.Template
-import Language.Nomyx.Game
 import Language.Haskell.Interpreter.Server (ServerHandle)
 import Data.Acid (makeAcidic, Update, Query, AcidState)
 import Happstack.Auth (ProfileState, AuthState)
@@ -23,6 +23,8 @@
 type Port = Int
 type CompileError = String
 type LastRule = (SubmitRule, CompileError)
+
+
 data LastUpload = NoUpload
                 | UploadSuccess
                 | UploadFailure (FilePath, CompileError)
@@ -44,12 +46,12 @@
 $(deriveSafeCopy 1 'base ''PlayerSettings)
 
 
-data Settings = Settings { _logFilePath :: FilePath,
-                           _net :: Network,
-                           _sendMails :: Bool,
-                           _adminPassword :: String,
-                           _dataDir :: FilePath,
-                           _sourceDir :: FilePath}
+data Settings = Settings { _net           :: Network,  -- URL where the server is launched
+                           _sendMails     :: Bool,     -- send mails or not
+                           _adminPassword :: String,   -- admin password
+                           _saveDir       :: FilePath, -- location of the save file and uploaded files
+                           _dataDir       :: FilePath, -- location of the static files (profiles + website)
+                           _sourceDir     :: FilePath} -- location of the language files (from Nomyx-Language)
                            deriving (Eq, Show, Read, Typeable)
 
 --- | A structure to hold the active games and players
diff --git a/src/Utils.hs b/src/Utils.hs
--- a/src/Utils.hs
+++ b/src/Utils.hs
@@ -13,20 +13,36 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE NamedFieldPuns #-}
-    
+{-# OPTIONS -cpp #-}
 module Utils where
 
 import Data.Maybe
-import Data.Char
 import Control.Monad.State
 import Types
 import Language.Nomyx
-import Language.Nomyx.Game
+import Language.Nomyx.Engine
 import Data.Lens
-import Control.Category hiding ((.))
+import Control.Category hiding ((.), id)
 import Safe
 import Control.Concurrent.STM
 import qualified Data.Acid.Advanced as A (query', update')
+import System.IO.Temp
+import Codec.Archive.Tar as Tar
+import System.Directory
+import System.FilePath
+import Control.Monad.CatchIO
+import Data.Time
+import Data.List
+import System.PosixCompat.Files (getFileStatus, isRegularFile, setFileMode, ownerModes, groupModes)
+#ifndef WINDOWS
+import qualified System.Posix.Signals as S
+#endif
+
+saveFile, profilesDir, uploadDir, tarFile :: FilePath
+saveFile    = "Nomyx.save"
+profilesDir = "profiles"
+uploadDir   = "uploads"
+tarFile     = "Nomyx.tar"
    
 -- | this function will return just a if it can cast it to an a.
 maybeRead :: Read a => String -> Maybe a
@@ -38,10 +54,6 @@
         -> [a] -- ^ Input list
         -> [a] -- ^ Output list
 replace x y = map (\z -> if z == x then y else z)
-
-yes = ["o", "oui", "y", "yes", "v", "vrai", "true"]
-toLowerS = map toLower
-isYes a = toLowerS a `elem` yes
 
 -- | generic function to say things on transformers like GameState, ServerState etc.
 say :: String -> StateT a IO ()
@@ -108,3 +120,57 @@
    s <- liftIO $ atomically $ readTVar ts
    getProfile s pn
 
+getSaveFile :: Settings -> FilePath
+getSaveFile set = (_saveDir set) </> saveFile
+
+makeTar :: FilePath -> IO ()
+makeTar saveDir = do
+   putStrLn $ "creating tar in " ++ (show saveDir)
+   Tar.create (saveDir </> tarFile) saveDir [saveFile, uploadDir]
+
+untar :: FilePath -> IO (FilePath)
+untar fp = do
+   dir <- createTempDirectory "/tmp" "Nomyx"
+   extract dir fp
+   return dir
+
+getUploadedModules :: FilePath -> IO [FilePath]
+getUploadedModules saveDir = do
+   mods <- getDirectoryContents $ saveDir </> uploadDir
+   getRegularFiles (saveDir </> uploadDir) mods
+
+getRegularFiles :: FilePath -> [FilePath] -> IO [FilePath]
+getRegularFiles dir fps = filterM (getFileStatus . (\f -> dir </> f) >=> return . isRegularFile) $ fps
+
+setMode :: FilePath -> IO()
+setMode file = setFileMode file (ownerModes + groupModes)
+
+#ifdef WINDOWS
+
+--no signals under windows
+protectHandlers :: MonadCatchIO m => m a -> m a
+protectHandlers = id
+
+#else
+
+helper :: MonadCatchIO m => S.Handler -> S.Signal -> m S.Handler
+helper handler signal = liftIO $ S.installHandler signal handler Nothing
+
+signals :: [S.Signal]
+signals = [ S.sigQUIT
+          , S.sigINT
+          , S.sigHUP
+          , S.sigTERM
+          ]
+
+saveHandlers :: MonadCatchIO m => m [S.Handler]
+saveHandlers = liftIO $ mapM (helper S.Ignore) signals
+
+restoreHandlers :: MonadCatchIO m => [S.Handler] -> m [S.Handler]
+restoreHandlers h  = liftIO . sequence $ zipWith helper h signals
+
+
+protectHandlers :: MonadCatchIO m => m a -> m a
+protectHandlers a = bracket saveHandlers restoreHandlers $ const a
+
+#endif
diff --git a/src/Web/Common.hs b/src/Web/Common.hs
--- a/src/Web/Common.hs
+++ b/src/Web/Common.hs
@@ -15,6 +15,7 @@
 import Control.Monad.State
 import Control.Concurrent.STM
 import Language.Nomyx
+import Language.Nomyx.Engine
 import Happstack.Server as HS
 import Types as T
 import qualified Data.ByteString.Char8 as C
@@ -100,9 +101,6 @@
              [(n,[])] -> Just n
              _ ->        Nothing
 
-modDir :: FilePath
-modDir = "modules"
-
 evalCommand :: (TVar Session) -> StateT Session IO a -> RoutedNomyxServer a
 evalCommand ts sm = liftIO $ do
    s <- atomically $ readTVar ts
@@ -113,7 +111,7 @@
    s <- atomically $ readTVar ts
    s' <- execStateT sm s
    atomically $ writeTVar ts s'
-   save (_logFilePath $ _mSettings $ _multi $ s') (_multi s') --TODO not really nice to put that here
+   save (_multi s') --TODO not really nice to put that here
 
 
 webCommand' :: (TVar Session) -> StateT Session IO () -> RoutedNomyxServer ()
@@ -121,7 +119,7 @@
    s <- atomically $ readTVar ts
    s' <- execStateT sm s
    atomically $ writeTVar ts s'
-   save (_logFilePath $ _mSettings $ _multi $ s') (_multi s') --TODO not really nice to put that here
+   save (_multi s') --TODO not really nice to put that here
 
 
 protectedExecCommand :: (TVar Session) -> StateT Session IO a -> IO ()
diff --git a/src/Web/Game.hs b/src/Web/Game.hs
--- a/src/Web/Game.hs
+++ b/src/Web/Game.hs
@@ -14,7 +14,7 @@
 import Data.Monoid
 import Control.Concurrent.STM
 import Language.Nomyx
-import Language.Nomyx.Game
+import Language.Nomyx.Engine
 import Data.Maybe
 import Text.Reform.Happstack
 import Text.Reform
@@ -29,6 +29,7 @@
 import Mail
 import Text.Printf
 import Data.String
+import Data.List
 import Data.Text(Text)
 import qualified Text.Reform.Blaze.Common as RBC
 import qualified Language.Haskell.HsColour.HTML as HSC
@@ -40,6 +41,7 @@
 import System.Locale
 import Data.Lens
 import Control.Category hiding ((.))
+import Safe
 default (Integer, Double, Data.Text.Text)
 
 viewGame :: Game -> PlayerNumber -> (Maybe LastRule) -> Bool -> RoutedNomyxServer Html
@@ -57,8 +59,10 @@
 viewGameDesc :: Game -> PlayerNumber -> Html
 viewGameDesc g pn = do
    p $ h3 $ string $ "Viewing game: " ++ _gameName g
-   p $ h4 $ "Description:" >> br >> string (_desc $ _gameDesc g)
-   p $ h4 $ a "Agora" ! (A.href $ toValue (_agora $ _gameDesc g))
+   p $ do
+      h4 $ "Description:"
+      string (_desc $ _gameDesc g)
+   p $ h4 $ "This game is discussed in the " >> a "Agora" ! (A.href $ toValue (_agora $ _gameDesc g)) >> "."
    p $ h4 $ "Players in game:"
    viewPlayers (_players g) pn
    p $ viewVictory g
@@ -106,7 +110,7 @@
 
 viewRule :: Game -> Rule -> Html
 viewRule g nr = tr $ do
-   let pl = fromMaybe (show $ _rProposedBy nr) (_playerName <$> (Utils.getPlayer g $ _rProposedBy nr))
+   let pl = fromMaybe ("Player " ++ (show $ _rProposedBy nr)) (_playerName <$> (Utils.getPlayer g $ _rProposedBy nr))
    td ! A.class_ "td" $ string . show $ _rNumber nr
    td ! A.class_ "td" $ string $ _rName nr
    td ! A.class_ "td" $ string $ _rDescription nr
@@ -129,9 +133,6 @@
             a ! A.href "#close" ! A.title "Close" ! A.class_ "close" $ "X"
             div ! A.id "modalCode"$ code
 
-concatMapM        :: (Monad m) => (a -> m [b]) -> [a] -> m [b]
-concatMapM f xs   =  liftM concat (mapM f xs)
-
 viewDetails :: PlayerNumber -> Game -> Html
 viewDetails pn g = showHideTitle "Details" False False (h3 "Details") $ do
    p $ titleWithHelpIcon (h4 "Variables:") Help.variables
@@ -201,7 +202,8 @@
       [] -> Nothing
       os -> Just $ mapM_ viewOutput os
 
-isPn pn (Output _ _ mypn _ SActive) = mypn == pn
+isPn pn (Output _ _ (Just mypn) _ SActive) = mypn == pn
+isPn _ (Output _ _ Nothing _ SActive) = True
 isPn _ _ = False
 
 viewInput :: PlayerNumber -> GameName -> EventHandler -> RoutedNomyxServer (Maybe Html)
@@ -272,8 +274,8 @@
              s' <- readTVarIO ts  --TODO clean this
              gn <- getPlayersGame pn s
              gn' <- getPlayersGame pn s'
-             let rs = _rules $ _game $ fromJust gn
-             let rs' = _rules $ _game $ fromJust gn'
+             let rs = _rules $ _game $ fromJustNote "newRule" gn
+             let rs' = _rules $ _game $ fromJustNote "newRule" gn'
              when (length rs' > length rs) $ sendMailsNewRule s' sr pn
        Right (sr, Just _) -> webCommand ts $ adminSubmitRule sr pn gn sh
        (Left _) -> liftIO $ putStrLn $ "cannot retrieve form data"
@@ -295,7 +297,7 @@
     pn <- getPlayerNumber ts
     s <- liftIO $ atomically $ readTVar ts
     let g = find ((== gn) . getL (game >>> gameName)) (_games $ _multi s)
-    let eventHandler = fromJust $ findEvent en (_events $ _game $ fromJust g)
+    let eventHandler = getEventHandler en (fromJust g)
     methodM POST
     r <- liftRouteT $ eitherForm environment "user" (getNomyxForm eventHandler)
     link <- showURL MainPage
diff --git a/src/Web/Help.hs b/src/Web/Help.hs
--- a/src/Web/Help.hs
+++ b/src/Web/Help.hs
@@ -42,5 +42,6 @@
 getSaveFile = "With the following link, you can download the save file of the game. This allows you to load it in a local instance of the game.\n" ++
               "This way, you will be able to compose and test the effects of your new rules locally, without affecting the online game. \n" ++
               "The procedure is: \n" ++
-              "$> cabal install Nomyx \n" ++
-              "$> Nomyx -r <save file name>\n"
+              "$> cabal install Nomyx-<version> \n" ++
+              "$> Nomyx -r <save file name>\n" ++
+              "Warning: Nomyx and Nomyx-Language should have the same exact version as the online instance.\n"
diff --git a/src/Web/MainPage.hs b/src/Web/MainPage.hs
--- a/src/Web/MainPage.hs
+++ b/src/Web/MainPage.hs
@@ -21,10 +21,9 @@
 import Data.Monoid
 import Control.Concurrent.STM
 import Language.Nomyx
+import Language.Nomyx.Engine
 import Happstack.Server as HS
-import System.Directory
 import System.FilePath
-import System.Posix.Files
 import qualified Web.Help as Help
 import Types as T
 import Web.Game
@@ -32,20 +31,20 @@
 import Web.Settings
 import Web.NewGame
 import Web.Login
+import Data.List
 import Utils
 import Data.Text(Text, pack)
-import qualified Language.Nomyx.Game as G
+import qualified Language.Nomyx.Engine as G
 import Happstack.Auth
 import Safe
-
+import Paths_Nomyx_Language
 default (Integer, Double, Data.Text.Text)
 
-
 viewMulti :: PlayerNumber -> PlayerNumber -> FilePath -> Session -> RoutedNomyxServer Html
-viewMulti pn playAs dataDir s = do
+viewMulti pn playAs saveDir s = do
    pfd <- getProfile s pn
    let isAdmin = _isAdmin $ _pAdmin $ fromJustNote "viewMulti" pfd
-   gns <- viewGamesTab (map G._game $ _games $ _multi s) isAdmin dataDir
+   gns <- viewGamesTab (map G._game $ _games $ _multi s) isAdmin saveDir
    mgn <- liftRouteT $ lift $ getPlayersGame pn s
    vg <- case mgn of
       Just g -> viewGame (G._game g) playAs (_pLastRule $ fromJustNote "viewMulti" pfd) isAdmin
@@ -55,14 +54,13 @@
       div ! A.id "game" $ vg
 
 viewGamesTab :: [Game] -> Bool -> FilePath -> RoutedNomyxServer Html
-viewGamesTab gs isAdmin dataDir = do
+viewGamesTab gs isAdmin saveDir = do
    gns <- mapM (viewGameName isAdmin) gs
    newGameLink <- showURL NewGame
    settingsLink <- showURL W.PlayerSettings
    advLink <- showURL Advanced
    logoutURL  <- showURL (U_AuthProfile $ AuthURL A_Logout)
-   mods <- liftIO $ getDirectoryContents $ dataDir </> modDir
-   fmods <- liftIO $ filterM (getFileStatus . (\f -> joinPath [dataDir, modDir, f]) >=> return . isRegularFile) $ mods
+   fmods <- liftIO $ getUploadedModules saveDir
    ok $ do
       h3 "Main menu" >> br
       "Active games:" >> br
@@ -71,13 +69,12 @@
             [] -> tr $ td "No Games"
             _ ->  sequence_ gns
       when isAdmin $ H.a "Create a new game" ! (href $ toValue newGameLink) >> br
-      br >> "Nomyx language files:" >> br
-      H.a "Rules examples"    ! (href $ "/src/Language/Nomyx/Examples.hs") >> br
-      H.a "Basic rules"       ! (href $ "/src/Language/Nomyx/Rule.hs") >> br
-      H.a "Rules definitions" ! (href $ "/src/Language/Nomyx/Definition.hs") >> br
-      H.a "Rules types"       ! (href $ "/src/Language/Nomyx/Expression.hs") >> br
-      H.a "Voting system"     ! (href $ "/src/Language/Nomyx/Vote.hs") >> br
-      mapM_ (\f -> (H.a $ toHtml f ) ! (href $ toValue (pathSeparator : modDir </> f)) >> br) fmods
+      br >> "Help files:" >> br
+      H.a "Rules examples"    ! (href $ "/html/Language-Nomyx-Examples.html") >> br
+      H.a "Nomyx language"    ! (href $ "/html/Language-Nomyx.html") >> br
+      when (fmods /= []) $ do
+         br >> "Uploaded files:" >> br
+         mapM_ (\f -> (H.a $ toHtml f ) ! (href $ toValue (pathSeparator : uploadDir </> f)) >> br) (sort fmods)
       br >> "Settings:" >> br
       H.a "Player settings" ! (href $ toValue settingsLink) >> br
       H.a "Advanced"        ! (href $ toValue advLink) >> br
@@ -87,32 +84,37 @@
 viewGameName :: Bool -> Game -> RoutedNomyxServer Html
 viewGameName isAdmin g = do
    let gn = _gameName g
-   join  <- showURL (JoinGame gn)
-   leave <- showURL (LeaveGame gn)
-   view  <- showURL (ViewGame gn)
-   del  <- showURL (DelGame gn)
+   join  <- showURL (W.JoinGame gn)
+   leave <- showURL (W.LeaveGame gn)
+   view  <- showURL (W.ViewGame gn)
+   del   <- showURL (W.DelGame gn)
    ok $ tr $ do
       td ! A.id "gameName" $ string $ (gn ++ "   ")
       td $ H.a "View"  ! (href $ toValue view) ! (A.title $ toValue Help.view)
       td $ H.a "Join"  ! (href $ toValue $ "#openModalJoin" ++ gn) ! (A.title $ toValue Help.join)
-      td $ H.a "Leave" ! (href $ toValue leave)
+      td $ H.a "Leave" ! (href $ toValue $ "#openModalLeave" ++ gn)
       when isAdmin $ td $ H.a "Del"   ! (href $ toValue del)
       div ! A.id (toValue $ "openModalJoin" ++ gn) ! A.class_ "modalWindow" $ do
          div $ do
             h2 "Joining the game. Please register in the Agora (see the link) and introduce yourself to the other players! \n \
                 If you do not wich to play, you can just view the game."
-            H.a "Join" ! (href $ toValue join) ! A.class_ "join" ! (A.title $ toValue Help.join)
-            H.a "View" ! (href $ toValue view) ! A.class_ "view" ! (A.title $ toValue Help.view)
+            H.a "Join" ! (href $ toValue join) ! A.class_ "modalButton" ! (A.title $ toValue Help.join)
+            H.a "View" ! (href $ toValue view) ! A.class_ "modalButton" ! (A.title $ toValue Help.view)
+      div ! A.id (toValue $ "openModalLeave" ++ gn) ! A.class_ "modalWindow" $ do
+         div $ do
+            h2 "Do you really want to leave? You will loose your assets in the game (for example, your bank account)."
+            H.a "Leave" ! (href $ toValue leave) ! A.class_ "modalButton"
+            H.a "Stay"  ! (href $ toValue view)  ! A.class_ "modalButton"
 
 
 nomyxPage :: (TVar Session) -> RoutedNomyxServer Response
 nomyxPage ts = do
    pn <- getPlayerNumber ts
    s <- liftIO $ atomically $ readTVar ts
-   let dataDir = _dataDir $ _mSettings $ _multi s
+   let saveDir = _saveDir $ _mSettings $ _multi s
    name <- liftIO $ Utils.getPlayerName pn s
    playAs <- getPlayAs ts
-   m <- viewMulti pn playAs dataDir s
+   m <- viewMulti pn playAs saveDir s
    let body = do
        string $ "Welcome to Nomyx, " ++ name ++ "! "
        when (playAs /= pn) $ (b ! A.style "color:red;" $ string ("Playing as Player #" ++ (show playAs)) )
@@ -129,8 +131,8 @@
 routedNomyxCommands ts PostAuth              = postAuthenticate  ts
 routedNomyxCommands ts HomePage              = homePage          ts
 routedNomyxCommands ts MainPage              = nomyxPage         ts
-routedNomyxCommands ts (JoinGame game)       = joinGame          ts game
-routedNomyxCommands ts (LeaveGame game)      = leaveGame         ts game
+routedNomyxCommands ts (W.JoinGame game)     = joinGame          ts game
+routedNomyxCommands ts (W.LeaveGame game)    = leaveGame         ts game
 routedNomyxCommands ts (ViewGame game)       = viewGamePlayer    ts game
 routedNomyxCommands ts (DelGame game)        = delGame           ts game
 routedNomyxCommands ts (NewRule game)        = newRule           ts game
@@ -154,13 +156,20 @@
 server :: (TVar Session) -> Network -> ServerPartT IO Response
 server ts net = do
   s <- liftIO $ atomically $ readTVar ts
-  let d = _dataDir $ _mSettings $ _multi s
-  let d' = _sourceDir $ _mSettings $ _multi s
+  let set = _mSettings $ _multi s
+  docdir <- liftIO $ getDocDir
   mconcat [
-    serveDirectory DisableBrowsing [] d,
-    serveDirectory DisableBrowsing [] d',
+    serveDirectory DisableBrowsing [] (_saveDir set),
+    serveDirectory DisableBrowsing [] docdir,
+    serveDirectory DisableBrowsing [] (_dataDir set),
+    serveDirectory DisableBrowsing [] (_sourceDir set),
     do decodeBody (defaultBodyPolicy "/tmp/" 102400 4096 4096)
        html <- implSite (pack (nomyxURL net)) "/Nomyx" (nomyxSite ts)
        return $ toResponse html]
 
 
+getDocDir :: IO FilePath
+getDocDir = do
+   datadir <- getDataDir
+   let (x:xs) = reverse $ splitDirectories datadir
+   return $ joinPath $ reverse $ (x:"doc":xs)
diff --git a/src/Web/NewGame.hs b/src/Web/NewGame.hs
--- a/src/Web/NewGame.hs
+++ b/src/Web/NewGame.hs
@@ -15,7 +15,7 @@
 import Text.Reform.Happstack
 import Web.Common
 import Control.Monad.State
-import Language.Nomyx
+import Language.Nomyx.Engine
 import Web.Routes.RouteT
 import Control.Concurrent.STM
 import Data.Text(Text)
diff --git a/src/Web/Settings.hs b/src/Web/Settings.hs
--- a/src/Web/Settings.hs
+++ b/src/Web/Settings.hs
@@ -28,6 +28,11 @@
 import qualified Language.Haskell.HsColour.HTML as HSC
 import Language.Haskell.HsColour.Colourise hiding (string)
 import Text.Blaze.Internal hiding (Text)
+import Safe
+import Paths_Nomyx as PN
+import Paths_Nomyx_Language as PNL
+import Data.Version (showVersion)
+import System.FilePath
 default (Integer, Double, Data.Text.Text)
 
 playerSettingsForm :: (Maybe PlayerSettings) -> [PlayerName] -> [String] -> NomyxForm PlayerSettings
@@ -73,7 +78,7 @@
    pfd <- getProfile' ts pn
    names <- liftIO $ forbiddenNames ts pn
    emails <- liftIO $ forbiddenEmails ts pn
-   settingsPage (_pPlayerSettings $ fromJust pfd) names emails
+   settingsPage (_pPlayerSettings $ fromJustNote "playerSettings" pfd) names emails
 
 newPlayerSettings :: (TVar Session) -> RoutedNomyxServer Response
 newPlayerSettings ts = toResponse <$> do
@@ -113,7 +118,7 @@
    pfd <- getProfile session pn
    pfds <- liftIO $ getAllProfiles session
    session <- liftIO $ atomically $ readTVar ts
-   page <- advancedPage (_pLastUpload $ fromJust pfd) (_pAdmin $ fromJust pfd) (_mSettings $ _multi session) pfds
+   page <- advancedPage (_pLastUpload $ fromJustNote "advanced" pfd) (_pAdmin $ fromJustNote "advanced" pfd) (_mSettings $ _multi session) pfds
    mainPage "Advanced" "Advanced" page False True
 
 
@@ -127,10 +132,16 @@
    ap <- lift $ viewForm "user" $ adminPassForm
    paf <- lift $ viewForm "user" $ playAsForm []
    set <- lift $ viewForm "user" $ settingsForm (_sendMails settings)
+   liftIO $ makeTar (_saveDir settings)
    ok $ do
       p $ do
+         string $ "Versions:"
+         pre $ string $ "Nomyx " ++ showVersion PN.version ++ "\n" ++
+                        "Nomyx-Language " ++ showVersion PNL.version
+      hr
+      p $ do
          pre $ string Help.getSaveFile
-         H.a "get save file" ! (href $ "/Nomyx.save")
+         H.a "get save file" ! (href $ toValue (pathSeparator : tarFile))
       H.br
       hr
       p $ do
@@ -146,7 +157,7 @@
             NoUpload -> p ""
       hr
       p $ do
-         h5 "Enter admin password to get admin rights:"
+         h5 "Enter admin password to get admin rights (necessary to create a new game):"
          blazeForm ap (submitAdminPass)
          when admin $ h5 "You are admin"
       when admin $ do
@@ -257,3 +268,5 @@
       (Left errorForm) -> do
          settingsLink <- showURL SubmitAdminPass
          mainPage  "Admin settings" "Admin settings" (blazeForm errorForm settingsLink) False True
+
+
