code: def step(self, actions):
      
      if self._store_rollouts and \
          self._rollouts_by_epoch_and_split[self.current_epoch]:
        raise ValueError(
            "Data for current epoch has already been loaded from disk."
        )
      (obs, unclipped_rewards, dones) = self._step(actions)
      obs = self._preprocess_observations(obs)
      (min_reward, max_reward) = self.reward_range
      rewards = np.around(np.clip(unclipped_rewards, min_reward, max_reward))
      if self._store_rollouts:
        unclipped_rewards = unclipped_rewards.astype(np.float64)
        encoded_obs = self._encode_observations(obs)
        for (rollout, frame, action) in zip(
            self._current_batch_rollouts, self._current_batch_frames, actions
        ):
          rollout.append(frame._replace(action=action))
  
        # orud = (observation, reward, unclipped_reward, done)
        self._current_batch_frames = [
            Frame(*orud, action=None)
            for orud in zip(encoded_obs, rewards, unclipped_rewards, dones)
        ]
      return (obs, rewards, dones)
docs: Makes a step in all environments.
  
      Does any preprocessing and records frames.
  
      Args:
        actions: Batch of actions.
  
      Returns:
        (obs, rewards, dones) - batches of observations, rewards and done flags
        respectively.
  
      Raises:
        ValueError: when the data for current epoch has already been loaded.