class_docstr: A Starcraft II environment.
  
  The implementation details of the action and observation specs are in
  lib/features.py
code: def _observe(self, target_game_loop):
      self._get_observations(target_game_loop)
  
      # TODO(tewalds): How should we handle more than 2 agents and the case where
      # the episode can end early for some agents?
      outcome = [0] * self._num_agents
      discount = self._discount
      episode_complete = any(o.player_result for o in self._obs)
  
      if episode_complete:
          self._state = environment.StepType.LAST
          discount = 0
          for i, o in enumerate(self._obs):
              player_id = o.observation.player_common.player_id
              for result in o.player_result:
                  if result.player_id == player_id:
                      outcome[i] = possible_results.get(
                          result.result, 0
                      )
  
      if self._score_index >= 0:  # Game score, not win/loss reward.
          cur_score = [
              _get_score(o, self._score_index) for o in self._agent_obs
          ]
          if self._episode_steps == 0:  # First reward is always 0.
              reward = [0] * self._num_agents
          else:
              reward = [
                  cur - last
                  for cur, last in zip(cur_score, self._last_score)
              ]
          self._last_score = cur_score
      else:
          reward = outcome
  
      if self._renderer_human:
          self._renderer_human.render(self._obs[0])
          cmd = self._renderer_human.get_actions(
              self._run_config, self._controllers[0]
          )
          if cmd == renderer_human.ActionCmd.STEP:
              pass
          elif cmd == renderer_human.ActionCmd.RESTART:
              self._state = environment.StepType.LAST
          elif cmd == renderer_human.ActionCmd.QUIT:
              raise KeyboardInterrupt("Quit?")
  
      game_loop = _get_game_loop(self._agent_obs[0])
      self._total_steps += game_loop - self._episode_steps
      self._episode_steps = game_loop
      if self._episode_steps >= self._episode_length:
          self._state = environment.StepType.LAST
          if self._discount_zero_after_timeout:
              discount = 0.0
          if self._episode_steps >= MAX_STEP_COUNT:
              logging.info(
                  "Cut short to avoid SC2's max step count of 2^19=524288."
              )
  
      if self._state == environment.StepType.LAST:
          if (
              self._save_replay_episodes > 0
              and self._episode_count % self._save_replay_episodes == 0
          ):
              self.save_replay(self._replay_dir, self._replay_prefix)
          logging.info(
              (
                  "Episode %s finished after %s game steps. "
                  "Outcome: %s, reward: %s, score: %s"
              ),
              self._episode_count,
              self._episode_steps,
              outcome,
              reward,
              [_get_score(o) for o in self._agent_obs],
          )
  
      def zero_on_first_step(value):
          return (
              0.0
              if self._state == environment.StepType.FIRST
              else value
          )
  
      return tuple(
          environment.TimeStep(
              step_type=self._state,
              reward=zero_on_first_step(r * self._score_multiplier),
              discount=zero_on_first_step(discount),
              observation=o,
          )
          for r, o in zip(reward, self._agent_obs)
      )
  
imports: import collections
  import copy
  import random
  import time
  from absl import logging
  from pysc2 import maps
  from pysc2 import run_configs
  from pysc2.env import enums
  from pysc2.env import environment
  from pysc2.lib import actions
  from pysc2.lib import features
  from pysc2.lib import metrics
  from pysc2.lib import portspicker
  from pysc2.lib import renderer_human
  from pysc2.lib import run_parallel
  from pysc2.lib import stopwatch
  from s2clientprotocol import sc2api_pb2
label_desc: Use image node_id 20 for calling the SC2Env obj's underlying member method code with example usage: obj._observe(target_game_loop) and returns: tuple, unknown