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

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

Тема для обсуждения скриптов всего и всех в серии игр STALKER.


Задавая вопрос (!):
1. Внимательно изучите суть вопроса. Вопрос должен соответствовать выбранной Вами темы. Это поможет сохранить порядок и читабельность темы, а также облегчит поиск и понимание сего;
2. Изучите то, что уже есть в теме (пролистайте "руками", воспользуйтесь поиском на форуме);
3. Изучите информацию которая может вам помочь:

  Информация (Показать)

4. Дабы не превращать обсуждение в "кашу" разной информативной направленности, задавайте несколько вопросов по порядку (в разных постах) после того, как получите ответ на предыдущий вопрос;
5. "Спасибо" и тому подобное - будьте так любезны в ПМ. Если не любите писать в ПМ, в конце вопроса напишите фразу: "Заранее спасибо!" - или что-то в этом духе;
6. ПОЖАЛУЙСТА! Указывайте, для какой игры Вам необходима информация (ТЧ, ЧН, ЗП), если стоит мод - укажите название мода;
7. Если Вы что-то сделали и результат не такой, какой Вами задумывался, то, пожалуйста, приводите коды которые Вы изменяли/писали целиком! Это поможет другим правильно ответить на Ваш вопрос, а также оградит Вас от лишней писанины.
8. Оформляйте сообщение. Пользуйтесь тегами для того, чтобы отделить код от текста. Пишите грамотно - ПОЛЬЗУЙТЕСЬ ЗНАКАМИ ПРЕПИНАНИЯ.
9. И помните: «Правильно заданный вопрос – половина ответа».

 

Какие вопросы следует задавать, а какие нет...

  Читать рекомендуется. (Показать)

И последнее: очень рекомендовано к прочтению Правила форума
 


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

OFF_ender,

  Цитата

По мере заполнения таблиц получаю либо зависание при сохранении, либо вылет при попытке загрузки (чаще).

С большой вероятностью происходит переполнение нетпакета. Эти функции сохраняют всё в один нетпакет, скорее всего актора. Размер нетпакета - 8кб. При этом он частично заполнен другими данными, зачастую более, чем наполовину. Если твои таблицы большие, то риск переполнения вполне реальный.

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

  Полезный утиль (Показать)
Ссылка на комментарий

 malandrinus, спасибо за ответ.

Немного поэкспериментировал, сначала выкинул из таблиц стринговые секции - вылеты стали реже. Потом вообще исключил подтаблицы и сделал 5 отдельных таблиц, немного save/load - пока вроде не было вылетов, но может только пока...

Вообще, нет ли каких недостатков именно у этих amk-шных функций сохранения таблиц? Может есть другие, более надежные функции, поскольку вылет, так понимаю, именно из-за переполнения 8кб ?

Спасибо.

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

OFF_ender

Если очень нужно, то именно для твоих таблиц могу дать вариант "на скорую руку". Насколько я понял таблиц будет сохраняться две. Если в каждой будет по 50 полей, то размер сохраняемой строки составит около 1кб +-. Так что если ещё актуально - прошу.

Хотя сорри. Что означает <1..65535>? кол-во символов или числа из этого диапазона?

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

 Gun12, <1..65535> - id об'екта, я так понимаю, он в этих пределах. В общем в таблицах важны только числовые значения. По возможности стринги можно исключить. (писал в лс - буду благодарен за твой вариант)

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

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

Любое использование нет-пакетов игровых объектов имеет недостаток - отсутствие контроля переполнения! Т.о. если модмейкер не контролирует свои записи (и тем самым вероятность переполнения), то только незначительные объемы "пользовательских" сохранений могут быть "безопасными".

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

 

Gun12, запись id_a=<1..65535> вероятно означает, что ключ id_a в таблице может принимать значение из диапазона 1..65535 (и т.п.). Хотя замечу, что 65535  это уже перебор для игровых id (u16) и правильнее: 0...65534.

 

