docs: def get_actions(self, run_config, controller):
      """Get actions from the UI, apply to controller, and return an ActionCmd."""
      if not self._initialized:
        return ActionCmd.STEP
  
      for event in pygame.event.get():
        ctrl = pygame.key.get_mods() & pygame.KMOD_CTRL
        shift = pygame.key.get_mods() & pygame.KMOD_SHIFT
        alt = pygame.key.get_mods() & pygame.KMOD_ALT
        if event.type == pygame.QUIT:
          return ActionCmd.QUIT
        elif event.type == pygame.KEYDOWN:
          if self._help:
            self._help = False
          elif event.key in (pygame.K_QUESTION, pygame.K_SLASH):
            self._help = True
          elif event.key == pygame.K_PAUSE:
            pause = True
            while pause:
              time.sleep(0.1)
              for event2 in pygame.event.get():
                if event2.type == pygame.KEYDOWN:
                  if event2.key in (pygame.K_PAUSE, pygame.K_ESCAPE):
                    pause = False
                  elif event2.key == pygame.K_F4:
                    return ActionCmd.QUIT
                  elif event2.key == pygame.K_F5:
                    return ActionCmd.RESTART
          elif event.key == pygame.K_F4:
            return ActionCmd.QUIT
          elif event.key == pygame.K_F5:
            return ActionCmd.RESTART
          elif event.key == pygame.K_F7:  # Toggle rgb rendering.
            if self._rgb_screen_px and self._feature_screen_px:
              self._render_rgb = not self._render_rgb
              print("Rendering", self._render_rgb and "RGB" or "Feature Layers")
              self.init_window()
          elif event.key == pygame.K_F8:  # Toggle synchronous rendering.
            self._render_sync = not self._render_sync
            print("Rendering", self._render_sync and "Sync" or "Async")
          elif event.key == pygame.K_F9:  # Save a replay.
            self.save_replay(run_config, controller)
          elif event.key in (pygame.K_PLUS, pygame.K_EQUALS) and ctrl:
            self.zoom(1.1)  # zoom in
          elif event.key in (pygame.K_MINUS, pygame.K_UNDERSCORE) and ctrl:
            self.zoom(1 / 1.1)  # zoom out
          elif event.key in (pygame.K_PAGEUP, pygame.K_PAGEDOWN):
            if ctrl:
              if event.key == pygame.K_PAGEUP:
                self._step_mul += 1
              elif self._step_mul > 1:
                self._step_mul -= 1
              print("New step mul:", self._step_mul)
            else:
              self._fps *= 1.25 if event.key == pygame.K_PAGEUP else 1 / 1.25
              print("New max game speed: %.1f" % self._fps)
          elif event.key == pygame.K_F1:
            if self._obs.observation.player_common.idle_worker_count > 0:
              controller.act(self.select_idle_worker(ctrl, shift))
          elif event.key == pygame.K_F2:
            if self._obs.observation.player_common.army_count > 0:
              controller.act(self.select_army(shift))
          elif event.key == pygame.K_F3:
            if self._obs.observation.player_common.warp_gate_count > 0:
              controller.act(self.select_warp_gates(shift))
            if self._obs.observation.player_common.larva_count > 0:
              controller.act(self.select_larva())
          elif event.key in self.cmd_group_keys:
            controller.act(self.control_group(self.cmd_group_keys[event.key],
                                              ctrl, shift, alt))
          elif event.key in self.camera_actions:
            if self._obs:
              controller.act(self.camera_action_raw(
                  point.Point.build(
                      self._obs.observation.raw_data.player.camera) +
                  self.camera_actions[event.key]))
          elif event.key == pygame.K_ESCAPE:
            if self._queued_action:
              self.clear_queued_action()
            else:
              cmds = self._abilities(lambda cmd: cmd.hotkey == "escape")  # Cancel
              for cmd in cmds:  # There could be multiple cancels.
                assert not cmd.requires_point
                controller.act(self.unit_action(cmd, None, shift))
          else:
            if not self._queued_action:
              key = pygame.key.name(event.key).lower()
              new_cmd = self._queued_hotkey + key
              cmds = self._abilities(lambda cmd, n=new_cmd: (  # pylint: disable=g-long-lambda
                  cmd.hotkey != "escape" and cmd.hotkey.startswith(n)))
              if cmds:
                self._queued_hotkey = new_cmd
                if len(cmds) == 1:
                  cmd = cmds[0]
                  if cmd.hotkey == self._queued_hotkey:
                    if cmd.requires_point:
                      self.clear_queued_action()
                      self._queued_action = cmd
                    else:
                      controller.act(self.unit_action(cmd, None, shift))
        elif event.type == pygame.MOUSEBUTTONDOWN:
          mouse_pos = self.get_mouse_pos(event.pos)
          if event.button == MouseButtons.LEFT and mouse_pos:
            if self._queued_action:
              controller.act(self.unit_action(
                  self._queued_action, mouse_pos, shift))
            elif mouse_pos.surf.surf_type & SurfType.MINIMAP:
              controller.act(self.camera_action(mouse_pos))
            else:
              self._select_start = mouse_pos
          elif event.button == MouseButtons.RIGHT:
            if self._queued_action:
              self.clear_queued_action()
            cmds = self._abilities(lambda cmd: cmd.name == "Smart")
            if cmds:
              controller.act(self.unit_action(cmds[0], mouse_pos, shift))
        elif event.type == pygame.MOUSEBUTTONUP:
          mouse_pos = self.get_mouse_pos(event.pos)
          if event.button == MouseButtons.LEFT and self._select_start:
            if (mouse_pos and mouse_pos.surf.surf_type & SurfType.SCREEN and
                mouse_pos.surf.surf_type == self._select_start.surf.surf_type):
              controller.act(self.select_action(
                  self._select_start, mouse_pos, ctrl, shift))
            self._select_start = None
      return ActionCmd.STEP