Перейти к контенту

Рефакторинг


Рекомендуемые сообщения

Насколько я понимаю, здесь обсуждается переписывание оригинальных игровых скриптов, которые кочуют из мода в мод либо копипастой, либо с очень мелкими изменениями. На мой взгляд, проблема намного шире, чем просто оптимизация. Во-первых, надо обозначить, с какого набора скриптов (то есть - оригинал или какой-то мод, какая версия и т.д.) начинать, чтобы осилить и не "забуксовать", но в то же время чтобы изменения были заметными. Во-вторых, надо знать, какие вносятся правки - оптимизация и повышение производительности, правка багов, упрощение отладки, или же более глубокое переписывание механизмов игры. Если с этими вопросами не определиться, в правках не будет порядка.

  • Согласен 1

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Dennis_Chikin


Кстати, взял бы еще много всякого разного отовсюду, если бы был простой быстрый апи. Собственно, почему вот весь "рефакторинг" - что я хочу таки это сделать, и потом туда еще интегрировать этого "всякого разного".

То есть опять всё сводится к тому, что нужен набор дописанных, переписанных и новых скриптов, которые сделали бы код более универсальным. А с адаптациями проблема в том, что в модах изменения общих скриптов не отделены от изменений скриптов, привязанных логике объектов и локаций - всё слишком переплетено, чтобы отделить.
 
И ещё
 
treasure_manager.script

function CTreasure:dialog( npc )
    local comm = npc.character_community()

Там должно быть двоеточие вместо точки, надо поправить.

Упс ! Спасибо. Что-то не проверил эту ветку. dc

Мда, поправил, так поправил... Закинул вместо ООПшного от соли обезжиренной. Ну и черт с ним, с ООПшным... Все равно уже ни кому не нужен.

Изменено пользователем Dennis_Chikin

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Думал сейчас по поводу системы "просто подключаемых скриптов", и неожиданно обнаружил, что у себя я кое-какие шаги в эту сторону сделал, но заметил это только сейчас. Я делал правки для упрощения отладки и отслеживания зависаний, и для этого мне понадобилось сделать отслеживание "источников вызовов" - всех тех мест, откуда скрипты вызываются из движка (за исключением тех случаев, когда вызываемая из скрипта движковая функция приводит к вызову скриптовой). Собственно вот код, который я для этого использую (размещаю его в _G):

 

call_source_timer = nil
call_source_markers = {}
max_ptime = 0
max_ptime_marker = ""
function add_call_source_marker(marker)
    if not (marker and marker:len() > 0) then
        abort("Blank string cannot be used as marker!")
    end
    check_markers()
    table.insert(call_source_markers, marker)
    if not call_source_timer then
        call_source_timer = profile_timer()
    end
    --printf("~ Marker %s called", marker)
    call_source_timer:start()
end


function remove_call_source_marker()
    if #call_source_markers > 0 then
        if call_source_timer then
            call_source_timer:stop()
            if call_source_timer:time() > max_ptime then
                  max_ptime = call_source_timer:time()
                  max_ptime_marker = call_source_markers[#call_source_markers]
                  print("~ maximum time marker "..call_source_markers[#call_source_markers].." time: "..(call_source_timer and call_source_timer:time()))
            --else
                  --print("~ marker "..call_source_markers[#call_source_markers].." time: "..(call_source_timer and call_source_timer:time()))
               end
               call_source_timer = nil
         end
         table.remove(call_source_markers)
    end
end


function check_markers()
    if #call_source_markers > 0 then
        print("! Hanged calls suspected:")
        for i, mark in pairs(call_source_markers) do
            print(mark)
        end
        clear_table(call_source_markers)
        if debug then
           print(debug.traceback())
        end
        call_source_timer = nil
    end
end

 
Как работает? В каждой функции, вызываемой движком, в самом начале пишу add_call_source_marker("название_маркера"), а в конце функции - remove_call_source_marker(). Чтобы не делать удаление маркера перед каждым return, который прописан в функции A, можно функцию A переименовать в функцию B, а на её прежнем месте поставить вызов функции B между вызовами установки/удаления маркера. Таким образом, если при вызове add_call_source_marker окажется, что маркер предыдущего вызова не удалён, значит функция зависла (или маркер был добавлен несколько раз внутри одного движкового вызова). При наличии правленой библиотеки XR_LUA.DLL можно точно узнать место, где проявилось зависание. Сначала эти функции использовались только для вылавливания зависаний, позже я добавил туда замер времени для поиска наиболее "тормозных" мест в коде.
 
И раньше я как-то не задумывался о том, чтобы немного доработать эти функции для того, чтобы на добавление или удаление маркера можно было вешать коллбек. При уникальных именах маркеров, или же при добавлении дополнительных параметров для идентификации, на основе этого можно сделать что-то отдалённо похожее на то, что нужно для простого и удобного подключения скриптов.
 
В xs_sandbox уже было реализовано что-то подобное. Но там для вызова подписанных на событие коллбеков каждый раз создаётся новый объект event, что не очень хорошо для производительности, когда это будет происходить практически в каждом вызове из движка. Но если этот недостаток исправить, будет достаточно подставить вызов события с именем маркера в мой код, чтобы в результате получилась удобная система подключения скриптов.
Изменено пользователем Полтергейст

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Если делать как следует, то все условия выдачи тайников лучше хранить в customdata самих тайников. И тогда можно хранить как в оригинале, только отвалится target за ненадобностью. Только работать это будет в тех случаях, когда и серверный и клиентский класс тайника экспортирован из движка.

Параметры active и done дублируют друг друга с незначительными изменениями, можно оставить только один из них. А его уже определять по наличию метки (mapspot), чтобы не забивать сейвы ерундой.

Изменено пользователем Полтергейст

Поделиться этим сообщением


Ссылка на сообщение

 

 

Так вот коли выдаем с трупов, да еще и со случайным содержимым - во-первых, не нужен конфиг, во-вторых, не нужна куча невидимых и неиспользуемых объектов, и, следовательно, не нужен весь "менеджер".

Конфиг нужен, но не отдельно для каждого тайника, а для описания вероятностей и условий выпадания вещей - распределение по уровням, группировкам, рангам и прочим параметрам. Ну и конечно же condlist'ы с проверками на глобальные infoportion'ы. И весь "менеджер" должен только считать всё это из конфига и проверять вероятности при каждом шмоне. Остальное - не нужно. Сохранение выданности/невыданности не нужно даже в оригинале, т.к. метка на объекте УЖЕ сохраняется. Достаточно проверить наличие отметки на карте - это и будет "выданностью". Если при "заглядывании" снимать метку всегда, то и второй параметр сохранять не нужно. А без них обоих и u16 вообще не нужен. Такая вот экономия.

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

    Ни один зарегистрированный пользователь не просматривает эту страницу.

AMK-Team.ru

×
×
  • Создать...