Скриптинг курилка

Проблема заключалась в том, что во "вставке" 1 не было ссылки на функцию для второй "вставки".
Reply

Меня плющит, или часть форумов с другими языками пропадают ?
Reply

Quote:
Originally Posted by cm666
View Post
Меня плющит, или часть форумов с другими языками пропадают ?
их закрывают из-за неактивности, скорее всего
Reply

Вроде только ссылку на немецкий форум убрали
Reply

Quote:
Originally Posted by S4D
View Post
Вроде только ссылку на немецкий форум убрали
Убрали почти половину разделов.
Reply

Quote:
Originally Posted by S4D
View Post
Вроде только ссылку на немецкий форум убрали
плюс удалили голландский и французский
Reply

И загрузка клиента вроде как было с 3 сайтов, сейчас 2
Reply

Можно ли как-то определить, что игрок врезался в машину другого игрока?

OnVehicleDamageStatusUpdate вызывается когда машине наносятся только визуальные повреждения.
Reply

Quote:
Originally Posted by cm666
View Post
И загрузка клиента вроде как было с 3 сайтов, сейчас 2
Последняя версия была с двух, точно помню. 0.3z и прошлые было 3.
Reply

Quote:
Originally Posted by Urukhay
View Post
Можно ли как-то определить, что игрок врезался в машину другого игрока?

OnVehicleDamageStatusUpdate вызывается когда машине наносятся только визуальные повреждения.
А разве машина визуально не повреждается, когда врезается в другую? о_0
Reply

Quote:
Originally Posted by Bombo
Посмотреть сообщение
Доброе время суток!

Вопрос у меня такой: в каких версиях удалялись модели из SAMP.img (интересует весь ряд от 0.3c до 0.3.7)
18846 удален в 0.3d RC3-3
19300 - 19307 удалены в 0.3d

Скорее всего, это все
Reply

Для ежесекундных операций с игроками лучше будет для каждого игрока создавать отдельный таймер или один таймер и пробегаться по всем игрокам?
Reply

Quote:
Originally Posted by themakar
Посмотреть сообщение
Для ежесекундных операций с игроками лучше будет для каждого игрока создавать отдельный таймер или один таймер и пробегаться по всем игрокам?
Лучше группами, человек так по 8.
Reply

Quote:
Originally Posted by XemyL
Посмотреть сообщение
Лучше группами, человек так по 8.
Разница ?
Reply

Quote:
Originally Posted by themakar
Посмотреть сообщение
Для ежесекундных операций с игроками лучше будет для каждого игрока создавать отдельный таймер или один таймер и пробегаться по всем игрокам?
У каждого из вариантов как свои плюсы, так и свои минусы.

1 вариант: Цикл
Из плюсов то, что таймер всего один, но есть цикл, присутствие которого уже не есть хорошо, особенно если много слотов. Пробегаться он будет всегда по всем слотам (а если на сервере 1000 слотов, а игроков всего 8 человек? Итераций 1000, а нужно-то всего 8). Конечно можно это обойти через GetPlayerPoolSize или лучше foreach - это сократит количество итераций до минимума в ситуации с 8 игроками, но на полном сервере это уже абсолютно никак не поможет.

2 вариант: Индивидуальный таймер для каждого
В этом случае никакие циклы уже мешать не будут, но, предположим, у нас есть популярный сервер с 1000 игроков онлайн - тут уже выгода от них, по моему, не очень большая. Вызываться они будут с очень частой периодичностью, и лучше ли они цикла в данной ситуации, над этим ещё можно поспорить.
С другой стороны, каждый игрок играет в среднем от 15 до 30 минут например. И для каждого при входе таймер создаётся, при выходе удаляется. Иды таймеров становятся всё больше, и если долго не делать рестарт, то возможно значения идов таймеров могут достигнуть какого-то порога (хотя в этом я не уверен).

Имхо, если на сервере играет мало людей, лучше делать отдельный таймер для каждого, а если сервер забит и людей довольно много, то наверное цикл.
Reply

Обрабатывать частями лучше, соглашусь, но по другим причинам, и не всегда.

Если вам нужно производить какие-то простые задачи каждую секунду (например, уменьшать сытость игроков), лучшим вариантом будет foreach и один цикл в одном таймере. Это проще, а значит, лучше.

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

Представим ситуацию, когда на обработку одного игрока уходит 1мс, игроков на сервере 200, один добавленный таймер отнимает 1мс (не будем говорить о количестве итераций в циклах, это практически не скажется на результатах). Обратите внимание, что цифры я взял для примера, на самом деле они могут быть больше (на обработку игроков) или меньше (таймеры обычно кушают меньше времени).
Если мы используем вариант с одним таймером и циклом по всем игрокам, вот сколько времени это займет в секунду:
200 игроков * 1мс + 1мс на таймер = 201мс работы процессора в секунду (грубо говоря, 20.1%)
А если будем давать каждому игроку отдельный таймер:
200 игроков * 1мс + 200 игроков * 1мс на таймер = 400мс процессорного времени в секунду (также грубо говоря 40%) (это НЕ значит, что вариант у 2 раза медленнее, так как числа взяты для примера)

Теперь рассмотрим с другой стороны все это.

В первом варианте сервер будет "висеть" 201мс до тех пор, пока все игроки не будут обработаны, и в это время больше ничего обрабатываться не будет. Грубо говоря, это самый натуральный лаг на 0.2 секунды каждую секунду (и, если не ошибаюсь, такие операции дурно сказываются на точности таймеров сервера). На многопользовательском игровом сервере типа SA-MP я бы это считал недопустимым. Например потому, что параллельно может работать второй таймер с интервалом в 300мс, и из-за первого таймера его интервал будет "прыгать" между 300 и 500+ (это я тоже для примера, но такое возможно).

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

Третий вариант с обработкой игроков небольшими пачками в этом случае подойдет лучше (имхо), и я объясню, почему, на примере.
Допустим, обработка одного игрока все так же требует 1мс, таймер кушает 1мс, и вызывается это все раз в секунду для 200 игроков. Также предположим, что на сервере 300 слотов.
Создадим 1 таймер с интервалом запуска в 200мс, в отдельной переменной будем хранить текущий "указатель" на слот игрока. Функция, которая будет вызываться в таймере, будет обрабатывать следующих 60 игроков после указателя, либо начинать остчет с 0, если прошлась по всем игрокам, и каждый раз сохранять указатель.
Таким образом, функция будет вызвана примерно 5 раз в секунду для 60 слотов - в идеале, 300 слотов в секунду, при этом
В секунду будет потреблять (в идеале) 5 вызовов * ( 60 слотов * 1мс на слот (или меньше, если игрок оффлайн) ) + 1мс на таймер = 301мс (в случае прямого перебора всех слотов, т.е. не самый оптимизированный вариант), но со стороны это будет что-то вроде [60мс работает] [140мс делает что-то другое] [60мс работает] [140мс делает что-то другое]...
Как видно, "время лагания" по сравнению с 1 вариантом (200мс) больше чем у 3 раза короче, а значит, лаги менее заметны и нагрузка лучше распределена.

Чтобы еще больше уменьшить лаги, можно сделать интервал меньше - например, 50мс (15 игроков за раз) будут вызывать практически незаметные лаги длительностью 15мс (+время на более частый вызов функции) и почти равномерно распределять нагрузку, но не стоит забывать, что вызов функции и запуск цикла тоже потребляют процессорное время - нужно найти золотую средину.

Касательно того, как в третьем варианте не обрабатывать ненужные слоты (в случае с онлайном 200/300 речь идет о последних 100 слотах, 200-299).
В простом подходе с прямым перебором слотов будет тратиться лишнее время на проверку пустых слотов и циклы, что тоже не есть хорошо. Навскидку я бы предложил решить эту проблему ценой оперативной памяти:
1. Создать глобально массив из n итераторов (не помню, как правильно, в общем iterable из foreach), где n - количество "пачек" игроков (при n=10 мы будем вызывать функцию в цикле с интервалом в 100мс, 10 раз в секунду, при 20 - с интервалом в 50мс)
2. Равномерно распихивать игроков по всем итераторам при входе на сервер (особо не скажется на производительности, так как выполняется единожды)
3. В обработчике, который запускается таймером каждых 1/n секунд, по очереди брать следующий итератор из массива и обрабатывать находящихся там игроков.
4. При выходе игрока из сервера, убирать его ID из итератора.

Я не проверял, что писал, поэтому дико извиняюсь, если есть ошибки или перепутал что, но идею старался объяснить. Если у вас есть подходы получше - с удовольствием послушаю
Reply

Сколько игроков должно быть в стриме игрока(ов), чтобы сервер/клиент начал "лагать"?
И может ли быть такое, что 1000 игроков находятся в одной точке, и сервер ни чуть ни "лагает"?
Reply

Quote:
Originally Posted by Urukhay
Посмотреть сообщение
Сколько игроков должно быть в стриме игрока(ов), чтобы сервер/клиент начал "лагать"?
И может ли быть такое, что 1000 игроков находятся в одной точке, и сервер ни чуть ни "лагает"?
Тут, наверное, от пропускной способности канала больше зависит
Reply

Quote:
Originally Posted by prineside
Посмотреть сообщение
Обрабатывать частями лучше, соглашусь, но по другим причинам, и не всегда.

Если вам нужно производить какие-то простые задачи каждую секунду (например, уменьшать сытость игроков), лучшим вариантом будет foreach и один цикл в одном таймере. Это проще, а значит, лучше.

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

Представим ситуацию, когда на обработку одного игрока уходит 1мс, игроков на сервере 200, один добавленный таймер отнимает 1мс (не будем говорить о количестве итераций в циклах, это практически не скажется на результатах). Обратите внимание, что цифры я взял для примера, на самом деле они могут быть больше (на обработку игроков) или меньше (таймеры обычно кушают меньше времени).
Если мы используем вариант с одним таймером и циклом по всем игрокам, вот сколько времени это займет в секунду:
200 игроков * 1мс + 1мс на таймер = 201мс работы процессора в секунду (грубо говоря, 20.1%)
А если будем давать каждому игроку отдельный таймер:
200 игроков * 1мс + 200 игроков * 1мс на таймер = 400мс процессорного времени в секунду (также грубо говоря 40%) (это НЕ значит, что вариант у 2 раза медленнее, так как числа взяты для примера)

Теперь рассмотрим с другой стороны все это.

В первом варианте сервер будет "висеть" 201мс до тех пор, пока все игроки не будут обработаны, и в это время больше ничего обрабатываться не будет. Грубо говоря, это самый натуральный лаг на 0.2 секунды каждую секунду (и, если не ошибаюсь, такие операции дурно сказываются на точности таймеров сервера). На многопользовательском игровом сервере типа SA-MP я бы это считал недопустимым. Например потому, что параллельно может работать второй таймер с интервалом в 300мс, и из-за первого таймера его интервал будет "прыгать" между 300 и 500+ (это я тоже для примера, но такое возможно).

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

Третий вариант с обработкой игроков небольшими пачками в этом случае подойдет лучше (имхо), и я объясню, почему, на примере.
Допустим, обработка одного игрока все так же требует 1мс, таймер кушает 1мс, и вызывается это все раз в секунду для 200 игроков. Также предположим, что на сервере 300 слотов.
Создадим 1 таймер с интервалом запуска в 200мс, в отдельной переменной будем хранить текущий "указатель" на слот игрока. Функция, которая будет вызываться в таймере, будет обрабатывать следующих 60 игроков после указателя, либо начинать остчет с 0, если прошлась по всем игрокам, и каждый раз сохранять указатель.
Таким образом, функция будет вызвана примерно 5 раз в секунду для 60 слотов - в идеале, 300 слотов в секунду, при этом
В секунду будет потреблять (в идеале) 5 вызовов * ( 60 слотов * 1мс на слот (или меньше, если игрок оффлайн) ) + 1мс на таймер = 301мс (в случае прямого перебора всех слотов, т.е. не самый оптимизированный вариант), но со стороны это будет что-то вроде [60мс работает] [140мс делает что-то другое] [60мс работает] [140мс делает что-то другое]...
Как видно, "время лагания" по сравнению с 1 вариантом (200мс) больше чем у 3 раза короче, а значит, лаги менее заметны и нагрузка лучше распределена.

Чтобы еще больше уменьшить лаги, можно сделать интервал меньше - например, 50мс (15 игроков за раз) будут вызывать практически незаметные лаги длительностью 15мс (+время на более частый вызов функции) и почти равномерно распределять нагрузку, но не стоит забывать, что вызов функции и запуск цикла тоже потребляют процессорное время - нужно найти золотую средину.

Касательно того, как в третьем варианте не обрабатывать ненужные слоты (в случае с онлайном 200/300 речь идет о последних 100 слотах, 200-299).
В простом подходе с прямым перебором слотов будет тратиться лишнее время на проверку пустых слотов и циклы, что тоже не есть хорошо. Навскидку я бы предложил решить эту проблему ценой оперативной памяти:
1. Создать глобально массив из n итераторов (не помню, как правильно, в общем iterable из foreach), где n - количество "пачек" игроков (при n=10 мы будем вызывать функцию в цикле с интервалом в 100мс, 10 раз в секунду, при 20 - с интервалом в 50мс)
2. Равномерно распихивать игроков по всем итераторам при входе на сервер (особо не скажется на производительности, так как выполняется единожды)
3. В обработчике, который запускается таймером каждых 1/n секунд, по очереди брать следующий итератор из массива и обрабатывать находящихся там игроков.
4. При выходе игрока из сервера, убирать его ID из итератора.

Я не проверял, что писал, поэтому дико извиняюсь, если есть ошибки или перепутал что, но идею старался объяснить. Если у вас есть подходы получше - с удовольствием послушаю
Спасибо за такую большую расстыковку, буду использовать один таймер и foreach.
Reply

Такое вопрос:
Если лимит TD для игрока 256, а я хочу использовать гораздо больше в будущем, сейчас пока около 100, тестировал только с одним игроком онлайн.

Я создаю их только тогда когда они используется, и удаляю когда не используются.
Например инвентарь, игрок открыл инвентарь я создаю 80 TD и показываю их игроку, игрок закрывает инвентарь TD удаляются.

Будет ли такой алгоритм постепенно отнимать память и нагружать систему?
Reply


Forum Jump:


Users browsing this thread: 10 Guest(s)