В одном из обновлений бота были добавлены списки доступных для изучения умений: LearnList (если скилы можно учить везде) и LearnList2 (если скилы нужно учить у NPC)
Элементами этих списков являются объекты класса TLearnItem

В связи с этим, все велосипеды и костыли, написанные ранее для изучения умений теперь можно преобразить примерно к такой процедуре:

procedure LearnSkills();
var i: integer;
begin
  for i:= 0 to LearnList.Count-1 do begin                    // пробегаем по списку доступных умений
    if (User.Level >= LearnList(i).NeedLevel)                // если наш уровень подходит
    and (User.SP >= LearnList(i).SpCost) then begin          // и у нас хватает SP (+ можно проверять другие условия)
      if Engine.LearnSkill(LearnList(i).ID) then             // изучаем умение
        Print('Изучил: ' + LearnList(i).Name)
      else 
        Print('Не удалось изучить: ' + LearnList(i).Name);
    end;  
  end;
end;

Если нам не нужно подбегать к NPC, то такую функцию можно запустить например в потоке, добавив в нее бесконечный цикл:

procedure LearnSkillsThread();
var i: integer;
begin
  while delay(999) do begin
    for i:= 0 to LearnList.Count-1 do begin                    // пробегаем по списку доступных умений
      if (User.Level >= LearnList(i).NeedLevel)                // если наш уровень подходит
      and (User.SP >= LearnList(i).SpCost) then begin          // и у нас хватает SP (+ можно проверять другие условия)
        if Engine.LearnSkill(LearnList(i).ID) then             // изучаем умение
          Print('Изучил: ' + LearnList(i).Name)
        else 
          Print('Не удалось изучить: ' + LearnList(i).Name);
      end;
    end;
  end;  
end;

begin
  Script.NewThread(@LearnSkillsThread);
  // code
end.

Если же Вам необходимо подходить к NPC для изучения умений, то добавляем в скрипте подбег к наставнику, открываем с ним диалог и запускаем такую же функцию, заменив везде LearnList на LearnList2