* file naming is inconsistent: some times we use '_' to separate
   words, sometimes we don't
 
-* get rid of NDEBUG and conditional compilation, these should be
-  reserved for a few tiny cases, not spread all over the code
-
 * collect all manager classes into globals.hpp
 
 * more moving directories around?
 
 
     if (badguys.size() > 1) {
       if (random) {
-        next_badguy = systemRandom.rand(badguys.size());
+        next_badguy = gameRandom.rand(badguys.size());
       }
       else {
         next_badguy++;
 
 void
 FlyingSnowBall::activate()
 {
-  puff_timer.start(systemRandom.randf(PUFF_INTERVAL_MIN, PUFF_INTERVAL_MAX));
-  normal_propeller_speed = systemRandom.randf(0.95, 1.05);
+  puff_timer.start(gameRandom.randf(PUFF_INTERVAL_MIN, PUFF_INTERVAL_MAX));
+  normal_propeller_speed = gameRandom.randf(0.95, 1.05);
 }
 
 bool
   // spawn smoke puffs
   if (puff_timer.check()) {
     Vector ppos = bbox.get_middle();
-    Vector pspeed = Vector(systemRandom.randf(-10, 10), 150);
+    Vector pspeed = Vector(gameRandom.randf(-10, 10), 150);
     Vector paccel = Vector(0,0);
     Sector::current()->add_object(new SpriteParticle("images/objects/particles/smoke.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
-    puff_timer.start(systemRandom.randf(PUFF_INTERVAL_MIN, PUFF_INTERVAL_MAX));
+    puff_timer.start(gameRandom.randf(PUFF_INTERVAL_MIN, PUFF_INTERVAL_MAX));
 
-    normal_propeller_speed = systemRandom.randf(0.95, 1.05);
+    normal_propeller_speed = gameRandom.randf(0.95, 1.05);
     physic.set_velocity_y(physic.get_velocity_y() - 50);
   }
 }
 
       for(iter = willowisps.begin(); iter != willowisps.end(); ++iter) {
         TreeWillOWisp *willo = *iter;
         if(willo->get_color() == col) {
-          willo->start_sucking(get_bbox().get_middle() + SUCK_TARGET_OFFSET + Vector(systemRandom.randf(-SUCK_TARGET_SPREAD, SUCK_TARGET_SPREAD), systemRandom.randf(-SUCK_TARGET_SPREAD, SUCK_TARGET_SPREAD)));
+          willo->start_sucking(get_bbox().get_middle() + SUCK_TARGET_OFFSET + Vector(gameRandom.randf(-SUCK_TARGET_SPREAD, SUCK_TARGET_SPREAD), gameRandom.randf(-SUCK_TARGET_SPREAD, SUCK_TARGET_SPREAD)));
         }
       }
       mystate = STATE_SUCKING;
 
     sprite->set_action("flying");
     physic.set_velocity_y(0);
     //Set random initial speed and direction
-    direction = systemRandom.rand(2)? 1: -1;
-    int speed = (BASE_SPEED + (systemRandom.rand(RAND_SPEED))) * direction;
+    direction = gameRandom.rand(2)? 1: -1;
+    int speed = (BASE_SPEED + (gameRandom.rand(RAND_SPEED))) * direction;
     physic.set_velocity_x(speed);
     movement_timer.start(MOVETIME);
     lifetime.start(LIFETIME);
     if (groundhit_pos_set) {
       if (movement_timer.check()) {
         if (direction == 1) direction = -1; else direction = 1;
-        int speed = (BASE_SPEED + (systemRandom.rand(RAND_SPEED))) * direction;
+        int speed = (BASE_SPEED + (gameRandom.rand(RAND_SPEED))) * direction;
         physic.set_velocity_x(speed);
         movement_timer.start(MOVETIME);
       }
 
   float px = get_bbox().get_middle().x;
   float py = get_bbox().get_middle().y;
 
-  float angle = systemRandom.rand(90 - 15, 90 + 15) * (M_PI / 180);
+  float angle = gameRandom.rand(90 - 15, 90 + 15) * (M_PI / 180);
   float vx = cos(angle) * THROW_VELOCITY;
   float vy = -sin(angle) * THROW_VELOCITY;
 
 
   // TODO: provide convenience function in MovingSprite or MovingObject?
   for (int px = (int)stumpy->get_bbox().p1.x; px < (int)stumpy->get_bbox().p2.x; px+=10) {
     Vector ppos = Vector(px, stumpy->get_bbox().p1.y-5);
-    float angle = systemRandom.randf(-M_PI_2, M_PI_2);
-    float velocity = systemRandom.randf(45, 90);
+    float angle = graphicsRandom.randf(-M_PI_2, M_PI_2);
+    float velocity = graphicsRandom.randf(45, 90);
     float vx = sin(angle)*velocity;
     float vy = -cos(angle)*velocity;
     Vector pspeed = Vector(vx, vy);
 
   // TODO: provide convenience function in MovingSprite or MovingObject?
   for (int i = 0; i < 3; i++) {
     Vector ppos = bbox.get_middle();
-    float angle = systemRandom.randf(-M_PI_2, M_PI_2);
-    float velocity = systemRandom.randf(350, 400);
+    float angle = graphicsRandom.randf(-M_PI_2, M_PI_2);
+    float velocity = graphicsRandom.randf(350, 400);
     float vx = sin(angle)*velocity;
     float vy = -cos(angle)*velocity;
     Vector pspeed = Vector(vx, vy);
 
     physic.set_velocity_y(0);
     sprite->set_action(dir == LEFT ? "standing-left" : "standing-right");
 
-    float recover_time = systemRandom.randf(MIN_RECOVER_TIME,MAX_RECOVER_TIME);
+    float recover_time = gameRandom.randf(MIN_RECOVER_TIME,MAX_RECOVER_TIME);
     recover_timer.start(recover_time);
   } else
     if (newState == CHARGING) {
 
       }
     }
   } else if(state == STALACTITE_SHAKING) {
-    shake_delta = Vector(systemRandom.rand(-3,3), 0);
+    shake_delta = Vector(graphicsRandom.rand(-3,3), 0);
     if(timer.check()) {
       state = STALACTITE_FALLING;
       physic.enable_gravity(true);
 
     // TODO: provide convenience function in MovingSprite or MovingObject?
     for (int i = 0; i < 25; i++) {
       Vector ppos = bbox.get_middle();
-      float angle = systemRandom.randf(-M_PI_2, M_PI_2);
-      float velocity = systemRandom.randf(45, 90);
+      float angle = graphicsRandom.randf(-M_PI_2, M_PI_2);
+      float velocity = graphicsRandom.randf(45, 90);
       float vx = sin(angle)*velocity;
       float vy = -cos(angle)*velocity;
       Vector pspeed = Vector(vx, vy);
 
   last_self_pos()
 {
   state = FLYING;
-  speed = systemRandom.rand(130, 171);
+  speed = gameRandom.rand(130, 171);
   physic.enable_gravity(false);
 }
 
   last_self_pos()
 {
   state = FLYING;
-  speed = systemRandom.rand(130, 171);
+  speed = gameRandom.rand(130, 171);
   physic.enable_gravity(false);
 }
 
 
 
 #include "math/random_generator.hpp"
 
-RandomGenerator systemRandom;               // global random number generator
+RandomGenerator graphicsRandom;               // graphic RNG
+RandomGenerator gameRandom;                   // game RNG
 
 RandomGenerator::RandomGenerator() :
   initialized(),
 
   RandomGenerator& operator=(const RandomGenerator&);
 };
 
-extern RandomGenerator systemRandom;
+// Use for random particle fx or whatever
+extern RandomGenerator graphicsRandom;
+// Use for game-changing random numbers
+extern RandomGenerator gameRandom;
 
 #endif //__RANDOM_GENERATOR__
 
 
 BrokenBrick::draw(DrawingContext& context)
 {
   sprite->draw_part(context,
-                    Vector(systemRandom.rand(16), systemRandom.rand(16)), Vector(16, 16),
+                    Vector(graphicsRandom.rand(16), graphicsRandom.rand(16)), Vector(16, 16),
                     position, LAYER_OBJECTS + 1);
 }
 
 
     context.push_target();
     context.set_target(DrawingContext::LIGHTMAP);
     // draw approx. 1 in 10 frames darker. Makes the candle flicker
-    if (systemRandom.rand(10) != 0) {
+    if (gameRandom.rand(10) != 0) {
       context.draw_surface(candle_light_1, pos, layer);
     } else {
       context.draw_surface(candle_light_2, pos, layer);
 
   // create some random clouds
   for(size_t i=0; i<15; ++i) {
     CloudParticle* particle = new CloudParticle;
-    particle->pos.x = systemRandom.rand(static_cast<int>(virtual_width));
-    particle->pos.y = systemRandom.rand(static_cast<int>(virtual_height));
+    particle->pos.x = graphicsRandom.rand(static_cast<int>(virtual_width));
+    particle->pos.y = graphicsRandom.rand(static_cast<int>(virtual_height));
     particle->texture = cloudimage;
-    particle->speed = -systemRandom.randf(25.0, 54.0);
+    particle->speed = -graphicsRandom.randf(25.0, 54.0);
 
     particles.push_back(particle);
   }
 
   size_t cometcount = 2;
   for(size_t i=0; i<cometcount; ++i) {
     CometParticle* particle = new CometParticle;
-    particle->pos.x = systemRandom.rand(int(virtual_width));
-    particle->pos.y = systemRandom.rand(int(virtual_height));
-    int cometsize = systemRandom.rand(2);
+    particle->pos.x = graphicsRandom.rand(int(virtual_width));
+    particle->pos.y = graphicsRandom.rand(int(virtual_height));
+    int cometsize = graphicsRandom.rand(2);
     particle->texture = cometimages[cometsize];
     do {
-      particle->speed = (cometsize+1)*30 + systemRandom.randf(3.6);
+      particle->speed = (cometsize+1)*30 + graphicsRandom.randf(3.6);
     } while(particle->speed < 1);
     particle->speed *= 10; // gravity
 
       if ((particle->pos.y <= SCREEN_HEIGHT + abs_y) && (col >= 1)) {
         Sector::current()->add_object(new Bomb(particle->pos, LEFT));
       }
-      int new_x = systemRandom.rand(int(virtual_width)) + int(abs_x);
+      int new_x = graphicsRandom.rand(int(virtual_width)) + int(abs_x);
       int new_y = 0;
       //FIXME: Don't move particles over solid tiles
       particle->pos.x = new_x;
 
     // TODO: provide convenience function in MovingSprite or MovingObject?
     for (int i = 0; i < 100; i++) {
       Vector ppos = bbox.get_middle();
-      float angle = systemRandom.randf(-M_PI_2, M_PI_2);
-      float velocity = systemRandom.randf(450, 900);
+      float angle = graphicsRandom.randf(-M_PI_2, M_PI_2);
+      float velocity = graphicsRandom.randf(450, 900);
       float vx = sin(angle)*velocity;
       float vy = -cos(angle)*velocity;
       Vector pspeed = Vector(vx, vy);
 
     // TODO: provide convenience function in MovingSprite or MovingObject?
     for (int i = 0; i < 5; i++) {
       Vector ppos = bbox.get_middle();
-      float angle = systemRandom.randf(-M_PI_2, M_PI_2);
-      float velocity = systemRandom.randf(450, 900);
+      float angle = graphicsRandom.randf(-M_PI_2, M_PI_2);
+      float velocity = graphicsRandom.randf(450, 900);
       float vx = sin(angle)*velocity;
       float vy = -cos(angle)*velocity;
       Vector pspeed = Vector(vx, vy);
 
   if(timer.check()) {
     Sector* sector = Sector::current();
     Vector pos = sector->camera->get_translation();
-    pos += Vector(systemRandom.randf(SCREEN_WIDTH),
-                  systemRandom.randf(SCREEN_HEIGHT/2));
+    pos += Vector(graphicsRandom.randf(SCREEN_WIDTH),
+                  graphicsRandom.randf(SCREEN_HEIGHT/2));
 
-    float red = systemRandom.randf(1.0);
-    float green = systemRandom.randf(1.0);
+    float red = graphicsRandom.randf(1.0);
+    float green = graphicsRandom.randf(1.0);
     //float red = 0.7;
     //float green = 0.9;
     (void) red;
                                      Vector(0, 0), 45, Color(red, green, 0), 3, 1.3f,
                                      LAYER_FOREGROUND1+1));
     sound_manager->play("sounds/fireworks.wav");
-    timer.start(systemRandom.randf(1.0, 1.5));
+    timer.start(graphicsRandom.randf(1.0, 1.5));
   }
 }
 
 
   size_t ghostcount = 2;
   for(size_t i=0; i<ghostcount; ++i) {
     GhostParticle* particle = new GhostParticle;
-    particle->pos.x = systemRandom.randf(virtual_width);
-    particle->pos.y = systemRandom.randf(SCREEN_HEIGHT);
-    int size = systemRandom.rand(2);
+    particle->pos.x = graphicsRandom.randf(virtual_width);
+    particle->pos.y = graphicsRandom.randf(SCREEN_HEIGHT);
+    int size = graphicsRandom.rand(2);
     particle->texture = ghosts[size];
-    particle->speed = systemRandom.randf(std::max(50, (size * 10)), 180 + (size * 10));
+    particle->speed = graphicsRandom.randf(std::max(50, (size * 10)), 180 + (size * 10));
     particles.push_back(particle);
   }
 }
     particle->pos.x -= particle->speed * elapsed_time;
     if(particle->pos.y > SCREEN_HEIGHT) {
       particle->pos.y = fmodf(particle->pos.y , virtual_height);
-      particle->pos.x = systemRandom.rand(static_cast<int>(virtual_width));
+      particle->pos.x = graphicsRandom.rand(static_cast<int>(virtual_width));
     }
   }
 }
 
     Particle* particle = new Particle;
     particle->pos = epicenter;
 
-    float angle = systemRandom.rand(min_angle, max_angle)
+    float angle = graphicsRandom.rand(min_angle, max_angle)
       * (M_PI / 180);  // convert to radius (radians?)
     particle->vel.x = /*fabs*/(sin(angle)) * initial_velocity.x;
     //    if(angle >= M_PI && angle < M_PI*2)
 
   // when invincible, spawn particles
   if (invincible_timer.started())
   {
-    if (systemRandom.rand(0, 2) == 0) {
-      float px = systemRandom.randf(bbox.p1.x+0, bbox.p2.x-0);
-      float py = systemRandom.randf(bbox.p1.y+0, bbox.p2.y-0);
+    if (graphicsRandom.rand(0, 2) == 0) {
+      float px = graphicsRandom.randf(bbox.p1.x+0, bbox.p2.x-0);
+      float py = graphicsRandom.randf(bbox.p1.y+0, bbox.p2.y-0);
       Vector ppos = Vector(px, py);
       Vector pspeed = Vector(0, 0);
       Vector paccel = Vector(0, 0);
       {
         // the numbers: starting x, starting y, velocity y
         Sector::current()->add_object(new FallingCoin(get_pos() +
-                                                      Vector(systemRandom.rand(5), systemRandom.rand(-32,18)),
-                                                      systemRandom.rand(-100,100)));
+                                                      Vector(graphicsRandom.rand(5), graphicsRandom.rand(-32,18)),
+                                                      graphicsRandom.rand(-100,100)));
       }
       player_status->coins -= std::max(player_status->coins/10, 25);
     }
 }
 
 void
-Player::check_bounds(Camera* camera)
+Player::check_bounds()
 {
   /* Keep tux in sector bounds: */
   if (get_pos().x < 0) {
     kill(true);
     return;
   }
-
-  // can happen if back scrolling is disabled
-  if(get_pos().x < camera->get_translation().x) {
-    set_pos(Vector(camera->get_translation().x, get_pos().y));
-  }
-  if(get_pos().x >= camera->get_translation().x + SCREEN_WIDTH - bbox.get_width())
-  {
-    set_pos(Vector(
-              camera->get_translation().x + SCREEN_WIDTH - bbox.get_width(),
-              get_pos().y));
-  }
 }
 
 void
 
   }
 
   void kill(bool completely);
-  void check_bounds(Camera* camera);
+  void check_bounds();
   void move(const Vector& vector);
 
   virtual bool add_bonus(const std::string& bonus);
 
   assert(cycle_len > 0);
 
   // start with random phase offset
-  t = systemRandom.randf(0.0, cycle_len);
+  t = gameRandom.randf(0.0, cycle_len);
 }
 
 PulsingLight::~PulsingLight()
 
   size_t raindropcount = size_t(virtual_width/6.0);
   for(size_t i=0; i<raindropcount; ++i) {
     RainParticle* particle = new RainParticle;
-    particle->pos.x = systemRandom.rand(int(virtual_width));
-    particle->pos.y = systemRandom.rand(int(virtual_height));
-    int rainsize = systemRandom.rand(2);
+    particle->pos.x = graphicsRandom.rand(int(virtual_width));
+    particle->pos.y = graphicsRandom.rand(int(virtual_height));
+    int rainsize = graphicsRandom.rand(2);
     particle->texture = rainimages[rainsize];
     do {
-      particle->speed = (rainsize+1)*45 + systemRandom.randf(3.6);
+      particle->speed = (rainsize+1)*45 + graphicsRandom.randf(3.6);
     } while(particle->speed < 1);
     particle->speed *= 10; // gravity
 
            Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
            } */
       }
-      int new_x = systemRandom.rand(int(virtual_width)) + int(abs_x);
+      int new_x = graphicsRandom.rand(int(virtual_width)) + int(abs_x);
       int new_y = 0;
       //FIXME: Don't move particles over solid tiles
       particle->pos.x = new_x;
 
   Vector pos = get_pos();
   // shaking
   if(timer.get_timegone() > CRACKTIME) {
-    pos.x += systemRandom.rand(-3, 3);
+    pos.x += graphicsRandom.rand(-3, 3);
   }
 
   sprite->draw(context, pos, layer);
 
   size_t snowflakecount = size_t(virtual_width/10.0);
   for(size_t i=0; i<snowflakecount; ++i) {
     SnowParticle* particle = new SnowParticle;
-    int snowsize = systemRandom.rand(3);
+    int snowsize = graphicsRandom.rand(3);
 
-    particle->pos.x = systemRandom.randf(virtual_width);
-    particle->pos.y = systemRandom.randf(SCREEN_HEIGHT);
-    particle->anchorx = particle->pos.x + (systemRandom.randf(-0.5, 0.5) * 16);
+    particle->pos.x = graphicsRandom.randf(virtual_width);
+    particle->pos.y = graphicsRandom.randf(SCREEN_HEIGHT);
+    particle->anchorx = particle->pos.x + (graphicsRandom.randf(-0.5, 0.5) * 16);
     // drift will change with wind gusts
-    particle->drift_speed = systemRandom.randf(-0.5, 0.5) * 0.3;
+    particle->drift_speed = graphicsRandom.randf(-0.5, 0.5) * 0.3;
     particle->wobble = 0.0;
 
     particle->texture = snowimages[snowsize];
     particle->flake_size = powf(snowsize+3,4); // since it ranges from 0 to 2
 
-    particle->speed = 2 * (1 + (2 - snowsize)/2 + systemRandom.randf(1.8)) * 10; // gravity
+    particle->speed = 2 * (1 + (2 - snowsize)/2 + graphicsRandom.randf(1.8)) * 10; // gravity
 
     // Spinning
-    particle->angle = systemRandom.randf(360.0);
-    particle->spin_speed = systemRandom.randf(-SNOW::SPIN_SPEED,SNOW::SPIN_SPEED);
+    particle->angle = graphicsRandom.randf(360.0);
+    particle->spin_speed = graphicsRandom.randf(-SNOW::SPIN_SPEED,SNOW::SPIN_SPEED);
 
     particles.push_back(particle);
   }
       // stop wind
       gust_current_velocity = 0;
       // new wind strength
