Index: orxonox/trunk/src/Makefile.am
===================================================================
--- orxonox/trunk/src/Makefile.am	(revision 2589)
+++ orxonox/trunk/src/Makefile.am	(revision 2636)
@@ -6,5 +6,5 @@
 
 bin_PROGRAMS=orxonox
-orxonox_SOURCES=orxonox.cc world.cc player.cc data_tank.cc world_entity.cc vector.cc camera.cc collision.cc command_node.cc ini_parser.cc keynames.cc track.cc base_entity.cc 
+orxonox_SOURCES=orxonox.cc world.cc player.cc data_tank.cc world_entity.cc vector.cc camera.cc collision.cc command_node.cc ini_parser.cc keynames.cc track.cc base_entity.cc game_loader.cc campaign.cc story_entity.cc
 
 noinst_HEADERS=ability.h data_tank.h npc.h stdincl.h ai.h environment.h orxonox.h synchronisable.h base_entity.h error.h player.h track.h camera.h ini_parser.h power_up.h vector.h collision.h keynames.h proto_class.h world.h command_node.h list.h shoot_laser.h world_entity.h coordinates.h message_structures.h shoot_rocket.h
Index: orxonox/trunk/src/Makefile.in
===================================================================
--- orxonox/trunk/src/Makefile.in	(revision 2589)
+++ orxonox/trunk/src/Makefile.in	(revision 2636)
@@ -117,5 +117,5 @@
 #"-O3 -pedantic -fPIC -ffast-math -I/usr/X11R6/include"
 bin_PROGRAMS = orxonox
-orxonox_SOURCES = orxonox.cc world.cc player.cc data_tank.cc world_entity.cc vector.cc camera.cc collision.cc command_node.cc ini_parser.cc keynames.cc track.cc base_entity.cc 
+orxonox_SOURCES = orxonox.cc world.cc player.cc data_tank.cc world_entity.cc vector.cc camera.cc collision.cc command_node.cc ini_parser.cc keynames.cc track.cc base_entity.cc game_loader.cc campaign.cc story_entity.cc
 
 noinst_HEADERS = ability.h data_tank.h npc.h stdincl.h ai.h environment.h orxonox.h synchronisable.h base_entity.h error.h player.h track.h camera.h ini_parser.h power_up.h vector.h collision.h keynames.h proto_class.h world.h command_node.h list.h shoot_laser.h world_entity.h coordinates.h message_structures.h shoot_rocket.h
@@ -132,5 +132,6 @@
 	camera.$(OBJEXT) collision.$(OBJEXT) command_node.$(OBJEXT) \
 	ini_parser.$(OBJEXT) keynames.$(OBJEXT) track.$(OBJEXT) \
-	base_entity.$(OBJEXT)
+	base_entity.$(OBJEXT) game_loader.$(OBJEXT) campaign.$(OBJEXT) \
+	story_entity.$(OBJEXT)
 orxonox_OBJECTS = $(am_orxonox_OBJECTS)
 orxonox_LDADD = $(LDADD)
@@ -142,9 +143,10 @@
 am__depfiles_maybe = depfiles
 @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/base_entity.Po ./$(DEPDIR)/camera.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/collision.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/campaign.Po ./$(DEPDIR)/collision.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/command_node.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/data_tank.Po ./$(DEPDIR)/ini_parser.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/keynames.Po ./$(DEPDIR)/orxonox.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/player.Po ./$(DEPDIR)/track.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/data_tank.Po ./$(DEPDIR)/game_loader.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/ini_parser.Po ./$(DEPDIR)/keynames.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/orxonox.Po ./$(DEPDIR)/player.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/story_entity.Po ./$(DEPDIR)/track.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/vector.Po ./$(DEPDIR)/world.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/world_entity.Po
@@ -157,5 +159,5 @@
 HEADERS = $(noinst_HEADERS)
 
-DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.in INSTALL \
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.in ChangeLog INSTALL \
 	Makefile.am
 SOURCES = $(orxonox_SOURCES)
@@ -206,11 +208,14 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base_entity.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camera.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/campaign.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/command_node.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data_tank.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/game_loader.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ini_parser.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keynames.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orxonox.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/player.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/story_entity.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/track.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vector.Po@am__quote@
Index: orxonox/trunk/src/camera.cc
===================================================================
--- orxonox/trunk/src/camera.cc	(revision 2589)
+++ orxonox/trunk/src/camera.cc	(revision 2636)
@@ -27,6 +27,7 @@
    This standard constructor sets all parameters to zero
 */
-Camera::Camera ()
-{
+Camera::Camera (World* world)
+{
+  this->world = world;
   bound = NULL;
   /* give it some physical live */
@@ -36,5 +37,4 @@
   fs = new Vector(0.0, 0.0, 0.0);
   cameraMode = NORMAL;
-
   deltaTime = 3000.0;
   cameraOffset = 1.0;
@@ -179,10 +179,9 @@
       /* the camera is handled like an entity and rolls on the track */
     case NORMAL:
-      Orxonox *orx = Orxonox::getInstance();
       Location lookat;  
-      if( bound != NULL)
+      if( bound != NULL && world != NULL )
 	{
 	  bound->get_lookat (&lookat);
-	  orx->get_world()->calc_camera_pos (&lookat, &desired_place);
+	  world->calc_camera_pos (&lookat, &desired_place);
 	} 
       else
@@ -293,2 +292,8 @@
     } 
 }
+
+
+void Camera::setWorld(World* world)
+{
+  this->world = world;
+}
Index: orxonox/trunk/src/camera.h
===================================================================
--- orxonox/trunk/src/camera.h	(revision 2589)
+++ orxonox/trunk/src/camera.h	(revision 2636)
@@ -10,12 +10,13 @@
 
 class WorldEntity;
+class World;
 
 //! Camera
 /**
- 	This class controls the viewpoint from which the World is rendered. To use the 
-	Camera it has to be bound to a WorldEntity which serves as the reference focus 
-	point. The Camera itself calls the WorldEntity::get_lookat() and 
-	World::calc_camera_pos() functions to calculate the position it currently should
-	be in.
+   This class controls the viewpoint from which the World is rendered. To use the 
+   Camera it has to be bound to a WorldEntity which serves as the reference focus 
+   point. The Camera itself calls the WorldEntity::get_lookat() and 
+   World::calc_camera_pos() functions to calculate the position it currently should
+   be in.
 */
 
@@ -27,4 +28,5 @@
   Placement actual_place;	        //!< the Camera's current position
   Placement desired_place;        //!< where the Camera should be according to calculations
+  World* world;
   
   /* physical system - not needed yet */
@@ -49,17 +51,19 @@
   Quaternion *res;
   
+  
+  CAMERA_MODE cameraMode; //!< saves the camera mode: how the camera follows the entity
+  
+  void update_desired_place ();
+  
+ public:
+  Camera (World* world);
+  ~Camera ();
+  
+  void time_slice (Uint32 deltaT);
+  void apply ();
+  void bind (WorldEntity* entity);
+  void jump (Placement* plc);
 
-  CAMERA_MODE cameraMode; //!< saves the camera mode: how the camera follows the entity
-
-	void update_desired_place ();
-	
- public:
-  Camera ();
-  ~Camera ();
-
-	void time_slice (Uint32 deltaT);
-	void apply ();
-	void bind (WorldEntity* entity);
-	void jump (Placement* plc);
+  void setWorld(World* world);  
 
 };
Index: orxonox/trunk/src/campaign.cc
===================================================================
--- orxonox/trunk/src/campaign.cc	(revision 2636)
+++ orxonox/trunk/src/campaign.cc	(revision 2636)
@@ -0,0 +1,157 @@
+
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: 
+*/
+
+
+#include "campaign.h"
+#include "world.h"
+#include "camera.h"
+#include "story_entity.h"
+
+using namespace std;
+
+
+Campaign::Campaign () 
+{
+  this->entities = new List<StoryEntity>();
+  this->isInit = false;
+}
+
+Campaign::~Campaign () {}
+
+
+Error Campaign::init()
+{
+  this->isInit = true;
+}
+
+/** 
+    \brief adds an game stroy entity to the campaign
+
+    \param se: The entity
+    \param storyID: The number that identifies the entity in the campaign. Each ID only used once in a Campaign
+
+    An entity can be a world (playable), a cinematic, a shop, sounds, whatever you
+    want to queue up in the campaign.
+*/
+void Campaign::addEntity(StoryEntity* se, Uint32 storyID)
+{
+  se->setStoryID(storyID);
+  this->addEntity(se);
+}
+
+void Campaign::addEntity(StoryEntity* se)
+{
+  this->entities->add(se);
+}
+
+
+void Campaign::removeEntity(Uint32 storyID)
+{
+  this->removeEntity(this->getStoryEntity(storyID));
+  
+}
+
+
+void Campaign::removeEntity(StoryEntity* se)
+{
+  this->entities->remove(se);
+}
+
+
+Error Campaign::start()
+{
+  this->start(0);
+}
+
+Error Campaign::start(Uint32 storyID = 0)
+{
+  printf("World::start() - starting new StoryEntity Nr:%i\n", storyID);
+  Error errorCode;
+  if(!this->isInit) return errorCode; 
+  if(storyID == WORLD_ID_GAMEEND) return errorCode;
+  this->running = true;
+  StoryEntity* se = this->getStoryEntity(storyID);
+  while(se != NULL && this->running)
+    {
+      se = this->getStoryEntity(storyID);
+      this->currentEntity = se;
+      
+      se->displayEntityScreen();
+      se->load();
+      se->init();
+      se->releaseEntityScreen();
+      se->start();
+
+      int nextWorldID = se->getNextStoryID();
+      if(nextWorldID == WORLD_ID_GAMEEND) return errorCode;
+      se = this->getStoryEntity(nextWorldID);
+      if(se == NULL)
+	printf("Campaign::start() - ERROR: world it not found, oh oh...");
+    }
+}
+
+Error Campaign::stop()
+{
+  this->running = false;
+  if(this->currentEntity != NULL) 
+    {
+      this->currentEntity->stop();
+      delete this->currentEntity;
+      this->currentEntity = NULL;
+    }
+}
+
+Error Campaign::pause()
+{
+  if(this->currentEntity != NULL)
+    this->isPaused = true;
+}
+
+
+Error Campaign::resume()
+{
+  if(this->currentEntity != NULL)
+    this->isPaused = false;
+}
+
+
+void Campaign::nextLevel()
+{
+  printf("Campaign|nextLevel\n");
+  int nextID = this->currentEntity->getNextStoryID();
+  this->stop();
+  this->start(nextID);
+}
+
+void Campaign::previousLevel()
+{}
+
+
+StoryEntity* Campaign::getStoryEntity(Uint32 storyID)
+{
+  List<StoryEntity>* l;
+  StoryEntity* entity;
+  l = this->entities->get_next();  
+  while( l != NULL) 
+    { 
+      entity = l->get_object();
+      l = l->get_next();
+      if(entity->getStoryID() == storyID)
+	return entity;
+    }
+  return NULL;
+}
Index: orxonox/trunk/src/campaign.h
===================================================================
--- orxonox/trunk/src/campaign.h	(revision 2636)
+++ orxonox/trunk/src/campaign.h	(revision 2636)
@@ -0,0 +1,41 @@
+
+#ifndef CAMPAIGN_H
+#define CAMPAIGN_H
+
+#include "stdincl.h"
+#include "story_entity.h"
+
+
+class World;
+
+class Campaign : public StoryEntity {
+
+ public:
+  Campaign ();
+  ~Campaign ();
+
+  StoryEntity* currentEntity;
+
+  virtual Error init();
+  virtual Error start();
+  virtual Error start(Uint32 storyID);
+  virtual Error stop();
+  virtual Error pause();
+  virtual Error resume();
+
+  void addEntity(StoryEntity* se, Uint32 storyID);
+  void addEntity(StoryEntity* se);
+  void removeEntity(Uint32 storyID);
+  void removeEntity(StoryEntity* se);
+  
+  void nextLevel();
+  void previousLevel();
+
+ private:
+  List<StoryEntity>* entities;
+  bool running;
+
+  StoryEntity* getStoryEntity(Uint32 storyID);
+};
+
+#endif
Index: orxonox/trunk/src/command_node.cc
===================================================================
--- orxonox/trunk/src/command_node.cc	(revision 2589)
+++ orxonox/trunk/src/command_node.cc	(revision 2636)
@@ -19,4 +19,5 @@
 #include "ini_parser.h"
 #include "world_entity.h"
+#include "game_loader.h"
 
 #include <stdio.h>
@@ -27,187 +28,188 @@
 
 /**
-	\brief constructs a CommandNode to handle remote input
-	\param ID: unique denumerator to identify the node in the network
+   \brief constructs a CommandNode to handle remote input
+   \param ID: unique denumerator to identify the node in the network
 */
 CommandNode::CommandNode (int ID)
 {
-	bound = new List<WorldEntity>();
-	aliases = NULL;
-	netID = ID;
-	bLocalInput = false;
-}
-
-/**
-	\brief constructs a CommandNode to handle local input
-	\param filename: The path and name of the file to load the key bindings from
+  bound = new List<WorldEntity>();
+  aliases = NULL;
+  netID = ID;
+  bLocalInput = false;
+}
+
+/**
+   \brief constructs a CommandNode to handle local input
+   \param filename: The path and name of the file to load the key bindings from
 */
 CommandNode::CommandNode (char* filename = DEFAULT_KEYBIND_FILE)
 {
-	aliases = NULL;
-	bLocalInput = true;
-	netID = 0;
-	bound = new List<WorldEntity>();
-	load_bindings (filename);
-}
-
-/**
-	\brief removes the CommandNode from memory
+  aliases = NULL;
+  bLocalInput = true;
+  netID = 0;
+  bound = new List<WorldEntity>();
+  load_bindings (filename);
+}
+
+/**
+   \brief removes the CommandNode from memory
 */
 CommandNode::~CommandNode ()
 {
-	if( aliases != NULL) free (aliases);
-	if( bound != NULL) delete bound;
-}
-
-/**
-	\brief loads new key bindings from a file
-	\param filename: The path and name of the file to load the bindings from
+  if( aliases != NULL) free (aliases);
+  if( bound != NULL) delete bound;
+}
+
+/**
+   \brief loads new key bindings from a file
+   \param filename: The path and name of the file to load the bindings from
 */
 void CommandNode::load_bindings (char* filename)
 {
-	FILE* stream;
-	
-	printf("Loading key bindings from %s\n", filename);
-	
-	if( filename == NULL) filename = DEFAULT_KEYBIND_FILE;
-	
-		// remove old bindings if present
-	if( aliases != NULL)
+  FILE* stream;
+  
+  printf("Loading key bindings from %s\n", filename);
+  
+  if( filename == NULL) filename = DEFAULT_KEYBIND_FILE;
+  
+  // remove old bindings if present
+  if( aliases != NULL)
+    {
+      free (aliases);
+      aliases = NULL;
+    }
+  
+  // create parser
+  IniParser parser (filename);
+  if( parser.get_section ("Bindings") == -1)
+    {
+      printf("Could not find key bindings in %s\n", filename);
+      return;
+    }
+  // allocate empty lookup table
+  aliases = (KeyBindings*) calloc (1, sizeof (KeyBindings));
+  
+  char namebuf[256];
+  char valuebuf[256];
+  memset (namebuf, 0, 256);
+  memset (valuebuf, 0, 256);
+  int* index;
+  
+  while( parser.next_var (namebuf, valuebuf) != -1)
+    {
+      index = name_to_index (namebuf);
+      switch( index[0])
 	{
-		free (aliases);
-		aliases = NULL;
+	case 0:
+	  printf("Key binding %d(%s) set to %s\n", index[1], SDLK_to_keyname( index[1]), valuebuf);
+	  strcpy (aliases->keys[index[1]], valuebuf);
+	  break;
+	case 1:
+	  printf("Button binding %d(%s) set to %s\n", index[1], SDLB_to_buttonname( index[1]), valuebuf);
+	  strcpy (aliases->buttons[index[1]], valuebuf);
+	  break;
+	default:
+	  break;
 	}
-			
-		// create parser
-	IniParser parser (filename);
-	if( parser.get_section ("Bindings") == -1)
+      memset (namebuf, 0, 256);
+      memset (valuebuf, 0, 256);
+    }
+}
+
+/**
+   \brief binds a WorldEntity to the CommandNode
+   \param entity: Pointer to the entity to bind
+*/
+void CommandNode::bind (WorldEntity* entity)
+{
+  bound->add (entity, LIST_ADD_NEXT, true);
+}
+
+/**
+   \brief removes an entity from the list of the CommandNode
+   \param entity: Pointer to the entity to relese
+*/
+void CommandNode::unbind (WorldEntity* entity)
+{
+  bound->remove (entity, LIST_FIND_FW);
+}
+
+int* CommandNode::name_to_index (char* name)
+{
+  coord[0] = -1;
+  coord[1] = -1;
+  int c;
+  if( (c = keyname_to_SDLK (name)) != -1)
+    {
+      coord[1] = c;
+      coord[0] = 0;
+    }
+  if( (c = buttonname_to_SDLB (name)) != -1)
+    {
+      coord[1] = c;
+      coord[0] = 1;
+    }
+  return coord;
+}
+
+/**
+   \brief tells the CommandNode to run through all pending events and relay them accordingly
+*/
+void CommandNode::process ()
+{
+  if( bLocalInput) process_local ();
+  else process_network ();
+}
+
+void CommandNode::process_local ()
+{
+  SDL_Event event;
+  Command cmd;
+  
+  while( SDL_PollEvent (&event))
+    {
+      memset (cmd.cmd, 0, CMD_LENGHT); 
+      switch( event.type)
 	{
-		printf("Could not find key bindings in %s\n", filename);
-		return;
+	case SDL_KEYDOWN:
+	  strcpy (cmd.cmd, aliases->keys[event.key.keysym.sym]);
+	  cmd.bUp = false;
+	  if( strlen (cmd.cmd) > 0) relay (&cmd);
+	  break;
+	case SDL_KEYUP:
+	  strcpy( cmd.cmd, aliases->keys[event.key.keysym.sym]);
+	  cmd.bUp = true;
+	  if( strlen (cmd.cmd) > 0) relay (&cmd);
+	  break;
+	case SDL_MOUSEMOTION:
+	  strcpy( cmd.cmd, "cursor");
+	  cmd.x = event.motion.x;
+	  cmd.y = event.motion.y;
+	  cmd.xrel = event.motion.xrel;
+	  cmd.yrel = event.motion.yrel;
+	  break;
+	case SDL_MOUSEBUTTONUP:
+	  strcpy( cmd.cmd, aliases->buttons[event.button.button]);
+	  cmd.bUp = true;
+	  if( strlen (cmd.cmd) > 0) relay (&cmd);
+	  break;
+	case SDL_MOUSEBUTTONDOWN:
+	  strcpy( cmd.cmd, aliases->buttons[event.button.button]);
+	  cmd.bUp = false;
+	  if( strlen (cmd.cmd) > 0) relay (&cmd);
+	  break;
+	case SDL_JOYAXISMOTION:
+	case SDL_JOYBALLMOTION:
+	case SDL_JOYHATMOTION:
+	case SDL_JOYBUTTONDOWN:
+	case SDL_JOYBUTTONUP:
+	  break;
+	default:
+	  Orxonox *orx = Orxonox::getInstance();
+	  orx->event_handler (&event);
+	  
+	  break;
 	}
-			// allocate empty lookup table
-	aliases = (KeyBindings*) calloc (1, sizeof (KeyBindings));
-	
-	char namebuf[256];
-	char valuebuf[256];
-	memset (namebuf, 0, 256);
-	memset (valuebuf, 0, 256);
-	int* index;
-
-	while( parser.next_var (namebuf, valuebuf) != -1)
-	{
-		index = name_to_index (namebuf);
-		switch( index[0])
-		{
-			case 0:
-				printf("Key binding %d(%s) set to %s\n", index[1], SDLK_to_keyname( index[1]), valuebuf);
-				strcpy (aliases->keys[index[1]], valuebuf);
-				break;
-			case 1:
-				printf("Button binding %d(%s) set to %s\n", index[1], SDLB_to_buttonname( index[1]), valuebuf);
-				strcpy (aliases->buttons[index[1]], valuebuf);
-				break;
-			default:
-				break;
-		}
-		memset (namebuf, 0, 256);
-		memset (valuebuf, 0, 256);
-	}
-}
-
-/**
-	\brief binds a WorldEntity to the CommandNode
-	\param entity: Pointer to the entity to bind
-*/
-void CommandNode::bind (WorldEntity* entity)
-{
-	bound->add (entity, LIST_ADD_NEXT, true);
-}
-
-/**
-	\brief removes an entity from the list of the CommandNode
-	\param entity: Pointer to the entity to relese
-*/
-void CommandNode::unbind (WorldEntity* entity)
-{
-	bound->remove (entity, LIST_FIND_FW);
-}
-
-int* CommandNode::name_to_index (char* name)
-{
-	coord[0] = -1;
-	coord[1] = -1;
-	int c;
-	if( (c = keyname_to_SDLK (name)) != -1)
-	{
-		coord[1] = c;
-		coord[0] = 0;
-	}
-	if( (c = buttonname_to_SDLB (name)) != -1)
-	{
-		coord[1] = c;
-		coord[0] = 1;
-	}
-	return coord;
-}
-
-/**
-	\brief tells the CommandNode to run through all pending events and relay them accordingly
-*/
-void CommandNode::process ()
-{
-	if( bLocalInput) process_local ();
-	else process_network ();
-}
-
-void CommandNode::process_local ()
-{
-	SDL_Event event;
-	Command cmd;
-	
-	while( SDL_PollEvent (&event))
-	{
-		memset (cmd.cmd, 0, CMD_LENGHT); 
-		switch( event.type)
-		{
-			case SDL_KEYDOWN:
-				strcpy (cmd.cmd, aliases->keys[event.key.keysym.sym]);
-				cmd.bUp = false;
-				if( strlen (cmd.cmd) > 0) relay (&cmd);
-				break;
-			case SDL_KEYUP:
-				strcpy( cmd.cmd, aliases->keys[event.key.keysym.sym]);
-				cmd.bUp = true;
-				if( strlen (cmd.cmd) > 0) relay (&cmd);
-				break;
-			case SDL_MOUSEMOTION:
-				strcpy( cmd.cmd, "cursor");
-				cmd.x = event.motion.x;
-				cmd.y = event.motion.y;
-				cmd.xrel = event.motion.xrel;
-				cmd.yrel = event.motion.yrel;
-				break;
-			case SDL_MOUSEBUTTONUP:
-				strcpy( cmd.cmd, aliases->buttons[event.button.button]);
-				cmd.bUp = true;
-				if( strlen (cmd.cmd) > 0) relay (&cmd);
-				break;
-			case SDL_MOUSEBUTTONDOWN:
-				strcpy( cmd.cmd, aliases->buttons[event.button.button]);
-				cmd.bUp = false;
-				if( strlen (cmd.cmd) > 0) relay (&cmd);
-				break;
-			case SDL_JOYAXISMOTION:
-			case SDL_JOYBALLMOTION:
-			case SDL_JOYHATMOTION:
-			case SDL_JOYBUTTONDOWN:
-			case SDL_JOYBUTTONUP:
-				break;
-			default:
-  				Orxonox *orx = Orxonox::getInstance();
-  				orx->event_handler (&event);
-				break;
-		}
-	}
+    }
 }
 