malandrinus, если контролировать размер строки (а большие таблицы сериализовать) - то резать на куски и хранить куски, а при считывании склеивать куски - поможет "более продвинутым системам хранения" обойти и этот недостаток. ;-) (но лучше не допускать больших строк /таблиц)

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Artos, спасибо. Да, как-то попадался ваш пост:

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

Раз уж возникла нужда в нетпакетах, то придется видимо разбираться серьезно.

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

В твоём примере я стрингов не видел.

В общем так. Я исхожу из следующих утверждений.

1. Таблицы две.

2. В каждой из этих таблиц находится массив из таблиц

3. Все таблицы из массива имеют одинаковые ключи (id_a, id_b и numb)

4. Каждое значение ключа - число из указанного диапазона.

Если так, то, как я уже говорил, для 50-ти полей в каждой из таблиц и максимальных значений каждого поля размер будет 1074 байта

  на скорую руку (Показать)
Изменено пользователем ColR_iT
Ссылка на комментарий

Gun12, спасибо

  Цитата

В твоём примере я стрингов не видел.

Я имел ввиду ключи: id_a, id_b, numb. Если их совсем исключить и сделать таблицу вида:
table1 = {[1] = <1..65534>, [2]=<1..8>, [3]=<1..65535>, [4] = <1..65534>, [5]=<1..8>, [6]=<1..65535>,...}, тогда в ней прошлая 1-я подтаблица - это элементы [1],[2],[3], следующая - [4],[5],[6] и т.д. Надёжность в таком варианте не пострадает? Всё-таки раньше обращались к конкретному ключу конкретной подтаблицы, а здесь если выпадет один элемент, то всё сместится и посыпется... А также выигрыш по размеру пакета будет существенный?
Имеет ли смысл записывать только одну таблицу, если ко второй ещё не обращались? В твоём варианте сохраняются сразу обе, или особой разницы нет?

И ещё: 8кб - это общий размер всех сохраняемых данных или размер каждого пакета в отдельности?

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

В моём варианте ключи id_a, id_b, numb записываются только один раз. В сохраняемой строке они занимают всего 16 байт. Вот и весь выигрыш в пакете. Всё остальное это значения каждой из подтаблиц. После загрузки строки подтаблицы примут первоначальный вид, каждая с ключами и естественно со значениями. Так что решай что тебе нужнее - 16 байт или нормальный вид подтаблиц.

 

Дальше. Если ты не обращался ко второй таблице, то и записывать её нет смысла. Передавай в вызове только одну s=toString(table1). ну или какую нужно.

8192 байта размер пакета



Если тебе будет жалко 16-ти байт, давай подкину вариант, который экономит ещё порядка 200 (может и больше) байт (т.е. максимальный размер таблицы формата 2х50 не превысит 874 байта). А ещё другими словами - в тот же размер (1074) можно записать таблицы формата 2х62

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

Gun12, если тебе не сложно, я только за.

Кстати, если numb [1..1000] загнать в диапазон 1..100, я так понимаю, еще по одному байту экономиться будет? Можно конечно еще извернуться, и сохранять в таблице не id об'ектов, а индексы 1,2,3,... но наверно уж слишком много вычислений будет производиться при каждом действии...

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

OFF_ender и Gun12 , вы явно не в ту сторону идете...

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

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

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

4. Выше, malandrinus, упомянул о способе децентрализации сохраняемых данных (размазать по множеству объектов) - следует все же его рассмотреть, хотя автор вопроса пока ничего не говорит о сути сохраняемых данных.

