anchor.diff:  //For caching unit/house/group IDs. Shared between States and Actions.
   //Because scripts runs the same on every computer (i.e. no access to gMySpectator)
   //we can safely use pointers within the cache
  +
  +// We cache nil objects too, cos our goal is to resolve UID asap, no matter its state.
  +// Hence UID can be valid and pointer = nil when the object is dying
   const
     CACHE_SIZE = 16; //Too big means caching becomes slow
   
  
positive.code: 
  
  function TKMScriptingIdCache.GetHouse(aUID:Integer): TKMHouse;
  var I: ShortInt;
  begin
    for I := Low(fHouseCache) to High(fHouseCache) do
      if fHouseCache[I].UID = aUID then
  
negative.code:   SaveStream.PlaceMarker('ScriptingIdCache_Units');
    SaveStream.Write(fUnitLastAdded);
    for I := Low(fUnitCache) to High(fUnitCache) do
    begin
      SaveStream.Write(fUnitCache[I].UID);
      if fUnitCache[I].U <> nil then
        SaveStream.Write(fUnitCache[I].U.UID) //Store ID, then substitute it with reference on SyncLoad
      else
        SaveStream.Write(Integer(0));
    end;
  
    SaveStream.PlaceMarker('ScriptingIdCache_Houses');
    SaveStream.Write(fHouseLastAdded);
    for I := Low(fHouseCache) to High(fHouseCache) do
    begin
      SaveStream.Write(fHouseCache[I].UID);
      if fHouseCache[I].H <> nil then
        SaveStream.Write(fHouseCache[I].H.UID) //Store ID, then substitute it with reference on SyncLoad
      else
        SaveStream.Write(Integer(0));
    end;
  
    SaveStream.PlaceMarker('ScriptingIdCache_Groups');
    SaveStream.Write(fGroupLastAdded);
    for I := Low(fGroupCache) to High(fGroupCache) do
    begin
      SaveStream.Write(fGroupCache[I].UID);
      if fGroupCache[I].G <> nil then
        SaveStream.Write(fGroupCache[I].G.UID) //Store ID, then substitute it with reference on SyncLoad
      else
        SaveStream.Write(Integer(0));
    end;
  end;
  
  
  