Dennis_Chikin 3 658 Опубликовано 4 Января 2015 Поделиться Опубликовано 4 Января 2015 (изменено) С чего начинать и где взять. Установка Lua:http://www.amk-team.ru/forum/index.php?showtopic=11584&p=629106 Руководство «Программирование на языке Lua», третье издание:http://www.amk-team.ru/forum/index.php?showtopic=11584&p=905308 Изменено 2 Марта 2015 пользователем Kirgudu Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
xStream 86 Опубликовано 6 Ноября 2011 Поделиться Опубликовано 6 Ноября 2011 Не знаю, насколько это актуально, но я часто использовала в последних своих изысканиях по сталкеру (но это относится к ЛУА в целом) следующее свойство: ключами и значениями у таблиц в ЛУА может быть что угодно. В качестве ключей можно использовать другие таблицы или функции! Это было откровение, и оказалось удобно. Еще одним хорошим методом увеличения гибкости кода является использование безымянных функций, в частности, когда их передаешь как аргумент в другие функции. (Был уже пример, как я понимаю, - итератор). Получается неплохое такое приближение к полиморфизму в С++ (учитывая, что с помощью метатаблиц в ЛУА можно сымитировать классы и их поведение). Или, например, можно написать итератор по таблице, который будет выполнять функции, хранящиеся в таблицах-значениях, в зависимости от других значений этих таблиц или даже ключа (или выполнять ключ, если он является функцией). В общем - гибкость бешеная. Код, обычно, сокращался раза в 2-3. Есть только минус - отлаживать гораздо сложнее Все, кто стоит на моем пути: идите нахрен и там погибните! © Ссылка на комментарий
xStream 86 Опубликовано 6 Ноября 2011 Поделиться Опубликовано 6 Ноября 2011 Зачем? В зависимости от надобности. Пример был даже приведен. У меня было, например, одно место, где использовалась очередь колбеков - таблица, в которой ключ являлся ссылкой на функцию, а значением была таблица, передаваемая этой функции. Вполне удобно оказалось - заранее составляем таблицу, потом просто используем. Так программировалось поведение в рейде, при изменении условий, очередь перестраивалась заново. Своеобразный планировщик получался. Все, кто стоит на моем пути: идите нахрен и там погибните! © Ссылка на комментарий
xStream 86 Опубликовано 6 Ноября 2011 Поделиться Опубликовано 6 Ноября 2011 (изменено) Без кода, принцип: Есть некая непись, она составляет рейд, причем в каждой точке (ключевой) планирует некое действие (например - отдельную схему, выполнение квеста и т.п.). Действие - функция (у меня подставлялась в экшн), а параметры - "настройка действия" (типа надо пойти и найти такой-то предмет, отыграть такую-то анимацию и бляблябля). В результате я получала для непися таблицу с парами "функция - параметры". Ну и непись отправляется под схему. При смене состояния (непись дошел до цели, например) делается next из таблицы, пишется в переменные (self.четотам, например). В эвалюаторе/экшене просто выполняется сохраненная функция с параметрами. В результате получается разнообразное поведение, в зависимости от того, что происходит вокруг непися и на контрольных точках. А схема - одна. Ну и никаких захардкоденых графов. Когда таблица "исчерпана", рейд завершается и непись возвращается в исходную (ну или какую выберет) точку. ------ Поздно, я уже ответила Изменено 6 Ноября 2011 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Ссылка на комментарий
*Shoker* 322 Опубликовано 6 Ноября 2011 Поделиться Опубликовано 6 Ноября 2011 (изменено) xStream Спасибо за ценную информацию _____ Кто знает, возможно ли в луа делать таблицы из интервалов? Допустим у меня есть число от 1 до 100 и 10 каких то значений. Я хочу составить таблицу так, чтобы в зависимости от числа, выбиралось определённое значение. Тоесть если чсло равно от 1 до 10, то берётся значение 1 и так дале... Делать через if не очень хочется. Вот такой код нужно упростить: local num = math.random(1,100) if num <= 10 then return -2000 end if num > 10 and <= 20 then return -1500 end if num > 20 and <= 30 then return -1000 end if num > 30 and <= 40 then return -500 end if num > 40 and <= 50 then return 0 end if num > 50 and <= 60 then return 500 end if num > 60 and <= 70 then return 1000 end if num > 70 and <= 80 then return 1500 end if num > 80 and <= 90 then return 2000 end if num > 90 then return 2500 end return 0 Изменено 6 Ноября 2011 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
xStream 86 Опубликовано 6 Ноября 2011 Поделиться Опубликовано 6 Ноября 2011 Мне кажется, здесь проще всего составить функцию, в данном конкретном случае: деление на 10, получение целой части, отнимание 5, умножение на 500, обрезание с помощью min & max Все, кто стоит на моем пути: идите нахрен и там погибните! © Ссылка на комментарий
*Shoker* 322 Опубликовано 6 Ноября 2011 Поделиться Опубликовано 6 Ноября 2011 (изменено) В принципе можно и так, но хорошо бы найти решение не тока для "конкретного" случая, ибо уже пару раз сталкивался с такой необходимостью, и приходилось через if-ы действовать... Как я понял, в LUA похожего интервального решения не предусмотрено. Может помимо if-ов есть ещё какие то варианты. ЗЫ: Случайно ошибся в функции, после and не написал num, но на суть вопроса не влияет. Изменено 6 Ноября 2011 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
xStream 86 Опубликовано 6 Ноября 2011 Поделиться Опубликовано 6 Ноября 2011 Честно, не встречался ни один язык с "выборками интервалами". То, что тебе надо - поиск по массиву. В терминах ЛУА можно составить таблицу, каждый элемент которой содержит минимум и максимум, и значение. А там уж бегать по нему, пока не попадется нужное. Или, как я выше писала, ключ - функция, которая вернет тру или фалс; если тру, берем значение и останавливаем перебор. Это более универсальное решение Все, кто стоит на моем пути: идите нахрен и там погибните! © Ссылка на комментарий
Artos 99 Опубликовано 7 Ноября 2011 Поделиться Опубликовано 7 Ноября 2011 (изменено) malandrinus, полностью солидарен с высказанным. Та же таблица умножения является универсальной, но только сам человек может исходя из потребностей брать из нее то, что ему нужно. Выше приведенный пример банально укладывается в простейшее: local MyFunc = function() return math.random(-4,5)*500 end Меняя цифирьки - получаем условную универсальность. В конце концов задача любого кода в первую очередь дать результат и дать быстро, а красота/компактность/... - все же вторичны. Универсальность как раз относится к вторичным критериям и тем более, как правило, в противоречиях со скоротью получения результата. Изменено 7 Ноября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
xStream 86 Опубликовано 7 Ноября 2011 Поделиться Опубликовано 7 Ноября 2011 (изменено) Честно говоря, считаю, что "прятать" логику - очень дурной тон. Я про оператор индексации. В С++ схожая ситуация, но там оно более очевидно и потому используется широко. Типизированный язык как никак. А вот спрятанный алгоритм поиска введет в недоумение не-автора. Что при работе в команде зачастую - очень нехорошо. Согласна с Артосом: лучшее - враг хорошего. Быстрее и проще решить частный случай, чем клепать универсальный, никому не нужный код, который использован то будет всего пару раз. И в то же время, если код пишется в команде, то про красивость и ясность забывать нельзя - сэкономишь на одном, потеряешь на другом. Изменено 7 Ноября 2011 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Ссылка на комментарий
Artos 99 Опубликовано 7 Ноября 2011 Поделиться Опубликовано 7 Ноября 2011 (изменено) xStream, работа кодера в команде конечно же имеет свои особености и критерии. Хотя ... и времена команд практически прошли (в Сталкере) и в основном работа или одиночек или строго параллельно кодер+моделлер+дизайнер+ ... Т.е. один никак не мешает другому. Забывать о ясности и даже красивости кода при его публикации (ведь моды - публичный продукт) никогда конечно не стОит, но и приносить оптимизацию/скорость в угоду 'рюшечкам' так же не разумно. Чаще всего, функция/блок/модуль должны быть не изнутри понятны, а ясна/понятна/и проста суть их применения для других, т.е. точки входа/выхода. В общем все должно быть в меру, разумном сочетании и в обязательной привязке к контексту задачи. И упражнения в изощренности кода и в его упрощенности - вредны при их передозировке (эти слова для *Shoker*'а, дабы не замудрился ...). :-) (сорри за оффтопик) Изменено 7 Ноября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
xStream 86 Опубликовано 7 Ноября 2011 Поделиться Опубликовано 7 Ноября 2011 [offtopic] Ну как бы никто не спорит Я немножко увлеклась "жизненным" примером: у меня 3 подчиненных, так что работать в команде надо уметь. Я придерживаюсь довольно строгих правил и требую от других того же (code guideline). Получается пока довольно эффективно. Начиная от именования переменных, до самодокументирования кода. Так что вопрос о "единственно верном способе программирования" явно выходит за рамки этого топика, да и ненужно это. А вот использовать возможности языка тогда, когда это не вредит ни красоте, ни скорости, ни гибкости - вай нот? [/offtopic] Кстати, вспомнился вопрос оптимизации - зачастую лучше потратить память и выиграть в скорости, создавая временные, часто используемые, контейнеры и переменные. Это в тему топика. Тогда и не придется заниматься экономией на циклах (30% быстрее и т.п.), так как итерация по 100 элементам - совершенно не то же самое, что по 10 000, к примеру. Это применительно и к сталкеру. Была мода в свое время пробегать по всем ИДшникам игровым с 1 до 65к, проще сделать один раз и составить таблицу, откуда удалять элементы и добавлять их туда уже по колбекам регистрации/разрегистрации. Это просто пример и мое имхо. Возможно, я отстала от жизни. Все, кто стоит на моем пути: идите нахрен и там погибните! © Ссылка на комментарий
Artos 99 Опубликовано 7 Ноября 2011 Поделиться Опубликовано 7 Ноября 2011 (изменено) xStream, к сожалению, времена идут но ... новички как ранее начинают, как правило с итераций по 65К таблицам ... Но это уже вопрос больше из области 'не хочу учиться, а хочу жениться', т.е. не уча азы и наработанное - сразу выдать на гора 'свой мод'. Насчет отдельных таблиц - конечно же решение верное, но ... и не напасешься порой таблиц на все про все и не все в таблице учтешь. Например тот же офф-лайн-алайф из АМК. Локаций немало, объектов и их типов куча, событий мониторится тоже не раз-два ... Все коллбэками не охватить, тем более на постоянно пополняемых кодах модов. А сканировать все же нужно. Тут недавно про 'coroutine' GUN12 нам всем напомнил, и вышел довольно неплохой промежуточный вариант распределенного сканирования: Вот это на апдейте у актора: local iPrgScan = 25 --/ периодичность сканирования Зоны (25ms => ~15 минут) function OnUpdate(uo,delta) --/ непрерывное циклическое сканирование локаций по всему диапазону ID объектов (1...65534) if coroutine.status(CoScan) == 'suspended' then --/ статус сопрограммы: приостановлена? local bFlg,Result = coroutine.resume(CoScan, iPrgScan) --/ (пере)запуск сопрограммы if not bFlg then --/ ошибка при выполнении сопрограммы printf("OnUpdate:Error_CoScan=[%s]:<%s>", Result, "Error!") end end end А это основа сорограммы: local tOAMain,tTmpMain = {},{} --/ дин.массив основных объектов (используется в m_news.script) local tOwners,tTmpOwn = {},{} --/ дин.массив владельцев предметов local CoScan = coroutine.create( --/ сопрограмма сканирования объектов игры function(iTimeLimit) --/ функция сканирования объектов игры с ограничением времени работы -- log("%s:CoScan:TimeLimit=[%s]:[%s]", sModule, iTimeLimit, ">") --/#~# local oPTimer,iTimeStop,soObj = nil,nil,nil local iCurID = 65535 --/ начальный ID while true do if iCurID >= 65534 then --/ проверка: цикл закончен (или предустановка)? --coroutine.yield(iCurID) --/ приостановка (опционально) if iCurID == 65534 then tOAMain,tOwners = tTmpMain,tTmpOwn --/ обновляем основные массивы log("%s:CoScan:Owners=[%s]:Time=[%s]%s", sModule, GetSizeTable(tOwners), Get_StrTime(), "") --/#~# --Print_Tables_OffLineAlife() --/#~# for Debug end --/ предустановки для нового цикла: tTmpMain,tTmpOwn = {},{} --/ временные массивы iCurID = 0 --/ начальный ID (опускаем 0-actor) iTimeStop = iTimeLimit --/ начальная установка для таймера oPTimer = profile_timer() --/ (пере)создаем объект таймера end iCurID = iCurID +1 --/ переход к следующему ID soObj = sim:object(iCurID) --/ очередной серверный объект игры if soObj then --/ объект в игре? ('пустышки' пропускаются и таймером) oPTimer:start() --/ старт таймера (на продолжение) --/ -- обработка объекта ---------------- this.Build_TableObj(soObj,iCurID) --/ ------------------------------------- oPTimer:stop() --/ (при)остановка таймера if oPTimer:time() > iTimeStop then --/ проверка: не закончен ли лимит времени? coroutine.yield(iCurID) --/ приостановка цикла iTimeStop = oPTimer:time() + iTimeLimit --/ обновляем для текущего подцикла сканирования end end end printf("%s:DoScan:<Error!>") return 65535 --/> end ) Т.о. и эксклюзивные таблицы доступны и коллбэки их актуализируют и ... периодически каждые 10...15 минут эти таблицы освежаются просканнированным глобальным диапазоном по всем объектам, котрый не единовременно выполняется (давая лаги в игре), а размазанно по всему временному интервалу. Т.е. вариант включает в себя все достоинства известных вариантов, исключает лаги и почти исключает зависимость от 'пропущенных' недоработок коллбэков. Будучи запущенным один раз - на протяжении всей игры периодически сканирует всю Зону по всем объектам создавая соответствующие 'тематические' таблицы. И все это практически в фоновом режиме. Изменено 7 Ноября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
xStream 86 Опубликовано 7 Ноября 2011 Поделиться Опубликовано 7 Ноября 2011 (изменено) и не напасешься порой таблиц на все про все и не все в таблице учтешь. Ну так и решение то не претендует на универсальность это как способ "оптимизации циклов" :-D ... оптимизации архитектуры. Тут недавно про 'coroutine' GUN12 нам всем напомнил, и вышел довольно неплохой промежуточный вариант распределенного сканирования: Недурно, да. Но нити дают накладные расходы при выполнении, ну и никак не экономят процессорное время. И отлаживать тоже тяжелее. В принципе, это ж не противопоставление архитектурному решению, а просто еще одна техника. Те же апдейты актора и других - такие же по сути корутины. Полагаю, топик как раз для "не новичков" и всякие техники полезны будут. Изменено 7 Ноября 2011 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Ссылка на комментарий
Artos 99 Опубликовано 7 Ноября 2011 Поделиться Опубликовано 7 Ноября 2011 (изменено) Имел ввиду конечно де не универсальность при создании 'таматических' таблиц, а то, что и этого порой не достаточно. И конечно же доп. нить (тред) дает накладные расходы, не упомянуто и то, что создаются двойные таблицы (рабочая и временная), что тоже минус. Но(!) тут или иметь периодические 'быстрые' итерации по всему диапазону ID (65К) и иметь лаги, или ... размазать эти лаги во времени, чтобы их не заметно было. Т.о. получился не обособленный 'еще один' вариант, а вариант 'симбиоз' с глобальным сканирование 65К + создание тематических (архитектурных) таблиц + распределение издержек во времени == в результате все довольны, игрок не видит лагов, кодер работает со своими таблицами, экономя другие ресурсы ... :-) А отлаживать то как раз проще, обработка объектов в вынесенном блоке и имеет свою диагностику. Один раз написав - даже не приказался к отладке, т.к. все заработало сразу и работает как часы (да и проще просто врядли бывает, ИМХО, "ломаться" нечему). Изменено 7 Ноября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
xStream 86 Опубликовано 7 Ноября 2011 Поделиться Опубликовано 7 Ноября 2011 (изменено) Сложно, если там логика сложная и вылезло какое-нибудь переполнение стека Простое и отлаживать просто, бесспорно. Все зависит от мозгов программиста - чем он наполнит это все дело ЗЫ Завязываю оффтопить Изменено 7 Ноября 2011 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Ссылка на комментарий
Artos 99 Опубликовано 7 Ноября 2011 Поделиться Опубликовано 7 Ноября 2011 (изменено) Ну ... с перехватчиком Lua от alpet (ссылка) и добавленным дебагером от RvP уже и переполнения стека не так страшны и сложны в отладке как в былые времена. ;-) (тоже и извиняюсь за некоторый оффтопик и прекращаю ... на время) Изменено 7 Ноября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
xStream 86 Опубликовано 7 Ноября 2011 Поделиться Опубликовано 7 Ноября 2011 Ну, инструментарий появился со времени, когда я последний раз занималась сталком, - это ж замечательно! Я отстала от жизни. Тем не менее, это инструменты, а речь шла о довольно примитивных техниках. ЗЫ Все, точно завязываю Вернусь с чем-нить интересным, если вспомню. Просто некоторые вещи из Луа в принципе не подходят к сталкеру Все, кто стоит на моем пути: идите нахрен и там погибните! © Ссылка на комментарий
Nazgool 250 Опубликовано 7 Ноября 2011 Поделиться Опубликовано 7 Ноября 2011 xStream Ну на оффтоп это мало похоже. Как никак "...Общие вопросы программирования" в названии темы также присутствует. А тот, кому это нужно, извлечет не мало полезного из всего вышесказанного именно по вопросу программирования. Ссылка на комментарий
RvP 1 Опубликовано 7 Ноября 2011 Поделиться Опубликовано 7 Ноября 2011 xStream, Просто некоторые вещи из Луа в принципе не подходят к сталкеру например? Vita sine libertate, nihil Vita sine litteris - mors est Ссылка на комментарий
7.9 174 Опубликовано 7 Ноября 2011 Поделиться Опубликовано 7 Ноября 2011 Интересно!.. кстати... Многоядерные CPU (2-3-4) и движок xRay 1.x. Использует-ли xRay (реально) 3 и 4 ядра? Загружены-ли они работой? А есть-ли у самой Lua свойства (или средства) "многоядерность"? всё легко Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти