From cc61f53ff8dffe90dad8aa8178e2803229626c96 Mon Sep 17 00:00:00 2001
From: auria <auria@178a84e3-b1eb-0310-8ba1-8eac791a3b58>
Date: Sun, 21 Sep 2008 16:07:56 +0000
Subject: [PATCH] more cleanup, replaced World global variable with
 singleton-like implementation, removed lots of includes to world.hpp

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2291 178a84e3-b1eb-0310-8ba1-8eac791a3b58
---
 src/Makefile.am                               | 144 ++++++++--------
 src/attachment.cpp                            |   1 -
 src/camera.cpp                                |  10 +-
 src/challenges/challenge.cpp                  |   3 +-
 src/challenges/challenge_data.cpp             |   9 +-
 src/collectable.cpp                           |  10 +-
 src/file_manager.cpp                          |   1 -
 src/flyable.cpp                               |  15 +-
 src/gui/base_gui.cpp                          |   3 +-
 src/gui/grand_prix_ending.cpp                 |   4 +-
 src/gui/race_gui.cpp                          |  75 ++++----
 src/gui/race_gui.hpp                          |  22 +--
 src/gui/race_menu.cpp                         |  11 +-
 src/gui/race_results_gui.cpp                  |  16 +-
 src/herring.cpp                               |   1 -
 src/history.cpp                               |   7 +-
 .../Xcode/STK_XCode.xcodeproj/project.pbxproj |  54 ++++--
 src/kart.cpp                                  |  67 ++++----
 src/main_loop.cpp                             |  10 +-
 src/modes/follow_the_leader.cpp               |  18 +-
 src/modes/follow_the_leader.hpp               |   4 +-
 src/modes/standard_race.cpp                   |  21 ++-
 src/modes/standard_race.hpp                   |   4 +-
 src/{ => modes}/world.cpp                     | 161 +-----------------
 src/{ => modes}/world.hpp                     | 130 +-------------
 src/moveable.cpp                              |   1 -
 src/moving_physics.cpp                        |   6 +-
 src/moving_texture.cpp                        |   4 +-
 src/network/kart_control_message.cpp          |   8 +-
 src/network/kart_update_message.cpp           |   8 +-
 src/network/race_state.cpp                    |  18 +-
 src/physics.cpp                               |   4 +-
 src/player_kart.cpp                           |  10 +-
 src/race_manager.cpp                          |  31 +++-
 src/race_manager.hpp                          |   9 +
 src/replay_recorder.cpp                       |  14 +-
 src/robots/default_robot.cpp                  | 124 +++++++-------
 src/robots/empty_robot.cpp                    |   2 +-
 src/scene.cpp                                 |  10 +-
 src/terrain_info.cpp                          |   5 +-
 src/track.cpp                                 |   6 +-
 src/traffic.cpp                               |   4 +-
 src/triangle_mesh.cpp                         |   6 +-
 43 files changed, 427 insertions(+), 644 deletions(-)
 rename src/{ => modes}/world.cpp (80%)
 rename src/{ => modes}/world.hpp (68%)

diff --git a/src/Makefile.am b/src/Makefile.am
index d8cc6d706..de862f371 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,116 +25,114 @@ libstatic_ssg_a_CXXFLAGS = @NOREGMOVE@
 
 AM_CPPFLAGS=-DSUPERTUXKART_DATADIR="\"$(datadir)/games/@PACKAGE@/\""
 
-supertuxkart_SOURCES =             main.cpp  			\
-	vec3.cpp		   vec3.hpp			\
+supertuxkart_SOURCES =     main.cpp  			\
+	vec3.cpp		       vec3.hpp			\
 	coord.hpp						\
 	actionmap.cpp		   actionmap.hpp		\
 	material.cpp		   material.hpp           	\
-	network/network_manager.cpp     network/network_manager.hpp 		\
-	network/network_kart.cpp        network/network_kart.hpp		\
-        network/message.cpp             network/message.hpp			\
-	network/race_info_message.hpp   network/race_info_message.cpp		\
-	network/remote_kart_info.hpp    network/character_selected_message.hpp	\
-	network/race_start_message.hpp  network/character_confirm_message.hpp	\
-	network/connect_message.hpp	network/connect_message.cpp		\
-	network/num_players_message.hpp network/world_loaded_message.hpp	\
-        network/connect_message.hpp     network/character_info_message.hpp	\
-	network/kart_update_message.hpp network/kart_update_message.cpp		\
+	network/network_manager.cpp      network/network_manager.hpp 		\
+	network/network_kart.cpp         network/network_kart.hpp		\
+    network/message.cpp              network/message.hpp			\
+	network/race_info_message.hpp    network/race_info_message.cpp		\
+	network/remote_kart_info.hpp     network/character_selected_message.hpp	\
+	network/race_start_message.hpp   network/character_confirm_message.hpp	\
+	network/connect_message.hpp	     network/connect_message.cpp		\
+	network/num_players_message.hpp  network/world_loaded_message.hpp	\
+    network/connect_message.hpp      network/character_info_message.hpp	\
+	network/kart_update_message.hpp  network/kart_update_message.cpp		\
 	network/kart_control_message.hpp network/kart_control_message.cpp	\
-	network/flyable_info.hpp	network/herring_info.hpp		\
-	network/race_state.hpp		network/race_state.cpp			\
+	network/flyable_info.hpp	     network/herring_info.hpp		\
+	network/race_state.hpp		     network/race_state.cpp			\
 	audio/music.hpp								\
-	audio/music_information.cpp 	audio/music_information.hpp 		\
-	audio/music_ogg.cpp	   	audio/music_ogg.hpp          		\
+	audio/music_information.cpp audio/music_information.hpp 		\
+	audio/music_ogg.cpp	   	    audio/music_ogg.hpp          		\
  	audio/sfx_base.hpp              					\
 	audio/sfx_manager.cpp	   	audio/sfx_manager.hpp      		\
 	audio/sfx_openal.cpp	   	audio/sfx_openal.hpp			\
 	audio/sound_manager.cpp	   	audio/sound_manager.hpp      		\
 	utils/random_generator.hpp	utils/random_generator.cpp		\
-	utils/ssg_help.cpp              tuils/ssg_help.hpp                	\
-	material_manager.cpp	   material_manager.hpp    	\
-	grand_prix_manager.cpp	   grand_prix_manager.hpp	\
-	attachment.cpp		   attachment.hpp	        \
-	attachment_manager.cpp     attachment_manager.hpp       \
-	collectable.cpp		   collectable.hpp	        \
-	collectable_manager.cpp	   collectable_manager.hpp   	\
-	smoke.cpp		   smoke.hpp			\
-	input.hpp 		   kart_control.hpp		\
-	isect.cpp		   isect.hpp                	\
-	track.cpp		   track.hpp                	\
+	utils/ssg_help.cpp          utils/ssg_help.hpp                	\
+	material_manager.cpp	    material_manager.hpp    	\
+	grand_prix_manager.cpp	    grand_prix_manager.hpp	\
+	attachment.cpp		        attachment.hpp	        \
+	attachment_manager.cpp      attachment_manager.hpp       \
+	collectable.cpp		        collectable.hpp	        \
+	collectable_manager.cpp	    collectable_manager.hpp   	\
+	smoke.cpp		       smoke.hpp			\
+	input.hpp 		       kart_control.hpp		\
+	isect.cpp		       isect.hpp                	\
+	track.cpp		       track.hpp                	\
 	herring.cpp 		   herring.hpp              	\
 	herring_manager.cpp	   herring_manager.hpp       	\
 	explosion.cpp		   explosion.hpp            	\
 	user_config.cpp		   user_config.hpp             	\
-	grand_prix_data.cpp   	   grand_prix_data.hpp        	\
+	grand_prix_data.cpp    grand_prix_data.hpp        	\
 	kart_properties_manager.cpp kart_properties_manager.hpp \
-	projectile_manager.cpp	   projectile_manager.hpp    	\
+	projectile_manager.cpp projectile_manager.hpp    	\
 	kart_properties.cpp	   kart_properties.hpp       	\
 	stk_config.cpp		   stk_config.hpp    		\
 	highscores.cpp		   highscores.hpp		\
-	highscore_manager.cpp	   highscore_manager.hpp	\
+	highscore_manager.cpp  highscore_manager.hpp	\
 	unlock_manager.cpp	   unlock_manager.hpp		\
-	file_manager.cpp           file_manager.hpp           	\
-	loader.cpp		   loader.hpp			\
+	file_manager.cpp       file_manager.hpp           	\
+	loader.cpp		       loader.hpp			\
 	race_manager.cpp	   race_manager.hpp          	\
 	string_utils.cpp	   string_utils.hpp          	\
 	track_manager.cpp	   track_manager.hpp         	\
-	world.cpp		   world.hpp                	\
 	callback.hpp 						\
 	moving_physics.hpp	   moving_physics.cpp		\
 	moving_texture.hpp	   moving_texture.cpp		\
-	callback_manager.cpp       callback_manager.hpp         \
-	physics.cpp                physics.hpp                  \
+	callback_manager.cpp   callback_manager.hpp         \
+	physics.cpp            physics.hpp                  \
 	skid_mark.cpp		   skid_mark.hpp	        \
-	shadow.cpp		   shadow.hpp	        	\
+	shadow.cpp		       shadow.hpp	        	\
 	particle_system.cpp	   particle_system.hpp       	\
 	main_loop.cpp	 	   main_loop.hpp        	\
-	camera.cpp		   camera.hpp	        	\
-	sdldrv.cpp		   sdldrv.hpp	        	\
+	camera.cpp		       camera.hpp	        	\
+	sdldrv.cpp		       sdldrv.hpp	        	\
 	moveable.cpp 		   moveable.hpp             	\
-	kart.cpp		   kart.hpp		        \
-	            		   auto_kart.hpp             	\
+	kart.cpp		       kart.hpp		        \
+	user_pointer.hpp	   auto_kart.hpp             	\
 	player_kart.cpp		   player_kart.hpp	        \
 	terrain_info.cpp	   terrain_info.hpp		\
-        triangle_mesh.cpp	   triangle_mesh.hpp		\
-				   user_pointer.hpp		\
-	flyable.cpp		   flyable.hpp			\
-	missile.cpp		   missile.hpp			\
-	homing.cpp		   homing.hpp			\
-	bowling.cpp		   bowling.hpp			\
-	history.cpp		   history.hpp	        	\
-	scene.hpp		   scene.cpp			\
+    triangle_mesh.cpp	   triangle_mesh.hpp		\
+	flyable.cpp		       flyable.hpp			\
+	missile.cpp		       missile.hpp			\
+	homing.cpp		       homing.hpp			\
+	bowling.cpp		       bowling.hpp			\
+	history.cpp		       history.hpp	        	\
+	scene.hpp		       scene.cpp			\
 	no_copy.hpp	           constants.hpp 		\
 	translation.cpp		   translation.hpp 		\
 	player.hpp		   				\
-	challenges/challenge.hpp   challenges/challenge.cpp	\
-	challenges/challenge_data.hpp   challenges/challenge_data.cpp	\
-	lisp/lisp.cpp		   lisp/lisp.hpp            	\
-	lisp/lexer.cpp		   lisp/lexer.hpp           	\
-	lisp/parser.cpp		   lisp/parser.hpp          	\
-	lisp/writer.cpp		   lisp/writer.hpp	        \
-	gui/widget_manager.cpp	   gui/widget_manager.hpp       \
-	gui/widget.cpp		   gui/widget.hpp	        \
+	challenges/challenge.hpp      challenges/challenge.cpp	\
+	challenges/challenge_data.hpp challenges/challenge_data.cpp	\
+	lisp/lisp.cpp		       lisp/lisp.hpp            	\
+	lisp/lexer.cpp		       lisp/lexer.hpp           	\
+	lisp/parser.cpp		       lisp/parser.hpp          	\
+	lisp/writer.cpp		       lisp/writer.hpp	        \
+	gui/widget_manager.cpp     gui/widget_manager.hpp       \
+	gui/widget.cpp		       gui/widget.hpp	        \
 	gui/menu_manager.cpp       gui/menu_manager.hpp     	\
-	gui/base_gui.cpp	   gui/base_gui.hpp	        \
-	gui/race_gui.cpp	   gui/race_gui.hpp	        \
+	gui/base_gui.cpp	       gui/base_gui.hpp	        \
+	gui/race_gui.cpp	       gui/race_gui.hpp	        \
 	gui/race_results_gui.cpp   gui/race_results_gui.hpp 	\
 	gui/grand_prix_ending.cpp  gui/grand_prix_ending.hpp 	\
-	gui/race_menu.cpp	   gui/race_menu.hpp	        \
-	gui/num_players.cpp	   gui/num_players.hpp       	\
-	gui/track_sel.cpp	   gui/track_sel.hpp	        \
+	gui/race_menu.cpp	       gui/race_menu.hpp	        \
+	gui/num_players.cpp	       gui/num_players.hpp       	\
+	gui/track_sel.cpp	       gui/track_sel.hpp	        \
 	gui/player_controls.cpp	   gui/player_controls.hpp   	\
 	gui/config_display.cpp	   gui/config_display.hpp    	\
 	gui/display_res_confirm.cpp gui/display_res_confirm.hpp	\
 	gui/config_sound.cpp	   gui/config_sound.hpp    	\
 	gui/config_controls.cpp	   gui/config_controls.hpp   	\
-	gui/options.cpp		   gui/options.hpp	        \
-	gui/game_mode.cpp	   gui/game_mode.hpp	        \
+	gui/options.cpp		       gui/options.hpp	        \
+	gui/game_mode.cpp	       gui/game_mode.hpp	        \
 	gui/race_options.cpp       gui/race_options.hpp       	\
-	gui/char_sel.cpp	   gui/char_sel.hpp	        \
+	gui/char_sel.cpp	       gui/char_sel.hpp	        \
 	gui/start_race_feedback.cpp gui/start_race_feedback.hpp	\
-	gui/network_gui.cpp	   gui/network_gui.hpp		\
-	gui/main_menu.cpp	   gui/main_menu.hpp         	\
+	gui/network_gui.cpp	       gui/network_gui.hpp		\
+	gui/main_menu.cpp	       gui/main_menu.hpp         	\
 	gui/help_page_one.cpp	   gui/help_page_one.hpp 	\
 	gui/help_page_two.cpp  	   gui/help_page_two.hpp	\
 	gui/help_page_three.cpp    gui/help_page_three.hpp	\
@@ -142,17 +140,19 @@ supertuxkart_SOURCES =             main.cpp  			\
 	gui/grand_prix_select.cpp  gui/grand_prix_select.hpp    \
 	gui/challenges_menu.cpp	   gui/challenges_menu.hpp	\
 	gui/feature_unlocked.cpp   gui/feature_unlocked.hpp	\
-	gui/font.hpp		   gui/font.cpp                 \
+	gui/font.hpp		       gui/font.cpp                 \
 	robots/default_robot.cpp   robots/default_robot.hpp	\
 	modes/follow_the_leader.cpp modes/follow_the_leader.hpp \
-	modes/standard_race.cpp modes/standard_race.hpp \
+	modes/standard_race.cpp    modes/standard_race.hpp \
+	modes/clock.cpp            modes/clock.hpp \
+	modes/world.cpp		       modes/world.hpp                	\
 	replay_buffer_tpl.hpp 					\
-	replay_buffers.hpp	   replay_buffers.cpp		\
-	replay_base.hpp		   replay_base.cpp		\
+	replay_buffers.hpp	       replay_buffers.cpp		\
+	replay_base.hpp		       replay_base.cpp		\
 	replay_player.hpp          replay_player.cpp		\
-	replay_recorder.hpp	   replay_recorder.cpp       	\
+	replay_recorder.hpp	       replay_recorder.cpp       	\
 	ide/vc8/supertuxkart.sln   ide/vc8/supertuxkart.vcproj	\
-	ide/vc8/bullet_lib.vcproj  ide/vc8/README
+	ide/vc8/bullet_lib.vcproj  ide/vc8/README \
 	ide/vc9/supertuxkart.sln   ide/vc9/supertuxkart.vcproj	\
 	ide/vc9/bullet_lib.vcproj  ide/vc9/enet.vcproj		\
 	ide/vc9/README						\
diff --git a/src/attachment.cpp b/src/attachment.cpp
index 6fdcef123..c1a71b7be 100644
--- a/src/attachment.cpp
+++ b/src/attachment.cpp
@@ -25,7 +25,6 @@
 #include "projectile_manager.hpp"
 #include "kart.hpp"
 #include "constants.hpp"
-#include "world.hpp"
 #include "stk_config.hpp"
 #include "user_config.hpp"
 #include "network/race_state.hpp"
diff --git a/src/camera.cpp b/src/camera.cpp
index 032a94d79..44a2d5cc0 100644
--- a/src/camera.cpp
+++ b/src/camera.cpp
@@ -21,7 +21,7 @@
 #define _WINSOCKAPI_
 #include <plib/ssg.h>
 #include "coord.hpp"
-#include "world.hpp"
+#include "modes/world.hpp"
 #include "player_kart.hpp"
 #include "track.hpp"
 #include "camera.hpp"
@@ -39,7 +39,7 @@ Camera::Camera(int camera_index, const Kart* kart)
     m_hpr      = Vec3(0,0,0);
 
     // FIXME: clipping should be configurable for slower machines
-    const Track* track  = world->getTrack();
+    const Track* track  = RaceManager::getTrack();
     if (track->useFog())
         m_context -> setNearFar ( 0.05f, track->getFogEnd() ) ;
     else
@@ -98,7 +98,7 @@ void Camera::setMode(Mode mode)
 {
     if(mode==CM_FINAL)
     {
-        const Track* track=world->getTrack();
+        const Track* track=RaceManager::getTrack();
         // If the track doesn't have a final position, ignore this mode
         if(!track->hasFinalCamera()) return;
         const float duration = 1.0f;
@@ -149,7 +149,7 @@ void Camera::update (float dt)
     // First define the position of the kart
     if(m_mode==CM_LEADER_MODE)
     {
-        kart     = world->getKart(0);
+        kart     = RaceManager::getKart(0);
         kart_hpr = kart->getHPR();
     }
     else
@@ -161,7 +161,7 @@ void Camera::update (float dt)
         kart_hpr.setRoll(0.0f);
         // Only adjust the pitch if it's not the race start, otherwise 
         // the camera will change pitch during ready-set-go.
-        if(world->getClock().isRacePhase())
+        if(RaceManager::getWorld()->getClock().isRacePhase())
         {
             // If the terrain pitch is 'significantly' different from the camera angle,
             // start adjusting the camera. This helps with steep declines, where
diff --git a/src/challenges/challenge.cpp b/src/challenges/challenge.cpp
index 3edff580d..c7cc7ba13 100755
--- a/src/challenges/challenge.cpp
+++ b/src/challenges/challenge.cpp
@@ -19,10 +19,11 @@
 
 #include "translation.hpp"
 #include "challenges/challenge.hpp"
-#include "world.hpp"
 #include "race_manager.hpp"
 #include "track_manager.hpp"
 #include "kart_properties_manager.hpp"
+#include "kart_properties.hpp"
+#include "track.hpp"
 
 #if defined(WIN32) && !defined(__CYGWIN__)
 #  define snprintf _snprintf
diff --git a/src/challenges/challenge_data.cpp b/src/challenges/challenge_data.cpp
index ad6920465..bb075b4b5 100755
--- a/src/challenges/challenge_data.cpp
+++ b/src/challenges/challenge_data.cpp
@@ -22,9 +22,10 @@
 #include "lisp/lisp.hpp"
 #include "lisp/parser.hpp"
 #include "translation.hpp"
-#include "world.hpp"
 #include "grand_prix_data.hpp"
 #include "grand_prix_manager.hpp"
+#include "kart.hpp"
+#include "track.hpp"
 
 #if defined(WIN32) && !defined(__CYGWIN__)
 #  define snprintf _snprintf
@@ -215,11 +216,11 @@ bool ChallengeData::raceFinished()
 
     // Single races
     // ------------
-    std::string track_name = world->getTrack()->getIdent();
+    std::string track_name = RaceManager::getTrack()->getIdent();
     if(track_name!=m_track_name                    ) return false;    // wrong track
     if((int)race_manager->getNumKarts()<m_num_karts) return false;    // not enough AI karts
 
-    Kart* kart=world->getPlayerKart(0);
+    Kart* kart = RaceManager::getPlayerKart(0);
     if(m_energy>0   && kart->getNumHerring()<m_energy) return false;  // not enough energy
     if(m_position>0 && kart->getPosition()>m_position) return false;  // too far behind
 
@@ -246,7 +247,7 @@ bool ChallengeData::grandPrixFinished()
         race_manager->getNumKarts()   < (unsigned int)m_num_karts            ||
         race_manager->getNumPlayers() > 1) return false;
 
-    Kart* kart=world->getPlayerKart(0);
+    Kart* kart = RaceManager::getPlayerKart(0);
     if(kart->getPosition()>m_position) return false;
     return true;
 }   // grandPrixFinished
diff --git a/src/collectable.cpp b/src/collectable.cpp
index 0138a93bd..af7c74cb2 100644
--- a/src/collectable.cpp
+++ b/src/collectable.cpp
@@ -27,7 +27,7 @@
 #include "kart.hpp"
 #include "audio/sfx_manager.hpp"
 #include "audio/sfx_base.hpp"
-#include "world.hpp"
+#include "modes/world.hpp"
 #include "stk_config.hpp"
 
 //-----------------------------------------------------------------------------
@@ -109,7 +109,7 @@ void Collectable::use()
         //by the bananas) to the kart in the 1st position.
         for(unsigned int i = 0 ; i < race_manager->getNumKarts(); ++i)
         {
-            Kart *kart=world->getKart(i);
+            Kart *kart=RaceManager::getKart(i);
             if(kart->isEliminated()) continue;
             if(kart == m_owner) continue;
             if(kart->getPosition() == 1)
@@ -135,7 +135,7 @@ void Collectable::use()
             //are in front of this one.
             for(unsigned int i = 0 ; i < race_manager->getNumKarts(); ++i)
             {
-                Kart *kart=world->getKart(i);
+                Kart *kart=RaceManager::getKart(i);
                 if(kart->isEliminated() || kart== m_owner) continue;
                 if(m_owner->getPosition() > kart->getPosition())
                 {
@@ -181,7 +181,7 @@ void Collectable::hitRedHerring(int n, const Herring &herring, int add_info)
             m_number  = 1;
             return;
         }
-        const int SPECIAL_PROB = (int)(15.0 / ((float)world->getCurrentNumKarts() /
+        const int SPECIAL_PROB = (int)(15.0 / ((float)RaceManager::getWorld()->getCurrentNumKarts() /
                                          (float)m_owner->getPosition()));
         const int RAND_NUM = m_random.get(100);
         if(RAND_NUM <= SPECIAL_PROB)
@@ -190,7 +190,7 @@ void Collectable::hitRedHerring(int n, const Herring &herring, int add_info)
             //the parachute.
             for(unsigned int i=0; i < race_manager->getNumKarts(); ++i)
             {
-                Kart *kart = world->getKart(i);
+                Kart *kart = RaceManager::getKart(i);
                 if(kart->isEliminated() || kart == m_owner) continue;
                 if(kart->getPosition() == 1 && kart->hasFinishedRace())
                 {
diff --git a/src/file_manager.cpp b/src/file_manager.cpp
index 67d96d238..3275a972a 100644
--- a/src/file_manager.cpp
+++ b/src/file_manager.cpp
@@ -41,7 +41,6 @@
 #define _WINSOCKAPI_
 #include <plib/ul.h>
 #include "file_manager.hpp"
-#include "world.hpp"
 #include "btBulletDynamicsCommon.h"
 #include "moving_physics.hpp"
 #include "moving_texture.hpp"
diff --git a/src/flyable.cpp b/src/flyable.cpp
index 95327e5aa..a2dafccd3 100644
--- a/src/flyable.cpp
+++ b/src/flyable.cpp
@@ -21,12 +21,13 @@
 
 #include "network/flyable_info.hpp"
 #include "flyable.hpp"
-#include "world.hpp"
 #include "kart.hpp"
 #include "projectile_manager.hpp"
 #include "callback_manager.hpp"
 #include "scene.hpp"
 #include "utils/ssg_help.hpp"
+#include "race_manager.hpp"
+#include "modes/world.hpp"
 
 // static variables:
 float      Flyable::m_st_speed[COLLECT_MAX];
@@ -78,7 +79,7 @@ void Flyable::createPhysics(float y_offset, const btVector3 velocity,
     m_shape = shape;
     createBody(m_mass, trans, m_shape);
     m_user_pointer.set(this);
-    world->getPhysics()->addBody(getBody());
+    RaceManager::getWorld()->getPhysics()->addBody(getBody());
 
     if(gravity) m_body->setGravity(btVector3(0.0f, 0.0f, -9.8f));
     else m_body->setGravity(btVector3(0.0f, 0.0f, 0.0f));
@@ -120,7 +121,7 @@ void Flyable::init(const lisp::Lisp* lisp, ssgEntity *model,
 Flyable::~Flyable()
 {
     if(m_shape) delete m_shape;
-    world->getPhysics()->removeBody(getBody());
+    RaceManager::getWorld()->getPhysics()->removeBody(getBody());
 }   // ~Flyable
 
 //-----------------------------------------------------------------------------
@@ -134,7 +135,7 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
     
     for(unsigned int i=0 ; i<race_manager->getNumKarts(); i++ )
     {
-        Kart *kart = world -> getKart(i);
+        Kart *kart = RaceManager::getKart(i);
         if(kart->isEliminated() || kart == m_owner || (!kart->isOnGround()) ) continue;
         btTransform t=kart->getTrans();
        
@@ -145,7 +146,7 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDistSquared,
         {
             // Ignore karts behind the current one
             float distance =  kart->getDistanceDownTrack() - inFrontOf->getDistanceDownTrack();
-            if(distance<0) distance += world->m_track->getTrackLength();
+            if(distance<0) distance += RaceManager::getTrack()->getTrackLength();
             if(distance > 50){ continue; } 
         }
         
@@ -220,12 +221,12 @@ void Flyable::explode(Kart *kart_hit, MovingPhysics* moving_physics)
     // The explosion is a bit higher in the air
     Vec3 pos_explosion=getXYZ();
     pos_explosion.setZ(pos_explosion.getZ()+1.2f);
-    world->getPhysics()->removeBody(getBody());
+    RaceManager::getWorld()->getPhysics()->removeBody(getBody());
 	m_exploded=true;
 
     for ( unsigned int i = 0 ; i < race_manager->getNumKarts() ; i++ )
     {
-        Kart *kart = world->getKart(i);
+        Kart *kart = RaceManager::getKart(i);
         // Handle the actual explosion. The kart that fired a flyable will 
         // only be affected if it's a direct hit. This allows karts to use
         // rockets on short distance.
diff --git a/src/gui/base_gui.cpp b/src/gui/base_gui.cpp
index a44613ca3..b00f85136 100644
--- a/src/gui/base_gui.cpp
+++ b/src/gui/base_gui.cpp
@@ -21,7 +21,6 @@
 
 #include "base_gui.hpp"
 #include "widget_manager.hpp"
-#include "world.hpp"
 #include "menu_manager.hpp"
 void
 BaseGUI::animateWidget(const int PREV_SELECTED_WGT, const int SELECTED_WGT)
@@ -87,7 +86,7 @@ BaseGUI::handle(GameAction action, int value)
         if (menu_manager->getMenuStackSize() > 1)
         {
            if(menu_manager->isCurrentMenu(MENUID_RACEMENU))
-             world->unpause();
+             RaceManager::getWorld()->unpause();
 
            menu_manager->popMenu();
         }
diff --git a/src/gui/grand_prix_ending.cpp b/src/gui/grand_prix_ending.cpp
index 3209f6c1a..310cd48c9 100644
--- a/src/gui/grand_prix_ending.cpp
+++ b/src/gui/grand_prix_ending.cpp
@@ -36,7 +36,6 @@
 #include "kart_properties.hpp"
 #include "translation.hpp"
 #include "kart.hpp"
-#include "world.hpp"
 #include "scene.hpp"
 #if defined(WIN32) && !defined(__CYGWIN__)
 #  define snprintf _snprintf
@@ -167,8 +166,7 @@ GrandPrixEnd::GrandPrixEnd()
     //FIXME: this is taken from RaceMode::exit_race,
     //this should be organized better.
     scene->clear();
-    delete world;
-    world = 0;
+    RaceManager::setWorld(NULL);
     race_manager->m_active_race = false;
 
 }
diff --git a/src/gui/race_gui.cpp b/src/gui/race_gui.cpp
index f29e75da3..3723809cf 100644
--- a/src/gui/race_gui.cpp
+++ b/src/gui/race_gui.cpp
@@ -157,7 +157,7 @@ RaceGUI::handle(GameAction ga, int value)
 		int playerNo = ka / KC_COUNT;
 		ka = ka % KC_COUNT;
 		
-		world->getLocalPlayerKart(playerNo)->action((KartAction) ka, value);
+		RaceManager::getWorld()->getLocalPlayerKart(playerNo)->action((KartAction) ka, value);
 		
 		return;
 	}
@@ -170,21 +170,21 @@ RaceGUI::handle(GameAction ga, int value)
 		case GA_DEBUG_ADD_BOWLING:
 			if (race_manager->getNumPlayers() ==1 )
 			{
-				Kart* kart = world->getLocalPlayerKart(0);
+				Kart* kart = RaceManager::getWorld()->getLocalPlayerKart(0);
 				kart->setCollectable(COLLECT_BOWLING, 10000);
 			}
 			break;
 		case GA_DEBUG_ADD_MISSILE:
 			if (race_manager->getNumPlayers() ==1 )
 			{
-				Kart* kart = world->getPlayerKart(0);
+				Kart* kart = RaceManager::getPlayerKart(0);
 				kart->setCollectable(COLLECT_MISSILE, 10000);
 			}
 			break;
 		case GA_DEBUG_ADD_HOMING:
 			if (race_manager->getNumPlayers() ==1 )
 			{
-				Kart* kart = world->getPlayerKart(0);
+				Kart* kart = RaceManager::getPlayerKart(0);
 				kart->setCollectable(COLLECT_HOMING, 10000);
 			}
 			break;
@@ -217,7 +217,7 @@ RaceGUI::handle(GameAction ga, int value)
 			// Fall through to put the game into pause mode.
 #endif
 		case GA_LEAVE_RACE:
-			world->pause();
+			RaceManager::getWorld()->pause();
 			menu_manager->pushMenu(MENUID_RACEMENU);
 		break;
 		case GA_DEBUG_HISTORY:
@@ -232,7 +232,6 @@ RaceGUI::handle(GameAction ga, int value)
 //-----------------------------------------------------------------------------
 void RaceGUI::update(float dt)
 {
-    assert(world != NULL);
     drawStatusText(dt);
     cleanupMessages();
 
@@ -260,14 +259,12 @@ void RaceGUI::drawFPS ()
 //-----------------------------------------------------------------------------
 void RaceGUI::drawTimer ()
 {
-   // if(world->getPhase() != RACE_PHASE         &&
-   //    world->getPhase() != DELAY_FINISH_PHASE   ) return;
-    if(!world->shouldDrawTimer()) return;
+    assert(RaceManager::getWorld() != NULL);
+    
+    if(!RaceManager::getWorld()->shouldDrawTimer()) return;
     char str[256];
-
-    assert(world != NULL);
-
-    TimeToString(world->getTime(), str);
+    
+    TimeToString(RaceManager::getWorld()->getTime(), str);
 #ifdef USE_WIDGET_MANAGER
     widget_manager->showWgtText( WTOK_CLOCK );
     widget_manager->setWgtText( WTOK_CLOCK, str );
@@ -283,17 +280,17 @@ void RaceGUI::drawTimer ()
 void RaceGUI::drawMap ()
 {
     glDisable ( GL_TEXTURE_2D ) ;
-    assert(world != NULL);
+    assert(RaceManager::getWorld() != NULL);
     int xLeft = 10;
     int yTop   =  10;
 
-    world -> m_track -> draw2Dview ( (float)xLeft,   (float)yTop   );
+    RaceManager::getTrack() -> draw2Dview ( (float)xLeft,   (float)yTop   );
 
     glBegin ( GL_QUADS ) ;
 
     for ( unsigned int i = 0 ; i < race_manager->getNumKarts() ; i++ )
     {
-        Kart* kart = world->getKart(i);
+        Kart* kart = RaceManager::getKart(i);
         if(kart->isEliminated()) continue;   // don't draw eliminated kart
         glColor3fv ( kart->getColor().toFloat());
 	const Vec3& xyz = kart->getXYZ();
@@ -301,17 +298,17 @@ void RaceGUI::drawMap ()
         /* If it's a player, draw a bigger sign */
         if (kart -> isPlayerKart ())
         {
-            world -> m_track->glVtx ( xyz.toFloat(), (float)xLeft+3, (float)yTop+3);
-            world -> m_track->glVtx ( xyz.toFloat(), (float)xLeft-2, (float)yTop+3);
-            world -> m_track->glVtx ( xyz.toFloat(), (float)xLeft-2, (float)yTop-2);
-            world -> m_track->glVtx ( xyz.toFloat(), (float)xLeft+3, (float)yTop-2);
+            RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft+3, (float)yTop+3);
+            RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft-2, (float)yTop+3);
+            RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft-2, (float)yTop-2);
+            RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft+3, (float)yTop-2);
         }
         else
         {
-            world -> m_track->glVtx ( xyz.toFloat(), (float)xLeft+2, (float)yTop+2);
-            world -> m_track->glVtx ( xyz.toFloat(), (float)xLeft-1, (float)yTop+2);
-            world -> m_track->glVtx ( xyz.toFloat(), (float)xLeft-1, (float)yTop-1);
-            world -> m_track->glVtx ( xyz.toFloat(), (float)xLeft+2, (float)yTop-1);
+            RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft+2, (float)yTop+2);
+            RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft-1, (float)yTop+2);
+            RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft-1, (float)yTop-1);
+            RaceManager::getTrack() -> glVtx ( xyz.toFloat(), (float)xLeft+2, (float)yTop-1);
         }
     }
 
@@ -323,7 +320,7 @@ void RaceGUI::drawMap ()
 // Draw players position on the race
 void RaceGUI::drawPlayerIcons ()
 {
-    assert(world != NULL);
+    assert(RaceManager::getWorld() != NULL);
 
     int x = 5;
     int y;
@@ -339,7 +336,7 @@ void RaceGUI::drawPlayerIcons ()
     // might have been overtaken by now
     for(unsigned int i = 0; i < race_manager->getNumKarts() ; i++)
     {
-        Kart* kart     = world->getKart(i);
+        Kart* kart     = RaceManager::getKart(i);
         if(kart->isEliminated()) continue;
         float lap_time = kart->getTimeAtLap();
         int laps       = kart->getLap();
@@ -359,7 +356,7 @@ void RaceGUI::drawPlayerIcons ()
     int bFirst                 = 1;
     for(unsigned int i = 0; i < race_manager->getNumKarts() ; i++)
     {
-        Kart* kart   = world->getKart(i);
+        Kart* kart   = RaceManager::getKart(i);
         if(kart->isEliminated()) continue;
         int position = kart->getPosition();
         int lap      = kart->getLap();
@@ -382,7 +379,7 @@ void RaceGUI::drawPlayerIcons ()
         glDisable(GL_CULL_FACE);
 
         if(laps_of_leader>0 &&    // Display position during first lap
-           (world->getTime() - kart->getTimeAtLap()<5.0f || lap!=laps_of_leader) &&
+           (RaceManager::getWorld()->getTime() - kart->getTimeAtLap()<5.0f || lap!=laps_of_leader) &&
            race_manager->raceHasLaps())
         {  // Display for 5 seconds
             char str[256];
@@ -394,7 +391,7 @@ void RaceGUI::drawPlayerIcons ()
             else
             {
                 float timeBehind;
-                timeBehind = (lap==laps_of_leader ? kart->getTimeAtLap() : world->getTime())
+                timeBehind = (lap==laps_of_leader ? kart->getTimeAtLap() : RaceManager::getWorld()->getTime())
                     - time_of_leader;
                 str[0]='+'; str[1]=0;
                 TimeToString(timeBehind, str+1);
@@ -901,7 +898,7 @@ void RaceGUI::drawMusicDescription()
 //-----------------------------------------------------------------------------
 void RaceGUI::drawStatusText(const float dt)
 {
-    assert(world != NULL);
+    assert(RaceManager::getWorld() != NULL);
 
     glMatrixMode   ( GL_MODELVIEW ) ;
     glPushMatrix   () ;
@@ -921,7 +918,7 @@ void RaceGUI::drawStatusText(const float dt)
     glEnable       ( GL_BLEND        );
 
     glOrtho        ( 0, user_config->m_width, 0, user_config->m_height, 0, 100 ) ;
-    switch (world->getPhase())
+    switch (RaceManager::getWorld()->getPhase())
     {
     case READY_PHASE:
         {
@@ -959,21 +956,21 @@ void RaceGUI::drawStatusText(const float dt)
 
     for(int i = 0; i < 10; ++i)
     {
-        if(world->m_debug_text[i] != "")
+        if(RaceManager::getWorld()->m_debug_text[i] != "")
         {
             GLfloat const COLORS[] = { 0.39f, 0.82f, 0.39f, 1.0f };
-            font_race->Print( world->m_debug_text[i].c_str(),
+            font_race->Print( RaceManager::getWorld()->m_debug_text[i].c_str(),
                              20, 20, 200 -i*20, COLORS );
         }
     }
     // The penalty message needs to be displayed for up to one second
     // after the start of the race, otherwise it disappears if 
     // "Go" is displayed and the race starts
-    if(world->getClock().isStartPhase() || world->getTime()<1.0f)
+    if(RaceManager::getWorld()->getClock().isStartPhase() || RaceManager::getWorld()->getTime()<1.0f)
     {
         for(unsigned int i=0; i<race_manager->getNumLocalPlayers(); i++)
         {
-            if(world->getLocalPlayerKart(i)->earlyStartPenalty())
+            if(RaceManager::getWorld()->getLocalPlayerKart(i)->earlyStartPenalty())
             {
                 GLfloat const COLORS[] = { 0.78f, 0.025f, 0.025f, 1.0f };
                 font_race->PrintShadow( _("Penalty time!!"), 80,
@@ -990,7 +987,7 @@ void RaceGUI::drawStatusText(const float dt)
     if(race_manager->getNumLocalPlayers() >= 3)
         split_screen_ratio_x = 0.5;
 
-    if ( world->getClock().isRacePhase() )
+    if ( RaceManager::getWorld()->getClock().isRacePhase() )
     {
         const int numPlayers = race_manager->getNumLocalPlayers();
 
@@ -1026,7 +1023,7 @@ void RaceGUI::drawStatusText(const float dt)
                 offset_x = user_config->m_width/2;
             }
 
-            Kart* player_kart=world->getLocalPlayerKart(pla);
+            Kart* player_kart = RaceManager::getWorld()->getLocalPlayerKart(pla);
             drawCollectableIcons(player_kart, offset_x, offset_y,
                                  split_screen_ratio_x, split_screen_ratio_y );
             drawEnergyMeter     (player_kart, offset_x, offset_y,
@@ -1043,12 +1040,12 @@ void RaceGUI::drawStatusText(const float dt)
                                  split_screen_ratio_x, split_screen_ratio_y );
         }   // for pla
         drawTimer           ();
-        if(world->getTime()<TIME_MUSIC_DESCRIPTION 
+        if(RaceManager::getWorld()->getTime()<TIME_MUSIC_DESCRIPTION 
           && race_manager->getMinorMode() != RaceManager::RM_FOLLOW_LEADER)
         {
             drawMusicDescription();
         }
-        else if (world->getTime()>stk_config->m_leader_intervals[0]-TIME_MUSIC_DESCRIPTION 
+        else if (RaceManager::getWorld()->getTime()>stk_config->m_leader_intervals[0]-TIME_MUSIC_DESCRIPTION 
           && race_manager->getMinorMode()== RaceManager::RM_FOLLOW_LEADER)
             drawMusicDescription();
             
diff --git a/src/gui/race_gui.hpp b/src/gui/race_gui.hpp
index 4c0e7ff5b..f275933a4 100644
--- a/src/gui/race_gui.hpp
+++ b/src/gui/race_gui.hpp
@@ -29,8 +29,8 @@
 #include "material.hpp"
 #include "player_kart.hpp"
 #include "player.hpp"
-#include "world.hpp"
 #include "race_manager.hpp"
+#include "modes/world.hpp"
 
 class InputMap;
 class RaceSetup;
@@ -56,18 +56,20 @@ class RaceGUI: public BaseGUI
             m_message    = message; 
             m_font_size  = size;
             m_kart       = kart;
-            m_end_time   = time>=0.0f 
-                         ? (race_manager->getMinorMode()==RaceManager::RM_FOLLOW_LEADER 
-                            ?world->getTime()-time
-                            :world->getTime()+time )
-                         : -1.0f;
+            World* world = RaceManager::getWorld();
+            if( time < 0.0f ) m_end_time = -1.0f;
+            else
+            {
+                m_end_time = race_manager->getMinorMode()==RaceManager::RM_FOLLOW_LEADER ?
+                             world->getTime()-time : world->getTime()+time;
+            }
             m_red=red; m_blue=blue; m_green=green; 
         }
         // in follow leader the clock counts backwards
-        bool done() const {return m_end_time<0 || 
-                           (race_manager->getMinorMode()==RaceManager::RM_FOLLOW_LEADER 
-                                  ? world->getTime()<m_end_time
-                                  : world->getTime()>m_end_time);}
+        bool done() const { const int time = RaceManager::getWorld()->getTime(); // work around gcc bug (doesn't accept :: in a ?)
+                            return m_end_time<0 || 
+                            (race_manager->getMinorMode()==RaceManager::RM_FOLLOW_LEADER ?
+                             time<m_end_time : time>m_end_time); }
     };
 public:
 
diff --git a/src/gui/race_menu.cpp b/src/gui/race_menu.cpp
index e0984f81f..2c386cfa0 100644
--- a/src/gui/race_menu.cpp
+++ b/src/gui/race_menu.cpp
@@ -22,7 +22,6 @@
 #include "widget_manager.hpp"
 #include "user_config.hpp"
 #include "race_menu.hpp"
-#include "world.hpp"
 
 #include "menu_manager.hpp"
 #include "race_manager.hpp"
@@ -77,13 +76,13 @@ void RaceMenu::select()
     switch (clicked_token)
     {
     case WTOK_RETURN_RACE:
-        world->unpause();
+        RaceManager::getWorld()->unpause();
         menu_manager->popMenu();
         if(user_config->m_fullscreen) SDL_ShowCursor(SDL_DISABLE);
         break;
 
     case WTOK_SETUP_NEW_RACE:
-        world->unpause();
+        RaceManager::getWorld()->unpause();
         race_manager->exit_race();
         menu_manager->pushMenu(MENUID_CHARSEL_P1);
         break;
@@ -91,7 +90,7 @@ void RaceMenu::select()
     case WTOK_RESTART_RACE:
         menu_manager->popMenu();
         if(user_config->m_fullscreen) SDL_ShowCursor(SDL_DISABLE);
-        world->restartRace();
+        RaceManager::getWorld()->restartRace();
         break;
 
     case WTOK_OPTIONS:
@@ -103,7 +102,7 @@ void RaceMenu::select()
         break;
 
     case WTOK_QUIT:
-        world->unpause();
+        RaceManager::getWorld()->unpause();
         race_manager->exit_race();
         break;
 
@@ -121,7 +120,7 @@ void RaceMenu::handle(GameAction ga, int value)
         if (value)
             break;
 		
-        world->unpause();
+        RaceManager::getWorld()->unpause();
         menu_manager->popMenu();
         break;
 
diff --git a/src/gui/race_results_gui.cpp b/src/gui/race_results_gui.cpp
index 3d3fc7695..36011b150 100644
--- a/src/gui/race_results_gui.cpp
+++ b/src/gui/race_results_gui.cpp
@@ -23,12 +23,12 @@
 #include "race_results_gui.hpp"
 #include "widget_manager.hpp"
 #include "kart_properties.hpp"
-#include "world.hpp"
 #include "menu_manager.hpp"
 #include "race_manager.hpp"
 #include "highscore_manager.hpp"
 #include "unlock_manager.hpp"
 #include "translation.hpp"
+#include "modes/world.hpp"
 
 enum WidgetTokens
 {
@@ -121,7 +121,7 @@ Widget *RaceResultsGUI::displayLeaderResults()
         }
     } while(!sorted);
     for(unsigned int i=1; i<NUM_KARTS; i++)
-        world->getKart(order[i])->setPosition(i);
+        RaceManager::getKart(order[i])->setPosition(i);
 
     Widget *w_prev=widget_manager->addTextWgt( WTOK_RESULTS, 5, 7, _("Race results") );
     widget_manager->hideWgtRect(WTOK_RESULTS);
@@ -151,7 +151,7 @@ Widget *RaceResultsGUI::displayRaceResults()
 
     for(unsigned int i=0; i < NUM_KARTS; i++)
     {
-        Kart *k = world->getKart(i);             // Display even for eliminated karts!
+        Kart *k = RaceManager::getKart(i);             // Display even for eliminated karts!
         order[k->getPosition()-1] = i;
         const std::string& s = k->getName();
         unsigned int l = (unsigned int)s.size();
@@ -168,7 +168,7 @@ Widget *RaceResultsGUI::displayRaceResults()
     widget_manager->hideWgtRect(WTOK_HIGHSCORES);
     w_prev->setPosition(WGT_DIR_FROM_RIGHT, 0.1f, NULL, WGT_DIR_FROM_TOP, 0.1f, NULL);
 
-    const Highscores *hs = world->getHighscores();
+    const Highscores *hs = RaceManager::getWorld()->getHighscores();
     unsigned int num_scores = hs->getNumberEntries();
     char *highscores = new char[num_scores * MAX_STR_LEN];
 
@@ -204,7 +204,7 @@ Widget *RaceResultsGUI::displayKartList(unsigned int from, unsigned int to,
     char *score = new char[(to-from+1) * MAX_STR_LEN];
     for(unsigned int i = from; i <= to; ++i)
     {
-        const Kart *KART = world->getKart(order[i]);
+        const Kart *KART = RaceManager::getKart(order[i]);
         const std::string& KART_NAME = KART->getName();
         char sTime[20];sTime[0]=0;
         const float T      = KART->getFinishTime();
@@ -265,16 +265,16 @@ void RaceResultsGUI::select()
         // 1) something was unlocked
         // 2) a Grand Prix is run
         // 3) "back to the main menu" otherwise
-        world->unpause();
+        RaceManager::getWorld()->unpause();
         race_manager->next();
         break;
     case WTOK_RESTART_RACE:
-        world->unpause();
+        RaceManager::getWorld()->unpause();
         menu_manager->popMenu();
         race_manager->rerunRace();
         break;
     case WTOK_SETUP_NEW_RACE:
-        world->unpause();
+        RaceManager::getWorld()->unpause();
         race_manager->exit_race();
         menu_manager->pushMenu(MENUID_GAMEMODE);
         break;
diff --git a/src/herring.cpp b/src/herring.cpp
index af151c66e..38f316d40 100644
--- a/src/herring.cpp
+++ b/src/herring.cpp
@@ -18,7 +18,6 @@
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "vec3.hpp"
-#include "world.hpp"
 #include "herring.hpp"
 #include "kart.hpp"
 #include "scene.hpp"
diff --git a/src/history.cpp b/src/history.cpp
index 2634a55ac..ce72022e3 100644
--- a/src/history.cpp
+++ b/src/history.cpp
@@ -18,7 +18,6 @@
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "history.hpp"
-#include "world.hpp"
 #include "kart.hpp"
 #include "track.hpp"
 #include "race_manager.hpp"
@@ -68,12 +67,12 @@ void History::Save()
     fprintf(fd, "numkarts: %d\n",   nKarts);
     fprintf(fd, "numplayers: %d\n", race_manager->getNumPlayers());
     fprintf(fd, "difficulty: %d\n", race_manager->getDifficulty());
-    fprintf(fd, "track: %s\n",      world->getTrack()->getIdent().c_str());
+    fprintf(fd, "track: %s\n",      RaceManager::getTrack()->getIdent().c_str());
 
     int k;
     for(k=0; k<nKarts; k++)
     {
-        fprintf(fd, "model %d: %s\n",k, world->getKart(k)->getName().c_str());
+        fprintf(fd, "model %d: %s\n",k, RaceManager::getKart(k)->getName().c_str());
     }
     fprintf(fd, "size:     %d\n", GetCount());
 
@@ -86,7 +85,7 @@ void History::Save()
 
     for(int k=0; k<nKarts; k++)
     {
-        Kart* kart= world->getKart(k);
+        Kart* kart= RaceManager::getKart(k);
         char s[1024];
         j = m_wrapped ? m_current : 0;
         for(int i=0; i<GetCount(); i++)
diff --git a/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj b/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj
index 04058b0ba..a4e1b16e0 100644
--- a/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj
+++ b/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj
@@ -112,7 +112,6 @@
 		95F0F2C10E85C054005F6693 /* actionmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95923D6E0E808ED700388BDC /* actionmap.cpp */; };
 		95F0F2C20E85C054005F6693 /* btOdeQuickstepConstraintSolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95923F160E808EDB00388BDC /* btOdeQuickstepConstraintSolver.cpp */; };
 		95F0F2C30E85C054005F6693 /* btSequentialImpulseConstraintSolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95923F1D0E808EDB00388BDC /* btSequentialImpulseConstraintSolver.cpp */; };
-		95F0F2C40E85C054005F6693 /* world.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 959242080E808EE300388BDC /* world.cpp */; };
 		95F0F2C50E85C054005F6693 /* particle_system.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 959241900E808EE200388BDC /* particle_system.cpp */; };
 		95F0F2C60E85C054005F6693 /* network_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9592417F0E808EE200388BDC /* network_manager.cpp */; };
 		95F0F2C70E85C054005F6693 /* btPersistentManifold.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95923EFA0E808EDA00388BDC /* btPersistentManifold.cpp */; };
@@ -228,6 +227,10 @@
 		95F0F3360E85C054005F6693 /* btSphereTriangleCollisionAlgorithm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95923EA30E808EDA00388BDC /* btSphereTriangleCollisionAlgorithm.cpp */; };
 		95F0F3380E85C054005F6693 /* parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 959241440E808EE100388BDC /* parser.cpp */; };
 		95F0F35D0E85C140005F6693 /* random_generator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 956F3FAB0E85BE0E006F93B0 /* random_generator.cpp */; };
+		95F0F36E0E85C6A6005F6693 /* clock.hpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 95F0F36C0E85C6A6005F6693 /* clock.hpp */; };
+		95F0F36F0E85C6A6005F6693 /* clock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95F0F36D0E85C6A6005F6693 /* clock.cpp */; };
+		95F0F3830E85C76B005F6693 /* world.hpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 95F0F3810E85C76B005F6693 /* world.hpp */; };
+		95F0F3840E85C76B005F6693 /* world.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95F0F3820E85C76B005F6693 /* world.cpp */; };
 		95F423130E26E3DC00692113 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95F423120E26E3DC00692113 /* OpenGL.framework */; };
 		95F4231F0E26E44800692113 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95F4231E0E26E44800692113 /* Cocoa.framework */; };
 		95F423300E26E58400692113 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95F4232F0E26E58400692113 /* Carbon.framework */; };
@@ -243,6 +246,8 @@
 			dstPath = /usr/share/man/man1/;
 			dstSubfolderSpec = 0;
 			files = (
+				95F0F36E0E85C6A6005F6693 /* clock.hpp in CopyFiles */,
+				95F0F3830E85C76B005F6693 /* world.hpp in CopyFiles */,
 			);
 			runOnlyForDeploymentPostprocessing = 1;
 		};
@@ -716,8 +721,6 @@
 		959241F70E808EE300388BDC /* user_pointer.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = user_pointer.hpp; sourceTree = "<group>"; };
 		959241FB0E808EE300388BDC /* vec3.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = vec3.cpp; sourceTree = "<group>"; };
 		959241FC0E808EE300388BDC /* vec3.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = vec3.hpp; sourceTree = "<group>"; };
-		959242080E808EE300388BDC /* world.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = world.cpp; sourceTree = "<group>"; };
-		959242090E808EE300388BDC /* world.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = world.hpp; sourceTree = "<group>"; };
 		95B422010E8586A900FA795B /* music.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = music.hpp; sourceTree = "<group>"; };
 		95B422020E8586A900FA795B /* music_information.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = music_information.cpp; sourceTree = "<group>"; };
 		95B422030E8586A900FA795B /* music_information.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = music_information.hpp; sourceTree = "<group>"; };
@@ -977,6 +980,10 @@
 		95E106DB0E28F66200503124 /* btTransformUtil.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = btTransformUtil.h; sourceTree = "<group>"; };
 		95E106DC0E28F66200503124 /* btTypedUserInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = btTypedUserInfo.h; sourceTree = "<group>"; };
 		95E106DD0E28F66200503124 /* btVector3.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = btVector3.h; sourceTree = "<group>"; };
+		95F0F36C0E85C6A6005F6693 /* clock.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = clock.hpp; path = modes/clock.hpp; sourceTree = "<group>"; };
+		95F0F36D0E85C6A6005F6693 /* clock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = clock.cpp; path = modes/clock.cpp; sourceTree = "<group>"; };
+		95F0F3810E85C76B005F6693 /* world.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = world.hpp; path = modes/world.hpp; sourceTree = "<group>"; };
+		95F0F3820E85C76B005F6693 /* world.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = world.cpp; path = modes/world.cpp; sourceTree = "<group>"; };
 		95F4221E0E26DF0A00692113 /* SuperTuxKart */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SuperTuxKart; sourceTree = BUILT_PRODUCTS_DIR; };
 		95F423120E26E3DC00692113 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
 		95F4231E0E26E44800692113 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
@@ -1042,10 +1049,13 @@
 			isa = PBXGroup;
 			children = (
 				95B422000E8586A900FA795B /* audio */,
-				957B11D70E8320CD002A69EA /* follow_the_leader.hpp */,
-				957B11D80E8320CD002A69EA /* follow_the_leader.cpp */,
-				957B11B30E831DA8002A69EA /* standard_race.hpp */,
-				957B11B40E831DA8002A69EA /* standard_race.cpp */,
+				95F0F3710E85C6D3005F6693 /* modes */,
+				95923F6A0E808EDC00388BDC /* challenges */,
+				95923FD50E808EDD00388BDC /* gui */,
+				956F3FAA0E85BE0E006F93B0 /* utils */,
+				9592413F0E808EE100388BDC /* lisp */,
+				9592416F0E808EE200388BDC /* network */,
+				959241B50E808EE200388BDC /* robots */,
 				95923D6E0E808ED700388BDC /* actionmap.cpp */,
 				95923D6F0E808ED700388BDC /* actionmap.hpp */,
 				95923D710E808ED700388BDC /* attachment.cpp */,
@@ -1055,20 +1065,17 @@
 				95923D770E808ED700388BDC /* auto_kart.hpp */,
 				95923D790E808ED700388BDC /* bowling.cpp */,
 				95923D7A0E808ED700388BDC /* bowling.hpp */,
-				95923D7C0E808ED700388BDC /* bullet */,
 				95923F610E808EDB00388BDC /* callback.hpp */,
 				95923F620E808EDB00388BDC /* callback_manager.cpp */,
 				95923F630E808EDB00388BDC /* callback_manager.hpp */,
 				95923F650E808EDB00388BDC /* camera.cpp */,
 				95923F660E808EDB00388BDC /* camera.hpp */,
-				95923F6A0E808EDC00388BDC /* challenges */,
 				95923F710E808EDC00388BDC /* collectable.cpp */,
 				95923F720E808EDC00388BDC /* collectable.hpp */,
 				95923F740E808EDC00388BDC /* collectable_manager.cpp */,
 				95923F750E808EDC00388BDC /* collectable_manager.hpp */,
 				95923F7B0E808EDC00388BDC /* constants.hpp */,
 				95923F7C0E808EDC00388BDC /* coord.hpp */,
-				95923F800E808EDC00388BDC /* enet */,
 				95923FC00E808EDD00388BDC /* explosion.cpp */,
 				95923FC10E808EDD00388BDC /* explosion.hpp */,
 				95923FC40E808EDD00388BDC /* file_manager.cpp */,
@@ -1079,11 +1086,9 @@
 				95923FCE0E808EDD00388BDC /* grand_prix_data.hpp */,
 				95923FD10E808EDD00388BDC /* grand_prix_manager.cpp */,
 				95923FD20E808EDD00388BDC /* grand_prix_manager.hpp */,
-				95923FD50E808EDD00388BDC /* gui */,
 				959240150E808EDD00388BDC /* herring.cpp */,
 				959240160E808EDD00388BDC /* herring.hpp */,
 				959240180E808EDD00388BDC /* herring_manager.cpp */,
-				956F3FAA0E85BE0E006F93B0 /* utils */,
 				959240190E808EDD00388BDC /* herring_manager.hpp */,
 				9592401B0E808EDD00388BDC /* highscore_manager.cpp */,
 				9592401C0E808EDD00388BDC /* highscore_manager.hpp */,
@@ -1103,7 +1108,6 @@
 				959241360E808EE100388BDC /* kart_properties.hpp */,
 				959241380E808EE100388BDC /* kart_properties_manager.cpp */,
 				959241390E808EE100388BDC /* kart_properties_manager.hpp */,
-				9592413F0E808EE100388BDC /* lisp */,
 				959241490E808EE100388BDC /* loader.cpp */,
 				9592414A0E808EE100388BDC /* loader.hpp */,
 				9592414C0E808EE100388BDC /* main.cpp */,
@@ -1121,7 +1125,6 @@
 				959241630E808EE200388BDC /* moving_physics.hpp */,
 				959241650E808EE200388BDC /* moving_texture.cpp */,
 				959241660E808EE200388BDC /* moving_texture.hpp */,
-				9592416F0E808EE200388BDC /* network */,
 				9592418C0E808EE200388BDC /* no_copy.hpp */,
 				959241900E808EE200388BDC /* particle_system.cpp */,
 				959241910E808EE200388BDC /* particle_system.hpp */,
@@ -1143,7 +1146,6 @@
 				959241B00E808EE200388BDC /* replay_player.hpp */,
 				959241B20E808EE200388BDC /* replay_recorder.cpp */,
 				959241B30E808EE200388BDC /* replay_recorder.hpp */,
-				959241B50E808EE200388BDC /* robots */,
 				959241BD0E808EE200388BDC /* scene.cpp */,
 				959241BE0E808EE200388BDC /* scene.hpp */,
 				959241C00E808EE200388BDC /* sdldrv.cpp */,
@@ -1178,8 +1180,8 @@
 				959241F70E808EE300388BDC /* user_pointer.hpp */,
 				959241FB0E808EE300388BDC /* vec3.cpp */,
 				959241FC0E808EE300388BDC /* vec3.hpp */,
-				959242080E808EE300388BDC /* world.cpp */,
-				959242090E808EE300388BDC /* world.hpp */,
+				95923D7C0E808ED700388BDC /* bullet */,
+				95923F800E808EDC00388BDC /* enet */,
 			);
 			name = src;
 			path = ../..;
@@ -2043,6 +2045,21 @@
 			path = LinearMath;
 			sourceTree = "<group>";
 		};
+		95F0F3710E85C6D3005F6693 /* modes */ = {
+			isa = PBXGroup;
+			children = (
+				95F0F3810E85C76B005F6693 /* world.hpp */,
+				95F0F3820E85C76B005F6693 /* world.cpp */,
+				95F0F36C0E85C6A6005F6693 /* clock.hpp */,
+				95F0F36D0E85C6A6005F6693 /* clock.cpp */,
+				957B11D70E8320CD002A69EA /* follow_the_leader.hpp */,
+				957B11D80E8320CD002A69EA /* follow_the_leader.cpp */,
+				957B11B30E831DA8002A69EA /* standard_race.hpp */,
+				957B11B40E831DA8002A69EA /* standard_race.cpp */,
+			);
+			name = modes;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -2189,7 +2206,6 @@
 				95F0F2C10E85C054005F6693 /* actionmap.cpp in Sources */,
 				95F0F2C20E85C054005F6693 /* btOdeQuickstepConstraintSolver.cpp in Sources */,
 				95F0F2C30E85C054005F6693 /* btSequentialImpulseConstraintSolver.cpp in Sources */,
-				95F0F2C40E85C054005F6693 /* world.cpp in Sources */,
 				95F0F2C50E85C054005F6693 /* particle_system.cpp in Sources */,
 				95F0F2C60E85C054005F6693 /* network_manager.cpp in Sources */,
 				95F0F2C70E85C054005F6693 /* btPersistentManifold.cpp in Sources */,
@@ -2305,6 +2321,8 @@
 				95F0F3360E85C054005F6693 /* btSphereTriangleCollisionAlgorithm.cpp in Sources */,
 				95F0F3380E85C054005F6693 /* parser.cpp in Sources */,
 				95F0F35D0E85C140005F6693 /* random_generator.cpp in Sources */,
+				95F0F36F0E85C6A6005F6693 /* clock.cpp in Sources */,
+				95F0F3840E85C76B005F6693 /* world.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/src/kart.cpp b/src/kart.cpp
index b9ece4089..7ded0cf46 100644
--- a/src/kart.cpp
+++ b/src/kart.cpp
@@ -37,7 +37,6 @@
 #include "constants.hpp"
 #include "shadow.hpp"
 #include "track.hpp"
-#include "world.hpp"
 #include "kart.hpp"
 #include "physics.hpp"
 #include "translation.hpp"
@@ -180,7 +179,7 @@ void Kart::createPhysics(ssgEntity *obj)
     // Create the actual vehicle
     // -------------------------
     m_vehicle_raycaster = 
-        new btDefaultVehicleRaycaster(world->getPhysics()->getPhysicsWorld());
+        new btDefaultVehicleRaycaster(RaceManager::getWorld()->getPhysics()->getPhysicsWorld());
     m_tuning  = new btRaycastVehicle::btVehicleTuning();
 	m_tuning->m_maxSuspensionTravelCm = m_kart_properties->getSuspensionTravelCM();
     m_vehicle = new btRaycastVehicle(*m_tuning, m_body, m_vehicle_raycaster);
@@ -251,7 +250,7 @@ void Kart::createPhysics(ssgEntity *obj)
     m_uprightConstraint->setErp(1.0f);
     m_uprightConstraint->setLimitSoftness(1.0f);
     m_uprightConstraint->setDamping(0.0f);
-    world->getPhysics()->addKart(this, m_vehicle);
+    RaceManager::getWorld()->getPhysics()->addKart(this, m_vehicle);
 
     //create the engine sound
     if(m_engine_sound)
@@ -290,7 +289,7 @@ Kart::~Kart()
     if(m_skidmark_left ) delete m_skidmark_left ;
     if(m_skidmark_right) delete m_skidmark_right;
 
-    world->getPhysics()->removeKart(this);
+    RaceManager::getWorld()->getPhysics()->removeKart(this);
     delete m_vehicle;
     delete m_tuning;
     delete m_vehicle_raycaster;
@@ -305,7 +304,7 @@ Kart::~Kart()
 void Kart::eliminate()
 {
     m_eliminated = true;
-    world->getPhysics()->removeKart(this);
+    RaceManager::getWorld()->getPhysics()->removeKart(this);
 
     // make the kart invisible by placing it way under the track
     sgVec3 hell; hell[0]=0.0f; hell[1]=0.0f; hell[2] = -10000.0f;
@@ -341,7 +340,7 @@ void Kart::reset()
 {
     if(m_eliminated)
     {
-        world->getPhysics()->addKart(this, m_vehicle);
+        RaceManager::getWorld()->getPhysics()->addKart(this, m_vehicle);
     }
 
     m_attachment.clear();
@@ -373,14 +372,14 @@ void Kart::reset()
 
     setTrans(m_reset_transform);
 
-    world->m_track->findRoadSector(getXYZ(), &m_track_sector);
+    RaceManager::getTrack()->findRoadSector(getXYZ(), &m_track_sector);
 
     //If m_track_sector == UNKNOWN_SECTOR, then the kart is not on top of
     //the road, so we have to use another function to find the sector.
     if (m_track_sector == Track::UNKNOWN_SECTOR )
     {
         m_on_road = false;
-        m_track_sector = world->m_track->findOutOfRoadSector(
+        m_track_sector = RaceManager::getTrack()->findOutOfRoadSector(
             getXYZ(), Track::RS_DONT_KNOW, Track::UNKNOWN_SECTOR );
     }
     else
@@ -388,7 +387,7 @@ void Kart::reset()
         m_on_road = true;
     }
 
-    world->m_track->spatialToTrack(m_curr_track_coords, getXYZ(),
+    RaceManager::getTrack()->spatialToTrack(m_curr_track_coords, getXYZ(),
                                    m_track_sector );
 
     m_vehicle->applyEngineForce (0.0f, 2);
@@ -404,7 +403,7 @@ void Kart::reset()
     // add the vehicle back into the physical world!
     if(m_rescue)
     {
-        world->getPhysics()->addKart(this, m_vehicle);
+        RaceManager::getWorld()->getPhysics()->addKart(this, m_vehicle);
     }
     m_rescue               = false;
     TerrainInfo::update(getXYZ());
@@ -421,7 +420,7 @@ void Kart::doLapCounting ()
         // will begin another countdown).
         if(m_race_lap+1<=race_manager->getNumLaps())
         {
-            setTimeAtLap(world->getTime());
+            setTimeAtLap(RaceManager::getWorld()->getTime());
             m_race_lap++ ;
         }
         // Race finished
@@ -429,7 +428,7 @@ void Kart::doLapCounting ()
         if(m_race_lap>=race_manager->getNumLaps() && 
             race_manager->getMinorMode()!=RaceManager::RM_FOLLOW_LEADER)
         {
-            raceFinished(world->getTime());
+            raceFinished(RaceManager::getWorld()->getTime());
         }
         // Only do timings if original time was set properly. Driving backwards
         // over the start line will cause the lap start time to be set to -1.
@@ -438,17 +437,17 @@ void Kart::doLapCounting ()
             float time_per_lap;
             if (m_race_lap == 1) // just completed first lap
             {
-            	time_per_lap=world->getTime();
+            	time_per_lap=RaceManager::getWorld()->getTime();
             }
             else //completing subsequent laps
             {
-            	time_per_lap=world->getTime()-m_lap_start_time;
+            	time_per_lap=RaceManager::getWorld()->getTime()-m_lap_start_time;
             }
                         
-            if(time_per_lap < world->getFastestLapTime() &&
+            if(time_per_lap < RaceManager::getWorld()->getFastestLapTime() &&
                 race_manager->raceHasLaps())
             {
-                world->setFastestLap(this, time_per_lap);
+                RaceManager::getWorld()->setFastestLap(this, time_per_lap);
                 RaceGUI* m=(RaceGUI*)menu_manager->getRaceMenu();
                 if(m)
                 {
@@ -461,14 +460,14 @@ void Kart::doLapCounting ()
                     m->addMessage(m_fastest_lap_message, NULL, 
                                   2.0f, 40, 100, 210, 100);
                 }   // if m
-            }   // if time_per_lap < world->getFasterstLapTime()
+            }   // if time_per_lap < RaceManager::getWorld()->getFasterstLapTime()
             if(isPlayerKart())
             {
                 // Put in in the highscore list???
                 //printf("Time per lap: %s %f\n", getName().c_str(), time_per_lap);
             }
         }
-        m_lap_start_time = world->getTime();
+        m_lap_start_time = RaceManager::getWorld()->getTime();
     }
     else if ( m_curr_track_coords.getY() > 300.0f && m_last_track_coords[1] <  20.0f)
     {
@@ -479,7 +478,7 @@ void Kart::doLapCounting ()
     } else
     {   // Switch to fast music in case of follow the leader when only 3 karts are left
         if(race_manager->getMinorMode()==RaceManager::RM_FOLLOW_LEADER &&
-            world->getCurrentNumKarts()==3)  
+            RaceManager::getWorld()->getCurrentNumKarts()==3)  
         {
             sound_manager->switchToFastMusic();
         }
@@ -625,7 +624,7 @@ void Kart::update(float dt)
             m_attachment.set( ATTACH_TINYTUX, rescue_time ) ;
             m_rescue_pitch = getHPR().getPitch();
             m_rescue_roll  = getHPR().getRoll();
-            world->getPhysics()->removeKart(this);
+            RaceManager::getWorld()->getPhysics()->removeKart(this);
             race_state->herringCollected(getWorldKartId(), -1, -1);
         }
         btQuaternion q_roll (btVector3(0.f, 1.f, 0.f),
@@ -706,10 +705,10 @@ void Kart::update(float dt)
 
     int prev_sector = m_track_sector;
     if(!m_rescue)
-        world->m_track->findRoadSector(getXYZ(), &m_track_sector);
+        RaceManager::getTrack()->findRoadSector(getXYZ(), &m_track_sector);
 
     // Check if the kart is taking a shortcut (if it's not already doing one):
-    if(!m_rescue && world->m_track->isShortcut(prev_sector, m_track_sector))
+    if(!m_rescue && RaceManager::getTrack()->isShortcut(prev_sector, m_track_sector))
     {
 	    forceRescue(/*is rescue*/ true);  // bring karts back to where they left the track.     
 	    if(isPlayerKart())
@@ -726,10 +725,10 @@ void Kart::update(float dt)
     {
         m_on_road = false;
         if( m_curr_track_coords[0] > 0.0 )
-            m_track_sector = world->m_track->findOutOfRoadSector(
+            m_track_sector = RaceManager::getTrack()->findOutOfRoadSector(
                getXYZ(), Track::RS_RIGHT, prev_sector );
         else
-            m_track_sector = world->m_track->findOutOfRoadSector(
+            m_track_sector = RaceManager::getTrack()->findOutOfRoadSector(
                getXYZ(), Track::RS_LEFT, prev_sector );
     }
     else
@@ -737,7 +736,7 @@ void Kart::update(float dt)
         m_on_road = true;
     }
 
-    world->m_track->spatialToTrack( m_curr_track_coords, 
+    RaceManager::getTrack()->spatialToTrack( m_curr_track_coords, 
                                     getXYZ(),
                                     m_track_sector      );
 
@@ -771,7 +770,7 @@ void Kart::draw()
     t.getOpenGLMatrix(m);
 
     btVector3 wire_color(0.5f, 0.5f, 0.5f);
-    world->getPhysics()->debugDraw(m, m_body->getCollisionShape(), 
+    RaceManager::getWorld()->getPhysics()->debugDraw(m, m_body->getCollisionShape(), 
                                    wire_color);
     btCylinderShapeX wheelShape( btVector3(0.1f,
                                         m_kart_properties->getWheelRadius(),
@@ -782,7 +781,7 @@ void Kart::draw()
         m_vehicle->updateWheelTransform(i, true);
         float m[16];
         m_vehicle->getWheelInfo(i).m_worldTransform.getOpenGLMatrix(m);
-        world->getPhysics()->debugDraw(m, &wheelShape, wheelColor);
+        RaceManager::getWorld()->getPhysics()->debugDraw(m, &wheelShape, wheelColor);
     }
 }   // draw
 
@@ -985,9 +984,9 @@ void Kart::forceRescue(bool is_shortcut)
 void Kart::endRescue()
 {
     if ( m_track_sector > 0 ) m_track_sector-- ;
-    setXYZ( world->m_track->trackToSpatial(m_track_sector) );
+    setXYZ( RaceManager::getTrack()->trackToSpatial(m_track_sector) );
     btQuaternion heading(btVector3(0.0f, 0.0f, 1.0f), 
-                         DEGREE_TO_RAD(world->m_track->m_angle[m_track_sector]) );
+                         DEGREE_TO_RAD(RaceManager::getTrack()->m_angle[m_track_sector]) );
     setRotation(heading);
     m_rescue = false ;
 
@@ -1005,9 +1004,9 @@ void Kart::endRescue()
     // a rescue, ...
     pos.setOrigin(getXYZ()+btVector3(0, 0, 0.5f*getKartHeight()+0.1f));
     pos.setRotation(btQuaternion(btVector3(0.0f, 0.0f, 1.0f), 
-                                 DEGREE_TO_RAD(world->m_track->m_angle[m_track_sector])));
+                                 DEGREE_TO_RAD(RaceManager::getTrack()->m_angle[m_track_sector])));
     m_body->setCenterOfMassTransform(pos);
-    world->getPhysics()->addKart(this, m_vehicle);
+    RaceManager::getWorld()->getPhysics()->addKart(this, m_vehicle);
     setTrans(pos);
 }   // endRescue
 
@@ -1179,16 +1178,16 @@ float Kart::estimateFinishTime  ()
     // higher average speed and therefore finish the race earlier 
     // than karts further behind), so the position doesn't have to
     // be updated to get the correct scoring.
-    float distance_covered  = getLap()*world->m_track->getTrackLength()
+    float distance_covered  = getLap()*RaceManager::getTrack()->getTrackLength()
                             + getDistanceDownTrack();
     // In case that a kart is rescued behind start line, or ...
     if(distance_covered<0) distance_covered =1.0f;
 
-    float average_speed     = distance_covered/world->getTime();
+    float average_speed     = distance_covered/RaceManager::getWorld()->getTime();
 
     // Finish time is the time needed for the whole race with 
     // the average speed computed above.
-    return race_manager->getNumLaps()*world->getTrack()->getTrackLength() 
+    return race_manager->getNumLaps()*RaceManager::getTrack()->getTrackLength() 
           / average_speed;
 
 }   // estimateFinishTime
diff --git a/src/main_loop.cpp b/src/main_loop.cpp
index 568130683..a9375068d 100644
--- a/src/main_loop.cpp
+++ b/src/main_loop.cpp
@@ -35,7 +35,7 @@
 #include "audio/sound_manager.hpp"
 #include "material_manager.hpp"
 #include "race_manager.hpp"
-#include "world.hpp"
+#include "modes/world.hpp"
 #include "user_config.hpp"
 #include "scene.hpp"
 #include "history.hpp"
@@ -120,18 +120,18 @@ void MainLoop::run()
             if(user_config->m_profile) dt=1.0f/60.0f;
             // In the first call dt might be large (includes loading time),
             // which can cause the camera to significantly tilt
-            scene->draw(world->getPhase()==SETUP_PHASE ? 0.0f : dt);
+            scene->draw(RaceManager::getWorld()->getPhase()==SETUP_PHASE ? 0.0f : dt);
 
             network_manager->receiveUpdates();
 
-            if ( world->getPhase() != LIMBO_PHASE)
+            if ( RaceManager::getWorld()->getPhase() != LIMBO_PHASE)
             {
-                world->update(dt);
+                RaceManager::getWorld()->update(dt);
 
                 if(user_config->m_profile>0)
                 {
                     m_frame_count++;
-                    if (world->getTime()>user_config->m_profile)
+                    if (RaceManager::getWorld()->getTime()>user_config->m_profile)
                     {
                         //FIXME: SDL_GetTicks() includes the loading time,
                         //so the FPS will be skewed for now.
diff --git a/src/modes/follow_the_leader.cpp b/src/modes/follow_the_leader.cpp
index a5b012c13..0fac24b5c 100644
--- a/src/modes/follow_the_leader.cpp
+++ b/src/modes/follow_the_leader.cpp
@@ -20,8 +20,8 @@
 #include "gui/menu_manager.hpp"
 #include "user_config.hpp"
 
-// -----------------------------
-FollowTheLeaderRace::FollowTheLeaderRace() : World(), ClockListener()
+//-----------------------------------------------------------------------------
+FollowTheLeaderRace::FollowTheLeaderRace() : World(), Clock::ClockListener()
 {
     m_leader_intervals    = stk_config->m_leader_intervals;
     
@@ -29,22 +29,26 @@ FollowTheLeaderRace::FollowTheLeaderRace() : World(), ClockListener()
     m_clock.setMode(COUNTDOWN, m_leader_intervals[0]);
 }
 
-// ----------------------------
+//-----------------------------------------------------------------------------
 FollowTheLeaderRace::~FollowTheLeaderRace()
 {
 }
 
+//-----------------------------------------------------------------------------
 void FollowTheLeaderRace::restartRace()
 {
     World::restartRace();
     m_leader_intervals    = stk_config->m_leader_intervals;
 }
 
-// clock events
+#pragma mark -
+#pragma mark clock events
+
+//-----------------------------------------------------------------------------
 void FollowTheLeaderRace::countdownReachedZero()
 {
 }
-
+//-----------------------------------------------------------------------------
 void FollowTheLeaderRace::onGo()
 {
     // Reset the brakes now that the prestart 
@@ -55,7 +59,7 @@ void FollowTheLeaderRace::onGo()
         m_kart[i]->resetBrakes();
     }
 }
-
+//-----------------------------------------------------------------------------
 void FollowTheLeaderRace::update(float delta)
 {
     m_clock.updateClock(delta);
@@ -107,7 +111,7 @@ void FollowTheLeaderRace::update(float delta)
         }
     }
 }
-
+//-----------------------------------------------------------------------------
 void FollowTheLeaderRace::onTerminate()
 {
     World::terminateRace();
diff --git a/src/modes/follow_the_leader.hpp b/src/modes/follow_the_leader.hpp
index 9107d4fb8..57989c205 100644
--- a/src/modes/follow_the_leader.hpp
+++ b/src/modes/follow_the_leader.hpp
@@ -18,9 +18,9 @@
 #ifndef _follow_the_leader_hpp_
 #define _follow_the_leader_hpp_
 
-#include "world.hpp"
+#include "modes/world.hpp"
 
-class FollowTheLeaderRace : public World, public ClockListener
+class FollowTheLeaderRace : public World, public Clock::ClockListener
 {
     std::vector<float>  m_leader_intervals;    // time till elimination in follow leader
 public:
diff --git a/src/modes/standard_race.cpp b/src/modes/standard_race.cpp
index 213bac041..12c7c1584 100644
--- a/src/modes/standard_race.cpp
+++ b/src/modes/standard_race.cpp
@@ -20,21 +20,24 @@
 #include "unlock_manager.hpp"
 #include "gui/menu_manager.hpp"
 
-// -----------------------------
-StandardRace::StandardRace() : World(), ClockListener()
+//-----------------------------------------------------------------------------
+StandardRace::StandardRace() : World(), Clock::ClockListener()
 {
     m_clock.registerEventListener(this);
     m_clock.setMode(CHRONO);
 }
 
-// ----------------------------
+//-----------------------------------------------------------------------------
 StandardRace::~StandardRace()
 {
 }
     
-// clock events
-void StandardRace::countdownReachedZero() { }
+#pragma mark -
+#pragma mark clock events
 
+//-----------------------------------------------------------------------------
+void StandardRace::countdownReachedZero() { }
+//-----------------------------------------------------------------------------
 void StandardRace::onGo()
 {
     // Reset the brakes now that the prestart 
@@ -45,12 +48,12 @@ void StandardRace::onGo()
         m_kart[i]->resetBrakes();
     }
 }
-
+//-----------------------------------------------------------------------------
 void StandardRace::restartRace()
 {
     World::restartRace();
 }
-
+//-----------------------------------------------------------------------------
 void StandardRace::update(float delta)
 {
     m_clock.updateClock(delta);
@@ -58,7 +61,7 @@ void StandardRace::update(float delta)
     World::update(delta);
     if(!m_clock.isRacePhase()) return;
     
-    // =========================================================
+    // All karts are finished
     if(race_manager->getFinishedKarts() >= race_manager->getNumKarts() )
     {
         m_clock.raceOver();
@@ -75,7 +78,7 @@ void StandardRace::update(float delta)
         m_clock.raceOver(true /* delay */);
     }
 }
-
+//-----------------------------------------------------------------------------
 void StandardRace::onTerminate()
 {
     World::terminateRace();
diff --git a/src/modes/standard_race.hpp b/src/modes/standard_race.hpp
index 24b34b88a..0296a4929 100644
--- a/src/modes/standard_race.hpp
+++ b/src/modes/standard_race.hpp
@@ -18,9 +18,9 @@
 #ifndef _standard_race_
 #define _standard_race_
 
-#include "world.hpp"
+#include "modes/world.hpp"
 
-class StandardRace : public World, public ClockListener
+class StandardRace : public World, public Clock::ClockListener
 {
 public:
     StandardRace();
diff --git a/src/world.cpp b/src/modes/world.cpp
similarity index 80%
rename from src/world.cpp
rename to src/modes/world.cpp
index 83526324c..47587416b 100644
--- a/src/world.cpp
+++ b/src/modes/world.cpp
@@ -23,7 +23,7 @@
 #include <algorithm>
 #include <ctime>
 
-#include "world.hpp"
+#include "modes/world.hpp"
 #include "herring_manager.hpp"
 #include "projectile_manager.hpp"
 #include "gui/menu_manager.hpp"
@@ -54,161 +54,10 @@
 #  define snprintf  _snprintf
 #endif
 
-
-//-----------------------------------------------------------------------------
-Clock::Clock()
-{
-    m_mode = CHRONO;
-    m_time = 0.0f;
-    m_auxiliary_timer = 0.0f;
-    m_listener = NULL;
-    m_phase = SETUP_PHASE;
-    m_previous_phase = SETUP_PHASE;  // initialise it just in case
-    
-    // for profiling AI
-    m_phase = user_config->m_profile ? RACE_PHASE : SETUP_PHASE;
-    
-    m_prestart_sound = sfx_manager->newSFX(SFXManager::SOUND_PRESTART);
-    m_start_sound    = sfx_manager->newSFX(SFXManager::SOUND_START);
-}
-//-----------------------------------------------------------------------------
-void Clock::reset()
-{
-    m_time = 0.0f;
-    m_auxiliary_timer = 0.0f;
-    m_phase = READY_PHASE; // FIXME - unsure
-    m_previous_phase      = SETUP_PHASE;
-}
-//-----------------------------------------------------------------------------
-Clock::~Clock()
-{
-    sfx_manager->deleteSFX(m_prestart_sound);
-    sfx_manager->deleteSFX(m_start_sound);
-}
-//-----------------------------------------------------------------------------
-void Clock::setMode(const ClockType mode, const float initial_time)
-{
-    m_mode = mode;
-    m_time = initial_time;
-}
-//-----------------------------------------------------------------------------
-void Clock::raceOver(const bool delay)
-{
-    if(m_phase == DELAY_FINISH_PHASE || m_phase == FINISH_PHASE) return; // we already know
-    
-    if(delay)
-    {
-        m_phase = DELAY_FINISH_PHASE;
-        m_auxiliary_timer = 0.0f;
-    }
-    else
-        m_phase = FINISH_PHASE;
-}
-//-----------------------------------------------------------------------------
-void Clock::updateClock(const float dt)
-{
-    switch(m_phase)
-    {
-        // Note: setup phase must be a separate phase, since the race_manager
-        // checks the phase when updating the camera: in the very first time
-        // step dt is large (it includes loading time), so the camera might
-        // tilt way too much. A separate setup phase for the first frame
-        // simplifies this handling
-        case SETUP_PHASE:
-            m_auxiliary_timer = 0.0f;  
-            m_phase = READY_PHASE;
-            m_prestart_sound->play();
-            return;               // loading time, don't play sound yet
-        case READY_PHASE:
-            if(m_auxiliary_timer>1.0)
-            {
-                m_phase=SET_PHASE;   
-                m_prestart_sound->play();
-            }
-            m_auxiliary_timer += dt;
-            return;
-        case SET_PHASE  :
-            if(m_auxiliary_timer>2.0) 
-            {
-                // set phase is over, go to the next one
-                m_phase=GO_PHASE;
-
-                m_start_sound->play();
-                
-                assert(m_listener != NULL);
-                m_listener -> onGo();
-            }
-            m_auxiliary_timer += dt;
-            return;
-        case GO_PHASE  :
-            if(m_auxiliary_timer>3.0)    // how long to display the 'go' message  
-                m_phase=RACE_PHASE;    
-            m_auxiliary_timer += dt;
-            break;
-        case DELAY_FINISH_PHASE :
-        {
-            m_auxiliary_timer += dt;
-            
-            // Nothing more to do if delay time is not over yet
-            if(m_auxiliary_timer < TIME_DELAY_TILL_FINISH) break;
-            
-            m_phase = FINISH_PHASE;
-            break;            
-        }
-        case FINISH_PHASE:
-            m_listener->onTerminate();
-            return;
-        default:   //RACE_PHASE, LIMBO_PHASEL nothing to do, but avoid a warning
-            break;
-    }
-    
-    switch(m_mode)
-    {
-        case CHRONO:
-            m_time += dt;
-            break;
-        case COUNTDOWN:
-            m_time -= dt;
-            
-            if(m_time <= 0.0)
-            {
-                assert(m_listener != NULL);
-                m_listener -> countdownReachedZero();
-            }
-            
-            break;
-        default: break;
-    }
-}
-//-----------------------------------------------------------------------------
-void Clock::setTime(const float time)
-{
-    m_time = time;
-}
-//-----------------------------------------------------------------------------
-void Clock::registerEventListener(ClockListener* listener)
-{
-    m_listener = listener;
-}
-//-----------------------------------------------------------------------------
-void Clock::pause()
-{
-    m_previous_phase = m_phase;
-    m_phase = LIMBO_PHASE;
-}
-//-----------------------------------------------------------------------------
-void Clock::unpause()
-{
-    m_phase = m_previous_phase;
-}
-
-World* world = 0; // FIXME, use singleton or something instead of this global variable
-
 //-----------------------------------------------------------------------------
 World::World()
 {
-    delete world;
-    world                 = this;
+    RaceManager::setWorld(this);
     race_state            = new RaceState();
     m_track               = NULL;
     m_faster_music_active = false;
@@ -257,8 +106,8 @@ World::World()
         {
             // In profile mode, load only the old kart
             newkart = new DefaultRobot(kart_name, position, init_pos);
-            // Create a camera for the last kart (since this way more of the 
-            // karts can be seen.
+    	    // Create a camera for the last kart (since this way more of the 
+	        // karts can be seen.
             if(i==race_manager->getNumKarts()-1) 
             {
                 scene->createCamera(local_player_id, newkart);
@@ -399,7 +248,7 @@ void World::resetAllKarts()
                 if(!material)
                 {
                     fprintf(stderr, "ERROR: no valid starting position for kart %d on track %s.\n",
-                            (int)(i-m_kart.begin()), m_track->getIdent().c_str());
+			    (int)(i-m_kart.begin()), m_track->getIdent().c_str());
                     exit(-1);
                 }
                 all_finished=false;
diff --git a/src/world.hpp b/src/modes/world.hpp
similarity index 68%
rename from src/world.hpp
rename to src/modes/world.hpp
index d72a376ff..5b9f2fd8a 100644
--- a/src/world.hpp
+++ b/src/modes/world.hpp
@@ -31,6 +31,7 @@
 #include "highscores.hpp"
 #include "network/network_kart.hpp"
 #include "utils/random_generator.hpp"
+#include "modes/clock.hpp"
 
 class SFXBase;
 
@@ -73,130 +74,13 @@ class SFXBase;
  *        would be done in the mode specific world (instead of in the
  *        RaceManager).
  */
-enum ClockType
-{
-    CLOCK_NONE,
-    CHRONO, // counts up
-    COUNTDOWN
-};
 
-/**
-  * abstract base class, derive from it to receive events from the clock
-  */
-class ClockListener
-{
-public:
-    virtual ~ClockListener(){};
-    /*
-     * Will be called to notify your derived class that the clock,
-     * which is in COUNTDOWN mode, has reached zero.
-     */
-    virtual void countdownReachedZero() = 0;
-    
-    /*
-     * Called when the race actually starts.
-     */
-    virtual void onGo() = 0;
-    
-    /**
-      * Called when race is over and should be terminated (mostly called by the clock).
-      */
-    virtual void onTerminate() = 0;
-};
-
-enum Phase {
-    // Game setup, e.g. track loading
-    SETUP_PHASE,
-    // 'Ready' is displayed
-    READY_PHASE,
-    // 'Set' is displayed
-    SET_PHASE,
-    // 'Go' is displayed, but this is already race phase
-    GO_PHASE,
-    // the actual race has started, no ready/set/go is displayed anymore
-    RACE_PHASE,
-    // All players have finished, now wait a certain amount of time for AI
-    // karts to finish. If they do not finish in that time, finish the race
-    DELAY_FINISH_PHASE,
-    // The player crossed the finishing line and his and the time of
-    // the other players is displayed, controll is automatic
-    FINISH_PHASE,
-    // The state after finish where no calculations are done.
-    LIMBO_PHASE,
-};
-
-/**
-  * A class that manages the clock (countdown, chrono, etc.) Also manages stuff
-  * like the 'ready/set/go' text at the beginning or the delay at the end of a race.
-  */
-class Clock
-{
-private:
-    SFXBase    *m_prestart_sound;
-    SFXBase    *m_start_sound;
-    
-    /**
-     * Elasped/remaining time in seconds
-     */
-    float           m_time;
-    ClockType       m_mode;
-    /**
-      * This object will be called to notify it of time events. Currently,
-      * this is only relevant for countdown mode.
-      */
-    ClockListener*  m_listener;
-    
-
-    Phase           m_phase;
-    /**
-      * Counts time during the initial 'ready/set/go' phase, or at the end of a race.
-      * This timer basically kicks in when we need to calculate non-race time like labels.
-      */
-    float           m_auxiliary_timer;
-    
-    /**
-      * Remember previous phase e.g. on pause
-      */
-    Phase          m_previous_phase;
-public:
-    Clock();
-    ~Clock();
-    
-    void reset();
-    
-    // Note: GO_PHASE is both: start phase and race phase
-    bool    isStartPhase() const  { return m_phase<GO_PHASE;                         }
-    bool    isRacePhase()  const  { return m_phase>=GO_PHASE && m_phase<LIMBO_PHASE; }
-    const Phase getPhase() const  { return m_phase; }
-    
-    /**
-      * Call to specify what kind of clock you want. The second argument
-      * can be used to specify the initial time value (especially useful
-      * for countdowns)
-      */
-    void    setMode(const ClockType mode, const float initial_time=0.0f);
-    int     getMode() const { return m_mode; }
-    /**
-      * Call each frame, with the elapsed time as argument.
-      */
-    void    updateClock(const float dt);
-
-    float   getTime() const                 { return m_time; }
-    void    setTime(const float time);
-    
-    void    pause();
-    void    unpause();
-    
-    void    raceOver(const bool delay=false);
-    
-    void    registerEventListener(ClockListener* listener);
-};
 
 class World
 {
-public:
-    typedef std::vector<Kart*> Karts;
 protected:
+    typedef std::vector<Kart*> Karts;
+    
     std::vector<PlayerKart*>  m_player_karts;
     std::vector<PlayerKart*>  m_local_player_karts;
     std::vector<NetworkKart*> m_network_karts; 
@@ -224,9 +108,9 @@ protected:
     void  printProfileResultAndExit();
     void  estimateFinishTimes();
     
-public:
     Track* m_track;
     
+public:
     /** debug text that will be overlaid to the screen */
     std::string m_debug_text[10];
     
@@ -270,15 +154,13 @@ public:
       * The code that draws the timer should call this first to know
       * whether the game mode wants a timer drawn
       */
-    bool shouldDrawTimer() const    { return ((m_clock.getPhase() == RACE_PHASE || 
-                                               m_clock.getPhase() == DELAY_FINISH_PHASE) &&
+    bool shouldDrawTimer() const    { return ((m_clock.getPhase() == RACE_PHASE or 
+                                               m_clock.getPhase() == DELAY_FINISH_PHASE) and
                                                m_clock.getMode() != CLOCK_NONE); }
     
 
 };
 
-extern World* world;
-
 #endif
 
 /* EOF */
diff --git a/src/moveable.cpp b/src/moveable.cpp
index 5ba05598d..d2d328546 100644
--- a/src/moveable.cpp
+++ b/src/moveable.cpp
@@ -18,7 +18,6 @@
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-#include "world.hpp"
 #include "player_kart.hpp"
 #include "material_manager.hpp"
 #include "material.hpp"
diff --git a/src/moving_physics.cpp b/src/moving_physics.cpp
index fc1f78d64..964100fd4 100644
--- a/src/moving_physics.cpp
+++ b/src/moving_physics.cpp
@@ -25,9 +25,9 @@
 #include <plib/sg.h>
 
 #include "string_utils.hpp"
-#include "world.hpp"
 #include "scene.hpp"
 #include "utils/ssg_help.hpp"
+#include "modes/world.hpp"
 
 // -----------------------------------------------------------------------------
 MovingPhysics::MovingPhysics(const std::string data)
@@ -81,7 +81,7 @@ MovingPhysics::MovingPhysics(const std::string data)
 // -----------------------------------------------------------------------------
 MovingPhysics::~MovingPhysics()
 {
-    world->getPhysics()->removeBody(m_body);
+    RaceManager::getWorld()->getPhysics()->removeBody(m_body);
     delete m_body;
     delete m_motion_state;
     delete m_shape;
@@ -195,7 +195,7 @@ void MovingPhysics::init()
     m_body = new btRigidBody(info);
     m_user_pointer.set(this);
     m_body->setUserPointer(&m_user_pointer);
-    world->getPhysics()->addBody(m_body);
+    RaceManager::getWorld()->getPhysics()->addBody(m_body);
 }   // init
 
 // -----------------------------------------------------------------------------
diff --git a/src/moving_texture.cpp b/src/moving_texture.cpp
index a781635c4..8a5759f2a 100644
--- a/src/moving_texture.cpp
+++ b/src/moving_texture.cpp
@@ -20,8 +20,8 @@
 #include "constants.hpp"
 #include "moving_texture.hpp"
 #include "string_utils.hpp"
-#include "world.hpp"
 #include "translation.hpp"
+#include "modes/world.hpp"
 
 MovingTexture::MovingTexture(char *data, ssgBranch *branch)
 {
@@ -88,7 +88,7 @@ void MovingTexture::update(float dt)
     sgCoord add;
 
 
-    float timer = world->getTime() + m_phase ;
+    float timer = RaceManager::getWorld()->getTime() + m_phase ;
 
     if ( m_cycle != 0.0 && m_mode != MODE_FORWARD )
     {
diff --git a/src/network/kart_control_message.cpp b/src/network/kart_control_message.cpp
index 2ef498c4e..7d47df12b 100644
--- a/src/network/kart_control_message.cpp
+++ b/src/network/kart_control_message.cpp
@@ -17,18 +17,18 @@
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "kart_control_message.hpp"
-#include "world.hpp"
+#include "modes/world.hpp"
 #include "network/network_kart.hpp"
 
 KartControlMessage::KartControlMessage()
                   : Message(Message::MT_KART_CONTROL)
 {
-    unsigned int num_local_players = world->getCurrentNumLocalPlayers();
+    unsigned int num_local_players = RaceManager::getWorld()->getCurrentNumLocalPlayers();
     unsigned int control_size      = KartControl::getLength();
     allocate(control_size*num_local_players);
     for(unsigned int i=0; i<num_local_players; i++)
     {
-        const Kart *kart            = world->getLocalPlayerKart(i);
+        const Kart *kart            = RaceManager::getWorld()->getLocalPlayerKart(i);
         const KartControl& controls = kart->getControls();
         controls.serialise(this);
     }
@@ -43,7 +43,7 @@ KartControlMessage::KartControlMessage(ENetPacket* pkt, int kart_id_offset,
     for(int i=kart_id_offset; i<kart_id_offset+num_local_players; i++)
     {
         KartControl kc(this);
-        NetworkKart *kart=world->getNetworkKart(i);
+        NetworkKart *kart = RaceManager::getWorld()->getNetworkKart(i);
         kart->setControl(kc);
     }
 };   // KartControlMessage
diff --git a/src/network/kart_update_message.cpp b/src/network/kart_update_message.cpp
index f92d2c475..947fe61ae 100644
--- a/src/network/kart_update_message.cpp
+++ b/src/network/kart_update_message.cpp
@@ -17,13 +17,13 @@
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "kart_update_message.hpp"
-#include "world.hpp"
+#include "modes/world.hpp"
 #include "kart.hpp"
 
 KartUpdateMessage::KartUpdateMessage()
                  : Message(Message::MT_KART_INFO)
 {
-    unsigned int num_karts = world->getCurrentNumKarts();
+    unsigned int num_karts = RaceManager::getWorld()->getCurrentNumKarts();
 
     // Send the number of karts and for each kart the compressed 
     // control structure (3 ints) and xyz,hpr (4 floats: quaternion:
@@ -33,7 +33,7 @@ KartUpdateMessage::KartUpdateMessage()
     addChar(num_karts);
     for(unsigned int i=0; i<num_karts; i++)
     {
-        const Kart* kart=world->getKart(i);
+        const Kart* kart = RaceManager::getKart(i);
         const KartControl& kc=kart->getControls();
         kc.serialise(this);
         addVec3(kart->getXYZ());
@@ -51,7 +51,7 @@ KartUpdateMessage::KartUpdateMessage(ENetPacket* pkt)
         KartControl kc(this);
         Vec3 xyz = getVec3();
         btQuaternion q = getQuaternion();
-        Kart *kart = world->getKart(i);
+        Kart *kart = RaceManager::getKart(i);
         kart->setXYZ(xyz);
         kart->setRotation(q);
     }   // for i
diff --git a/src/network/race_state.cpp b/src/network/race_state.cpp
index 265fa398e..5f709f63e 100644
--- a/src/network/race_state.cpp
+++ b/src/network/race_state.cpp
@@ -17,7 +17,7 @@
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-#include "world.hpp"
+#include "modes/world.hpp"
 #include "network/network_manager.hpp"
 #include "network/race_state.hpp"
 #include "projectile_manager.hpp"
@@ -33,7 +33,7 @@ void RaceState::serialise()
 
     // 1. Add all kart information
     // ---------------------------
-    unsigned int num_karts = world->getCurrentNumKarts();
+    unsigned int num_karts = RaceManager::getWorld()->getCurrentNumKarts();
     KartControl c;
     // Send the number of karts and for each kart the compressed 
     // control structure, xyz,hpr, and speed (which is necessary to
@@ -63,7 +63,7 @@ void RaceState::serialise()
     addChar(num_karts);
     for(unsigned int i=0; i<num_karts; i++)
     {
-        const Kart* kart=world->getKart(i);
+        const Kart* kart = RaceManager::getKart(i);
         m_kart_controls[i].serialise(this);
         addVec3(kart->getXYZ());
         addQuaternion(kart->getRotation());
@@ -121,7 +121,7 @@ void RaceState::receive(ENetPacket *pkt)
         // Currently not used!
         Vec3 xyz       = getVec3();
         btQuaternion q = getQuaternion();
-        Kart *kart     = world->getKart(i);
+        Kart *kart     = RaceManager::getKart(i);
         // Firing needs to be done from here to guarantee that any potential
         // new rockets are created before the update for the rockets is handled
         if(kc.fire)
@@ -138,10 +138,10 @@ void RaceState::receive(ENetPacket *pkt)
     {
         HerringInfo hi(this);
         if(hi.m_herring_id==-1)     // Rescue triggered
-            world->getKart(hi.m_kart_id)->forceRescue();
+            RaceManager::getKart(hi.m_kart_id)->forceRescue();
         else
             herring_manager->eatenHerring(hi.m_herring_id,
-                                          world->getKart(hi.m_kart_id),
+                                          RaceManager::getKart(hi.m_kart_id),
                                           hi.m_add_info);
     }
 
@@ -166,12 +166,12 @@ void RaceState::receive(ENetPacket *pkt)
         signed char kart_id2 = getChar();
         if(kart_id2==-1)
         {   // kart - track collision
-            world->getKart(kart_id1)->crashed(NULL);
+            RaceManager::getKart(kart_id1)->crashed(NULL);
         }
         else
         {
-            world->getPhysics()->KartKartCollision(world->getKart(kart_id1),
-                                                   world->getKart(kart_id2));
+            RaceManager::getWorld()->getPhysics()->KartKartCollision(RaceManager::getKart(kart_id1),
+                                                        RaceManager::getKart(kart_id2));
         }
     }   // for(i=0; i<num_collisions; i+=2)
     clear();  // free message buffer
diff --git a/src/physics.cpp b/src/physics.cpp
index b5897721c..dc00e67f0 100644
--- a/src/physics.cpp
+++ b/src/physics.cpp
@@ -19,13 +19,13 @@
 
 #include "physics.hpp"
 
-#include "world.hpp"
 #include "flyable.hpp"
 #include "moving_physics.hpp"
 #include "user_config.hpp"
 #include "material_manager.hpp"
 #include "network/race_state.hpp"
 #include "utils/ssg_help.hpp"
+#include "track.hpp"
 
 // ----------------------------------------------------------------------------
 /** Initialise physics.
@@ -50,7 +50,7 @@ void Physics::init(const Vec3 &world_min, const Vec3 &world_max)
                                                       this,
                                                       m_collision_conf);
     m_dynamics_world->setGravity(btVector3(0.0f, 0.0f, 
-                                           -world->getTrack()->getGravity()));
+                                           -RaceManager::getTrack()->getGravity()));
     if(user_config->m_bullet_debug)
     {
         m_debug_drawer=new GLDebugDrawer();
diff --git a/src/player_kart.cpp b/src/player_kart.cpp
index 91f41161a..cdb29e028 100644
--- a/src/player_kart.cpp
+++ b/src/player_kart.cpp
@@ -25,7 +25,7 @@
 #include "player.hpp"
 #include "sdldrv.hpp"
 #include "herring.hpp"
-#include "world.hpp"
+#include "modes/world.hpp"
 #include "gui/menu_manager.hpp"
 #include "gui/race_gui.hpp"
 #include "translation.hpp"
@@ -171,7 +171,7 @@ void PlayerKart::update(float dt)
 {
     steer(dt, m_steer_val);
 
-    if(world->getClock().isStartPhase())
+    if(RaceManager::getWorld()->getClock().isStartPhase())
     {
         if(m_controls.accel!=0.0 || m_controls.brake!=false ||
            m_controls.fire|m_controls.wheelie|m_controls.jump)
@@ -234,10 +234,10 @@ void PlayerKart::crashed(Kart *kart)
     // this, the crash sound is only played if there was at least 0.5
     // seconds since the last time it was played (for this kart)
 
-    if(world->getTime() - m_time_last_crash_sound > 0.5f) 
+    if(RaceManager::getWorld()->getTime() - m_time_last_crash_sound > 0.5f) 
     {
         m_crash_sound->play();
-        m_time_last_crash_sound = world->getTime();
+        m_time_last_crash_sound = RaceManager::getWorld()->getTime();
     }
 }   // crashed
 
@@ -324,7 +324,7 @@ void PlayerKart::addMessages()
     // ------------------------------------------------------
     if(race_manager->getDifficulty()==RaceManager::RD_EASY)
     {
-      float angle_diff = RAD_TO_DEGREE(getHPR().getHeading()) - world->m_track->m_angle[getSector()];
+      float angle_diff = RAD_TO_DEGREE(getHPR().getHeading()) - RaceManager::getTrack()->m_angle[getSector()];
         if(angle_diff > 180.0f) angle_diff -= 360.0f;
         else if (angle_diff < -180.0f) angle_diff += 360.0f;
         // Display a warning message if the kart is going back way (unless
diff --git a/src/race_manager.cpp b/src/race_manager.cpp
index ac5659382..565517126 100644
--- a/src/race_manager.cpp
+++ b/src/race_manager.cpp
@@ -25,7 +25,7 @@
 #include "kart_properties_manager.hpp"
 #include "unlock_manager.hpp"
 #include "gui/menu_manager.hpp"
-#include "world.hpp"
+#include "modes/world.hpp"
 #include "scene.hpp"
 #include "user_config.hpp"
 #include "stk_config.hpp"
@@ -35,6 +35,33 @@
 
 RaceManager* race_manager= NULL;
 
+//-----------------------------------------------------------------------------
+World* world = NULL;
+World* RaceManager::getWorld()
+{
+    return world;
+}
+/** Call to set the world, or call setWorld(NULL) to delete the current world.
+ */
+void RaceManager::setWorld(World* world_arg)
+{
+    if(world != NULL) delete world;
+    world = world_arg;
+}
+Track* RaceManager::getTrack()
+{
+    return world->getTrack();
+}
+Kart* RaceManager::getPlayerKart(const unsigned int n)
+{
+    return world->getPlayerKart(n);
+}
+Kart* RaceManager::getKart(const unsigned int n)
+{
+    return world->getKart(n);
+}
+//-----------------------------------------------------------------------------
+
 /** Constructs the race manager.
  */
 RaceManager::RaceManager()
@@ -291,7 +318,7 @@ void RaceManager::exit_race()
 
 //-----------------------------------------------------------------------------
 /** A kart has finished the race at the specified time (which can be 
- *  different from world->getClock() in case of setting extrapolated arrival 
+ *  different from RaceManager::getWorld()->getClock() in case of setting extrapolated arrival 
  *  times).
  *  \param kart The kart that finished the race.
  *  \param time Time at which the kart finished the race.
diff --git a/src/race_manager.hpp b/src/race_manager.hpp
index aaa5ba8ef..4b77bfb1e 100644
--- a/src/race_manager.hpp
+++ b/src/race_manager.hpp
@@ -27,6 +27,9 @@
 #include "grand_prix_data.hpp"
 #include "network/remote_kart_info.hpp"
 
+class World;
+class Track;
+
 /** The race manager has two functions:
  *  1) it stores information about the race the user selected (e.g. number
  *     of karts, track, race mode etc.). Most of the values are just stored
@@ -127,6 +130,12 @@ private:
 public:
     bool                             m_active_race; //True if there is a race
 
+    static World* getWorld();
+    static void setWorld(World* world);
+    static Track* getTrack();
+    static Kart* getPlayerKart(const unsigned int n);
+    static Kart* getKart(const unsigned int n);
+    
 public:
                  RaceManager();
                 ~RaceManager();
diff --git a/src/replay_recorder.cpp b/src/replay_recorder.cpp
index 8ea0ac908..a9f4cb703 100644
--- a/src/replay_recorder.cpp
+++ b/src/replay_recorder.cpp
@@ -22,7 +22,7 @@
 #include <cassert>
 
 #include "replay_recorder.hpp"
-#include "world.hpp"
+#include "modes/world.hpp"
 
 const float ReplayRecorder::REPLAY_TIME_STEP_MIN = 1.0f / (float)ReplayRecorder::REPLAY_FREQUENCY_MAX;
 
@@ -55,25 +55,25 @@ bool ReplayRecorder::initRecorder( unsigned int number_karts, size_t number_prea
 bool ReplayRecorder::pushFrame()
 {
 	// we dont record the startphase ..
-    assert( world->getPhase() != World::START_PHASE );
-    assert( world->getNumKarts() == m_ReplayBuffers.getNumberKarts() );
+    assert( RaceManager::getWorld()->getPhase() != World::START_PHASE );
+    assert( RaceManager::getWorld()->getNumKarts() == m_ReplayBuffers.getNumberKarts() );
 
     // make sure we're not under time-step-min 
     if( m_ReplayBuffers.getNumberFrames() )
     {
         ReplayFrame const *last_Frame = m_ReplayBuffers.getFrameAt( m_ReplayBuffers.getNumberFrames() - 1 );
-        if( (world->getTime() - last_Frame->time) < REPLAY_TIME_STEP_MIN ) return true;
+        if( (RaceManager::getWorld()->getTime() - last_Frame->time) < REPLAY_TIME_STEP_MIN ) return true;
     }
 
     ReplayFrame *pFrame = getNewFrame();
     if( !pFrame ) return false;
-    pFrame->time = world->getClock();
+    pFrame->time = RaceManager::getWorld()->getClock();
 
     Kart const *kart;
-    int number_karts = world->getNumKarts();
+    int number_karts = RaceManager::getWorld()->getNumKarts();
     for( int kart_index = 0; kart_index < number_karts; ++kart_index )
     {
-        kart = world->getKart( kart_index );
+        kart = RaceManager::getKart( kart_index );
         sgCopyCoord( &( pFrame->p_kart_states[ kart_index ].position ), 
                      kart->getCoord() );
     }
diff --git a/src/robots/default_robot.cpp b/src/robots/default_robot.cpp
index 66542bc1a..86913a8e6 100755
--- a/src/robots/default_robot.cpp
+++ b/src/robots/default_robot.cpp
@@ -39,7 +39,7 @@
 #include <iostream>
 #include "constants.hpp"
 #include "scene.hpp"
-#include "world.hpp"
+#include "modes/world.hpp"
 #include "race_manager.hpp"
 #include "network/network_manager.hpp"
 
@@ -97,7 +97,7 @@ void DefaultRobot::update( float delta )
         return;
     }
 
-    if( world->getClock().isStartPhase() )
+    if( RaceManager::getWorld()->getClock().isStartPhase() )
     {
         handle_race_start();
         AutoKart::update( delta );
@@ -155,21 +155,21 @@ void DefaultRobot::handle_braking()
 {
     // In follow the leader mode, the kart should brake if they are ahead of
     // the leader (and not the leader, i.e. don't have initial position 1)
-    if(race_manager->getMinorMode()==RaceManager::RM_FOLLOW_LEADER &&
-        getPosition()<world->getKart(0)->getPosition()             &&
+    if(race_manager->getMinorMode() == RaceManager::RM_FOLLOW_LEADER &&
+        getPosition() < RaceManager::getKart(0)->getPosition()             &&
         getInitialPosition()>1                                       )
     {
         m_controls.brake = true;
         return;
     }
-    const float MIN_SPEED = world->m_track->getWidth()[m_track_sector];
+    const float MIN_SPEED = RaceManager::getTrack()->getWidth()[m_track_sector];
 
     //We may brake if we are about to get out of the road, but only if the
     //kart is on top of the road, and if we won't slow down below a certain
     //limit.
     if ( m_crashes.m_road && m_on_road && getVelocityLC().getY() > MIN_SPEED)
     {
-        float kart_ang_diff = world->m_track->m_angle[m_track_sector] -
+        float kart_ang_diff = RaceManager::getTrack()->m_angle[m_track_sector] -
                               RAD_TO_DEGREE(getHPR().getHeading());
         kart_ang_diff = normalize_angle(kart_ang_diff);
         kart_ang_diff = fabsf(kart_ang_diff);
@@ -184,9 +184,8 @@ void DefaultRobot::handle_braking()
             //if the curve angle is bigger than what the kart can steer, brake
             //even if we are in the inside, because the kart would be 'thrown'
             //out of the curve.
-            if(!(getDistanceToCenter() > world->m_track->
-                getWidth()[m_track_sector] * -CURVE_INSIDE_PERC ||
-                m_curve_angle > getMaxSteerAngle()))
+            if(!(getDistanceToCenter() > RaceManager::getTrack()->getWidth()[m_track_sector] *
+                 -CURVE_INSIDE_PERC || m_curve_angle > getMaxSteerAngle()))
             {
                 m_controls.brake = false;
                 return;
@@ -194,9 +193,8 @@ void DefaultRobot::handle_braking()
         }
         else if( m_curve_angle < -MIN_TRACK_ANGLE ) //Next curve is right
         {
-            if(!(getDistanceToCenter() < world->m_track->
-                getWidth()[m_track_sector] * CURVE_INSIDE_PERC ||
-                m_curve_angle < -getMaxSteerAngle()))
+            if(!(getDistanceToCenter() < RaceManager::getTrack()->getWidth()[m_track_sector] *
+                 CURVE_INSIDE_PERC || m_curve_angle < -getMaxSteerAngle()))
             {
                 m_controls.brake = false;
                 return;
@@ -206,8 +204,8 @@ void DefaultRobot::handle_braking()
         //Brake if the kart's speed is bigger than the speed we need
         //to go through the curve at the widest angle, or if the kart
         //is not going straight in relation to the road.
-        float angle_adjust = world->m_track->getAIAngleAdjustment();
-        float speed_adjust = world->m_track->getAICurveSpeedAdjustment();
+        float angle_adjust = RaceManager::getTrack()->getAIAngleAdjustment();
+        float speed_adjust = RaceManager::getTrack()->getAICurveSpeedAdjustment();
         if(getVelocityLC().getY() > speed_adjust*m_curve_target_speed ||
            kart_ang_diff          > angle_adjust*MIN_TRACK_ANGLE         )
         {
@@ -226,7 +224,7 @@ void DefaultRobot::handle_braking()
 //-----------------------------------------------------------------------------
 void DefaultRobot::handle_steering()
 {
-    const unsigned int DRIVELINE_SIZE = (unsigned int)world->m_track->m_driveline.size();
+    const unsigned int DRIVELINE_SIZE = (unsigned int)RaceManager::getTrack()->m_driveline.size();
     const size_t NEXT_SECTOR = (unsigned int)m_track_sector + 1 < DRIVELINE_SIZE ?
         m_track_sector + 1 : 0;
     float steer_angle = 0.0f;
@@ -236,9 +234,9 @@ void DefaultRobot::handle_steering()
      */
     //Reaction to being outside of the road
     if( fabsf(getDistanceToCenter()) + 0.5 >
-        world->m_track->getWidth()[m_track_sector] )
+        RaceManager::getTrack()->getWidth()[m_track_sector] )
     {
-        steer_angle = steer_to_point( world->m_track->
+        steer_angle = steer_to_point( RaceManager::getTrack()->
             m_driveline[NEXT_SECTOR] );
 
 #ifdef AI_DEBUG
@@ -263,7 +261,7 @@ void DefaultRobot::handle_steering()
         }
         else
         {
-            if(getDistanceToCenter() > world->getKart(m_crashes.m_kart)->
+            if(getDistanceToCenter() > RaceManager::getKart(m_crashes.m_kart)->
                getDistanceToCenter())
             {
                 steer_angle = steer_to_angle( NEXT_SECTOR, -90.0f );
@@ -349,7 +347,7 @@ void DefaultRobot::handle_items( const float DELTA, const int STEPS )
             case COLLECT_ZIPPER:
                 {
                     const float ANGLE_DIFF = fabsf( normalize_angle(
-                        world->m_track->m_angle[m_track_sector]-
+                        RaceManager::getTrack()->m_angle[m_track_sector]-
                         RAD_TO_DEGREE(getHPR().getHeading()) ) );
 
                     if( m_time_since_last_shot > 10.0f && ANGLE_DIFF <
@@ -365,7 +363,7 @@ void DefaultRobot::handle_items( const float DELTA, const int STEPS )
             case COLLECT_HOMING:
                 if( m_time_since_last_shot > 5.0f && m_crashes.m_kart != -1 )
                 {
-		  if( (getXYZ()-world->getKart(m_crashes.m_kart)->getXYZ() ).length_2d() >
+		  if( (getXYZ()-RaceManager::getKart(m_crashes.m_kart)->getXYZ() ).length_2d() >
 		      m_kart_properties->getKartLength() * 2.5f )
                     {
                         m_controls.fire = true;
@@ -414,7 +412,7 @@ void DefaultRobot::handle_acceleration( const float DELTA )
         //Find if any player is ahead of this kart
         bool player_winning = false;
         for(unsigned int i = 0; i < race_manager->getNumPlayers(); ++i )
-            if( m_race_position > world->getPlayerKart(i)->getPosition() )
+            if( m_race_position > RaceManager::getPlayerKart(i)->getPosition() )
             {
                 player_winning = true;
                 break;
@@ -463,13 +461,13 @@ bool DefaultRobot::do_wheelie ( const int STEPS )
     {
         step_coord = getXYZ()+vel_normal* m_kart_properties->getKartLength() * float(i);
 
-        world->m_track->spatialToTrack(step_track_coord, step_coord,
+        RaceManager::getTrack()->spatialToTrack(step_track_coord, step_coord,
                                        m_future_sector );
 
         distance = step_track_coord[0] > 0.0f ?  step_track_coord[0]
                    : -step_track_coord[0];
 
-        if( distance > world->m_track->getWidth()[m_track_sector] )
+        if( distance > RaceManager::getTrack()->getWidth()[m_track_sector] )
         {
             return false;
         }
@@ -513,7 +511,7 @@ void DefaultRobot::handle_rescue(const float DELTA)
 
 
     // check if kart is stuck
-    if(getSpeed()<2.0f && !isRescue() && !world->getClock().isStartPhase())
+    if(getSpeed()<2.0f && !isRescue() && !RaceManager::getWorld()->getClock().isStartPhase())
     {
         m_time_since_stuck += DELTA;
         if(m_time_since_stuck > 2.0f)
@@ -531,7 +529,7 @@ void DefaultRobot::handle_rescue(const float DELTA)
 //-----------------------------------------------------------------------------
 float DefaultRobot::steer_to_angle (const size_t SECTOR, const float ANGLE)
 {
-    float angle = world->m_track->m_angle[SECTOR];
+    float angle = RaceManager::getTrack()->m_angle[SECTOR];
 
     //Desired angle minus current angle equals how many angles to turn
     float steer_angle = angle - RAD_TO_DEGREE(getHPR().getHeading());
@@ -577,7 +575,7 @@ void DefaultRobot::check_crashes( const int STEPS, const Vec3& pos )
 
     Vec3 vel_normal;
 	//in this func we use it as a 2d-vector, but later on it is passed
-	//to world->m_track->findRoadSector, there it is used as a 3d-vector
+	//to RaceManager::getTrack()->findRoadSector, there it is used as a 3d-vector
 	//to find distance to plane, so z must be initialized to zero
     Vec3 step_coord;
     SGfloat kart_distance;
@@ -612,19 +610,19 @@ void DefaultRobot::check_crashes( const int STEPS, const Vec3& pos )
         {
             for( unsigned int j = 0; j < NUM_KARTS; ++j )
             {
-                const Kart* kart=world->getKart(j);
+                const Kart* kart = RaceManager::getKart(j);
                 if(kart==this||kart->isEliminated()) continue;   // ignore eliminated karts
 
-		kart_distance = (step_coord-world->getKart(j)->getXYZ()).length_2d();
+		kart_distance = (step_coord - RaceManager::getKart(j)->getXYZ()).length_2d();
 
                 if( kart_distance < m_kart_properties->getKartLength() + 0.125f * i )
-                    if( getVelocityLC().getY() > world->getKart(j)->
+                    if( getVelocityLC().getY() > RaceManager::getKart(j)->
                        getVelocityLC().getY() * 0.75f ) m_crashes.m_kart = j;
             }
         }
 
         /*Find if we crash with the drivelines*/
-        world->m_track->findRoadSector(step_coord, &m_sector);
+        RaceManager::getTrack()->findRoadSector(step_coord, &m_sector);
 
 #ifdef SHOW_FUTURE_PATH
 
@@ -666,7 +664,7 @@ void DefaultRobot::check_crashes( const int STEPS, const Vec3& pos )
 
         if( m_sector == Track::UNKNOWN_SECTOR )
         {
-            m_future_sector = world->getTrack()->findOutOfRoadSector( step_coord,
+            m_future_sector = RaceManager::getTrack()->findOutOfRoadSector( step_coord,
                 Track::RS_DONT_KNOW, m_future_sector );
             m_crashes.m_road = true;
             break;
@@ -688,7 +686,7 @@ void DefaultRobot::check_crashes( const int STEPS, const Vec3& pos )
  */
 void DefaultRobot::find_non_crashing_point( sgVec2 result )
 {
-    const unsigned int DRIVELINE_SIZE = (unsigned int)world->m_track->m_driveline.size();
+    const unsigned int DRIVELINE_SIZE = (unsigned int)RaceManager::getTrack()->m_driveline.size();
 
     unsigned int sector = (unsigned int)m_track_sector + 1 < DRIVELINE_SIZE ?
         m_track_sector + 1 : 0;
@@ -707,7 +705,7 @@ void DefaultRobot::find_non_crashing_point( sgVec2 result )
         target_sector = sector + 1 < DRIVELINE_SIZE ? sector + 1 : 0;
 
         //direction is a vector from our kart to the sectors we are testing
-	direction = world->m_track->m_driveline[target_sector] - getXYZ();
+	direction = RaceManager::getTrack()->m_driveline[target_sector] - getXYZ();
 
         float len=direction.length_2d();
         steps = int( len / m_kart_properties->getKartLength() );
@@ -724,17 +722,16 @@ void DefaultRobot::find_non_crashing_point( sgVec2 result )
         {
             step_coord = getXYZ()+direction*m_kart_properties->getKartLength() * float(i);
 
-            world->m_track->spatialToTrack( step_track_coord, step_coord,
+            RaceManager::getTrack()->spatialToTrack( step_track_coord, step_coord,
                 sector );
 
             distance = step_track_coord[0] > 0.0f ? step_track_coord[0]
                        : -step_track_coord[0];
 
             //If we are outside, the previous sector is what we are looking for
-            if ( distance + m_kart_properties->getKartLength() * 0.5f > world->
-                m_track->getWidth()[sector] )
+            if ( distance + m_kart_properties->getKartLength() * 0.5f > RaceManager::getTrack()->getWidth()[sector] )
             {
-                sgCopyVec2( result, world->m_track->m_driveline[sector] );
+                sgCopyVec2( result, RaceManager::getTrack()->m_driveline[sector] );
 
 #ifdef SHOW_NON_CRASHING_POINT
                 ssgaSphere *sphere = new ssgaSphere;
@@ -819,7 +816,7 @@ int DefaultRobot::calc_steps()
     if( fabsf(m_controls.lr) > 0.95 )
     {
         const int WIDTH_STEPS = 
-            (int)( world->m_track->getWidth()[m_future_sector] 
+            (int)( RaceManager::getTrack()->getWidth()[m_future_sector] 
                    /( m_kart_properties->getKartLength() * 2.0 ) );
 
         steps += WIDTH_STEPS;
@@ -869,35 +866,36 @@ float DefaultRobot::get_approx_radius(const int START, const int END) const
 
     if(m_inner_curve == -1)
     {
+        X1 = RaceManager::getTrack()->m_left_driveline[START][0];
+        Y1 = RaceManager::getTrack()->m_left_driveline[START][1];
 
-    X1 = world->m_track->m_left_driveline[START][0];
-    Y1 = world->m_track->m_left_driveline[START][1];
+        X2 = RaceManager::getTrack()->m_left_driveline[MIDDLE][0];
+        Y2 = RaceManager::getTrack()->m_left_driveline[MIDDLE][1];
 
-    X2 = world->m_track->m_left_driveline[MIDDLE][0];
-    Y2 = world->m_track->m_left_driveline[MIDDLE][1];
-
-    X3 = world->m_track->m_left_driveline[END][0];
-    Y3 = world->m_track->m_left_driveline[END][1];
-    }else if (m_inner_curve == 0)
+        X3 = RaceManager::getTrack()->m_left_driveline[END][0];
+        Y3 = RaceManager::getTrack()->m_left_driveline[END][1];
+    }
+    else if (m_inner_curve == 0)
     {
-    X1 = world->m_track->m_driveline[START][0];
-    Y1 = world->m_track->m_driveline[START][1];
+        X1 = RaceManager::getTrack()->m_driveline[START][0];
+        Y1 = RaceManager::getTrack()->m_driveline[START][1];
 
-    X2 = world->m_track->m_driveline[MIDDLE][0];
-    Y2 = world->m_track->m_driveline[MIDDLE][1];
+        X2 = RaceManager::getTrack()->m_driveline[MIDDLE][0];
+        Y2 = RaceManager::getTrack()->m_driveline[MIDDLE][1];
 
-    X3 = world->m_track->m_driveline[END][0];
-    Y3 = world->m_track->m_driveline[END][1];
-    }else if (m_inner_curve == 1)
+        X3 = RaceManager::getTrack()->m_driveline[END][0];
+        Y3 = RaceManager::getTrack()->m_driveline[END][1];
+    }
+    else if (m_inner_curve == 1)
     {
-    X1 = world->m_track->m_right_driveline[START][0];
-    Y1 = world->m_track->m_right_driveline[START][1];
+        X1 = RaceManager::getTrack()->m_right_driveline[START][0];
+        Y1 = RaceManager::getTrack()->m_right_driveline[START][1];
 
-    X2 = world->m_track->m_right_driveline[MIDDLE][0];
-    Y2 = world->m_track->m_right_driveline[MIDDLE][1];
+        X2 = RaceManager::getTrack()->m_right_driveline[MIDDLE][0];
+        Y2 = RaceManager::getTrack()->m_right_driveline[MIDDLE][1];
 
-    X3 = world->m_track->m_right_driveline[END][0];
-    Y3 = world->m_track->m_right_driveline[END][1];
+        X3 = RaceManager::getTrack()->m_right_driveline[END][0];
+        Y3 = RaceManager::getTrack()->m_right_driveline[END][1];
     }
 
     const float A = X2 - X1;
@@ -927,7 +925,7 @@ float DefaultRobot::get_approx_radius(const int START, const int END) const
  */
 void DefaultRobot::find_curve()
 {
-    const int DRIVELINE_SIZE = (unsigned int)world->m_track->m_driveline.size();
+    const int DRIVELINE_SIZE = (unsigned int)RaceManager::getTrack()->m_driveline.size();
     float total_dist = 0.0f;
     int next_hint = m_track_sector;
     int i;
@@ -935,14 +933,14 @@ void DefaultRobot::find_curve()
     for(i = m_track_sector; total_dist < getVelocityLC().getY(); i = next_hint)
     {
         next_hint = i + 1 < DRIVELINE_SIZE ? i + 1 : 0;
-        total_dist += sgDistanceVec2(world->m_track->m_driveline[i], world->m_track->m_driveline[next_hint]);
+        total_dist += sgDistanceVec2(RaceManager::getTrack()->m_driveline[i], RaceManager::getTrack()->m_driveline[next_hint]);
     }
 
 
-    m_curve_angle = normalize_angle(world->m_track->m_angle[i] - world->m_track->m_angle[m_track_sector]);
+    m_curve_angle = normalize_angle(RaceManager::getTrack()->m_angle[i] - RaceManager::getTrack()->m_angle[m_track_sector]);
     m_inner_curve = m_curve_angle > 0.0 ? -1 : 1;
     // FIXME: 0.9 is the tire grip - but this was never used. For now this
     // 0.9 is left in place to reproduce the same results and AI behaviour,
     // but this function should be updated to bullet physics
-    m_curve_target_speed = sgSqrt(get_approx_radius(m_track_sector, i) * world->m_track->getGravity() * 0.9f);
+    m_curve_target_speed = sgSqrt(get_approx_radius(m_track_sector, i) * RaceManager::getTrack()->getGravity() * 0.9f);
 }
diff --git a/src/robots/empty_robot.cpp b/src/robots/empty_robot.cpp
index 8813be292..d4678f4f8 100755
--- a/src/robots/empty_robot.cpp
+++ b/src/robots/empty_robot.cpp
@@ -30,7 +30,7 @@
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-#include "world.hpp"
+#include "modes/world.hpp"
 
 #include "empty_robot.hpp"
 
diff --git a/src/scene.cpp b/src/scene.cpp
index 5a50fa7f7..9805a8a19 100644
--- a/src/scene.cpp
+++ b/src/scene.cpp
@@ -22,7 +22,7 @@
 #include "material.hpp"
 #include "camera.hpp"
 #include "track.hpp"
-#include "world.hpp"
+#include "modes/world.hpp"
 #include "user_config.hpp"
 
 #include "btBulletDynamicsCommon.h"
@@ -97,7 +97,7 @@ void Scene::draw(float dt)
 {
     glEnable ( GL_DEPTH_TEST ) ;
 
-    const Track* TRACK = world->m_track;
+    const Track* TRACK = RaceManager::getTrack();
 
     ssgGetLight ( 0 ) -> setPosition ( TRACK->getSunPos() ) ;
     ssgGetLight ( 0 ) -> setColour ( GL_AMBIENT , TRACK->getAmbientCol()  ) ;
@@ -178,7 +178,7 @@ void Scene::draw(float dt)
             float f=2.0f;
             glFrustum(-f, f, -f, f, 1.0, 1000.0);
             
-            Vec3 xyz = world->getKart(race_manager->getNumKarts()-1)->getXYZ();
+            Vec3 xyz = RaceManager::getKart(race_manager->getNumKarts()-1)->getXYZ();
             gluLookAt(xyz.getX(), xyz.getY()-5.f, xyz.getZ()+4,
                       xyz.getX(), xyz.getY(),     xyz.getZ(),
                       0.0f, 0.0f, 1.0f);
@@ -186,10 +186,10 @@ void Scene::draw(float dt)
             
             for (World::Karts::size_type i = 0 ; i < race_manager->getNumKarts(); ++i)
             {
-                Kart *kart=world->getKart((int)i);
+                Kart *kart=RaceManager::getKart((int)i);
                 if(!kart->isEliminated()) kart->draw();
             }
-            world->getPhysics()->draw();
+            RaceManager::getWorld()->getPhysics()->draw();
         }   //  bullet_debug
     }   // for cameras
 
diff --git a/src/terrain_info.cpp b/src/terrain_info.cpp
index 8d585ff2a..db61b4996 100644
--- a/src/terrain_info.cpp
+++ b/src/terrain_info.cpp
@@ -20,8 +20,9 @@
 #include <math.h>
 
 #include "terrain_info.hpp"
-#include "world.hpp"
+#include "race_manager.hpp"
 #include "constants.hpp"
+#include "track.hpp"
 
 TerrainInfo::TerrainInfo(const Vec3 &pos, int frequency)
 {
@@ -36,7 +37,7 @@ void TerrainInfo::update(const Vec3& pos)
     m_HoT_counter++;
     if(m_HoT_counter>=m_HoT_frequency)
     {
-        world->getTrack()->getTerrainInfo(pos, &m_HoT, 
+        RaceManager::getTrack()->getTerrainInfo(pos, &m_HoT, 
                                           &m_normal, &m_material);
         m_normal.normalize();
         m_HoT_counter = 0;
diff --git a/src/track.cpp b/src/track.cpp
index 1b5526d10..40004caed 100644
--- a/src/track.cpp
+++ b/src/track.cpp
@@ -34,7 +34,7 @@
 #include "translation.hpp"
 #include "scene.hpp"
 #include "moving_physics.hpp"
-#include "world.hpp"
+#include "modes/world.hpp"
 #include "material_manager.hpp"
 #include "isect.hpp"
 #include "user_config.hpp"
@@ -1311,7 +1311,7 @@ void Track::loadTrackModel()
 
     Vec3 min, max;
     SSGHelp::MinMax(m_model, &min, &max);
-    world->getPhysics()->init(min, max);
+    RaceManager::getWorld()->getPhysics()->init(min, max);
     createPhysicsModel();
 }   // loadTrack
 
@@ -1361,7 +1361,7 @@ void  Track::getTerrainInfo(const Vec3 &pos, float *hot, Vec3 *normal,
         }   // AddSingleResult
     };   // myCollision
     MaterialCollision rayCallback(pos, to_pos);
-    world->getPhysics()->getPhysicsWorld()->rayTest(pos, to_pos, rayCallback);
+    RaceManager::getWorld()->getPhysics()->getPhysicsWorld()->rayTest(pos, to_pos, rayCallback);
 
     if(!rayCallback.HasHit()) 
     {
diff --git a/src/traffic.cpp b/src/traffic.cpp
index 38ae35cf6..f64b81733 100644
--- a/src/traffic.cpp
+++ b/src/traffic.cpp
@@ -19,7 +19,7 @@
 
 #include "kart.hpp"
 #include "constants.hpp"
-#include "world.hpp"
+#include "modes/world.hpp"
 
 inline float sgnsq ( float x ) { return ( x < 0 ) ? -(x * x) : (x * x) ; }
 
@@ -41,7 +41,7 @@ void TrafficDriver::update (float dt)
 //FIXME        m_velocity.hpr[0] = sgnsq(m_curr_track_coords[0])*12.0f ;
 
 //FIXME    m_velocity.xyz[1]  = TRAFFIC_VELOCITY ;
-//FIXME    m_velocity.xyz[2] -= world->getGravity()* dt ;
+//FIXME    m_velocity.xyz[2] -= RaceManager::getWorld()->getGravity()* dt ;
 
     if ( m_wheelie_angle != 0.0f )
         m_wheelie_angle = 0.0f ;
diff --git a/src/triangle_mesh.cpp b/src/triangle_mesh.cpp
index 845ef19d6..551c3ab38 100644
--- a/src/triangle_mesh.cpp
+++ b/src/triangle_mesh.cpp
@@ -18,14 +18,14 @@
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "triangle_mesh.hpp"
-#include "world.hpp"
+#include "modes/world.hpp"
 
 // -----------------------------------------------------------------------------
 TriangleMesh::~TriangleMesh()
 {
     if(m_body)
     {
-        world->getPhysics()->removeBody(m_body);
+        RaceManager::getWorld()->getPhysics()->removeBody(m_body);
         delete m_body;
         delete m_motion_state;
         delete m_collision_shape;
@@ -58,7 +58,7 @@ void TriangleMesh::createBody(btCollisionObject::CollisionFlags flags)
     btRigidBody::btRigidBodyConstructionInfo info(0.0f, m_motion_state, m_collision_shape);
     m_body=new btRigidBody(info);
 
-    world->getPhysics()->addBody(m_body);
+    RaceManager::getWorld()->getPhysics()->addBody(m_body);
     m_user_pointer.set(this);
     m_body->setUserPointer(&m_user_pointer);
     m_body->setCollisionFlags(m_body->getCollisionFlags()  |