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

Рефакторинг


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

Ну и раз начали про код, то я бы добавил просто еще один аргумент для action, т.к. я ненавижу писать одно и тоже несколько раз. Совместимость? а для _first все равно надо будет переделать.

ИМХО для таких вещей "флудилку" бы надо, типа как же все таки круче, односточник или нет. Ссылка просто так.

Да и для тестов давно пора сделать "тестовый стенд" в духе

function test_me(action, times, ...)
  local pt = profile_timer()
  pt:start()
  for i = 1, times do
    action(...)
  end
  pt:stop()
  return pt:time()
end

ТЧ 1.0004. SAP и Trans mod

github

Ссылка на комментарий
Да при чем тут наносекунды?
for i = ... специально придуман для обхода правильных массивов.
Оператор ... как раз и создаёт такой массив. Если что, на первой же "дырке"
цикл прекратиться (в оригинале это сделано через if (arg ~= nil) ... break).
Кстати pairs не годится для этой функции. Он читает всё, т.е. и nil-ы.

@Desertir

Ага. Я использую быстрые таймеры (быстрые - это в смысле без анализа множества результатов, вычисления среднестатистического значения и прочей ерунды)

local function call_timer(tab, name)
    local timer = {timer = profile_timer(), name = name or ''}
    
    function timer:start()
        self.timer:start()
        return self
    end
    
    function timer:stop(msg)
        self.timer:stop()
        self:print(msg)
        return self
    end
    
    function timer:point(name)
        self:stop("POINT '"..(name or '').."'"):start()
    end
    
    function timer:print(msg)
        print("TIMER '"..self.name.."' > "..(msg or 'STOP')..' >  TIME = '..self.timer:time())
    end
    
    return timer
end

debug.timer = setmetatable({}, {__call = call_timer})

Тут у меня  подключена Lua by RvP, но это не обязательно. Функция print тоже переписана.

И использую

local t1 = debug.timer('timer_1'):start()
...
t1:point('1') -- если нужно
...
t1:point('N') -- если нужно
...
t1:stop() -- тут в лог пишется
Изменено пользователем Nazgool
  • Нравится 1
Ссылка на комментарий
Ссылка на комментарий

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

 

  Код отслеживания (Показать)
Изменено пользователем Полтергейст
Ссылка на комментарий

Более того, в оригинале на каждой из локаций достаточно ограниченное разнообразие всего.

Ссылка на комментарий

А есть какой то глубинный смысл в том чтоб всем нпс писать в профиль, какое оружие и какой прочий лут у них должен быть?

А есть какой то глубинный смысл чтоб воткнуть за тем кустом кабанов через алл-спавн, и там всегда, всю игру будут кабаны и только кабаны. И заселить по такому принципу все локации. Только прибитое гвоздями население.

На самом деле у GSC мотив так делать определенно был. Если делать живую, изменяющуюся зону - в нее будет интересно играть, она будет реиграбельна. А кому же это выгодно? точно не разрабам. им надо продать коммерческий проект, чтоб люди поиграли, потом им надоело, и они купили следующий. (ЧН, ЗП). Вот поэтому и было выгодно нанять орду офисного планктона, который сделал то что мы имеем в виде сталкера ТЧ, вместо того чтоб найти еще пару толковых программистов, которые бы написали жизнь зоны.
У вас, у меня, интересы другие. Мы же не коммерческие проекты делаем, а делаем так чтоб было интересно играть. Это разные вещи, совершенно.

  • Нравится 1
  • Согласен 1

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Ссылка на комментарий

@Zander_driver, ну вы батенька расписали.

Не в выгоде дело. А в том дело, что локациями занимались геймдизы, левелдизы, никак не программисты. Вот они и расставляли. Вообще, всегда этим занимаются как раз такие люди.

Все, кто стоит на моем пути: идите нахрен и там погибните! ©

Ссылка на комментарий

Следующий вопрос, а вообще как-то где-то удивительный postprocess.PostProcess(ini_file(name_ini_file)) задействован? Я вот лично не видел что-бы им кто-то когда-то пользовался. Да и вообще слабо уловил смысл скрипта. А то там какие-то супер параметры передаются. Как я понял корнями уходит в CEffectorPP, ну мне это понять пока не под силу.

 

В ЗП, к слову, успешно выпилен. Ничего фатального не будет если и в ТЧ его зарубить? Ну он правда нигде вообще не используется.

Изменено пользователем Карлан
Ссылка на комментарий

@xStream, не стоит путать мух с котлетами, а работу дизайнеров - с обеспечением фоновой заселенности зоны.

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Ссылка на комментарий

@Zander_driver, я не путаю. Дизайнерам даются инструменты. В том числе и для "фоновой" заселенности. Другое дело то, как реализованы эти инструменты И как работают дизайнеры.

