code: def property_cache_once_per_frame(f):
      
      f.frame = -1
      f.cache = None
  
      @wraps(f)
      def inner(self):
          if f.frame != self.state.game_loop:
              f.frame = self.state.game_loop
              f.cache = None
          if f.cache is None:
              f.cache = f(self)
          return f.cache
  
      return property(inner)
docs: This decorator caches the return value for one game loop, then clears it if it is accessed in a different game loop
      Only works on properties of the bot object because it requires access to self.state.game_loop