5. Ну а если все же не стучаться в стенку, а обратить внимание на "универсальные хранилища", то отпадет нужда думать о "каждом байте" в каждом случае... и потратить время на более полезное. ;-)

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Ну это смотря как кодировать.
Если использовать HEX вариант то да, один байт экономиться. Т.е. число 1000 переводиться в 3-х значное hex-число, число 100 в 2-х значное
Это значит что числа диапазона 256-4095 кодируются 3-мя символами(байтам),  4096-65535 4-мя байтами и т.д.
Я использую кодирования с основанием 100
Поэтому диапазоны такие : 99-9999 кодируются 2-мя байтами), 10000-999999 - 3-мя, 1000000-99999999 4-мя и т.д.
Так что, как видишь, для этой системы кодирования всё-равно что 100, что 1000. Кодироваться всё равно будет 2-мя байтами в отличии от HEX

Насчёт индексов 1,2,3 или ключей стрингов. Функциям по барабану. Количество строки байтов увеличится на длину строк всех ключей - 3
Ну будет лишний десяток байт. Если не критично, то можешь писать стринги.

Artos, мне хорошо известно в какую сторону иду я.
Не знаю как для тебя, но для меня упражнения в lua дело очень даже полезное.
Так что всем спасибо за предупреждения. Приняли. Подумаем на досуге... как-то...

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

Ну возьму я хранилища. Нет. Чего мелочиться. Качать готовые моды паком, удалить на фиг lua с компа и не парить себе мозги. Вот.

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

Gun12, я все же обращу твое внимание на то, что конечный результат не только от упражнений с Lua зависит, а точнее Lua тут только промежуточная ступень.

Ты сейчас ориентирован на сериализацию таблиц и их запись строками в нет-пакет, в этом случае выбор метода сохранения (stringZ)  единственен. Полезное и интересное занятие, не спорю, тем более и сам грешен. :-) В этом случае и тебе будет полезным все же посмотреть и то, что уже имеется по этой теме. Подсказка: с'экономить можно и на ключах, если таблица является индексированной, помнишь, был такой разговор в теме?

Однако, как раз переполнение сэйва (пакета) этим вариантом наиболее вероятно, если в игре не только эти данные (по)требуется сохранять. Любая компрессия только отодвигает тупик. Нельзя же заранее просчитать в игре все объемы данных, которые потребуется сохранить.

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Artos,

 

  Показать

 



OFF_ender, пробуй :

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

Gun12, (тоже шепотом) ;-)

Просто напомню тебе это: lua_extension в котором и твои труды были в свое время учтены. ;-)

По сути это сборник, а table.compress и table.decompress имеют прямое отношение к текущему вопросу.

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Поделитесь, пожалуйста, ссылкой на универсальное хранилище. Или подскажите, как его регестрировать в class_registrator.script.

P.S. поиском нашёл только мёртвые ссылки.

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

Универсальные хранилища в контексте Сталкера имеют (мне известны) три реализации: by malandrinus,  by xStream и by Artos.

Последние две базируются на идее 1-ой.

По последней повторю свой ответ в ЛС автору вопроса (OFF_ender):

  Цитата

Последний вариант кодов для "публичного" использования лежит тут: se_stor_ext_120429-3

Актуальный вариант всегда в актуальной версии мода SIMBION:SHoC (скачать и взять).

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

Изменено пользователем Artos
  • Нравится 1

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Gun12, может я что-то недопонял...

  как-то так (к примеру)? (Показать)
Ссылка на комментарий

Нет. Просто вызывай :

s = toString(table1)

Таблица полностью запишется в строку. Вот эту строку и сохраняй

Если будет несколько таблиц, то так и пиши :

s = toString(table1,table2,table3,table4) -- и т.д.

Все эти таблицы запишутся в одну строку.

 

При загрузке получай из пакета строку и вызывай :

tab = toTable(s) - s это полученная строка, tab - таблица с восстановленными таблицами table1, и т.д.

 

Затем пишешь :

table1 = tab[1]

 

А если сохранял несколько, то :

table1 = tab[1]

table2 = tab[2]

table3 = tab[3]

и т.д.

 

И будут тебе твои таблицы в прежнем виде

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

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

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

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

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

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

Войти

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

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

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