Войти
ПроектыФорумСобираю команду

Делаем убийцу Diablo 1, нужен геймдизайнер (24 стр)

Страницы: 123 24 25 2674 Следующая »
#345
15:08, 15 июня 2022

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

#346
17:25, 15 июня 2022

Каждый день отслеживаю тему. Все на месте. Не переживайте.

#347
(Правка: 2:57) 2:57, 16 июня 2022

Рассказываю что там с проектом: у меня медведь бегает, бьет лапой троллей, тролли умирают и из них выпадает золото, которое медведь собирает. Умершие тролли воскресают через 30 секунд, снова приходят к медведю и убивают его. Из медведя выпадает золото. И через 30 секунд он воскресает. Вокруг растут деревья и кусты, которые становятся прозрачными если медведь подходит к ним сзади. Посреди уровня стоит ванна с дедом, играющие роль алтаря. И вот на этом месте начинается интересное.
Нужно сделать интерфейс прокачки у алтаря, и саму прокачку, однако делать ее надо по-разному для сингл-плеерной игры и для мморпг, потому что в мморпг прокачка должна происходить на сервере, а на клиенте должен только показываться интерфейс. И тут мы переходим к самому интересному: я придумал прикольную структуру данных, которую хочу использовать для хранения и передачи по сети состояний всего что может менять состояние в игре. Уверен, всем вам не терпится узнать подробности, поэтому расскажу в деталях, как все это будет устроено таким образом что на каждом сервере можно было обслуживать тысячи игроков.
Есть большой массив со всеми персонажами и активными монстрами, размер его заранее выбирается достаточно большим, чтобы не требовалось реаллокаций. В каждой ячейке кроме позиции и параметров персонажа хранится уникальный идентификатор персонажа, получаемый путем инкремента 64-битного счетчика при каждом создании нового персонажа. На персонажей таким образом можно хранить указатели, которые всегда указывают на валидную память в которой лежит либо тот самый персонаж на которого указатель указывал изначально, либо какой-то другой, который поместили в ту же ячейку после смерти старого. Для валидации указателей вместе с ними нужно хранить значение уникального идентификатора, если оно совпадает, персонаж точно тот самый, а если не совпадает - указатель протух. Для передачи по сети для каждого клиента заводится исходящий буфер, очередь отправки и массив битиков обозначающих присутствие в очереди соответствующего персонажа. Очередь организуется как циклический буфер достаточного размера чтобы туда уместились указатели на всех персонажей.
При изменении состояния персонажа, для каждого клиента проделываются следующие действия: в массиве битиков выставляется (если еще не была выставлена) единичка для этого персонажа. Если до этого там был нолик, то указатель на этого персонажа добавляется в очередь на отправку. Раз в кадр, если в буфере клиента есть свободное место, буфер заполняется данными о состоянии персонажей в порядке появления в очереди на отправку, и содержимое буфера отправляется по сети клиенту. Таким образом при быстром изменении состояния одного персонажа, клиент с медленной сетью получает не последовательность состояний, а только одно свежее состояние.
Очевидное преимущество такой системы в том, что в ходе работы не происходит ни одной аллокации или деаллокации, память не фрагментируется, обход памяти происходит в основном последовательно. Очевидные дальнейшие оптимизации: не ставить в очередь на отправку далекие и невидимые клиенту персонажи, не передавать мгновенные координаты, а использовать координаты начала и конца и моментах начала и конца движения, так что состояние начавшего двигаться из точки А в точку Б персонажа достаточно передать 1 раз, после чего персонаж на сервере и у всех клиентов будет двигаться синхронно до точки Б, где он и остановится. Часто кликающих туда-сюда игроков и ИИ можно затроттлить, чтобы персонажи не меняли текущее действие чаще чем 4 раза в секунду. Если мгновенное состояние персонажа состоит из набора типа «текущее состояние, х1, у1, т1, х2, у2, т2, уникальный идентификатор, индекс», то размер этого состояния выйдет порядка 50 байт. Это означает, что 100 мегабитный канал сервера (100/8 = 12.5) позволит передавать состояние 12500000/50 = 250000 персонажей в секунду. При рейте 4 состояния в секунду, это 250000/4=62500 персонажей. То есть можно передавать каждому клиентов состояние всех остальных если клиентов не более sqrt(62500) = 250, а значит при менее 250 клиентов на 1 сервере можно вообще не переживать. А если реалистично смотреть на вещи, одновременно на экране будет например 20 персонажей, так что сервер выдержит 62500/20=3125 клиентов с 4 кликами в секунду, или 12500 c 1 кликом в секунду.
Стоимость аренды сервера с безлимитным 100 мегабитным подключением 37.95 в месяц, а 37.95/12500= 0.003 доллара или менее 20 копеек в месяц с клиента по текущему курсу. Если продавать игру игрокам по 1200 рублей, часть денег положить в банк и проценты использовать для оплаты серверов, то процентов должно выходить 20*12=*240 копеек, и если класть под 1% годовых, класть надо 240 рублей, а остальные 1200-240=960 рублей можно использовать для покупки машины, квартиры, яхты и личного самолета.

