Это популярное сообщение. Malandrinus 615 Опубликовано 8 Июля 2009 Это популярное сообщение. Поделиться Опубликовано 8 Июля 2009 (изменено) В данной теме собраны сведения по скриптовой модели сталкера: функции и классы, методы и свойства, взаимосвязь классов и последовательность работы с ними, связь работы классов и файлов конфигураций. К наполнению темы приглашаются все желающие. В наполнении темы непосредственно участвовали и существенно мне помогли: @Monnoroch, @Kolmogor, @Unnamed Black Wolf, @меченый(стрелок), @IQDDD, @Kirag, @Taroz, @dan, @7.9, @Garry_Galler, @AKKK1, @Bak и много других людей. Скрытый текст Скрытый текст класс alife_simulator. Базовые операции с серверными объектами. Пространства имён. Глобальные функции для большого числа задач. "Создание своего класса" и "Наследование от экспортированных классов". Базовые сведения об объектно-ориентированном программировании для сталкера. Необходимо прочитать, для понимания темы про биндер и некоторых других. В одном посте: Общие слова об архитектуре и скриптовой модели сталкера "Класс object_binder" расширение онлайновых объектов, колбеки, сохранение состояния. "Класс net_packet" Регистрация скриптовых классов с помощью object_factory Серверные классы. Часть 1 Иерархия серверных классов, описание не закончено. Серверные классы. Часть 2 Картинка структуры наследования и несколько заключительных слов Клиентские классы Скрытый текст Класс game_object Интерфейс ко всем онлайновым (клиентским объектам) Класс hit для нанесения урона скриптом и другая информация (IQDDD) Некоторая информация по управлению путями патрулирования здесь (Kirag) и здесь (Taroz) Неполная информация по управлению памятью неписей с примером здесь (Bak) Физическая оболочка объектов (Garry_Galler) Пост о выборе (подборе) оружия НПС и стрельбы (*Shoker*) Скрытый текст Управление заданиями Класс CGameTask и другие вспомогательные классы и функции. Управление инфопорциями Функции, колбеки, форматы файлов Список специальных системных инфопорций (Unnamed Black Wolf) Система профилей и алгоритм генерации имён. Форматы файлов, функции Дополнительная информация по параметрам профилей terrain_sect (Kolmogor) Диалоги. Часть 1 Форматы файлов, базовые сведения Диалоги. Часть 2 Скриптовые диалоги Диалоги. Часть 3 Тематическая подборка функций управления диалогами Скрытый текст Функции времени Тематическая подборка функций, связанных с управлением игровым временем. Класс CTime Вспомогательный класс для управления игровым временем Полезная скриптовая функция с использованием CTime (Garry_Galler) Скрытый текст class ini_file (меченый(стрелок)) Класс FS и CSavedGameWrapper Бинарный доступ к файлам, в том числе в игровых архивах, управление сохранёнными играми. Скрипт уровня. Забытая фишка с колбеком на заход на уровень Класс vector Некоторая полезная информация о разных вещах (меченый(стрелок)) "Класс render_device" Направление и положение камеры, характеристики экрана, программная пауза игры и др. Некоторая информация о различиях между ТЧ и ЗП в системе оконных классов и колбеков. (lekzd) Неплохо бы развить эту тему! Некоторая полезная информация о скриптовых функциях из модуля _g.script. (lekzd) Также требует развития! Полезные функции для работы с графом игры (Garry_Galler) В одном посте: Класс profile_timer Отладочные измерения скорости работы фрагментов программы Класс client_spawn_manager Колбек на выход в онлайн без использования биндера. Работа с консолью. Класс CConsole Анимации цвета. Класс color_animator Всякие моргающие элементы в окнах и пр. Управление постэффектами. Скриптовые постэффекты. Класс effector Класс sound_object. Проигрывание звуков в игре в произвольном месте, от произвольного объекта, в голове актора. (Shadows) Пост удалён автором (прим. Kirgudu) Скрытый текст Оконные классы Некоторая общая информация о создании окон Список методов, XML-тегов и событий для оконных классов (ТЧ/ЧН/ЗП) (Norman Eisenherz) Представление материала в моих статьях оптимизировано для онлайнового просмотра. Если кому не хочется лазить по спойлерам, а нужно просмотреть текст какого-либо поста "потоком", то могу рекомендовать просмотр в режиме "текстовая версия". В этом же режиме удобно сохранять содержимое темы на диск. (прим. Malandrinus) Изменено 30 Июля пользователем Kirgudu 5 5 16 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
abramcumner 1 141 Опубликовано 8 Января 2012 Поделиться Опубликовано 8 Января 2012 _Призрак_, надо просто приаттачивать после открытия инвентаря, пда - тогда будет сверху Ссылка на комментарий
Malandrinus 615 Опубликовано 10 Февраля 2012 Автор Поделиться Опубликовано 10 Февраля 2012 Удалось заставить выполняться функцию alife_simulator:kill_entity(npc, gvid, sheduled) здесь npc - это сталкер или монстр, которого надо прикончить в оффлайне, gvid - вроде как геймвертекс, куда ляжет тушка, sheduled - по идее должно быть аномалией, которая по идее что-то должна спавнить по факту смерти в ней непися, но этот аргумент я не проверял и его можно игнорировать. Ранее всегда при выполнении был вылет. Удалось выяснить, что там стоит проверка на непустой инвентарь. Почему-то вылетает, если в инвентаре непися что-то есть. Если перед убиением перебрать шмотки и удалить все объекты, у которых parent_id равен id непися, то вылета нет и непись исправно подыхает. На самом деле особенного практического смысла в этой функции нет, поскольку методов прикончить непися в оффлайне хватает, и фактически они даже лучше работают, чем этот. Просто было непонятно, что этот метод делает и почему виснет. Между прочим, это фактически единственный сохранившийся метод из родной системы оффлайновой боёвки. Музейный экспонат, так сказать =) Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Полтергейст 37 Опубликовано 12 Февраля 2012 Поделиться Опубликовано 12 Февраля 2012 Между прочим, это фактически единственный сохранившийся метод из родной системы оффлайновой боёвки К слову об оффлайне. Оффлайновые обновления (те, что от планировщика) мне удалось заставить заработать. Для этого я всего лишь заменил вызов self:brain():update() на self:update() и перегрузил последнюю функцию, ничего не добавляя (осталось только cse_alife_*.update()). Не уверен, что последнее на что-то повлияло. После всех этих изменений игра вылетела, ругаясь на отсутствие некоторых параметров в m_person.ltx, проблему решил установкой параметра Scheduled = off. После этого оффлайн-обновления заработали. Ссылка на комментарий
Malandrinus 615 Опубликовано 12 Февраля 2012 Автор Поделиться Опубликовано 12 Февраля 2012 (изменено) Полтергейст, У сталкеров и монстров update серверного объекта не делает ничего, кроме как вызывает brain():update(). У остальных объектов и вовсе ничего не делает. С Scheduled = off вообще-то странно. По-моему, этот параметр нигде и никак не читается: ни в движке, ни в скриптах. Изменено 12 Февраля 2012 пользователем malandrinus Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Полтергейст 37 Опубликовано 16 Февраля 2012 Поделиться Опубликовано 16 Февраля 2012 (изменено) malandrinus С Scheduled = off вообще-то странно Сейчас ещё раз перепроверил - всё работает, никакого вылета. Возможно, была какая-то другая причина - ошибочка вышла. Оффлайн обновления тоже проверял ещё раз - нормально работают, как и написал. Обновляются через определённый промежуток времени. Это было бы полезно для скриптов типа amk_offline_alife, чтобы обновления объектов вызывались самими объектами, а не из обновления биндера игрока. И ещё. Скриптовый сет для группы (online_offline_group) может быть перегружен (только делать это нужно функцией c_register, а не cs_register). Только что проверил и заспавнил один такой объект - вылетов, зависаний и прочих ошибок замечено не было. В функции on_before_register() скриптового класса поставил вывод в лог - сообщение успешно вывелось. Изменено 16 Февраля 2012 пользователем Полтергейст Ссылка на комментарий
AndreySol 215 Опубликовано 1 Марта 2012 Поделиться Опубликовано 1 Марта 2012 float mass() - массаЭта ф-ция для инвентарных объектов работает ? такой, к примеру, код local obj = db.actor:object("medkit") if obj then return obj:mass() end всегда возвращает 0 Ссылка на комментарий
ColR_iT 171 Опубликовано 1 Марта 2012 Поделиться Опубликовано 1 Марта 2012 (изменено) AndreySol, функция рабочая. Только возвращает она не инвентарную массу, не ту которая в описании предметов. Скорее всего это масса для просчёта коллизий. Для оружия и патронов, точно возвращает 0, для инвентарного "хлама" вероятно тоже. Если применена к неподходящему объекту возвращает -1. Изменено 1 Марта 2012 пользователем ColR_iT Ссылка на комментарий
Artos 99 Опубликовано 1 Марта 2012 Поделиться Опубликовано 1 Марта 2012 AndreySol, возможно могу ошибиться в категоричности (надеюсь поправят), но движек не считает данным методом массу объектов, которые в инвентаре/ящике/... Правильнее вначале проверить имеет ли объект физическую оболочку obj:get_physics_shell() и тогда получать массу ... т.е. типа: if obj and obj:get_physics_shell() then ... "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Whisper 29 Опубликовано 30 Марта 2012 Поделиться Опубликовано 30 Марта 2012 RvP Используя эти константы можно установить действия на щелчки мышью Те значения - обычные скан-коды? А кручение колесика обрабатывается? Ссылка на комментарий
Malandrinus 615 Опубликовано 2 Апреля 2012 Автор Поделиться Опубликовано 2 Апреля 2012 За классом game.CTime замечено странное поведение, а именно: старшие 4 байта 64-х разрядного счётчика в этом классе могут спонтанно обнуляться. Пока такое замечено в объектах, сохранённых на предыдущем апдейте. Т.е. я имею примерно такой код: local previous_check_time function on_spawn() previous_check_time = game.get_game_time() end function on_update() local current_time = game.get_game_time() -- в этом месте previous_check_time может оказаться побитым local dt = current_time:diffSec(previous_check_time) previous_check_time = current_time -- делаю вычисления на основе dt end и вот из-за этого эффекта значение previous_check_time оказывается не тем, которое сохранил. Происходит это крайне редко, и никакой системы обнаружить не удалось. Тем не менее, это может происходить достаточно часто, чтобы приводить к заметным проблемам. К примеру, это может происходить раз в несколько игровых часов. Последствия могут быть от незаметных, до самых тяжёлых. К примеру, если в коде выше значение dt используется для вычислений какого-то эффекта, приводящего к постепенному снижению здоровья, к примеру как-то так: db.actor.health = k*dt гдк k - это скажем влияние артефакта в слоте или ещё что-то, то в результате данной ситуации вычисленная разница dt будет много миллионов, что приведёт к соответственному снижению здоровья на много миллионов и мгновенной смерти актора. Выхода из этой ситуации может быть два. 1. Не использовать CTime вообще, но в этом случае возникает известная проблема переполнения счётчика через игровой месяц. 2. Не хранить объекты CTime, а вместо них хранить их покомпонентно, т.е. в виде набора чисел для лет, месяцев, дней, часов, секунд, миллисекунд. Соответственно, раскладывать объект на эти компоненты, их хранить, потом собирать заново. Это естественно вызывает некие расходы. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
*Shoker* 322 Опубликовано 2 Апреля 2012 Поделиться Опубликовано 2 Апреля 2012 Такие "аномалии" на всех частях сталкера появляются? Тесты на ЗП или на ТЧ были? Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
Artos 99 Опубликовано 2 Апреля 2012 Поделиться Опубликовано 2 Апреля 2012 (изменено) malandrinus, однако практика показывет обратное ... В моде при старте игры устанавливаю игровое время: --/ установка игрового времени на дату из 'alife.ltx' function Set_Game_StartTime() local tT = ParseStr(system_ini():r_string("alife", "start_time"), ":") --/ 05:30:00 local tD = ParseStr(system_ini():r_string("alife", "start_date"), ".") --/ 01.05.2012 --/ Установка игрового времени. Формат установки: (Y,M,D, h,m,s, ms) oGameTime = game.CTime() --/ объект класса 'CTime' oGameTime:set(tD[3],tD[2],tD[1], tT[3],tT[2],tT[1], 0) --/< 2012,05,01, 05,30,00, 0 if iSSVer < 8 then --/SHOC utils.Set_CTime(oGameTime) --/ установка таймера игрового времени для сэйвов smart_terrain.Set_CTime(oGameTime) --/ установка гулагового таймера игрового времени end end - т.е. объект устанавливается на требуемое время, запоминается и этот же объект вводится для двух основных игровых скриптов. На всем протяжении игры этот объект используется для отсчета времени с начали игры и каких либо сбоев по вине обнуления старших битов не замечалось. Да и врядли (ИМХО) объект меняет свои данные, скорее, если все же тобою отмечены подобные сбои, их можно приписать самой функции вычисления разности ... Просьба уточнить, тобою отмечены некорректные значения для dt или все же что-то более общее? Если учесть в твоих кодах то, что постоянно сменяется/перезаписывается новым объектом previous_check_time, то все же скорее возможно нечто аномальное с новым полученным объектом, чем изменение прежнего. Если попробовать вот так вычислять dt: local basic_time = game.get_game_time() basic_time:set( 2000,1,1,0,0,0,0) --/ constant basic time (дата может быть из конфига) local previous_check_time = 0 function on_spawn() previous_check_time = game.get_game_time():diffSec(basic_time) end function on_update() local current_time = game.get_game_time():diffSec(basic_time) --/ sec local dt = current_time - previous_check_time previous_check_time = current_time -- делаю вычисления на основе dt end - т.е. не от переменной базы, а от постоянной, не исчезнут ли ошибки/сбои или не станут ли "разовыми", если все же есть сбои в функции diffSec? Изменено 2 Апреля 2012 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Malandrinus 615 Опубликовано 2 Апреля 2012 Автор Поделиться Опубликовано 2 Апреля 2012 (изменено) Artos, однако пактика показывет обратное ... Твоя может и не показывает, а я бы не писал так уверенно, если бы не видел это своими глазами. Я же говорю, это происходит один раз на сотни тысяч совершенно безпроблемных вычислений. Кроме того, я на своей машине такого и не видел. Я у себя поставил на целый день загруженную игру и ловушку на этот эффект, и ничего так и не случилось. Эффект обнаруживали наши тестеры, и частота его появления - один на много часов игры при работе вышеприведённого алгоритма на каждом апдейте (т.е. примерно 40 раз в секунду). Мне пришлось давать им отладочный модуль с выводом в лог и по этому логу смотреть. Если учесть в твоих кодах то, что постоянно сменяется/перезаписывается новым объектом previous_check_time, то все же скорее возможно нечто аномальное с новым полученным объектом, чем изменение прежнего. А можно поконкретнее? Весь алгоритм приведён выше, ничего сверх этого с объектами CTime не происходит. Т.е. вот три строки, которые работают на каждом апдейте: local current_time = game.get_game_time() -- <== 1 local dt = current_time:diffSec(previous_check_time) -- <== 2 previous_check_time = current_time -- <== 3 В строке 3 ссылка previous_check_time заменяется на ссылку на объект с текущим временем. В этот момент его значение в норме (проверено выводом в лог после строки 3). После этого до следующего апдейта previous_check_time никто не трогает. Начинается следующий апдейт, имеем строку 1 и перед этой строкой ставим проверку значения объекта CTime, на который ссылается previous_check_time. И это значение уже побитое! Где и что может произойти с этим объектом между этими двумя моментами времени? Переменная локальная, снаружи модуля не доступна. Да и врядли (ИМХО) объект меняет свои данные, скорее, если все же тобою отмечены подобные сбои, их можно приписать самой функции вычисления разности ... Как я описал выше, меняется именно объект, а diffSec уже честно вычислял получившуюся ерунду. Я именно это и проверял, значение объекта на текущем апдейте, потом его же на следующем. Меняется! Для меня это совершенно дико. Это как если бы я записал в переменную значение 4, а после апдейта там оказалось 5. Бред же, но что-то в этом стиле и происходит. Я бы даже больше понял, если бы портился весь объект разом, но обнуляются только старшие 4 байта. Если попробовать вот так вычислять dt: - т.е. не от переменной базы, а от постоянной, не исчезнут ли ошибки/сбои? Можно попробовать. Надо также проверить, что не будет копиться существенная ошибка округления, поскольку так итоговая маленькая разница вычисляется между большими числами с плавающей запятой. Я могу предположить, что никто не использует этот класс на регулярной основе. Я видел только единичные применения, которые с точки зрения времени случаются разы. Если мы условно оценим вероятность возникновения этого эффекта примерно как 1/100000 (на основе опыта тестеров), то при разовых применениях можно запросто и не дождаться. Если же и дождаться случайно, то всё равно ничего понять не выйдет, поскольку не удасться воспроизвести. И почему у меня такого не случается? От машины ещё зависит? В общем, у меня ответов нет. Я здесь написал, чтобы констатировать факт. Кто не верит, дело хозяйское. *Shoker*, Такие "аномалии" на всех частях сталкера появляются? Тесты на ЗП или на ТЧ были? Это собственно на ТЧ шестого патча. На других не проверял, да и не могу я проверить. Для этого надо ставить отладочный модуль на другую игру и гонять много часов и возможно не на моей машине. Я этого сейчас делать не могу и не хочу. Я решил проблему способом, который я выше описал в первом сообщении (с сохранением объекта поэлементно). Пока вроде работает. Изменено 2 Апреля 2012 пользователем malandrinus Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Artos 99 Опубликовано 3 Апреля 2012 Поделиться Опубликовано 3 Апреля 2012 (изменено) malandrinus, собственно обсуждаем нечто, чего ни ты ни я не "щупали" и только предполагалки можно строить. Все же место для такого сообщения (топик-справочник) требует не просто некоей информации, а реально подтверждаемого факта "для всех", а не ... "у кого-то". Во-первых, если это не некая страшилка, а реальный баг, то стОит его все же по-возможности выявить, т.к. твоя фраза "никто не использует этот класс на регулярной основе" не соответствует реалиям и даже в оригинальной игре (ТЧ) очень немало примеров именно прямого использования объектов CTime. Это и в гулагах (stateBegin, от которого состояния отсчитываются) и в логике (activation_game_time), и в тасках сплошные last_task_time ... и т.д. Так что, использований немало, а значит и ошибка может касаться самых азных аспектов. Отказаться же от использования напрямую объектов - переписывание многих "рабочих" кодов, на что редко кто из модмейкеров идет ... Во-вторых, жаль что не приведены коды проверок "до" и "после", а не в них ли кроется огреха выявления ошибки? Как можно "поконкретнее", когда пока только по дозированной инфрмации можно делать предположения. Да, в трех строках твоего кода нет изъяна, как и в том, что локально сохраненный объект также не может быть изменен. Но тогда, если подвергается некоему сомнению второе - то и первое также может быть оспорено!? Тем более таким образом:"Бред же, но что-то в этом стиле и происходит.". Все же это либо бред либо нет, и это требует выяснения. Так же, подобные сомнения можно распространить и на любой иной объект в игре, тем более утвердительно сказать, что на протяжение многих часов игры у кого-то из игроков хоть какой-то объект не CTime не "самоизменяется" никто не сможет. ИМХО, если ошибка не воспроизводима на других компьютерах - это уже ошибка или софта/железа, а не игры/движка, или особенность "того компа", на котором она якобы появляется. А это уже совершенно иная история и иные последствия. Предлагаю выложить полный комплект кодов (касаемых поднятой информации), на которых тестерами якобы обнаружены сбои, включая код поверки объекта "до" и после и вывод в лог. Также, по-возможности, другая информация от тестеров, которая могла повлиять так или иначе на проявление бага (ОС, CPU, ...). Как минимум, из-за именно смены объекта, соверенно не ясно, баг ли это именно объекта или нечто иное, например локальный сбой именно одного периода апдейта и т.п. Если это баг - то обязан появиться не только у "ваших тестеров", важно идентифицировать его именно относительно CTime. Кто не верит, дело хозяйское.Как говорится: "Доверяй, но проверяй!" Не верю (и конечно же это мое мнение), пока или информация не станет именно фактом для именно бага CТime в игре SHoC или не останется некоей особенностью именно "вашего" варианта игры и именно у отдельных "кого-то из ваших тестеров", а не у всех. Тем более и ты, по сути, из третьих рук этот "факт" получаешь. Плз, уточни, что за on_spawn и on_update подразумеваются в твоем примере, чтобы поставить в аналогичное место коды-ловушки и попробовать отловить баг, подтвердив или опровергнув (хотя бы частично) информацию. Надо также проверить, что не будет копиться существенная ошибка округления О каком накоплении идет речь? Каждый раз значение current_time вычисляется от неизменной базы (basic_time) и текущего игрового времени и из него вычитается предыдущий результат этого же вычисления (previous_check_time), которое было запомнено в предыдущем цикле. Т.о. накопление может относиться только к двум смежным периодам апдейта. Итоговая погрешность не может превышать двойной дискретности измерения (округления), т.е. 2х1 секунды игрового времени. Изменено 3 Апреля 2012 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Malandrinus 615 Опубликовано 3 Апреля 2012 Автор Поделиться Опубликовано 3 Апреля 2012 Предлагаю выложить полный комплект кодов (касаемых поднятой информации), на которых тестерами якобы обнаружены сбои, включая код поверки объекта "до" и после и вывод в лог. Я не пойму, что ты этим сказать хотел. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Artos 99 Опубликовано 3 Апреля 2012 Поделиться Опубликовано 3 Апреля 2012 (изменено) Пока не ясна причина, а нам даже собственно и сам факт сбоя пока неведом, и даже о чем конкретно гласит некое сообщение в каком-то логе о некоей ошибке, мною ставится под сомнение вот это: старшие 4 байта 64-х разрядного счётчика в этом классе могут спонтанно обнуляться Поэтому и использовал 'якобы сбой'. Чтобы все же информация высказанная тобою приобрела некий статус "для всех", а не "дело хозяйское", в подобных случаях проводят тест-проверку дабы получить результаты на самом разном железе/софте и при различных условиях. Естественно, для такой поверки требуются именно те строки кода, 'которые' обнаруживают ошибку. Т.о. получив результаты от различных источников с достаточно разными внешними факторами (версия игры/патча, мод, железо, софт, ...) и можно будет далее говорить, что это "бред" и является локальным сбоем "у юзера" или "в этом что-то есть" и это возникает при неких общих или конкретных частных условиях. И вот уже во втором случае и нужно решать модмейкерам - забить на редкую ошибку, исправить свои коды или перелопатить коды всей игры ... А пока, это все же является сташилкой, ИМХО. "Привидения" никто не видел, и только кем-то виденное пятно на полу дает пищу для слухов. Появись твое сообщение днем раньше - воспринял бы как перво-апрельскую шутку. ;-) Пока поставил у себя на апдейт актору двойную проверку на поиск этого бага, попробую собрать хоть какую-то статистику. Изменено 3 Апреля 2012 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Malandrinus 615 Опубликовано 3 Апреля 2012 Автор Поделиться Опубликовано 3 Апреля 2012 Вот код с тестовыми проверками (модуль для менеджера сигналов): function attach(sm) sm:subscribe({signal = "on_spawn", fun = this.on_spawn}) sm:subscribe({signal = "on_update", fun = this.on_update, queued = true}) end local previous_check_time function on_spawn() previous_check_time = game.CTime(game.get_game_time()) end function on_update() local pt = previous_check_time:timeToString(3).." "..previous_check_time:dateToString(0) local ptl, pth = previous_check_time:get_value() local current_time = game.CTime(game.get_game_time()) local dt = current_time:diffSec(previous_check_time) previous_check_time = current_time local ct = current_time:timeToString(3).." "..current_time:dateToString(0) local ctl, cth = current_time:get_value() log1("pt[%s, h=%08x, l=%08x] ct[%s, h=%08x, l=%08x]: dt=%5.3f", pt, pth, ptl, ct, cth, ctl, dt) end Там используются функции из x-ray extensions для получения компонент счётчика. Без этого насчёт младших и старших разрядов не понять, поскольку эффект виден как изменение даты в район нулевого года. И ещё вот что. Первое. Я никому ничего доказывать не обязан. Второе. "Дело хозяйское" относилось к "верить/не верить", а в том, что это происходило, я нисколько не сомневаюсь. Третье. Тратить жизнь на то, чтобы найти причину этой проблемы, я тоже не буду. Кроме этой, у меня не раз были ситуации, когда проблема не воспроизводилась на моей машине. От этого проблема не становится меньше и решать её всё равно надо. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Artos 99 Опубликовано 3 Апреля 2012 Поделиться Опубликовано 3 Апреля 2012 (изменено) Еслит бы не статус форума, как ведущего по моддингу игры (ИМХО) и топика, как именно справочника для руководства модмейкерам (тоже ИМХО), то не стал бы оспаривать иль сомневаться ... Никто никому конечно ничем не обязан, но ... сказав "А" обычно говорят и "Б", а в данном случае возникла неопределенная пауза. Спасибо за конкретные коды, будет с чем попытаться перепроверить наличие бага. Хотя мною пока использовался вариант: local oCTime,oCTimeSav = nil,nil local tSum = {["b"] = 0, ["p"] = 0, ["c"] = 0, ["dt"] = 0} function OnSpawn() oCTimeSav = game.get_game_time() oCTime = game.get_game_time() end local function Check_CTime(time,sFlg,iFlg) local Y,M,D,h,m,s,ms = time:get(0,0,0,0,0,0,0) local iSum = Y+M+D+h if iSum < tSum[sFlg] then log("%s:Check_CTime:[%s]=[%s]<x>[%s]:[%s:%s:%s:%s]:<%s>", sModule, sFlg, iSum, tSum[sFlg], Y, M, D, h, "Error!") table.print(tSum,sModule..":tSum|"..sFlg.."/"..tostring(iFlg)) abort("%s:Check_CTime:[%s]=[%s]:<%s>", sModule, sFlg, iSum, "Error!") else tSum[sFlg] = iSum end end function OnUpdate() Check_CTime(oCTime, "b") --/ базовый (эталонный) объект счетчика времени Check_CTime(oCTimeSav, "p", 1) --/ первичная проверка local oCTimeCur = game.get_game_time() Check_CTime(oCTimeSav, "p", 2) --/ вторичная проверка tSum.dt = oCTimeCur:diffSec(oCTimeSav) --/ sec oCTimeSav = oCTimeCur Check_CTime(oCTimeSav, "c") --/ конечная проверка --log("%s:OnUpdate:[%s]:[%s %s]", sModule, string.format("dt=%5.3f",tSum.dt), oCTimeCur:dateToString(0), oCTimeCur:timeToString(3) ) --/#~# end Суть собственно та же, только на доступных в любой версии игры методах и при ошибке игра прерывается с распечаткой достаточно информативным логом. Времени конечно пошло мало, но пока никаких абортов по багу не было. Метод же time:get(0,0,0,0,0,0,0) вполне адекватен чтению разрядов счетчика, т.к. при сбое аналогично покажет обнуление старших разрядов (точнее любое уменьшение текущего времени относительно предыдущего). Ну а тратить ли время на поиск причины и/или ограничение круга условий возникновения бага - это конечно же дело добровольное, как собственно и существование этого топика, за который многие тебе благодарны и в котором все же должна быть подтвержденная и/или проверенная информация, а не некие частности по непонятным причинам и не воспроизводимые даже при большом желании. (ИМХО) P.S. Пара побочных вопросов: 1. Каков смысл в обертке: game.CTime(game.get_game_time()) вместо просто: game.get_game_time() ? 2. log1 - уже научен в x-Ray Extensions выполнять функционал string.format (сборка строки по шаблонам) или это рудимент упрощения для "показать принцип"? Если 'да' - будет ли доступен и когда в сырцах? Изменено 4 Апреля 2012 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Malandrinus 615 Опубликовано 4 Апреля 2012 Автор Поделиться Опубликовано 4 Апреля 2012 Artos, 1. Каков смысл в обертке: game.CTime(game.get_game_time()) вместо просто: game.get_game_time() ? Это была попытка что-то изменить, сохраняя копию объекта, вместо того, что выдаёт game.get_game_time(). Ничего ровным счётом не изменило, поэтому можно спокойно заменить на просто game.get_game_time() 2. log1 - уже научен в x-Ray Extensions выполнять функционал string.format (сборка строки по шаблонам) или это рудимент упрощения для "показать принцип"? Если 'да' - будет ли доступен и когда в сырцах? Спасибо, что обратил внимание. Это опечатка (с работы посылал и в игре проверить не мог). Имел в виду log2, моя обёртка над log1, которая работает как string.format. Делать это в x-ray extensions естественно смысла нет. Так что здесь надо добавить string.format. А исходно там стоял вывод в отдельный файл с использованием io. Мне интересно. Вот скажем не сможешь ты воспроизвести эту ситуацию, что будешь делать? Скажешь, что такого не бывает? Мне ведь у себя так и не удалось. Я же говорил, поставил у себя этот код на целый день (пока на работе был), и ни черта так и не дождался. У меня конечно актор просто стоял на месте, и это отличается от ситуации у тестеров. Там всё более активно шевелится, и кто знает, что это меняет. Это не считая разницы в конфигурации системы. Но двое человек отмечали как минимум несколько инцидентов в течении пары дней. Я это естественно видел только в логах. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Artos 99 Опубликовано 4 Апреля 2012 Поделиться Опубликовано 4 Апреля 2012 (изменено) Что буду делать? дальше => Учитывая, что наличие бага для объектов класса CTiime довольно существенно для игры (немало кодов от этого зависит), то требуется все же или подтвердить наличие бага хотя бы на достаточном кол-ве различных платформ(компов) у различных игроков, или же "забить" на локальные сбои именно у отдельных тестеров, списав это на особенности их железа/софта/... В отличии от многих модмейкеров/комад, мною в моде SIMBION идет открытая разработка, т.е. различные новшества и тестовые коды выкладываются в очередные версии/фиксы. Наличие в моде игрового и нескольких дебаг- режимов и возможность от(в)ключать различные опциональные модули, вполне позволяет и поиграться и покопаться в логе/кодах. Отмечу, что многие игроки в мод (хотя это присуще не только симбионщикам) предпочитают играть именно в дебаг-режимах, суя нос в консоль и логи игры. Т.о. вставив в дебаговый модуль мода вот этот код: local oCTime,oCTimeErr = nil,nil local tCTimes = {["s"] = 0, ["c"] = 0, ["p"] = 0, ["e"] = 0} function OnSpawn() oCTime = game.get_game_time() end function OnUpdate() --/ проверка наличия 'бага CTime' local function GetCTime(time,typ) local Y,M,D,h,m,s,ms = time:get(0,0,0,0,0,0,0) local sStr = Y.."."..M.."."..D.." "..h..":"..m..":"..s.." :"..ms if type(time.get_value) == 'function' then local lo,hi = time:get_value() --/ читаем биты счетчика времени tCTimes[typ] = {tm = sStr, hi = string.format("%08x",hi), lo = string.format("%08x",lo)} log(string.format("%s:GetCTime:[%s]=>[%s]:(hi=%08x, lo=%08x):<%s>", sModule, typ, sStr, hi, lo, "Info")) else tCTimes[typ] = sStr log("%s:GetCTime:[%s]=>[%s]:<%s>", sModule, typ, sStr, "Info") end end local oCTimeCur = game.get_game_time() --/ текущее игровое время local iDiffSec = oCTimeCur:diffSec(oCTime) --/ дительность паузы между апдейтами (sec: ~0.02...0.05...) if iDiffSec < 0 or iDiffSec > 99 or oCTimeErr then --/ обнаружен 'баг CTime'? log("%s:OnUpdate:[%s %s]:DiffSec=[%s]", sModule, oCTimeCur:dateToString(0), oCTimeCur:timeToString(3), string.format("%5.3f",iDiffSec) ) --/#~# GetCTime(oCTimeCur, "c") --/ запоминаем значение текущего счетчика GetCTime(oCTime, "p") --/ запоминаем значение предыдущегосчетчика if not oCTimeErr then tCTimes.s = iDiffSec --/ запоминаем значение некорректной паузы oCTimeErr = oCTime --/ запоминаем значение предыдущего 'подозрительного' счетчика else log( string.rep("~",64) ) --/#~# GetCTime(oCTimeErr, "e") --/ перепроверка-распечатка 'подозрительного' счетчика print_table(tCTimes,sModule..":tCTimes|") --/ распечатка всех запомненных значений abort("%s:GetCTime:DiffSec=[%s]:<%s>", sModule, iDiffSec, "Error!") log( string.rep("~",64) ) --/#~# end end oCTime = oCTimeCur --/ запоминаем текущий счетчик времени end - можно от самых разных игроков получить информацию о проявлении/наличии бага ... Как видно из кода, он не сильно обременяет ресурсы игры и даже в дебаговом режиме игра практически не потеряет FPS или иного функционала, но при любом проявлении бага - последует вылет с выводом в лог достаточной для подтверждения и анализа информацией. При чем, это не зависит от наличия расширителей x-Ray и, учитывая работу мода на любом патче - можно параллельно получить информацию о наличии бага в любой версии игры/патча. Остается собрать "жалобы" игроков на подобные вылеты и проанализировать ... Ну а далее, если баг все же именно класса, а не причуд железа/софта/... - искать адекватное решение. При достаточно большой вероятности проявления бага - буду переписывать все коды, в которых применяется класс CTime на более стабильные варианты. Если же критичность бага для большинства игроков не подтвердится - вероятно забью на этот "бред", не буду принимать его во внимание и вырежу из мода проверку бага. При желании, указанный выше код любой модмейкер может встроить к себе в коды и также попытаться понять наличие бага именно на своих кодах/версии/патче ... Т.о. и может быть опровергнута или подтверждена информация о наличии бага в классе CTime. Собственно уже требуется только время ... P.S. Небольой коммент по log1 (и log2) Все чаще можно встречать коды с упоминанием log1 ... что говорит и о востребованности x-Ray Extensions и о том, что коды портируются и в другие моды. Однако(!), нередко и у начинающих модмейкеров возникают проблемы/ошибки при обращении к отсутствующей log1, если ими не используется библиотека-расширитель. А почему бы не сделать тем, кто использует расширитель, довольно простое добавление в тот же _g.script: if log1 then log = function(fmt,...) log1( string.format(fmt or "", ...) ) end end тем самым убив даже не двух, а трех зайцев(!): - т.к. функция log имеется в любой версии кодов - исключена ошибка вызова. Это заодно и реанимирует заглушенную штатную функцию; - коды с применением log1 становятся "стандартными" и даже отсутствие/изъятие расширенной библиотеки не повлечет фатальных ошибок; - применим любой вариант вызова как log1 (простых строк), так и log2, т.е. с использованием шаблонов. Итоговая строка в любом случае будет сформирована. ИМХО, подобная простенькая добавка более удобна для совместимости по кодам различных вариантов от самых разных модмейкеров/команд и снижает вероятность описок/ошибок. Те же, кто не имеет добавки (новички) - просто не будут иметь в логе соотв.строк, но и вылетов не будет. :-) Изменено 4 Апреля 2012 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти