docs: def handle(self, cmd=None, **kwargs):
          """Send a command to the LiSE core.
  
          The only positional argument should be the name of a
          method in :class:``EngineHandle``. All keyword arguments
          will be passed to it, with the exceptions of
          ``cb``, ``branching``, and ``silent``.
  
          With ``block=False``, don't wait for a result.
          This is best for when you want to make some change to the game
          state and already know what effect it will have.
  
          With ``branching=True``, handle paradoxes by creating new
          branches of history. I will switch to the new branch if needed.
          If I have an attribute ``branching_cb``, I'll call it if and
          only if the branch changes upon completing a command with
          ``branching=True``.
  
          With a function ``cb``, I will call ``cb`` when I get
          a result. If ``block=False`` this will happen in a thread.
          ``cb`` will be called with keyword arguments ``command``,
          the same command you asked for; ``result``, the value returned
          by it, possibly ``None``; and the present ``branch``,
          ``turn``, and ``tick``, possibly different than when you called
          ``handle``.
  
          If any of ``branching``, ``cb``, or ``future`` are ``True``,
          I will return a ``Future``. The ``Future``'s return value
          is a tuple of ``(command, branch, turn, tick, result)``.
  
          """
          if 'command' in kwargs:
              cmd = kwargs['command']
          elif cmd:
              kwargs['command'] = cmd
          else:
              raise TypeError("No command")
          branching = kwargs.get('branching', False)
          cb = kwargs.pop('cb', None)
          future = kwargs.pop('future', False)
          self._handle_lock.acquire()
          if kwargs.pop('block', True):
              assert not kwargs.get('silent')
              self.debug('EngineProxy: sending {}'.format(kwargs))
              self.send(self.pack(kwargs))
              command, branch, turn, tick, result = self.recv()
              assert cmd == command, \
                  "Sent command {} but received results for {}".format(
                      cmd, command
                  )
              r = self.unpack(result)
              self.debug('EngineProxy: received {}'.format((command, branch, turn, tick, r)))
              if (branch, turn, tick) != self._btt():
                  self._branch = branch
                  self._turn = turn
                  self._tick = tick
                  self.time.send(self, branch=branch, turn=turn, tick=tick)
              if isinstance(r, Exception):
                  self._handle_lock.release()
                  raise r
              if cb:
                  cb(command=command, branch=branch, turn=turn, tick=tick, result=r)
              self._handle_lock.release()
              return r
          else:
              kwargs['silent'] = not (branching or cb or future)
              self.debug('EngineProxy: asynchronously sending {}'.format(kwargs))
              self.send(self.pack(kwargs))
              if branching:
                  # what happens if more than one branching call is happening at once?
                  return self._submit(self._branching, cb)
              elif cb:
                  return self._submit(self._callback, cb)
              if future:
                  return self._submit(self._unpack_recv)
          self._handle_lock.release()