diff --git a/example/high_level_random_agent.cpp b/example/high_level_random_agent.cpp
index 3af6bb10b289595f209cb5688dcfd1781fdd2f3f..346afa97cb65284492c03c0a815ab747c71e68d4 100644
--- a/example/high_level_random_agent.cpp
+++ b/example/high_level_random_agent.cpp
@@ -17,8 +17,8 @@ string server_addr = "localhost";
 string team_name = "base_left";
 bool goalie = false;
 
-// We omit PASS & CATCH actions here
-action_t HIGH_LEVEL_ACTIONS[3] = { MOVE, SHOOT, DRIBBLE };
+// We omit PASS & CATCH & MOVE actions here
+action_t HIGH_LEVEL_ACTIONS[2] = { SHOOT, DRIBBLE };
 
 int main(int argc, char** argv) {
   // Create the HFO environment
@@ -34,7 +34,11 @@ int main(int argc, char** argv) {
       // Get the vector of state features for the current state
       const vector<float>& feature_vec = hfo.getState();
       // Perform the action
-      hfo.act(HIGH_LEVEL_ACTIONS[rand() % 3]);
+      if (feature_vec[5] == 1) { // Feature 5 is 1 when the player can kick the ball
+        hfo.act(HIGH_LEVEL_ACTIONS[rand() % 2]);
+      } else {
+        hfo.act(MOVE);
+      }
       // Advance the environment and get the game status
       status = hfo.step();
     }
diff --git a/example/random_2v1.sh b/example/random_2v1.sh
index f1cea3a116a2a46a53d03a27a2fa21aecb71cada..9457c06f0a0554d7d2ec710971134e1088a9f311 100755
--- a/example/random_2v1.sh
+++ b/example/random_2v1.sh
@@ -1,10 +1,10 @@
 #!/bin/bash
 
-./bin/HFO --offense-agents=2 --defense-npcs=1 --trials 100 --headless &
+./bin/HFO --offense-agents=2 --defense-npcs=1 --trials 20 --headless &
 sleep 5
-./example/high_level_random_agent 6000 &
+./example/high_level_random_agent 6000 &> agent1.txt &
 sleep 5
-./example/high_level_random_agent 6000 &
+./example/high_level_random_agent 6000 &> agent2.txt &
 
 # The magic line
 #   $$ holds the PID for this script
diff --git a/src/HFO.cpp b/src/HFO.cpp
index 66a9a2d275198e15f62a964ef277154f349ce191..326bf7329bf2717adf33d998e9baf587f28bc042 100644
--- a/src/HFO.cpp
+++ b/src/HFO.cpp
@@ -60,11 +60,21 @@ void HFOEnvironment::connectToServer(feature_set_t feature_set,
   act(NOOP);
   while (agent->getState().empty()) {
     if (!client->isServerAlive()) {
-      std::cerr << "Server Down!" << std::endl;
+      std::cerr << "[ConnectToServer] Server Down!" << std::endl;
       exit(1);
     }
-    client->runStep(agent);
+    ready_for_action = client->runStep(agent);
+    if (ready_for_action) {
+      agent->action();
+    }
   }
+  // Step until it is time to act
+  do {
+    ready_for_action = client->runStep(agent);
+  } while (!ready_for_action);
+  agent->ProcessTrainerMessages();
+  agent->ProcessTeammateMessages();
+  agent->UpdateFeatures();
   current_cycle = agent->currentTime().cycle();
 }
 
@@ -111,12 +121,24 @@ Player HFOEnvironment::playerOnBall() {
 
 status_t HFOEnvironment::step() {
   assert(agent->currentTime().cycle() == current_cycle);
-  while (agent->statusUpdateTime() <= current_cycle) {
-    if (!client->isServerAlive()) {
+  assert(ready_for_action);
+
+  // Execute the action
+  agent->action();
+
+  // Advance the environment by one step
+  do {
+    ready_for_action = client->runStep(agent);
+    if (!client->isServerAlive() || agent->getGameStatus() == SERVER_DOWN) {
       return SERVER_DOWN;
     }
-    client->runStep(agent);
-  }
+    agent->ProcessTrainerMessages();
+  } while (agent->statusUpdateTime() <= current_cycle || !ready_for_action);
+
+  // Update the state features
+  agent->ProcessTeammateMessages();
+  agent->UpdateFeatures();
+
   assert(agent->currentTime().cycle() == (current_cycle + 1));
   current_cycle = agent->currentTime().cycle();
   return agent->getGameStatus();
diff --git a/src/HFO.hpp b/src/HFO.hpp
index 41acfdeae0f474e1a76908894ffd4cda8006e6c3..e5b536b35a7c5ce31aacdbe5248318e2f1f486d9 100644
--- a/src/HFO.hpp
+++ b/src/HFO.hpp
@@ -60,6 +60,7 @@ class HFOEnvironment {
   rcsc::BasicClient* client;
   Agent* agent;
   long current_cycle;
+  bool ready_for_action;
 };
 
 } // namespace hfo
diff --git a/src/agent.cpp b/src/agent.cpp
index 7e09650752941d31cc08c5ad02471d9f23e3c9a6..ccc94bcf5e90ac33b5fbed380c10f4206b1dbcdf 100644
--- a/src/agent.cpp
+++ b/src/agent.cpp
@@ -311,14 +311,9 @@ void Agent::actionImpl() {
   this->setNeckAction(new Neck_TurnToBallOrScan());
 }
 
-/*-------------------------------------------------------------------*/
-/*!
-
- */
 void
-Agent::handleActionStart()
+Agent::ProcessTrainerMessages()
 {
-  // Process new trainer messages
   if (audioSensor().trainerMessageTime().cycle() > lastTrainerMessageTime) {
     const std::string& message = audioSensor().trainerMessage();
     if (feature_extractor == NULL) {
@@ -339,8 +334,11 @@ Agent::handleActionStart()
     hfo::ParsePlayerOnBall(message, player_on_ball);
     lastTrainerMessageTime = audioSensor().trainerMessageTime().cycle();
   }
+}
 
-  // Process new teammate message
+void
+Agent::ProcessTeammateMessages()
+{
   hear_msg.clear();
   if (audioSensor().teammateMessageTime().cycle() > lastTeammateMessageTime) {
     const std::list<HearMessage> teammateMessages = audioSensor().teammateMessages();
@@ -353,11 +351,22 @@ Agent::handleActionStart()
     }
     lastTeammateMessageTime = audioSensor().teammateMessageTime().cycle();
   }
+}
 
-  // Update state features
+void
+Agent::UpdateFeatures()
+{
   if (feature_extractor != NULL) {
     state = feature_extractor->ExtractFeatures(this->world());
   }
+}
+
+void
+Agent::handleActionStart()
+{
+  ProcessTrainerMessages();
+  ProcessTeammateMessages();
+  UpdateFeatures();
 
   // Optionally write to logfile
 #ifdef ELOG
diff --git a/src/agent.h b/src/agent.h
index a7f7c0a291ba01a49ef2a4500274c79ead97cbbe..49e31f95f7ae386dd034eee6378e243f20028454 100644
--- a/src/agent.h
+++ b/src/agent.h
@@ -24,6 +24,13 @@ public:
 
   inline long statusUpdateTime() { return lastStatusUpdateTime; }
 
+  // Process incoming trainer messages. Used to update the game status.
+  void ProcessTrainerMessages();
+  // Process incoming teammate messages.
+  void ProcessTeammateMessages();
+  // Update the state features from the world model.
+  void UpdateFeatures();
+
 protected:
   // You can override this method. But you must call
   // PlayerAgent::initImpl() in this method.
diff --git a/src/common.hpp b/src/common.hpp
index 7df2cca049921330510438a6430b7ff80d3286bd..2f5dc6389794a31ea31586cc45dc7eaf958a3947 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -263,6 +263,8 @@ inline bool ParseGameStatus(const std::string& message, status_t& status) {
     status = OUT_OF_TIME;
   } else if (message.find("IN_GAME") != std::string::npos){
     status = IN_GAME;
+  } else if (message.find("HFO_FINISHED") != std::string::npos){
+    status = SERVER_DOWN;
   } else {
     return false;
   }
diff --git a/src/feature_extractor.cpp b/src/feature_extractor.cpp
index c3040f5c53c2d0ea95c1cc16190bfd5b0f009b38..237750684c770c95ee45a5913d9195a32eb6fbdb 100644
--- a/src/feature_extractor.cpp
+++ b/src/feature_extractor.cpp
@@ -146,7 +146,7 @@ bool FeatureExtractor::valid(const rcsc::PlayerObject& player) {
       pos.x < -ALLOWED_PITCH_FRAC * rcsc::ServerParam::i().pitchHalfLength()) {
     return false;
   }
-  return player.unum() > 0 && pos.isValid();
+  return pos.isValid();
 }
 
 float FeatureExtractor::angleToPoint(const rcsc::Vector2D &self,