#348
(Правка: 3:22) 3:22, 16 июня 2022

То есть проще говоря обновляется только то что обновляется?

#349
(Правка: 3:44) 3:44, 16 июня 2022

FourGen
И только на свежую версию, старые версии не забивают очередь и сеть. И при этом все высокоэффективно.

#350
3:57, 16 июня 2022

Круто!

#351
12:33, 16 июня 2022

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

Вий
> Нужно сделать интерфейс прокачки у алтаря, и саму прокачку, однако делать ее
> надо по-разному для сингл-плеерной игры и для мморпг, потому что в мморпг
> прокачка должна происходить на сервере, а на клиенте должен только показываться
> интерфейс.
Т.е. делая передвижение, мобов, боевку, тебя ни чего не натолкнуло на мысль, что это все нужно делать по разному для сингла и мультиплеера, а вот создание интерфейса и прокачка натолкнули?

Вий
> В каждой ячейке кроме позиции и параметров персонажа хранится уникальный
> идентификатор персонажа, получаемый путем инкремента 64-битного счетчика при
> каждом создании нового персонажа. На персонажей таким образом можно хранить
> указатели, которые всегда указывают на валидную память в которой лежит либо тот
> самый персонаж на которого указатель указывал изначально, либо какой-то другой,
> который поместили в ту же ячейку после смерти старого. Для валидации указателей
> вместе с ними нужно хранить значение уникального идентификатора, если оно
> совпадает, персонаж точно тот самый, а если не совпадает - указатель протух.
...
> «текущее состояние, х1, у1, т1, х2, у2, т2, уникальный идентификатор, индекс»
Т.е. для валидации уникального идентификатора, нам нужен еще один уникальный идентификатор - серьезно? Допустим... а не проще клиенту оставить только один ID, а этот менеджмент пар уникальных идентификаторов вести на стороне сервера, а не гонять по сети?

Вий
> При изменении состояния персонажа, для каждого клиента проделываются следующие
> действия: в массиве битиков выставляется (если еще не была выставлена) единичка
> для этого персонажа. Если до этого там был нолик, то указатель на этого
> персонажа добавляется в очередь на отправку. Раз в кадр, если в буфере клиента
> есть свободное место, буфер заполняется данными о состоянии персонажей в
> порядке появления в очереди на отправку, и содержимое буфера отправляется по
> сети клиенту. Таким образом при быстром изменении состояния одного персонажа,
> клиент с медленной сетью получает не последовательность состояний, а только
> одно свежее состояние.
Вопрос, а кто в твоей схеме инициирует передачу данных? Если сервер, то не понятно почему клиент с медленным интернетом получит только свежие состояние? А если клиент ходит сам за данными, то это очень странная схема. Как будут разделяться значения которые гарантированно должны передаваться, от тех где важно только актуальное состояние?
Например смерть и применения заклинания должна гарантированно передаться, иначе у других клиентов это будет выглядеть так: другой игрок просто ходит по карте, а мобы, что вокруг него начинают идти на свой респаун, ну или просто остаются на месте.


Вий
> Очевидное преимущество такой системы в том, что в ходе работы не происходит ни
> одной аллокации или деаллокации, память не фрагментируется, обход памяти
> происходит в основном последовательно. Очевидные дальнейшие оптимизации: не
> ставить в очередь на отправку далекие и невидимые клиенту персонажи, не
> передавать мгновенные координаты, а использовать координаты начала и конца и
> моментах начала и конца движения, так что состояние начавшего двигаться из
> точки А в точку Б персонажа достаточно передать 1 раз, после чего персонаж на
> сервере и у всех клиентов будет двигаться синхронно до точки Б, где он и
> остановится. Часто кликающих туда-сюда игроков и ИИ можно затроттлить, чтобы
> персонажи не меняли текущее действие чаще чем 4 раза в секунду.
Диаблойд - это не шахматы, подобная реализация приведет к телепортациям и рассинхронам. И кста зачем тебе с таким подходом передавать точку "А"? - ведь эта информация и так есть у клиента.

Вий
> 100 мегабитный канал сервера (100/8 = 12.5) позволит передавать состояние
> 12500000/50 = 250000 персонажей в секунду. При рейте 4 состояния в секунду, это
> 250000/4=62500 персонажей. То есть можно передавать каждому клиентов состояние
> всех остальных если клиентов не более sqrt(62500) = 250, а значит при менее 250
> клиентов на 1 сервере можно вообще не переживать. А если реалистично смотреть
> на вещи, одновременно на экране будет например 20 персонажей, так что сервер
> выдержит 62500/20=3125 клиентов с 4 кликами в секунду, или 12500 c 1 кликом в
> секунду.

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

Вий
> Стоимость аренды сервера с безлимитным 100 мегабитным подключением 37.95 в
> месяц, а 37.95/12500= 0.003 доллара или менее 20 копеек в месяц с клиента по
> текущему курсу. Если продавать игру игрокам по 1200 рублей, часть денег
> положить в банк и проценты использовать для оплаты серверов, то процентов
> должно выходить 20*12=*240 копеек, и если класть под 1% годовых, класть надо
> 240 рублей, а остальные 1200-240=960 рублей можно использовать для покупки
> машины, квартиры, яхты и личного самолета.
Планирование бюджета от бога. Т.е. ты не задаешься вопросом, как привлечь 12500 клиентов, которые согласились бы купить твое поделие по 1200р. А размышляешь, как положить вырученные деньги в банк? Мне кажется ты *делишь шкуру не убитого медведя*  ;-)


Почему на форуме по созданию игр, на полном серьезе ведется подобная тема? Тут есть люди которые действительно понимают, как разрабатываются игры?

#352
(Правка: 16:14) 16:08, 16 июня 2022

Вий
> Для валидации указателей вместе с ними нужно хранить значение уникального
> идентификатора
можно обойтись индексом в массиве, причем коротким, т.к. вряд-ли единомоментно будет 64k героев/мобов и номером поколения, как это делается в расхожих ECS

по сети напрашивается отправка дельт к последним подтвержденным состояниям

50 байт на юнит это очень много, в один пакет под завязку (MТU)  влезет всего 30 героемобов

#353
(Правка: 19:45) 17:20, 16 июня 2022

#!
Я хочу делать open world mmo, поэтому лучше считать что на сервере мобов может быть много, пусть большинство из них спит в любой момент времени, но я не хочу их туда-сюда подгружать. Индекс вместо указателя это очевидно хорошо, можно использовать 24 или 32 битные индексы. Теоретически поколение в 8 бит более чем достаточно для заявленных нужд, это тоже очевидная оптимизация, можно дополнительно ужать данные о персонаже, выйдет не 50 а скажем 38 байт. Можно и координаты пожать и метки времени, но это не так важно на текущем этапе, пока игроков меньше 250, важно что в целом схема позволит сделать крайне производительный сервер.

Отправка дельт к подтверждённым данным требует хранения копии последнего подтверждённого состояния для каждого клиента, это загрузит CPU и память на сервере освободив сеть. У меня сейчас есть  крошечная виртуалка и там меньше гигабайта памяти, так что ее надо экономить

#354
(Правка: 21:11) 20:33, 16 июня 2022

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


GGMaster
> а не проще клиенту оставить только один ID, а этот менеджмент пар уникальных
> идентификаторов вести на стороне сервера, а не гонять по сети?

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

