Город Мастеров
IPB

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в эту темуОткрыть новую тему
> Крафт для мультика, да чтоб не лагал
_kaa_
сообщение Jun 17 2004, 11:06
Сообщение #1


Level 9
Иконки Групп

Класс: Волшебник
Характер: Chaotic Good
Раса: Дракон
NWN: Скриптинг [PW]



Вопрос для обсуждения - как сделать крафтовый движок, достаточно гибкий, удобный в обновлении и, самое главное, не приводящий к лагам.

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

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

Хочу предложить другой вариант, в чем-то менее удобный, но заметно более быстрый.

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

Что должен делать такой скрипт, на примере.

Вот кусок реальной 2da-таблицы (список ресурсов-спавнов, с Мидгарда)

Код

2DA V2.0

  Name   FullName             FullName2          ResRef         Price Spawn TTL   Radius Search Spot MaxValue MaxCount DC Desc                                                                
0  min020 "Торф"               "торфа"            "_res_min020"  1     2     6000  5      6      **** 5        48       8  "Торф._Применяется_для_выплавки_слитков_и_сплавов_из_руды."          
1  min022 "Уголь"              "угля"             "_res_min022"  15    1     6000  4      12     **** 7        25       12 "Каменный_уголь._Применяется_для_выплавки_слитков_и_сплавов_из_руды."
2  min013 "Болотное_железо"    "железа"           "_res_min013"  1     2     6000  2      10     **** 8        30       10 "Железная_руда_невысокого_качества"                                  

[...skip...]



Описывается имя резурса, русское имя, имя в падеже, ресреф, шансы на спавн, место спаван (поверхность\подземелье\везде), время жизни спавна, радиус обнаружения ресурса, DC на search, spot, на добычу, максимальное качество и количество ресурса в спавне и описание.

После работы скрипта получаем вот такой скрипт

Код


string _res_i()
{
   object oI = GetWaypointByTag("mg_wp_i");
   if (GetIsObjectValid(oI))
       return GetName(oI);
   else
       return "Я";
}

//return count of resources
int _cra_GetMaxRes();

struct stRes
{
   string Name,FullName,FullName2,ResRef, Desc;
   int Price, Spawn, TTL, Radius, Search, Spot, MaxValue, MaxCount, DC, Result;
};


