[SourcePawn] Урок 0 - Самые, самые основы

Grey83

не пишу плагины с весны 2022
Сообщения
8,555
Реакции
5,035
просто создать define и сэкономить память - я это сделаю
Так память можно сэкономить только если слотов на сервере будет меньше 64. И придётся перекомпиливать все плагины (в том числе и дефолтные из SM).
Ну и раз пошла такая пьянка, то изменять значение дефайна следует в файле инклюдов компилятора SM .../sourcemod/scripting/include/clients.inc
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,921
  • Команда форума
  • #22
Будет разница в производительности, если заменить MaxClients (64) на GetMaxHumanPlayers (игроков 10-20) к примеру у 100-150 плагинов? То есть мы получем выигрыш в итерациях, но большой ли?
Мне кажется, это хороший способ прострелить колено, и не понять сразу, как.
 

Svyatoy

Участник
Сообщения
335
Реакции
137
Так память можно сэкономить только если слотов на сервере будет меньше 64. И придётся перекомпиливать все плагины (в том числе и дефолтные из SM).
Ну и раз пошла такая пьянка, то изменять значение дефайна следует в файле инклюдов компилятора SM .../sourcemod/scripting/include/clients.inc
Об этом речь и шла вроде. А include я бы не стал изменять, так как это всё-таки файл SM. Да и в других случаях это только навредит. Всё-таки я писал в этом сообщении о своём плагине, а не перекомпиляции 150 публичных
GetMaxHumanPlayers (игроков 10-20)
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,555
Реакции
5,035
GetMaxHumanPlayers (игроков 10-20)
Не канает: это просто количество игроков, а не максимальный его индекс.
Экономия памяти с ограничением на количество ячеек массивов с большой вероятностью выльется ещё большей потерей памяти на попытки хранить только игроков на сервере.

Но размер массива можно задать иначе: int[] iArray = new int[MaxClients];
Возможно прокатит и для создания глобальных переменных.
 

Svyatoy

Участник
Сообщения
335
Реакции
137
Но размер массива можно задать иначе: int[] iArray = new int[MaxClients];
Так лучше не объявлять, насколько я знаю - нет никакой преграды выйти за пределы данного массива и взять/записать данные в соседнюю память
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,921
  • Команда форума
  • #26
Давайте лучше подумаем на другую тему.

В ксго даже если сервер запускается с 10 слотами, аллоцируются все 64 энтити (из-за чего MaxClients как раз и равен 64) под игроков. Я могу что-то путать, но по моим наблюдениям это раньше было так.
Я не знаю, как в ксго, а в тф если пять игроков зашло (и заняло пять первых энтити), после один выходит, и заходит ещё один, то он не займёт энтити вышедшего игрока. Он займёт следующую ранее никем не занятую энтити.

Исходя из того, что в ксго аллоцируются все энтити, и если предположить, что выбор свободной энтити в ксго работает так же, как в тф, то вопрос: что произойдёт, если:
  • GetMaxHumanPlayers() возвращает 10 слотов (что правда)
  • Мы создаём массив с размерностью именно 10.
  • Зашло 9 игроков, один вышел, и зашло ещё двое, один из которых получил ид энтити 11
  • Мы пытаемся записать для него что-то в этот массив
?)
 

Svyatoy

Участник
Сообщения
335
Реакции
137
Давайте лучше подумаем на другую тему.

В ксго даже если сервер запускается с 10 слотами, аллоцируются все 64 энтити (из-за чего MaxClients как раз и равен 64) под игроков. Я могу что-то путать, но по моим наблюдениям это раньше было так.
Я не знаю, как в ксго, а в тф если пять игроков зашло (и заняло пять первых энтити), после один выходит, и заходит ещё один, то он не займёт энтити вышедшего игрока. Он займёт следующую ранее никем не занятую энтити.

Исходя из того, что в ксго аллоцируются все энтити, и если предположить, что выбор свободной энтити в ксго работает так же, как в тф, то вопрос: что произойдёт, если:
  • GetMaxHumanPlayers() возвращает 10 слотов (что правда)
  • Мы создаём массив с размерностью именно 10.
  • Зашло 9 игроков, один вышел, и зашло ещё двое, один из которых получил ид энтити 11
  • Мы пытаемся записать для него что-то в этот массив
?)
В CS:GO сейчас так работает:
MaxClients действительно равен слотам, а заходящий игрок занимает первый доступный слот. Т.е. если кто-то вышел под индексом 5 и 3, новый игрок займёт 3, затем 5 и т.д.
 

Temlik

Участник
Сообщения
668
Реакции
174
Или я неправильно выразился или вы меня не поняли.
Есть цикл по игрокам:
C-подобный:
for (int i = 1; i <= MaxClients; i++) // MaxClients = 64
// Если на сервере, например, 2 игрока, то цикл будет впустую крутиться ещё 62 раза
Если получать заранее настоящее максимальное количество игроков, а не использовать константу MaxPlayers:
C-подобный:
int clients = GetMaxHumanPlayers(); // тут уже реальное количество слотов
for (int i = 1; i <= clients; i++)
// крутимся, например, 20 раз
Но, можно ещё упростить жизнь процессору):
C-подобный:
int clients = GetClientCount() // сколько игроков играет на сервере в текущий момент
for (int i = 1; i <= clients; i++)
// если играет 2 человека, то будет только 2 итерации
Сообщения автоматически склеены:

И вопрос в том, есть ли смысл упрощать жизнь процессору путём уменьшения количества итераций в несколько раз. Даст ли это что-то? (Допустим, на сервере стоит плагинов 100-150)
 

Nekro

Терра инкогнита
Сообщения
4,032
Реакции
2,276
Или я неправильно выразился или вы меня не поняли.
Есть цикл по игрокам:
C-подобный:
for (int i = 1; i <= MaxClients; i++) // MaxClients = 64
// Если на сервере, например, 2 игрока, то цикл будет впустую крутиться ещё 62 раза
Если получать заранее настоящее максимальное количество игроков, а не использовать константу MaxPlayers:
C-подобный:
int clients = GetMaxHumanPlayers(); // тут уже реальное количество слотов
for (int i = 1; i <= clients; i++)
// крутимся, например, 20 раз
Но, можно ещё упростить жизнь процессору):
C-подобный:
int clients = GetClientCount() // сколько игроков играет на сервере в текущий момент
for (int i = 1; i <= clients; i++)
// если играет 2 человека, то будет только 2 итерации
Сообщения автоматически склеены:

И вопрос в том, есть ли смысл упрощать жизнь процессору путём уменьшения количества итераций в несколько раз. Даст ли это что-то? (Допустим, на сервере стоит плагинов 100-150)
Два игрока на сервере с индексами 5 и 47, м?
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,555
Реакции
5,035
@Temlik, можно упростить только если сделать так:
C-подобный:
void SomeFunction()
{
    int num;
    int[] clients = new int[GetClientCount()];
    for(int i = 1; i <= MaxClients; i++) if(IsClientInGame(i) && !IsFakeClient(i)) clients[num++] = i;

    while(--num >= 0)
    {
        PrintToChat(clients[num], "LOL");
    }
}
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,921
  • Команда форума
  • #31
@Grey83, а упрощение-то в чём? 🤔
Те же итерации по всем игрокам, с пост-обработкой. По-моему, даже сложнее стало только.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,555
Реакции
5,035
@Kruzya, если нужно отправлять что-то вроде EmitSound(), например.
Вообще это ответ @Temlik на его циклы не по всем игрокам, т.к. он с какого-то перепугу решил, что его улучшения будут работать.
Зашло на сервак 60 человек, потом вышло 58 первых вошедших и остались игроки с индексами ClientID 59 и 60, зато он сделает цикл по индексам 1 и 2 и будет счатслив, что упростил цикл. =)
Сообщения автоматически склеены:

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

Temlik

Участник
Сообщения
668
Реакции
174
Всё, я понял о чём вы. Индексы только после перезахода обновляются. А при выходе одних игроков, у других свои останутся. Тогда от GetClientCount() смысла нет, согласен.
Но с GetMaxHumanPlayers() всё нормально, так как игроков больше не может быть, чем слотов.
И опять задам свой вопрос: есть ли смысл упрощать жизнь процессору путём уменьшения количества итераций в несколько раз. Даст ли это что-то? (Допустим, на сервере стоит плагинов 100-150)
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,921
  • Команда форума
  • #35
GetMaxHumanPlayers() всё нормально
Что-то мне подсказывает, что даже его сломать можно будет.
Зачем пытаться переломать стандарты разработки под сервер, которые строились десятилетиями? Ради освобождения пары тактов процессора, которые выполняются очень быстро и так?
 

Сергей68

Неуместный юмор
Сообщения
420
Реакции
377
@Kruzya, я в свое время писал всякие штуки для GTA, там используется Pawn, вот там действительно была проблема когда слотов 1000, а играет 100 и делать 1000 итераций было максимально глупо.
Куда выгоднее делать 100 итераций чем 1000, но индексы клиентов были динамечески-обновляемые, и то в случаях где нужно было записать индекс клиента, приходилось делать православный фор.
64 итерации это такой мизер, что там выиграешь? больше геморая получишь по итогу, тем более когда индексы статичные.
 

Kruzya

Участник
Сообщения
12,970
Реакции
10,921
  • Команда форума
  • #37
@Сергей68, я об этом сейчас и говорю.
64 и 10 игроков - это не 1000 и 100.

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