anchor.diff:  
   { TKMScriptingIdCache }
   procedure TKMScriptingIdCache.CacheUnit(aUnit: TKMUnit; aID: Integer);
  -var I, NewItem: Shortint;
  +var I: ShortInt;
   begin
  -  for I := 0 to fUnitCount - 1 do
  -    if fUnitCache[i].ID = aID then
  -      Exit; //Already in cache
  +  for I := Low(fUnitCache) to High(fUnitCache) do
  +  if fUnitCache[I].ID = aID then
  +    Exit; //Already in cache
   
  -  if fUnitCount < CACHE_SIZE then
  -  begin
  -    NewItem := fUnitCount;
  -    Inc(fUnitCount);
  -  end
  +  //We need to release pointer if we remove unit from cache
  +  if fUnitCache[fUnitLastAdded].U <> nil then
  +    fPlayers.CleanUpUnitPointer(fUnitCache[fUnitLastAdded].U);
  +
  +  fUnitCache[fUnitLastAdded].ID := aID;
  +  //We could be asked to cache that certain ID is nil (saves us time scanning Units to find out that this Id is removed)
  +  if aUnit <> nil then
  +    fUnitCache[fUnitLastAdded].U := aUnit.GetUnitPointer
     else
  -  begin
  -    //Cache full, overwrite the oldest item
  -    NewItem := fUnitLastAdded;
  -    Inc(fUnitLastAdded);
  -    if fUnitLastAdded = CACHE_SIZE then fUnitLastAdded := 0;
  -  end;
  +    fUnitCache[fUnitLastAdded].U := nil;
   
  -  fUnitCache[NewItem].ID := aID;
  -  if aUnit <> nil then
  -    fUnitCache[NewItem].U := aUnit.GetUnitPointer
  -  else
  -    fUnitCache[NewItem].U := nil;
  +  fUnitLastAdded := (fUnitLastAdded + 1) mod CACHE_SIZE;
   end;
   
   
   procedure TKMScriptingIdCache.CacheHouse(aHouse: TKMHouse; aID: Integer);
  -var I, NewItem: Shortint;
  +var I: ShortInt;
   begin
  -  for I := 0 to fHouseCount - 1 do
  -    if fHouseCache[i].ID = aID then
  -      Exit; //Already in cache
  +  for I := Low(fHouseCache) to High(fHouseCache) do
  +  if fHouseCache[i].ID = aID then
  +    Exit; //Already in cache
   
  -  if fHouseCount < CACHE_SIZE then
  -  begin
  -    NewItem := fHouseCount;
  -    Inc(fHouseCount);
  -  end
  +  //We need to release pointer if we remove house from cache
  +  if fHouseCache[fHouseLastAdded].H <> nil then
  +    fPlayers.CleanUpHousePointer(fHouseCache[fHouseLastAdded].H);
  +
  +  fHouseCache[fHouseLastAdded].ID := aID;
  +  //We could be asked to cache that certain ID is nil (saves us time scanning Houses to find out that this Id is removed)
  +  if aHouse <> nil then
  +    fHouseCache[fHouseLastAdded].H := aHouse.GetHousePointer
     else
  -  begin
  -    //Cache full, overwrite the oldest item
  -    NewItem := fHouseLastAdded;
  -    Inc(fHouseLastAdded);
  -    if fHouseLastAdded = CACHE_SIZE then fHouseLastAdded := 0;
  -  end;
  +    fHouseCache[fHouseLastAdded].H := nil;
   
  -  fHouseCache[NewItem].ID := aID;
  -  if aHouse <> nil then
  -    fHouseCache[NewItem].H := aHouse.GetHousePointer
  -  else
  -    fHouseCache[NewItem].H := nil;
  +  fHouseLastAdded := (fHouseLastAdded + 1) mod CACHE_SIZE;
   end;
   
   
   procedure TKMScriptingIdCache.CacheGroup(aGroup: TKMUnitGroup; aID: Integer);
  -var I, NewItem: Shortint;
  +var I: ShortInt;
   begin
  -  for I := 0 to fGroupCount - 1 do
  -    if fGroupCache[i].ID = aID then
  -      Exit; //Already in cache
  +  for I := Low(fGroupCache) to High(fGroupCache) do
  +  if fGroupCache[I].ID = aID then
  +    Exit; //Already in cache
   
  -  if fGroupCount < CACHE_SIZE then
  -  begin
  -    NewItem := fGroupCount;
  -    Inc(fGroupCount);
  -  end
  +  //We need to release pointer if we remove group from cache
  +  if fGroupCache[fGroupLastAdded].G <> nil then
  +    fPlayers.CleanUpGroupPointer(fGroupCache[fGroupLastAdded].G);
  +
  +  fGroupCache[fGroupLastAdded].ID := aID;
  +  //We could be asked to cache that certain ID is nil (saves us time scanning Groups to find out that this Id is removed)
  +  if aGroup <> nil then
  +    fGroupCache[fGroupLastAdded].G := aGroup.GetGroupPointer
     else
  -  begin
  -    //Cache full, overwrite the oldest item
  -    NewItem := fGroupLastAdded;
  -    Inc(fGroupLastAdded);
  -    if fGroupLastAdded = CACHE_SIZE then fGroupLastAdded := 0;
  -  end;
  +    fGroupCache[fGroupLastAdded].G := nil;
   
  -  fGroupCache[NewItem].ID := aID;
  -  if aGroup <> nil then
  -    fGroupCache[NewItem].G := aGroup.GetGroupPointer
  -  else
  -    fGroupCache[NewItem].G := nil;
  +  fGroupLastAdded := (fGroupLastAdded + 1) mod CACHE_SIZE;
   end;
   
   
  -function TKMScriptingIdCache.GetUnit(aID:Integer): TKMUnit;
  -var I: Shortint;
  +function TKMScriptingIdCache.GetUnit(aID: Integer): TKMUnit;
  +var I: ShortInt;
   begin
  -  for I := 0 to fUnitCount - 1 do
  -    if fUnitCache[i].ID = aID then
  -    begin
  -      Result := fUnitCache[i].U;
  -      Exit;
  -    end;
  +  for I := Low(fUnitCache) to High(fUnitCache) do
  +  if fUnitCache[I].ID = aID then
  +  begin
  +    Result := fUnitCache[I].U;
  +    Exit;
  +  end;
   
     //Not found so do lookup and add it to the cache
     Result := fPlayers.GetUnitByID(aID);
  