-      gust_onset   = systemRandom.randf(-SNOW::WIND_SPEED, SNOW::WIND_SPEED);
+      gust_onset   = graphicsRandom.randf(-SNOW::WIND_SPEED, SNOW::WIND_SPEED);
     }
-    timer.start(systemRandom.randf(SNOW::STATE_LENGTH));
+    timer.start(graphicsRandom.randf(SNOW::STATE_LENGTH));
   }
 
   // Update velocities
     // Falling
     particle->pos.y += particle->speed * elapsed_time;
     // Drifting (speed approaches wind at a rate dependent on flake size)
-    particle->drift_speed += (gust_current_velocity - particle->drift_speed) / particle->flake_size + systemRandom.randf(-SNOW::EPSILON,SNOW::EPSILON);
+    particle->drift_speed += (gust_current_velocity - particle->drift_speed) / particle->flake_size + graphicsRandom.randf(-SNOW::EPSILON,SNOW::EPSILON);
     particle->anchorx += particle->drift_speed * elapsed_time;
     // Wobbling (particle approaches anchorx)
     particle->pos.x += particle->wobble * elapsed_time;
     anchor_delta = (particle->anchorx - particle->pos.x);
-    particle->wobble += (SNOW::WOBBLE_FACTOR * anchor_delta) + systemRandom.randf(-SNOW::EPSILON, SNOW::EPSILON);
+    particle->wobble += (SNOW::WOBBLE_FACTOR * anchor_delta) + graphicsRandom.randf(-SNOW::EPSILON, SNOW::EPSILON);
     particle->wobble *= SNOW::WOBBLE_DECAY;
     // Spinning
     particle->angle += particle->spin_speed * elapsed_time;
 
   // if we have a path to follow, follow it
   if (walker.get()) {
     Vector v = walker->advance(elapsed_time);
-    movement = Vector(v.x-get_offset().x, std::max(0.0f,v.y-get_offset().y));
+    movement = v - get_offset();
     set_offset(v);
   }
 }
 
   Vector get_offset() const
   { return offset; }
 
-  const Vector& get_movement() const
+  Vector get_movement(bool actual = false) const
   {
-    return movement;
+    if(actual) {
+      return movement;
+    } else {
+      return Vector(movement.x, std::max(0.0f,movement.y));
+    }
   }
 
   Path *get_path()
 
   if (!blowing) return;
 
   // TODO: nicer, configurable particles for wind?
-  if (systemRandom.rand(0, 100) < 20) {
+  if (graphicsRandom.rand(0, 100) < 20) {
     // emit a particle
-    Vector ppos = Vector(systemRandom.randf(bbox.p1.x+8, bbox.p2.x-8), systemRandom.randf(bbox.p1.y+8, bbox.p2.y-8));
+    Vector ppos = Vector(graphicsRandom.randf(bbox.p1.x+8, bbox.p2.x-8), graphicsRandom.randf(bbox.p1.y+8, bbox.p2.y-8));
     Vector pspeed = Vector(speed.x, speed.y);
     Sector::current()->add_object(new Particles(ppos, 44, 46, pspeed, Vector(0,0), 1, Color(.4f, .4f, .4f), 3, .1f,
                                                 LAYER_BACKGROUNDTILES+1));
 
 
 int rand()
 {
-  return systemRandom.rand();
+  return gameRandom.rand();
 }
 
 void set_game_speed(float speed)
   }
   // Reset random seed
   g_config->random_seed = GameSession::current()->get_demo_random_seed(filename);
-  g_config->random_seed = systemRandom.srand(g_config->random_seed);
+  g_config->random_seed = gameRandom.srand(g_config->random_seed);
   GameSession::current()->restart_level();
   GameSession::current()->play_demo(filename);
 }
 
   if(capture_file != "") {
     int newSeed=0;               // next run uses a new seed
     while (newSeed == 0)            // which is the next non-zero random num.
-      newSeed = systemRandom.rand();
-    g_config->random_seed = systemRandom.srand(newSeed);
+      newSeed = gameRandom.rand();
+    g_config->random_seed = gameRandom.srand(newSeed);
     log_info << "Next run uses random seed " << g_config->random_seed <<std::endl;
     record_demo(capture_file);
   }
 
 {
   player_sprite = sprite_manager->create("images/creatures/tux/tux.sprite");
   player_sprite->set_action("small-walk-right");
-  player_sprite_jump_timer.start(systemRandom.randf(5,10));
+  player_sprite_jump_timer.start(graphicsRandom.randf(5,10));
 }
 
 LevelIntro::~LevelIntro()
   }
   if (player_sprite_jump_timer.check()) {
     player_sprite_vy = -300;
-    player_sprite_jump_timer.start(systemRandom.randf(2,3));
+    player_sprite_jump_timer.start(graphicsRandom.randf(2,3));
   }
   
 }
 
 void
 Main::init_rand()
 {
-  g_config->random_seed = systemRandom.srand(g_config->random_seed);
+  g_config->random_seed = gameRandom.srand(g_config->random_seed);
+
+  graphicsRandom.srand(0);
 
   //const char *how = config->random_seed? ", user fixed.": ", from time().";
   //log_info << "Using random seed " << config->random_seed << how << std::endl;
 
 #ifndef NDEBUG
   for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end();
       ++i) {
-    if(*i == object) {
-      assert("object already added to sector" == 0);
-    }
+    assert(*i != object);
   }
   for(GameObjects::iterator i = gameobjects_new.begin();
       i != gameobjects_new.end(); ++i) {
-    if(*i == object) {
-      assert("object already added to sector" == 0);
-    }
+    assert(*i != object);
   }
 #endif
 
 void
 Sector::update(float elapsed_time)
 {
-  player->check_bounds(camera);
+  player->check_bounds();
 
   /* update objects */
   for(GameObjects::iterator i = gameobjects.begin();
 
     default:
       assert (23 == 42);
+      return POS_NON_SOLID;
   }
 
   /* delta_x, delta_y: Gradient aware version of SHIFT_DELTA. Here, we set the
            * in quotation marks because because the slope's gradient is taken
            * Also, this uses the movement relative to the tilemaps own movement
            * (if any).  --octo */
-          status = check_movement_unisolid (movement - solids->get_movement(), tile);
+          status = check_movement_unisolid (movement - solids->get_movement(true), tile);
           /* If zero is returned, the unisolid tile is non-solid. */
           if (status == 0)
             continue;
 
     blue(blue_), 
     alpha(alpha_)
   {
-#ifndef NDEBUG
-    check_color_ranges();
-#endif
+    assert(0 <= red   && red <= 1.0);
+    assert(0 <= green && green <= 1.0);
+    assert(0 <= blue  && blue <= 1.0);
   }
 
   Color(const std::vector<float>& vals) :
       alpha = vals[3];
     else
       alpha = 1.0;
-#ifndef NDEBUG
-    check_color_ranges();
-#endif
+    assert(0 <= red   && red <= 1.0);
+    assert(0 <= green && green <= 1.0);
+    assert(0 <= blue  && blue <= 1.0);
   }
 
   bool operator==(const Color& other) const
       && alpha == other.alpha;
   }
 
-  void check_color_ranges()
-  {
-    if(red < 0 || red > 1.0 || green < 0 || green > 1.0
-       || blue < 0 || blue > 1.0
-       || alpha < 0 || alpha > 1.0)
-      log_warning << "color value out of range: " << red << ", " << green << ", " << blue << ", " << alpha << std::endl;
-  }
-
   float greyscale() const
   {
     return red * 0.30 + green * 0.59 + blue * 0.11;