docs: def process_replay(self, controller, replay_data, map_data, player_id):
      """Process a single replay, updating the stats."""
      self._update_stage("start_replay")
      controller.start_replay(sc_pb.RequestStartReplay(
          replay_data=replay_data,
          map_data=map_data,
          options=interface,
          observed_player_id=player_id))
  
      feat = features.features_from_game_info(controller.game_info())
  
      self.stats.replay_stats.replays += 1
      self._update_stage("step")
      controller.step()
      while True:
        self.stats.replay_stats.steps += 1
        self._update_stage("observe")
        obs = controller.observe()
  
        for action in obs.actions:
          act_fl = action.action_feature_layer
          if act_fl.HasField("unit_command"):
            self.stats.replay_stats.made_abilities[
                act_fl.unit_command.ability_id] += 1
          if act_fl.HasField("camera_move"):
            self.stats.replay_stats.camera_move += 1
          if act_fl.HasField("unit_selection_point"):
            self.stats.replay_stats.select_pt += 1
          if act_fl.HasField("unit_selection_rect"):
            self.stats.replay_stats.select_rect += 1
          if action.action_ui.HasField("control_group"):
            self.stats.replay_stats.control_group += 1
  
          try:
            func = feat.reverse_action(action).function
          except ValueError:
            func = -1
          self.stats.replay_stats.made_actions[func] += 1
  
        for valid in obs.observation.abilities:
          self.stats.replay_stats.valid_abilities[valid.ability_id] += 1
  
        for u in obs.observation.raw_data.units:
          self.stats.replay_stats.unit_ids[u.unit_type] += 1
  
        for ability_id in feat.available_actions(obs.observation):
          self.stats.replay_stats.valid_actions[ability_id] += 1
  
        if obs.player_result:
          break
  
        self._update_stage("step")
        controller.step(FLAGS.step_mul)