Все, кто стоит на моем пути: идите нахрен и там погибните! ©

Ссылка на комментарий
  Карлан писал(а):

Да и вообще слабо уловил смысл скрипта.

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

 

А почему никто не применил до сих пор - да просто потому, что для повседневных задач хватало экспортированных в пространство level методов (add/set/remove_effector).

  • Спасибо 1
Ссылка на комментарий

Просьба ко всем сюда заглядывающим, как по вашему мнению лучше всего переписать безобразие с level_tasks.script(?), там задумка то вроде и хорошая, но реализация просто насквозь пробагованная. Я всегда опасался этой системы, а сейчас решил заняться и так вжало меня от всех свистоплясок кои там имеют место быть.

 

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

 

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

Изменено пользователем Карлан
Ссылка на комментарий

Видимо я поднимаю очень актуальные вопросы, продолжу монолог. Как вы считаете, какая самая приемлемая архитектура таблиц должна быть в оригинале у тайников?

   val_secret_0029 = 
     {
      items = "af_mincer_meat,energy_drink,bandage,3",
      condlist = "{=npc_rank(experienced)}2",
      description = "val_secret_0029_description",
      active = false,
      target = 5429,
      done = false,
      name = "val_secret_0029_name",
     },

Пока прикололся по тупому копирайту, но по моему если вносить в скрипты, то надо как-то все же по другому данные сделать. Ну вот что итемы таблицей (точнее итемы мы просто уведем в логично дифференцированный рандом) - это понятно, а вот кондилст как? Все ли понимают распарсенный кондлист?

То есть кондлист вышеуказанной таблицы в распарсенном виде выглядит вот так:

      condlist = 
        {
          1 = 
            {
              infop_check = 
                {
                  1 = 
                    {
                      expected = true,
                      func = "npc_rank",
                      params = 
                        {
                          1 = "experienced",
                        },
                    },
                },
              infop_set = 
                {
                },
              section = "2",
            },
        },

Вариант очень так себе. И вот стоит вопрос как его оформить, либо оставить как есть и парсить как есть (так скорее всего и будет). Интересно было бы услышать мнения всяких тех кто со спавном (тайников в т.ч.) работает и все такое. Стоит что-то вообще менять, или нет?

 

У меня есть несколько идей по улучшению, я их обязательно реализую, но хочется услышать еще мнения что нравится/не нравится, так же возможно чего-то не хватает. 

Еще вопрос, стоит ли вводить тайники как в ЗП, и если да, то делать ли их в единой системе, или все-же разграничить? Если в единой, то как должны отличатся данные одних от других? Если в разных, то опять же как должны выглядеть данные в первом и втором случае? Вариант оставить как есть разумеется рассматривается, вопрос в том удобно ли это будет в скриптах, там все же царство таблиц.

 

Ссылка на комментарий

@Карлан, второй вариант конечно же не читаем совершенно. Кондлист должен быть понятным для человека-непрограммиста, иначе какой в нем смысл, если можно написать просто булевую функцию на Lua?

 

А все распарсивания - это наносекунды, никому они не нужны и ни на что не влияют.

Изменено пользователем Shadows
Ссылка на комментарий

, дело не в выигрыше времени, дело в субъективной стилистике :). Я думаю оставить все как есть, то есть первый вариант, ну и еще несколько несколько ключей добавить.

 

Что думаешь о идее тайников ЗП?

Ссылка на комментарий
  Карлан писал(а):

Что думаешь о идее тайников ЗП?

Сама идея мне в ЗП понравилась, но:

1) предметы могут провалиться под геометрию;

2) предметы могут выпасть из места тайника из-за каких-либо воздействий;

3) предметы легко обнаружить до получения инфы о тайнике.

Ссылка на комментарий

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

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

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

@Полтергейст, если говорить о исходниках, то там есть нормальное хранилище данных, и сейвы забивать/не забивать становится вопросом скорости загрузки (он немаловажен). Экспортировать ничего не нужно, можно оставить как есть, можно сделать ивент (нужно только событие), а там все в хранилище забивать без пакета актора. Вот и все "как следует". active и done можно записывать с помощью побитовых операций, они ничего не жрут абсолютно, я выкладывал когда-то здесь примеры, не вижу смысла как-то урезать функционал ради каких-то сомнительных экономий.

Ссылка на комментарий
  Полтергейст писал(а):

все условия выдачи тайников лучше хранить в customdata самих тайников.

Условия выдачи тайников не надо хранить вообще.

Выкладывал же.

 

А вот "выданный" и "невыданный" тайники - на самом деле - тоже не надо. Тайник надо спавнить при выдаче. А лучше - вообще при заходе актора на локацию.

  • Нравится 1
  • Согласен 2
Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

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