GGMaster
> а кто в твоей схеме инициирует передачу данных? Если сервер, то не понятно
> почему клиент с медленным интернетом получит только свежие состояние?
В моей схеме связь полнодуплексная и при этом по tcp. Сервер перестаёт слать клиенту данные если отправлено и ещё не доставлено больше заданного объема. Для клиента с медленным интернетом это означает, что сервер никогда не будет отправлять ему одним махом например десять мегабайт данных, которые будут долго и нудно передаваться пока игрок смотрит на заставший кадр. Игрок будет видеть как все вокруг постепенно обновляется, при этом достаточно легко приоритезировать отправку важных данных: про персонаж самого игрока, про те кто его атакует, про тех кого он атакует, про тех кто ближе всего. Это же поможет и при внезапном наплыве игроков и перегрузке сети на сервере.

GGMaster
> Диаблойд - это не шахматы, подобная реализация приведет к телепортациям и
> рассинхронам.
Телепортации могут возникать только если сетевое соединение совсем плохое, и в этом случае ничего лучше сделать невозможно. А рассинхроны возникать вообще не могут, потому что у игрока по сути просто проигрыватель мультика про персонажей передающий команды на сервер. Когда сеть лагает, мультик становится менее качественным, но в целом отображает суть происходящего достаточно точно для того, чтобы игрок мог продолжать слать осмысленные команды

Точку А надо слать для того, чтобы не было нужно следить, какие состояния какому клиенту были отправлены. Пример: персонаж П идёт из точки А в точку Б, это все далеко от персонажа Х, поэтому управляющему персонажем Х клиенту не надо передавать состояние персонажа П. Персонаж Х подходит ближе и сервер решает что состояние нужно передать. Он передаёт его, там записано откуда и куда идёт персонаж и в какие моменты времени движение начато и закончится. Этого достаточно чтобы клиент Х рисовал персонажа П на протяжении всего шествия в правильной позиции. При этом для клиента П не нужно готовить специальный набор данных о персонаже П, ему подходит точно такой же набор, как и любому другому клиенту. Это позволяет очень хорошо оптимизировать сервер.

Вообще оптимизаций можно сделать много разных: игрок видит вокруг персонажа не более 1000 пикселов в любую сторону, значит и идти персонажи дальше чем на 1000 по каждой оси не могут, это позволяет ужать координаты точки назначения в 22 бита. Если текущее время превышает время прибытия, слать второй набор координат и вовсе незачем. Время можно измерять в тиках, тогда 12 бит позволит описать 2 минутных эпохи, начинавшуюся и заканчивающуюся, тоже экономия. В общем шикарная схема. Если знаете лучше - присылайте ссылки на описание.

#355
21:26, 16 июня 2022

Вий
// для мморпг
Пусть в сингловой игре, игроки как хотят используют оборудование.
Но в мультип-плэер, надо внести глоб-откат на любое действие, которое
пойдёт в эфир (полетит на сервер). Например, 1 секунда такого глоб-отката.

Игрок нервно кликает в ярлык абилки, которая сейчас в откате.
Каждую секунду, один из трёх кликов проходит через глоб-откат в 1 секунду,
но натыкается на локальную проверку, что абилка в откате - ничего серверу не посылает.

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

#356
22:01, 16 июня 2022

// По мотивам видео-ролика

Игрок подходит к купцу квэсто-дателю, и тот делает генерацию задания..
1. кинул монетку (убить или собрать).
2. выбрал банку от результата монетки, и одну запись из нужной банки.
Банка с названиями монстров под генераторные квэсты.
Банка с названиями дропа и кустов под генераторные квэсты.

3. Учитывая ранг просителя квэста, выбирай пресет-офсет количества,
и добавляй рулетку, учитывая офсет следушего количества.
Для маленьких (от 5 до 10)., для средних (от 11 до 20).,
для большых рангов (от 21 до 40)., для каповых персов (от 50 до 90).
// награда будет примерно такая - маленьким мало - крутышам - большэ.
// Например, некая спец-валюта за генер-квэсты - за неё можно купить
// какие-то расходники.
Место не указываем - игрок сам разведает где такие мобы тусуют.
(из каких монстров выпадает нужный мусор).


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

3. Можно обойтись без этого, но название купца или саб-локации можт
указывать на ячейку с лимитом времени - админы разок пробежали до
каждого, прибавили 3 минуты, и поставили это число - если ты не смог
добежать за это время - значит, тебе не повезло - квэст провален,
завтра снова будет возможность поболтать с этим квэсто-дателем.