positive.code: 
  procedure TKMScriptingIdCache.UpdateState;
  var
    I: Integer;
  begin
    //Clear out dead IDs every now and again
    //Leave them in the cache as nils, because we still might need to lookup that ID
    if fGame.GameTickCount mod 11 = 0 then
    begin
      for I := 0 to fUnitCount - 1 do
        if (fUnitCache[I].U <> nil) and fUnitCache[I].U.IsDead then
          fPlayers.CleanUpUnitPointer(fUnitCache[I].U);
  
      for I := 0 to fHouseCount - 1 do
        if (fHouseCache[I].H <> nil) and fHouseCache[I].H.IsDestroyed then
          fPlayers.CleanUpHousePointer(fHouseCache[I].H);
  
      for I := 0 to fGroupCount - 1 do
        if (fGroupCache[I].G <> nil) and fGroupCache[I].G.IsDead then
          fPlayers.CleanUpGroupPointer(fGroupCache[I].G);
    end;
  
negative.code: 
  
  function TKMScriptingIdCache.GetHouse(aID:Integer): TKMHouse;
  var I: ShortInt;
  begin
    for I := Low(fHouseCache) to High(fHouseCache) do
    if fHouseCache[I].ID = aID then
    begin
      Result := fHouseCache[I].H;
      Exit;
    end;
  
    //Not found so do lookup and add it to the cache
    Result := fPlayers.GetHouseByID(aID);
  