@@ -219,25 +221,27 @@
 void CommandNode::relay (Command* cmd)
 {
-printf("CommandNode|relay()\n");
-	List<WorldEntity>* plist = bound;
-	
-	Orxonox *orx = Orxonox::getInstance();
-	if( orx->system_command (cmd)) return;
-		
-	if( bLocalInput) send_over_network (cmd);
-	
-	while( (plist = plist->get_next()) != NULL)
-	{
-		plist->get_object()->command (cmd);
-	}
-}
-
-/**
-	\brief sets the network identifier of the CommandNode
-	\param ID: the new ID to use
+  //printf("CommandNode|relay()\n");
+  List<WorldEntity>* plist = bound;
+  
+  Orxonox *orx = Orxonox::getInstance();
+  if( orx->system_command (cmd)) return;
+  GameLoader* gl = GameLoader::getInstance();
+  if(gl->worldCommand(cmd)) return;
+  
+  if( bLocalInput) send_over_network (cmd);
+  
+  while( (plist = plist->get_next()) != NULL)
+    {
+      plist->get_object()->command (cmd);
+    }
+}
+
+/**
+   \brief sets the network identifier of the CommandNode
+   \param ID: the new ID to use
 */
 void CommandNode::set_netID (int ID)
 {
-	netID = ID;
+  netID = ID;
 }
 
Index: orxonox/trunk/src/error.h
===================================================================
--- orxonox/trunk/src/error.h	(revision 2589)
+++ orxonox/trunk/src/error.h	(revision 2636)
@@ -22,5 +22,35 @@
 */ 
 
-
+// this are the two undefined error nr. Don't use them ...
 #define ERROR -1
 #define NO_ERROR 0
+
+/*!
+    \brief Error Definitions:
+
+    Error Classes:
+    0xx application framework codes
+    1xx graphics codes
+    2xx file/FS codes
+    3xx network codes
+    4xx general codes
+
+    Error Specifier 1:
+    x0x action finsished as desired
+    x1x initialisation error
+    x2x execution error
+    x3x uninitialisation error
+
+    Error Specifier 2:
+    xx0 no further informations
+    xx1 only a warning - feel free to ignore, the program will proceed
+    xx2 this could lead unexpected behaviour
+    xx3 this is a fatal error - you are invited to quit the program - panic!
+*/
+
+typedef struct 
+{
+  int code;
+  char* message;
+  char* location;
+} Error;
Index: orxonox/trunk/src/game_loader.cc
===================================================================
--- orxonox/trunk/src/game_loader.cc	(revision 2636)
+++ orxonox/trunk/src/game_loader.cc	(revision 2636)
@@ -0,0 +1,180 @@
+
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+
+#include "game_loader.h"
+#include "campaign.h"
+#include "world.h"
+#include "player.h"
+#include "orxonox.h"
+#include "camera.h"
+#include "command_node.h"
+#include "vector.h"
+#include "track.h"
+
+#include <string.h>
+
+
+using namespace std;
+
+
+GameLoader* GameLoader::singletonRef = 0;
+
+
+GameLoader::GameLoader () {}
+
+
+GameLoader::~GameLoader () {}
+
+
+GameLoader* GameLoader::getInstance()
+{
+  if(singletonRef == NULL)
+    singletonRef = new GameLoader();
+  return singletonRef;
+}
+
+
+Error GameLoader::init()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->init();
+}
+
+
+Error GameLoader::loadCampaign(char* name)
+{
+  Error errorCode;
+  
+  this->currentCampaign = this->fileToCampaign(name);
+}
+
+Error GameLoader::loadDebugCampaign(Uint32 campaignID)
+{
+  switch(campaignID)
+    {
+      // Debug Level 0: Debug level used to test the base frame work.
+    case DEBUG_CAMPAIGN_0:
+      {
+	Campaign* debugCampaign = new Campaign();
+	World* world0 = new World(DEBUG_WORLD_0);
+	world0->setNextStoryID(DEBUG_WORLD_1);
+	debugCampaign->addEntity(world0, WORLD_ID_0);
+	World* world1 = new World(DEBUG_WORLD_1);
+	world1->setNextStoryID(WORLD_ID_GAMEEND);
+	debugCampaign->addEntity(world1, WORLD_ID_1);
+
+	this->currentCampaign = debugCampaign;
+	break;
+      }
+    }
+}
+
+Error GameLoader::start()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->start();
+}
+
+
+Error GameLoader::stop()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->stop();
+  this->currentCampaign = NULL;
+}
+
+
+Error GameLoader::pause()
+{
+  this->isPaused = true;
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->pause();
+}
+
+
+Error GameLoader::resume()
+{
+  this->isPaused = false;
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->resume();
+}
+
+Error GameLoader::free()
+{}
+
+
+
+
+
+Campaign* GameLoader::fileToCampaign(char *name)
+{
+  /* do not entirely load the campaign. just the current world
+     before start of each world, it has to be initialized so it
+     can load everything it needs into memory then.
+  */
+}
+
+
+/**
+   \brief handle keyboard commands 
+   \param cmd: the command to handle
+   \return true if the command was handled by the system
+*/
+bool GameLoader::worldCommand (Command* cmd)
+{
+  if( !strcmp( cmd->cmd, "up_world"))
+    {
+      if( !cmd->bUp) 
+	{
+	  this->nextLevel();
+	}
+      return true;
+    }
+  else if( !strcmp( cmd->cmd, "down_world"))
+    {
+      if( !cmd->bUp)
+	{
+	  this->previousLevel();
+	}
+      return true;
+    }
+  else if( !strcmp( cmd->cmd, "pause"))
+    {
+      if( !cmd->bUp)
+	{
+	  if(this->isPaused)
+	    this->resume();
+	  else
+	    this->pause();
+	}
+      return true;
+    }
+  return false;
+}
+
+void GameLoader::nextLevel()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->nextLevel();
+}
+
+void GameLoader::previousLevel()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->previousLevel();
+}
Index: orxonox/trunk/src/game_loader.h
===================================================================
--- orxonox/trunk/src/game_loader.h	(revision 2636)
+++ orxonox/trunk/src/game_loader.h	(revision 2636)
@@ -0,0 +1,49 @@
+#ifndef GAME_LOADER_H
+#define GAME_LOADER_H
+
+#include "stdincl.h"
+#include "story_def.h"
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+class Campaign;
+class World;
+class Camera;
+class CammandNode;
+
+
+class GameLoader 
+{
+
+ public:
+  static GameLoader* getInstance();
+
+  Error init();
+  Error loadCampaign(char* name);
+  Error start();
+  Error stop();
+  Error pause();
+  Error resume();
+  Error free();
+
+  void nextLevel();
+  void previousLevel();
+
+  bool worldCommand(Command* cmd);
+  Error loadDebugCampaign(Uint32 campaignID);
+  
+ private:
+  GameLoader ();
+  ~GameLoader ();
+  Uint32 startTime; //!> start time of the campaign
+  static GameLoader* singletonRef;
+  bool isPaused;
+
+  Campaign* currentCampaign; //!> the current campaign playing
+  
+  Campaign* fileToCampaign(char* name);
+
+};
+
+#endif
Index: orxonox/trunk/src/list.h
===================================================================
--- orxonox/trunk/src/list.h	(revision 2589)
+++ orxonox/trunk/src/list.h	(revision 2636)
@@ -1,2 +1,21 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+
+   ADDONS/FIXES:
+  
+   Patrick Boenzli     :          Implemented getSize() function
+*/
+
+
 /*!
   \file list.h
@@ -21,4 +40,5 @@
   List<T>* prev;
   bool bReference;
+  int size;
   
  public:
@@ -35,4 +55,5 @@
   void set_prev (List<T>* ptr);
   int remove (T* obj, FINDMODE mode);
+  int getSize();
 };
 
@@ -52,4 +73,6 @@
   prev = p;
   bReference = bRef;
+  if(obj != NULL)
+    ++size;
 }
 
@@ -127,4 +150,5 @@
       break;
   }
+  ++size;
   return 0;
 }
@@ -224,4 +248,5 @@
     }
   }
+  --size;
   return 0;
 }
@@ -262,4 +287,13 @@
 
 
+/**
+  \brief Returns the current size of the List
+  \return Size of List
+*/
+template<class T>
+int List<T>::getSize()
+{
+  return this->size;
+}
 
 #endif
Index: orxonox/trunk/src/orxonox.cc
===================================================================
--- orxonox/trunk/src/orxonox.cc	(revision 2589)
+++ orxonox/trunk/src/orxonox.cc	(revision 2636)
@@ -29,4 +29,5 @@
 #include "data_tank.h"
 #include "command_node.h"
+#include "game_loader.h"
 #include <string.h>
 
@@ -34,5 +35,5 @@
 
 /**
-	\brief create a new Orxonox
+   \brief create a new Orxonox
 */
 Orxonox::Orxonox ()
@@ -42,13 +43,13 @@
 
 /**
-	\brief remove Orxonox from memory
+   \brief remove Orxonox from memory
 */
 Orxonox::~Orxonox () 
 {
-	Orxonox::singleton_ref = NULL;
-	if( world != NULL) delete world;
-	if( localinput != NULL) delete world;
-	if( localcamera != NULL) delete localcamera;
-	if( resources != NULL) delete resources;
+  Orxonox::singleton_ref = NULL;
+  if( world != NULL) delete world;
+  if( localinput != NULL) delete world;
+  if( localcamera != NULL) delete localcamera;
+  if( resources != NULL) delete resources;
 }
 
@@ -65,63 +66,63 @@
 
 /**
-	\brief this finds the config file
-	
-	Since the config file varies from user to user and since one may want to specify different config files
-	for certain occasions or platforms this function finds the right config file for every occasion and stores
-	it's path and name into configfilename
+   \brief this finds the config file
+   
+   Since the config file varies from user to user and since one may want to specify different config files
+   for certain occasions or platforms this function finds the right config file for every occasion and stores
+   it's path and name into configfilename
 */
 void Orxonox::get_config_file (int argc, char** argv)
 {
-/*	char* path;
-	#ifdef __WIN32__
-	path = getenv("");
-	#else
-	path = getenv("HOME");
-	#endif
-	
-	if( path != NULL) strcpy (configfilename, path);
-	else strcpy (configfilename, "./");
-	strcat (configfilename, "/.orxonox.conf");*/
-	
-	strcpy (configfilename, "orxonox.conf");
-}
-
-/**
-	\brief initialize Orxonox with command line
+  /*	char* path;
+    #ifdef __WIN32__
+    path = getenv("");
+    #else
+    path = getenv("HOME");
+    #endif
+    
+    if( path != NULL) strcpy (configfilename, path);
+    else strcpy (configfilename, "./");
+    strcat (configfilename, "/.orxonox.conf");*/
+  
+  strcpy (configfilename, "orxonox.conf");
+}
+
+/**
+   \brief initialize Orxonox with command line
 */
 int Orxonox::init (int argc, char** argv)
 {
-		// parse command line
-		// config file
-		
-	get_config_file (argc, argv);
-	
-		// initialize SDL
+  // parse command line
+  // config file
+  
+  get_config_file (argc, argv);
+  
+  // initialize SDL
   printf("> Initializing SDL\n");
   if( SDL_Init (SDL_INIT_EVERYTHING) == -1)
-  {
-    printf ("Could not SDL_Init(): %s\n", SDL_GetError());
-    return -1;
-  }
-  
-  	// initialize everything
+    {
+      printf ("Could not SDL_Init(): %s\n", SDL_GetError());
+      return -1;
+    }
+  
+  // initialize everything
   printf("> Initializing video\n");
-	if( init_video () == -1) return -1;
+  if( init_video () == -1) return -1;
   printf("> Initializing sound\n");
-	if( init_sound () == -1) return -1;
+  if( init_sound () == -1) return -1;
   printf("> Initializing input\n");
-	if( init_input () == -1) return -1;
+  if( init_input () == -1) return -1;
   printf("> Initializing networking\n");
-	if( init_networking () == -1) return -1;
+  if( init_networking () == -1) return -1;
   printf("> Initializing resources\n");
-	if( init_resources () == -1) return -1;
-  printf("> Initializing world\n");
-	if( init_world () == -1) return -1;
-	
-	return 0;
-}
-
-/**
-	\brief initializes SDL and OpenGL
+  if( init_resources () == -1) return -1;
+  //printf("> Initializing world\n");
+  //if( init_world () == -1) return -1; PB: world will be initialized when started
+  
+  return 0;
+}
+
+/**
+   \brief initializes SDL and OpenGL
 */
 int Orxonox::init_video () 
@@ -161,70 +162,88 @@
   
   // create camera
-  localcamera = new Camera();
-  
-  return 0;
-}
-
-/**
-	\brief initializes the sound engine
+  localcamera = new Camera(world);
+  
+  return 0;
+}
+
+/**
+   \brief initializes the sound engine
 */
 int Orxonox::init_sound () 
 {
-	printf("Not yet implemented\n");
-	return 0;
-}
-
-/**
-	\brief initializes input functions
+  printf("Not yet implemented\n");
+  return 0;
+}
+
+/**
+   \brief initializes input functions
 */
 int Orxonox::init_input () 
 {
-	// create localinput
-	localinput = new CommandNode( configfilename);
-	
-	return 0;
-}
-
-/**
-	\brief initializes network system
+  // create localinput
+  localinput = new CommandNode( configfilename);
+  
+  return 0;
+}
+
+/**
+   \brief initializes network system
 */
 int Orxonox::init_networking () 
 {
-	printf("Not yet implemented\n");
-	return 0;
-}
-
-/**
-	\brief initializes and loads resource files
+  printf("Not yet implemented\n");
+  return 0;
+}
+
+/**
+   \brief initializes and loads resource files
 */
 int Orxonox::init_resources () 
 {
-	printf("Not yet implemented\n");
-	return 0;
-}
-
-/**
-	\brief initializes the world
+  printf("Not yet implemented\n");
+  return 0;
+}
+
+/**
+   \brief initializes the world
 */
 int Orxonox::init_world () 
 {
-	world = new World();
-	
-	// TO DO: replace this with a menu/intro
-	world->load_debug_level();
-	
-	return 0;
-}
-
-/**
-	\brief exits Orxonox
+  //world = new World();
+  
+  // TO DO: replace this with a menu/intro
+  //world->load_debug_level();
+  
+  return 0;
+}
+
+
+/**
+   \brief starts the orxonox game or menu
+
+   here is the central orxonox state manager. There are currently two states
+   - menu
+   - game-play
+   both states manage their states themselfs again.
+*/
+void Orxonox::start()
+{
+  
+  this->gameLoader = GameLoader::getInstance();
+  this->gameLoader->loadDebugCampaign(DEBUG_CAMPAIGN_0);
+  this->gameLoader->init();
+  this->gameLoader->start();
+}
+
+/**
+   \brief exits Orxonox
 */
 void Orxonox::quitGame() 
 {
-	bQuitOrxonox = true;
-}
-
-/**
-	\brief this runs all of Orxonox
+  bQuitOrxonox = true;
+}
+
+/**
+   \brief this runs all of Orxonox
 */
 void Orxonox::mainLoop()
@@ -236,6 +255,4 @@
   while( !bQuitOrxonox)
     {
-      printf("<==");
-
       // Network
       synchronize();
@@ -248,6 +265,4 @@
       // Draw
       display();
-
-      printf(">\n");
     }
   printf("Orxonox|Exiting the main loop\n");
@@ -255,33 +270,33 @@
 
 /**
-	\brief handles sprecial events from localinput
-	\param event: an event not handled by the CommandNode 
+   \brief handles sprecial events from localinput
+   \param event: an event not handled by the CommandNode 
 */
 void Orxonox::event_handler (SDL_Event* event)
 {
-	// Handle special events such as reshape, quit, focus changes
-}
-
-/**
-	\brief synchronize local data with remote data
+  // Handle special events such as reshape, quit, focus changes
+}
+
+/**
+   \brief synchronize local data with remote data
 */
 void Orxonox::synchronize ()
 {
-	// Get remote input
-	// Update synchronizables
-}
-
-/**
-	\brief run all input processing
+  // Get remote input
+  // Update synchronizables
+}
+
+/**
+   \brief run all input processing
 */
 void Orxonox::handle_input ()
 {
-	// localinput
-		localinput->process();
-	// remoteinput
-}
-
-/**
-	\brief advance the timeline
+  // localinput
+  localinput->process();
+  // remoteinput
+}
+
+/**
+   \brief advance the timeline
 */
 void Orxonox::time_slice ()
@@ -295,5 +310,5 @@
 	{
 	  float fps = 1000/dt;
-	  printf("%f", fps);
+	  printf("fps = %f\n", fps);
 	}
       
@@ -306,82 +321,84 @@
 
 /**
-	\brief compute collision detection
+   \brief compute collision detection
 */
 void Orxonox::collision ()
 {
-	world->collide ();
-}
-
-/**
-	\brief handle keyboard commands that are not meant for WorldEntities
-	\param cmd: the command to handle
-	\return true if the command was handled by the system or false if it may be passed to the WorldEntities
+  world->collide ();
+}
+
+/**
+   \brief handle keyboard commands that are not meant for WorldEntities
+   \param cmd: the command to handle
+   \return true if the command was handled by the system or false if it may be passed to the WorldEntities
 */
 bool Orxonox::system_command (Command* cmd)
 {
-	if( !strcmp( cmd->cmd, "quit"))
-	{
-		if( !cmd->bUp) bQuitOrxonox = true;
-		return true;
-	}
-	return false;
-}
-
-/**
-	\brief render the current frame
+  if( !strcmp( cmd->cmd, "quit"))
+    {
+      if( !cmd->bUp) this->gameLoader->stop();
+      return true;
+    }
+  return false;
+}
+
+/**
+   \brief render the current frame
 */
 void Orxonox::display ()
 {
-		// clear buffer
-	glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
-		// set camera
-	localcamera->apply ();
-		// draw world
-	world->draw ();
-		// draw HUD
-		// flip buffers
-	SDL_GL_SwapBuffers();
-}
-
-/**
-	\brief retrieve a pointer to the local Camera
-	\return a pointer to localcamera
+  // clear buffer
+  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+  // set camera
+  localcamera->apply ();
+  // draw world
+  world->draw ();
+  // draw HUD
+  // flip buffers
+  SDL_GL_SwapBuffers();
+}
+
+/**
+   \brief retrieve a pointer to the local Camera
+   \return a pointer to localcamera
 */
 Camera* Orxonox::get_camera ()
 {
-	return localcamera;
-}
-
-/**
-	\brief retrieve a pointer to the local CommandNode
-	\return a pointer to localinput
+  return localcamera;
+}
+
+/**
+   \brief retrieve a pointer to the local CommandNode
+   \return a pointer to localinput
 */
 CommandNode* Orxonox::get_localinput ()
 {
-	return localinput;
-}
-
-/**
-	\brief retrieve a pointer to the local World
-	\return a pointer to world
+  return localinput;
+}
+
+/**
+   \brief retrieve a pointer to the local World
+   \return a pointer to world
 */
 World* Orxonox::get_world ()
 {
-	return world;
+  return world;
 }
 
 int main (int argc, char** argv) 
 {  
-	printf(">>> Starting Orxonox <<<\n");
+  printf(">>> Starting Orxonox <<<\n");
   Orxonox *orx = Orxonox::getInstance();
   
   if( (*orx).init(argc, argv) == -1)
-  {
-    printf("! Orxonox initialization failed\n");
-    return -1;
-  }
-	
-  (*orx).mainLoop();
-
+    {
+      printf("! Orxonox initialization failed\n");
+      return -1;
+    }
+  
+  //(*orx).mainLoop();
+
+  orx->start();
+  
   //delete orx;
   
Index: orxonox/trunk/src/orxonox.conf
===================================================================
--- orxonox/trunk/src/orxonox.conf	(revision 2589)
+++ orxonox/trunk/src/orxonox.conf	(revision 2636)
@@ -6,6 +6,10 @@
 SPACE=fire
 ESCAPE=quit
+p=pause
 q=quit
 BUTTON_LEFT=fire
 BUTTON_RIGHT=altfire
 b=benscho
+x=up_world
+z=down_world
+
Index: orxonox/trunk/src/orxonox.h
===================================================================
--- orxonox/trunk/src/orxonox.h	(revision 2589)
+++ orxonox/trunk/src/orxonox.h	(revision 2636)
@@ -16,4 +16,5 @@
 class World;
 class Camera;
+class GameLoader;
 
 //! Orxonox core singleton class
@@ -33,12 +34,13 @@
   Camera* localcamera;
   SDL_Surface* screen;
+  GameLoader* gameLoader;
   
   bool bQuitOrxonox;
   bool pause;
-	Uint32 lastframe;
-
-	void get_config_file (int argc, char** argv);
-	
-		// main loop functions
+  Uint32 lastframe;
+  
+  void get_config_file (int argc, char** argv);
+  
+  // main loop functions
   void synchronize ();
   void handle_input ();
@@ -57,4 +59,5 @@
  public:
   static Orxonox* getInstance ();
+  void start();
   void quitGame();
 
@@ -63,9 +66,9 @@
 
   int init (int argc, char** argv);
-	
-	CommandNode* get_localinput();
-	Camera* get_camera();
-	World* get_world();
-	
+  
+  CommandNode* get_localinput();
+  Camera* get_camera();
+  World* get_world();
+  
   void mainLoop();
 };
Index: orxonox/trunk/src/player.cc
===================================================================
--- orxonox/trunk/src/player.cc	(revision 2589)
+++ orxonox/trunk/src/player.cc	(revision 2636)
@@ -62,10 +62,10 @@
 void Player::command (Command* cmd)
 {
-	printf("Player|recieved command [%s]\n", cmd->cmd);
-	if( !strcmp( cmd->cmd, "up")) bUp = !cmd->bUp;
-	else if( !strcmp( cmd->cmd, "down")) bDown = !cmd->bUp;
-	else if( !strcmp( cmd->cmd, "left")) bLeft = !cmd->bUp;
-	else if( !strcmp( cmd->cmd, "right")) bRight = !cmd->bUp;
-	else if( !strcmp( cmd->cmd, "fire")) bFire = !cmd->bUp;
+  //printf("Player|recieved command [%s]\n", cmd->cmd);
+  if( !strcmp( cmd->cmd, "up")) bUp = !cmd->bUp;
+  else if( !strcmp( cmd->cmd, "down")) bDown = !cmd->bUp;
+  else if( !strcmp( cmd->cmd, "left")) bLeft = !cmd->bUp;
+  else if( !strcmp( cmd->cmd, "right")) bRight = !cmd->bUp;
+  else if( !strcmp( cmd->cmd, "fire")) bFire = !cmd->bUp;
 }
 
Index: orxonox/trunk/src/stdincl.h
===================================================================
--- orxonox/trunk/src/stdincl.h	(revision 2589)
+++ orxonox/trunk/src/stdincl.h	(revision 2636)
@@ -15,4 +15,5 @@
 #include "coordinates.h"
 #include "list.h"
+#include "error.h"
 #include "message_structures.h"
 #include "orxonox.h"
Index: orxonox/trunk/src/story_def.h
===================================================================
--- orxonox/trunk/src/story_def.h	(revision 2636)
+++ orxonox/trunk/src/story_def.h	(revision 2636)
@@ -0,0 +1,24 @@
+
+#ifndef STORY_DEF_H
+#define STORY_DEF_H
+
+
+#define DEBUG_CAMPAIGN_0 0
+#define DEBUG_CAMPAIGN_1 1
+#define DEBUG_CAMPAIGN_2 2
+
+#define DEBUG_WORLD_0 0
+#define DEBUG_WORLD_1 1
+#define DEBUG_WORLD_2 2
+
+#define WORLD_ID_0 0
+#define WORLD_ID_1 1
+#define WORLD_ID_2 2
+#define WORLD_ID_3 3
+#define WORLD_ID_4 4
+#define WORLD_ID_5 5
+#define WORLD_ID_GAMEEND 999
+
+#define MAX_STORY_ENTITIES 99; //!> maximal StoryEntities in a Campaign
+
+#endif
Index: orxonox/trunk/src/story_entity.cc
===================================================================
--- orxonox/trunk/src/story_entity.cc	(revision 2636)
+++ orxonox/trunk/src/story_entity.cc	(revision 2636)
@@ -0,0 +1,87 @@
+
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: 
+*/
+
+
+#include "story_entity.h"
+
+
+using namespace std;
+
+
+
+StoryEntity::StoryEntity () {}
+StoryEntity::~StoryEntity () {}
+
+
+/** 
+    \brief initialize the entity before use. 
+
+    After execution of this function, the Entity is ready to be played/executed, 
+    this shifts the initialisation work before the execution - very important...
+    
+*/
+Error StoryEntity::init()
+{}
+
+
+void StoryEntity::setStoryID(Uint32 storyID)
+{
+  this->storyID = storyID;
+}
+
+int StoryEntity::getStoryID()
+{
+  return this->storyID;
+}
+
+
+void StoryEntity::setNextStoryID(Uint32 nextStoryID)
+{
+  this->nextStoryID = nextStoryID;
+}
+
+Uint32 StoryEntity::getNextStoryID()
+{
+  return this->nextStoryID;
+}
+
+
+Error StoryEntity::start(Uint32 storyID)
+{}
+
+Error StoryEntity::start()
+{}
+
+Error StoryEntity::stop()
+{}
+
+Error StoryEntity::pause()
+{}
+
+Error StoryEntity::resume()
+{}
+
+
+void StoryEntity::load()
+{}
+
+
+void StoryEntity::displayEntityScreen()
+{}
+
+void StoryEntity::releaseEntityScreen()
+{}
Index: orxonox/trunk/src/story_entity.h
===================================================================
--- orxonox/trunk/src/story_entity.h	(revision 2636)
+++ orxonox/trunk/src/story_entity.h	(revision 2636)
@@ -0,0 +1,41 @@
+
+#ifndef STORY_ENTITY_H
+#define STORY_ENTITY_H
+
+#include "stdincl.h"
+#include "story_def.h"
+
+class StoryEntity {
+
+ public:
+  StoryEntity ();
+  ~StoryEntity ();
+
+  bool isInit;
+  bool isPaused;
+
+  virtual Error init();
+  virtual Error start(Uint32 storyID);
+  virtual Error start();
+  virtual Error stop();
+  virtual Error pause();
+  virtual Error resume();
+
+  virtual void load();
+
+  virtual void displayEntityScreen();
+  virtual void releaseEntityScreen();
+
+  void setStoryID(Uint32 storyID);
+  int getStoryID();
+
+  void setNextStoryID(Uint32 nextStoryID);
+  Uint32 getNextStoryID();
+
+
+ private:
+  Uint32 storyID;
+  Uint32 nextStoryID;
+};
+
+#endif
Index: orxonox/trunk/src/track.cc
===================================================================
--- orxonox/trunk/src/track.cc	(revision 2589)
+++ orxonox/trunk/src/track.cc	(revision 2636)
@@ -52,4 +52,10 @@
 {
 }
+
+void Track::init()
+{
+  
+}
+
 
 /**
Index: orxonox/trunk/src/track.h
===================================================================
--- orxonox/trunk/src/track.h	(revision 2589)
+++ orxonox/trunk/src/track.h	(revision 2636)
@@ -27,13 +27,14 @@
  	
  public:
- 	Track ();
+  Track ();
   Track (Uint32 number, Uint32 next, Vector* start, Vector* finish);
   ~Track ();
-	
-	virtual void post_enter (WorldEntity* entity);	// handle coordinate transition in here !!! (when dist < 0 or dist > lasttracklenght)
-	virtual void post_leave (WorldEntity* entity);
-	virtual void tick (float deltaT);
-	virtual void map_camera (Location* lookat, Placement* camplc);
-	virtual bool map_coords (Location* loc, Placement* plc);	// this should return true if the entity left track boundaries
+  virtual void init();
+  
+  virtual void post_enter (WorldEntity* entity);	// handle coordinate transition in here !!! (when dist < 0 or dist > lasttracklenght)
+  virtual void post_leave (WorldEntity* entity);
+  virtual void tick (float deltaT);
+  virtual void map_camera (Location* lookat, Placement* camplc);
+  virtual bool map_coords (Location* loc, Placement* plc);	// this should return true if the entity left track boundaries
 };
 
Index: orxonox/trunk/src/world.cc
===================================================================
--- orxonox/trunk/src/world.cc	(revision 2589)
+++ orxonox/trunk/src/world.cc	(revision 2636)
@@ -31,7 +31,16 @@
     This creates a new empty world!
 */
-World::World ()
-{
-  entities = new List<WorldEntity>();
+World::World (char* name)
+{
+  this->worldName = name;
+  this->debugWorldNr = -1;
+  this->entities = new List<WorldEntity>();
+}
+
+World::World (int worldID)
+{
+  this->debugWorldNr = worldID;
+  this->worldName = NULL;
+  this->entities = new List<WorldEntity>();
 }
 
@@ -44,4 +53,113 @@
   delete entities;
 }
+
+
+/** 
+    \brief initialize the world before use.
+*/
+Error World::init()
+{
+  this->bPause = false;
+}
+
+Error World::start()
+{
+  this->mainLoop();
+}
+
+Error World::stop()
+{
+  this->bQuitCurrentGame = true;
+  this->localCamera->setWorld(NULL);
+}
+
+Error World::pause()
+{
+  this->isPaused = true;
+}
+
+Error World::resume()
+{
+  this->isPaused = false;
+}
+
+void World::load()
+{
+  if(this->debugWorldNr != -1)
+    {
+      switch(this->debugWorldNr)
+	{
+	case DEBUG_WORLD_0:
+	  {
+	    // create some path nodes
+	    this->pathnodes = new Vector[6];
+	    this->pathnodes[0] = Vector(0, 0, 0);
+	    this->pathnodes[1] = Vector(-100, 40, 0);
+	    this->pathnodes[2] = Vector(-100, 140, 0);
+	    this->pathnodes[3] = Vector(0, 180, 0);
+	    this->pathnodes[4] = Vector(100, 140, 0);
+	    this->pathnodes[5] = Vector(100, 40, 0);
+	    
+	    // create the tracks
+	    this->tracklen = 6;
+	    this->track = new Track[6];
+	    for( int i = 0; i < this->tracklen; i++)
+	      {
+		this->track[i] = Track( i, (i+1)%this->tracklen, &this->pathnodes[i], &this->pathnodes[(i+1)%this->tracklen]);
+	      }
+	    
+	    // create a player
+	    WorldEntity* myPlayer = (WorldEntity*) this->spawn<Player>();
+	    
+	    // bind input
+	    Orxonox *orx = Orxonox::getInstance();
+	    orx->get_localinput()->bind (myPlayer);
+	    
+	    // bind camera
+	    this->localCamera = new Camera(this);
+	    this->getCamera()->bind (myPlayer);	
+	    break;
+	  }
+	case DEBUG_WORLD_1:
+	  {
+	    // create some path nodes
+	    this->pathnodes = new Vector[6];
+	    this->pathnodes[0] = Vector(0, 0, 0);
+	    this->pathnodes[1] = Vector(20, 10, 10);
+	    this->pathnodes[2] = Vector(40, 0, 10);
+	    this->pathnodes[3] = Vector(60, 10, 0);
+	    this->pathnodes[4] = Vector(80, 20, 10);
+	    this->pathnodes[5] = Vector(30, 50, 0);
+	    
+	    // create the tracks
+	    this->tracklen = 6;
+	    this->track = new Track[6];
+	    for( int i = 0; i < this->tracklen; i++)
+	      {
+		this->track[i] = Track( i, (i+1)%this->tracklen, &this->pathnodes[i], &this->pathnodes[(i+1)%this->tracklen]);
+	      }
+	    
+	    // create a player
+	    WorldEntity* myPlayer = (WorldEntity*) this->spawn<Player>();
+	    
+	    // bind input
+	    Orxonox *orx = Orxonox::getInstance();
+	    orx->get_localinput()->bind (myPlayer);
+	    
+	    // bind camera
+	    this->localCamera = new Camera(this);
+	    this->getCamera()->bind (myPlayer);	
+	    break;
+	  }
+	default:
+	  printf("World::load() - no world with ID %i found", this->debugWorldNr );
+	}
+    }
+  else if(this->worldName != NULL)
+    {
+
+    }
+}
+
 
 /** 
@@ -254,36 +372,5 @@
 }
 
-/**
-   \brief loads a simple level for testing purposes
-*/
-void World::load_debug_level()
-{
-  // create some path nodes
-  pathnodes = new Vector[6];
-  pathnodes[0] = Vector(0, 0, 0);
-  pathnodes[1] = Vector(-100, 40, 0);
-  pathnodes[2] = Vector(-100, 140, 0);
-  pathnodes[3] = Vector(0, 180, 0);
-  pathnodes[4] = Vector(100, 140, 0);
-  pathnodes[5] = Vector(100, 40, 0);	
-  
-  // create the tracks
-  tracklen = 6;
-  track = new Track[6];
-  for( int i = 0; i < tracklen; i++)
-    {
-      track[i] = Track( i, (i+1)%tracklen, &pathnodes[i], &pathnodes[(i+1)%tracklen]);
-    }
-  
-  // create a player
-  WorldEntity* myPlayer = (WorldEntity*) spawn<Player>();
-  
-  // bind input
-  Orxonox *orx = Orxonox::getInstance();
-  orx->get_localinput()->bind (myPlayer);
-  
-  // bind camera
-  orx->get_camera()->bind (myPlayer);
-}
+
 
 /**
@@ -295,2 +382,126 @@
   track[loc->part].map_camera (loc, plc);
 }
+
+
+void World::setTrackLen(Uint32 len)
+{
+  this->tracklen = len;
+}
+
+int World::getTrackLen()
+{
+  return this->tracklen;
+}
+
+
+void World::mainLoop()
+{
+  this->lastFrame = SDL_GetTicks();
+  this->bQuitOrxonox = false;
+  this->bQuitCurrentGame = false;
+  printf("World|Entering main loop\n");
+  while(!this->bQuitOrxonox && !this->bQuitCurrentGame) /* pause pause pause ?!?!?*/
+    {
+      // Network
+      synchronize();
+      // Process input
+      handle_input();
+      // Process time
+      time_slice();
+      // Process collision
+      collision();
+      // Draw
+      display();
+    }
+  printf("World|Exiting the main loop\n");
+}
+
+/**
+   \brief synchronize local data with remote data
+*/
+void World::synchronize ()
+{
+  // Get remote input
+  // Update synchronizables
+}
+
+/**
+   \brief run all input processing
+*/
+void World::handle_input ()
+{
+  // localinput
+  Orxonox::getInstance()->get_localinput()->process();
+  // remoteinput
+}
+
+/**
+   \brief advance the timeline
+*/
+void World::time_slice ()
+{
+  Uint32 currentFrame = SDL_GetTicks();
+  if(!this->bPause)
+    {
+      Uint32 dt = currentFrame - this->lastFrame;
+      /*
+      if(dt > 0)
+	{
+	  float fps = 1000/dt;
+	  printf("fps = %f\n", fps);
+	}
+      else
+	{
+	  printf("fps = 1000\n");
+	}
+      */
+      this->time_slice (dt);
+      this->update ();
+      this->localCamera->time_slice (dt);
+    }
+  this->lastFrame = currentFrame;
+}
+
+/**
+   \brief compute collision detection
+*/
+void World::collision ()
+{
+  this->collide ();
+}
+
+/**
+   \brief handle keyboard commands that are not meant for WorldEntities
+   \param cmd: the command to handle
+   \return true if the command was handled by the system or false if it may be passed to the WorldEntities
+*/
+bool World::system_command (Command* cmd)
+{
+  if( !strcmp( cmd->cmd, "quit"))
+    {
+      if( !cmd->bUp) this->bQuitOrxonox = true;
+      return true;
+    }
+  return false;
+}
+
+/**
+	\brief render the current frame
+*/
+void World::display ()
+{
+  // clear buffer
+  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+  // set camera
+  this->localCamera->apply ();
+  // draw world
+  this->draw();
+  // draw HUD
+  // flip buffers
+  SDL_GL_SwapBuffers();
+}
+
+Camera* World::getCamera()
+{
+  return this->localCamera;
+}
Index: orxonox/trunk/src/world.h
===================================================================
--- orxonox/trunk/src/world.h	(revision 2589)
+++ orxonox/trunk/src/world.h	(revision 2636)
@@ -8,39 +8,70 @@
 
 #include "stdincl.h"
+#include "story_entity.h"
+
+
 
 class Track;
 class WorldEntity;
+class Camera;
 
 //! The game environment
-class World {
+class World : public StoryEntity {
 
  public:
-  World ();
+  World (char* name);
+  World (int worldID);
   ~World ();
 
-	template<typename T> 
-	  T* spawn(Location* loc, WorldEntity* owner);	// template to be able to spawn any derivation of WorldEntity
-	template<typename T> 
-	  T* spawn(Placement* plc, WorldEntity* owner);
+  template<typename T> 
+    T* spawn(Location* loc, WorldEntity* owner);	// template to be able to spawn any derivation of WorldEntity
+  template<typename T> 
+    T* spawn(Placement* plc, WorldEntity* owner);
+  
+  virtual Error init();
+  virtual Error start();
+  virtual Error stop();
+  virtual Error pause();
+  virtual Error resume();
 
-	void time_slice (Uint32 deltaT);
-	void collide ();
-	void draw ();
-	void update ();	// maps Locations to Placements
-	void calc_camera_pos (Location* loc, Placement* plc);
+  virtual void load();
+
+  void time_slice (Uint32 deltaT);
+  void collide ();
+  void draw ();
+  void update ();	// maps Locations to Placements
+  void calc_camera_pos (Location* loc, Placement* plc);
 	
-	void unload ();
-	
-	void load_debug_level ();
-	
+  void unload ();
+  
+  void setTrackLen(Uint32 tracklen);
+  int getTrackLen();
+  bool system_command (Command* cmd);
+  Camera* getCamera();
+  //private:
+  
+  List<WorldEntity>* entities;
+  
+  // base level data
+  Track* track;
+  Uint32 tracklen;   // number of Tracks the World consist of
+  Vector* pathnodes;
+  Camera* localCamera;  
+
  private:
- 
-	List<WorldEntity>* entities;
-	
-		// base level data
-	Track* track;
-	Uint32 tracklen;   // number of Tracks the World consist of
-	Vector* pathnodes;
+  Uint32 lastFrame; //!> last time of frame
+  bool bQuitOrxonox; //!> quit this application
+  bool bQuitCurrentGame; //!> quit only the current game and return to menu
+  bool bPause;
 
+  char* worldName;
+  int debugWorldNr;
+
+  void mainLoop();
+  void synchronize();
+  void handle_input();
+  void time_slice();
+  void collision();
+  void display();
 };
 
@@ -63,6 +94,6 @@
 	if( loc == NULL)
 	{
-		zeroloc.dist = 0;
-		zeroloc.part = 0;
+	  zeroloc.dist = 0;
+	  zeroloc.part = 0;
 		zeroloc.pos = Vector();
 		zeroloc.rot = Quaternion();