#357
22:10, 16 июня 2022

Блин, забыл главную деталь про квэст _принеси.
Там герою сразу выдают невидимый кирпич-в-газете.

Тоесть, искомый предмет сразу найден, и лежыт в разделе квэстовых предметов,
куда игрок не можт класть свои предметы (и не можт выкидывать).

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

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

#358
0:16, 17 июня 2022

slatazan
> хакнутый клиент будет засирать частыми весточками,
> и если такое происходит - надо авто-бан клиенту на пару часов назначать.
Если клиент шлёт менее Порогового значения кб/с трафика, то никаких санкций к нему применять потребности нет. Если шлёт больше, то нужно рвать соединение и блекхолить.

#359
8:35, 17 июня 2022

О-хо-хох...

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

Вий
> Это ломает всю идею синхронизации только свежего состояния. Клиент может
> пропустить смерть и спавн персонажа, но обязательно различит старого и нового,
> хотя у них и совпадает адрес в памяти сервера. Это свойство позволит избежать
> массы глюков.
Все еще не вижу нужды гонять оба значения по сети. *ID* жестко привязан к игроку, а *Адрес в памяти* нет. Веди на стороне сервера маппинг. Если адрес по каким-то причинам занимает кто-то другой, а это происходит не случайно, то зануляй его для прошлого владельца.
Зачем все гонять по сети?

Вий
> В моей схеме связь полнодуплексная и при этом по tcp. Сервер перестаёт слать
> клиенту данные если отправлено и ещё не доставлено больше заданного объема. Для
> клиента с медленным интернетом это означает, что сервер никогда не будет
> отправлять ему одним махом например десять мегабайт данных, которые будут долго
> и нудно передаваться пока игрок смотрит на заставший кадр. Игрок будет видеть
> как все вокруг постепенно обновляется, при этом достаточно легко
> приоритезировать отправку важных данных: про персонаж самого игрока, про те кто
> его атакует, про тех кого он атакует, про тех кто ближе всего. Это же поможет и
> при внезапном наплыве игроков и перегрузке сети на сервере.
Ты просто на фундаментальном уровне не понимаешь, как подходить к проектированию игрового сервера. Ни кто и ни когда не отправляет *махом по 10 мб* пока игрок смотрит на застывший экран. Разделаются данные на требующие гарантированную доставки и на потоковые данные в которых важна актуальность, что бы у игрока не терялась причинно следственная связь.
А ты планируешь делать отдельные слепки мира лешая игрока всего того, что произойдет между ними.

Вий
> Телепортации могут возникать только если сетевое соединение совсем плохое, и в
> этом случае ничего лучше сделать невозможно. А рассинхроны возникать вообще не
> могут, потому что у игрока по сути просто проигрыватель мультика про персонажей
> передающий команды на сервер.
Телепортацию и рассинхрон ты закладываешь на уровне логики. Потому они гарантированно будут.
Давай нарисую пример, мб станет понятнее (Пояснение ниже):
net | Делаем убийцу Diablo 1, нужен геймдизайнер
Верхний ряд кадров - то как видит игру Игрок0, который управляет персонажем(зеленый круг)
Нижний ряд кадров - то как видит игру Игрок1 наблюдая за персонажем Игрок0
Кадр 1:
- Игрок0 - задает путь A-B
- Игрок1 - пока не получил обновленных данных
Кадр 2:
- Игрок0 - На половине пути решил изменить направление. Создав новый путь A1-B1
- Игрок1 - Игрок0 получил путь A-B
Кадр 3:
- Игрок0 - Двигается по пути A1-B1
- Игрок1 - Двигается по пути A0-B0
Кадр 4:
- Игрок0 - Завершил путь A1-B1
- Игрок1 - Завершил путь A0-B0 *РАССИНХРОН*. Получил новые данные о пути A1-B1
Кадр 4:
- Игрок0 - Стоит в точки B1
- Игрок1 - Скорректировал положение Игрок0 перенеся его в точку B1 *ТЕЛЕПОРТ*

Страницы: 123 24 25 2674 Следующая »
ПроектыФорумСобираю команду