struct stRes _cra_GetRes(int nNumber)
{
   struct stRes stResult;
   if (!nNumber || nNumber > _cra_GetMaxRes())
   {
       stResult.Result = 0;
       return stResult;
   }

 
   switch (nNumber)
   {

   case 1:
       stResult.Name      = "min020";
       stResult.FullName  = "Торф";
       stResult.FullName2 = "торфа";          
       stResult.ResRef    = "_res_min020";        
       stResult.Price     = 1;
       stResult.Spawn     = 2;
       stResult.TTL       = 6000;
       stResult.Radius    = 5;
       stResult.Search    = 6;
       stResult.Spot      = 0;
       stResult.MaxValue  = 5;
       stResult.MaxCount  = 48;
       stResult.DC        = 8;
       stResult.Desc      = "Торф. Примен"+_res_i()+"етс"+_res_i()+" дл"+_res_i()+" выплавки слитков и сплавов из руды.";
       stResult.Result    = 1;
       break;


   case 2:
       stResult.Name      = "min022";
       stResult.FullName  = "Уголь";
       stResult.FullName2 = "угл"+_res_i()+"";          
       stResult.ResRef    = "_res_min022";        
       stResult.Price     = 15;
       stResult.Spawn     = 1;
       stResult.TTL       = 6000;
       stResult.Radius    = 4;
       stResult.Search    = 12;
       stResult.Spot      = 0;
       stResult.MaxValue  = 7;
       stResult.MaxCount  = 25;
       stResult.DC        = 12;
       stResult.Desc      = "Каменный уголь. Примен"+_res_i()+"етс"+_res_i()+" дл"+_res_i()+" выплавки слитков и сплавов из руды.";
       stResult.Result    = 1;
       break;


   case 3:
       stResult.Name      = "min013";
       stResult.FullName  = "Болотное железо";
       stResult.FullName2 = "железа";          
       stResult.ResRef    = "_res_min013";        
       stResult.Price     = 1;
       stResult.Spawn     = 2;
       stResult.TTL       = 6000;
       stResult.Radius    = 2;
       stResult.Search    = 10;
       stResult.Spot      = 0;
       stResult.MaxValue  = 8;
       stResult.MaxCount  = 30;
       stResult.DC        = 10;
       stResult.Desc      = "Железна"+_res_i()+" руда невысокого качества";
       stResult.Result    = 1;
       break;

[...skip...]
return stResult;
}

int _cra_GetMaxRes()
{
   return 3;
}


Данный вариант - инклуд (можно делать и вызываемый скрипт), возвращает структуру по номеру и количество ресурсов.

Вставляем этот файл в папку с открытым модулем, компилим. Скорость работы - выше сложнее придумать, ведь мегабайтные файлы с АИ мобов выполняются шустро, а тут объемы гораздо меньше и все данные статичны.

Аналогично можно поступить с любой 2да-таблицей.
Как уже говорил - не обязаетельно делать вариант с инклудом полученного скрипта в другой, можно создавать полноценный скрипт с main() функцией и передавать в него параметры через SetLocalInt(GetModule()...), ExecuteScript("..",) и потом так-же получать результат - GetLocalInt(GetModule()...)

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

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

Предлагаю обсудить другие варианты и отвечу на вопросы - если будут (IMG:style_emoticons/kolobok_light/smile.gif)

Сообщение отредактировал _kaa_ - Jun 17 2004, 11:07
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
DBColl
сообщение Jun 17 2004, 21:38
Сообщение #2


4-х Кубовый
Иконки Групп

Класс: Некромант
Характер: Lawful Evil
Раса: Человек
NWN: Скриптинг [Sn]
Проклятие Левора



Каа, а ты не видел как сделан крафт у нас? Сейчас уже вообще без лагов. С 2да-таблицей. Думаю и в мульте прокатит такой вариант.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
_kaa_
сообщение Jun 19 2004, 09:57
Сообщение #3


Level 9
Иконки Групп

Класс: Волшебник
Характер: Chaotic Good
Раса: Дракон
NWN: Скриптинг [PW]



Цитата
аа, а ты не видел как сделан крафт у нас? Сейчас уже вообще без лагов. С 2да-таблицей. Думаю и в мульте прокатит такой вариант.


Нет еще, жду пока из бета-теста выйдет.
Вариант с 2да для мультика подойдет в случае, если как компонент используется "рецепт" или что-то похожее, однозначно определяющее строку в 2да-таблице. Я же говорил про "честный" вариант, без рецептов в виде компонента крафта.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
_kaa_
сообщение Jul 29 2004, 19:26
Сообщение #4


Level 9
Иконки Групп

Класс: Волшебник
Характер: Chaotic Good
Раса: Дракон
NWN: Скриптинг [PW]



Вот тут скриптик, помогающий создавать крафтовые рецепты для Мидгарда. Для работы требует всего лишь тектовый файлик с названием и тегом кастомных предметов (делается NWNExplorer'ом например, из файла item*.itp)
Работает в обе стороны, т.е. можно из компонентов получить строку для 2да-таблицы или же из строки получить список компонентов.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Valleo
сообщение Jul 31 2004, 05:56
Сообщение #5


Level 4
**

Класс: Друид
Характер: Neutral Evil
Раса: Эльф
NWN: Скриптинг [PW]



Вопрос таков: если обновить 2da на сервере (т.е. на сервере в папку override сунуть) - обновятся ли рецепты для ВСЕХ игроков или же им нужно будет обновлять сам файл 2da самим?
Если самим - уж лучше использовать скриптовой вариант.

ЗЫ: научился работать со структурами... и написал крафт на все виды эначанта (а точнее переписал старый), который использует очень много интерестных вещей и находится в 4х скриптах, 2 из которых - вспомогательные... Работает, и есть поддержка 2da т.е. я встроил ее. Вот так значит если первое работает с обновлением на сервере - буду в 2da рецепты писать... а если нет - придется извращаться через скрипты...
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Аваддон
сообщение Jul 31 2004, 13:10
Сообщение #6


Level 10
***

Класс: Воин
Характер: Lawful Neutral
Раса: Человек
NWN: Скриптинг [PW]



Нет, если только на серваке 2da обновишь то у игроков рецепты не изменятся.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
_kaa_
сообщение Jul 31 2004, 20:38
Сообщение #7


Level 9
Иконки Групп

Класс: Волшебник
Характер: Chaotic Good
Раса: Дракон
NWN: Скриптинг [PW]



Цитата(Аваддон @ Jul 31 2004, 13:10)
Нет, если только на серваке 2da обновишь то у игроков рецепты не изменятся.

Не совсем верно. Если 2да твоя, не используемая клиентом - а только сервером - то игрокам ее вообще противопоказанно иметь. Достаточно будет обновлять ее на сервере. Если же речь идет о _замене_ стандартных 2да, _используемых_ движком самого клиента - то без обновления на стороне клиента не обойтись
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Valleo
сообщение Aug 1 2004, 05:14
Сообщение #8


Level 4
**

Класс: Друид
Характер: Neutral Evil
Раса: Эльф
NWN: Скриптинг [PW]



2 kaa - о пасибки.
Я и не собирался игрокам 2da давать =)
Добавлено в [mergetime]1091326763[/mergetime]
Ах да чтобы облегчить использование 2da надо просто разделять их.
Например в 1 2da - 50 рецептов, во втором - тоже 50. И лагов не будет. Скрипт будет сам смотреть по индентификатору крафта в каком файле что лежит.
Если например индентификатор 161, то скрипт отнимет один раз 50 и передйет к след. файлу, еще раз 50, еще раз 50 и получится у нас 11 - он уже из четвертого файла и вытащит 11 рецепт. Легко и лагов нет. =)
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
_kaa_
сообщение Aug 2 2004, 16:55
Сообщение #9


Level 9
Иконки Групп

Класс: Волшебник
Характер: Chaotic Good
Раса: Дракон
NWN: Скриптинг [PW]



Есть много способов поделить рецепты в кучу разных 2да. Но из скрипта - все равно намного быстрее, пусть и сложнее их туда затолкать.
Кстати, есть такая фича - может пригодится. Если делать безрецептных крафт - то есть определять что получится исходя из того, что затолкали - можно использовать вот что. При переборе по GetFirstItemInInventory() - GetNext..() первым возвращается последняя затолканая вещь. Т.е. если ты будешь требовать правильный порядок рецепта - то получается совсем легко, простая проверка.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Valleo
сообщение Aug 3 2004, 08:41
Сообщение #10


Level 4
**

Класс: Друид
Характер: Neutral Evil
Раса: Эльф
NWN: Скриптинг [PW]



Да у меня крафт такой, что нельзя сделать из там металла+дерева топор.
У меня можно из этого топора забабахать +1 энчант, +2 урон кислотой и т.п. =) Смотря какие рецепты...
И кончно же этот энчант +1 можно сделать +2 и +3 и т.п....
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения

Ответить в эту темуОткрыть новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 29th March 2024 - 15:44