Навскидку могу сказать, что вероятно, будучи обеспеченный мощной системой поиска пути, которая независит от нодов, расставленных дизайнером (или же наоборот - не расставленных\расставленных неверно),
AI должен заработать лучше чем в халфе.
Правда мне сперва надо будет подружить эти две системы. К примеру в той же халфе монстр хранит всего-навсего 8 ближайших точек маршрута, причём расстояние между точками может быть произвольным. Очевидно это не ложится на мою систему, которая просто заспамит этот путь коротеньким отрезком, юнитов на 128, не больше.
Возможно надо будет сделать повторную симплификацию пути, вернув только ключевые точки маршрута.
Ссылка на цикл статей. Это от авторов имплементации в Order 1884.
Наверное это заверщающая техника, которая меня интерисовала в лайтмаппинге. Всё остальное я там в принципе уже попробовал и реализовал.
Ну чтоже, вот мы с вами потихоньку и добрались к очередному моменту принятия решений. Напомню вам как долго и мучительно я создавал свою систему материалов, размышляя над ней почти четыре года. Но в итоге создал и остался доволен. Следующая задачка попроще, но тоже ответственная. Поскольку я портирую ксаш-мод на XashNT, естественным образом появилась потребность в говорящих монстрах и сентенциях.
Новому ксашу достался звуковой движок в наследство от старого, это единственная вещь, которую я вообще не трогал с 2019-го года. Единственное что сделал - это поддержку ogg-формата.
Ну вот теперь пришла пора его отрефакторить. Сам рефакторинг видится мне довольно прозрачным, особых вопросов не вызывает.
Но надо определиться с системой описания звуковых материалов.
Да, звуки - это не рендеринг, они больше зависят от окружения, то есть какой-то фундаментальной привязки к текстовым настройкам тут как правило нет. Но тем не менее, какая-то система должна быть.
И вот вопрос - какая?
Добавлено 03-02-2025 в 00:05:
Поизучал уже существующие решения по быстрому и минимальное понимание появилось. В Doom3, как вы знаете, были так называемые звуковые шейдеры - по аналогии с обычными, где указаны текстуры.
Скорее всего их реализовали просто для консистенции. Потому что эта конструкция настолько надуманная и неудобная, что они даже толком параметры для нее придумать не смогли.
Звук в игре - это такая штука, которая привязана к конкретной точке.
А точка может перемещаться. И звук должен перемещаться вместе с ней.
Это поведение по умолчанию и не существует ситуации, когда бы нам потребовалось его изменить. Либо звук стоит на месте, либо движется вместе с объектом. Два варианта. Очевидно никакие материалы для описания этого не нужны.
Пойдем дальше. Так-то какие-то скрипты для звуков нужны, безусловно, но как вы знаете, тот простейший набор параметров, предложенный ещё Кармаком в ку1, в подавляющем большинстве случаев оказался достаточным.
Вспомним что там у нас было?
Канал - номер канала. Ну тут понятно, либо чтобы затереть один звук другим, либо чтобы проиграть несколько звуков вместе.
Затухание - дистанция до звука, на которой его ещё будет слышно. В принципе там есть три константы. Амбиентный звук, откуда-то издалека. Рычание монстров и типичное затухание, разговор или перестрелка.
Громкость - тут требуется пояснение. В норме этим параметром никто не пользуется. Его используют если попался слишком громкий звук, а под рукой нет редактора, чтобы нормализовать. Обратите внимание, что если звук слишком тихий, то вам этот параметр никак не поможет, он в норме стоит на максимуме. Valve добавила в этот набор ещё один параметр - pitch. Стало возможным динамически менять тон проигрываемого звука.
Используется в двух случаях - либо для иммитации раскрутки\останова func_rotating, либо для разнообразия голосов монстров. Хотя для голосов наверное параметров могло бы быть и поболее. Но не суть.
При портировании ксаш-мода на HeadShot я для удобства завернул функцию проигрывания звука прямо в базовый класс энтити и назначил аргументам дефолтные параметры
C++ Source Code:
void EmitSound( int channel, const string sample, float volume = VOL_NORM, float attn = ATTN_NORM, int pitch = PITCH_NORM );
Вот примерно так. То есть канал используется регулярно, чтобы звуки друг-друга не перезатирали или наоборот - перезатирали. Путь к звуку, естественно тоже. А всё остальное стоит по дефолту, оно особо и не нужно. Ну для монстров будет рандом-питч. Возможно ещё для выстрелов.
Теперь вопрос - где и главное зачем в такой стройной системе ещё и какие-то там текстовые скрипты и описания материалов? Правильно, они тут и не нужны.
Добавлено 03-02-2025 в 00:17:
Несмотря на то, что я не занимался звуковым движком, у меня тем не менее уже имеется скриптовое описание звуковых файлов. Но это вещь, которая опять же не имеет отношения к звуковым материалам.
То что у меня есть на данный момент реализовано в виде пресловутой поименованной секции фигурных скобок, такого плана
C++ Source Code:
1
soundDef "tele_sound"
2
{
3
sound "misc/r_tele1.wav"
4
sound "misc/r_tele2.wav"
5
sound "misc/r_tele3.wav"
6
sound "misc/r_tele4.wav"
7
sound "misc/r_tele5.wav"
8
volume "1.0"
9
channel "voice"
10
attenuation "0.8"
11
pitch "100"
12
}
Что мы здесь видим? Несколько подряд объявленных звуков (значит будет рандомный выбор между ними), громкость, канал, затухание, питч.
То есть ровно тот же набор параметров, о котором я писал выше при вызове функции PlaySound. Но вы меня спросите, как и зачем он здесь оказался? Отвечаю - это механизм для воспроизведения эффектов.
Эффекты в новом ксаше, это нечто вроде темпэнтитей. На данный момент он умеет вызывать две функции: ParticleEffect и PlaySound.
Первый понятно - там параметры партиклей. Эффект телепорта, эффект взрыва, возможно даже луч из партиклей или эффект funnel (когда партиклы затягиваются в одну точку). В принципе партиклям можно назначать анимированные текстуры, то есть они по сути превращаются в спрайты и получается полноценная замена темп-энтитям.
Ну а звуки нужны для звукового сопровождения этих эффектов, естественно. Разумеется я мог бы не делать никаких описаний скриптовых звуков, но рассудил, что так будет удобнее для всех. Таким образом программист из игрового кода вызывает функцию PlayEffect с определённым именем, та в свою очередь вызывает например вот такой скрипт
C++ Source Code:
1
TE_TELEPORT
2
{
3
ParticleEffect( "tele_splash" );
4
PlaySound( "tele_sound" );
5
}
Который создаёт кубик из партиклей, разлетающихся во все стороны и проигрывает звук из вышеприведённой секции. Очевидно что никаким звуковым материалом подобное назвать нельзя. Просто эффект, событие.
Но как видите - нам подобного функционала за глаза. И что особенно важно - эти параметры звука одинаково актуальны как для клиента, так и для сервера. То есть разницы нет. Отметим этот момент.
Ну или что нить в духе: sound "misc/r_tele[].wav" ?
__________________
У котёнка мокрый нос и гладенькая шерсть, у него забавный хвост и быстрых лапок шесть. Две задних, две средних и две передних лапы, такая многоножка получилася у папы.
Он ученый — папа мой — зверушек изучает, гуляет по помойкам, ловит крыс и чаек. Две крысы белокрылые и чайки две унылые покрытые пупырчатою кожей лягушат без пёрышек тоскуют и ускакать спешат.
А ещё есть муравей большой размером с гуся он пугает всех зверей, и я его боюся, когда он ковыляет на лапках на своих.
И в двери ударяет, и начинает стих: Я — муравей, воды налей! Не меньше ведра, напиться мне пора!
Во первых отметим тот факт, что сентенции с похожими именами образуют как бы неявную группу сентенций, которая может проигрываться рандомным образом. Правда документации нет и о подобных вещах приходится узнавать либо из кода, либо из экспериментов. Дальше обратите внимание, идёт путь к папке - hgrunt/. Эта штука работает по типу команды cd.
Т.е. сменив директорию единожды нам уже нет нужды писать этот путь всякий раз. Вроде бы удобно, но абсолютно не наглядно и неочевидно.
Опять-таки расширений звуков нет. Есть параметры в скобках.
Вопрос на засыпку - параметр в скобках применяется к уже объявленному звуку или к следующему? Снова неочевидно. И что значит восклицательный знак? Впрочем со знаком как раз проблем меньше всего - достаточно зайти в папку hgrunt, чтобы увидеть что там возгласы записаны и сохранены как раз в двух вариантах. С восклицательным знаком и без такового. То есть с разной экспрессией. Кое-где попадаются сентенции без пути к папке. Здесь по умолчанию используется захардкоденная папка vox. Тоже об этом прочитать негде. Только догадаться.
Просматривая параметры в круглых скобках можно наткнуться на таковые перед самым первым путём к звуку, из чего становится понятно - сначала параметр, потом звук. Так же неясности добавляют встречающиеся точки и запятые. Это сейчас мы знаем, что они означают автоподстановку пустых файлов, которые по смыслу соответствуют длине пауз, для запятой и точки соответственно. Причём наличие точки как бы уже предполагает что расширение файла мы указать не сможем - это будет понятно неправильно.
Хорошо, теперь переходим к однобуквенным параметрам: Их может быть всего пять штук:
v - громкость в процентах
p - pitch в процентах
s - смещение от начала звукового файла (тоже в процентах)
e - смещение от конца звукового файла (тоже в процентах)
t - тайм компрессия. Питч не меняется, но звук проигрывается быстрее.
Отсутствует в Xash3D и Source. Но есть в GoldSrc. Но только для 8-битных сэмплов. Величина тоже указывается в процентах.
Теперь когда мы во всём разобрались, посмотрим как этим пользоваться.
Следует так же упомянуть момент, что параметры задаются как бы глобально. То есть они не сбрасываются на следующем слове в сентенции. Пока пользователь сам их не поменяет. Таким образом можно установить изначальную громкость потише, а на каком-то слове выкрутить на максимум, акцентируя внимание. Зачем подрезать начало и конец звука я не очень понял, но скорее всего - для рандомизации. Плохо тут то, что невозможно задавать диапазоны рандомизации.
А теперь, товарищи, скажите мне, какие у вас соображения, по поводу всего вышенаписанного? Кратко, невнятно, но когда разберёшься - удобно. Но всё захардкодено, не поменять ни добавить. Хотя тут полноценная секвенция проигрывания. То есть мы вызываем даже не сентенцию - группу сентенций, выбирается одна из и дальше следует командам - поменять громкость, обрезать конец слова, ну итд.
Я полагаю что здесь неплохая точка приложения усилий для моей системы автозамены, которая используется для материалов рендринга.
Здесь тоже можно будет переопределить все эти точки и прочие запятые, чтобы писать ещё более лаконично, но при этом все переопределения будут у пользователя перед глазами. Как и в случае с системой материалов. Очевидно такой механизм вполне имеет право на жизнь.
Ну а некоторая изыбточность скомпенсируется наглядностью.
Разработка низкоуровневого синтаксиса для описания сентенций будет позже, когда я уже непосредственно приступлю к рефакторингу звукового движка. Ну а пока что - мысли по теме. Как когда-то давно, когда и Ксаш ешё не был написан, а я больше теоретизировал как оно будет
Может быть кто-то скучает по тем временам? Ну вот.
Продолжение следует...
Добавлено 03-02-2025 в 00:48:
Цитата:
FiEctro писал: Когда можно написать что то вроде:
sequence "misc/r_tele"
type "wav"
Ну или что нить в духе: sound "misc/r_tele[].wav" ?
Вот как раз в этом посте и находится ответ на твой вопрос.
В плане звуков не хватает наложения на них каких-либо DSP-эффектов, когда не хочется применять глобальный room_type, но на звук надо навесить.
Еще не хватает сдавливания верхних частот, когда звук находится за глухой стенкой.
То же самое касается, когда звук находится на дистанции (но, если добавлять такой параметр, ему следует быть опциональным). Я у себя реализовал нечто подобное путем смешения заранее заготовленных звуков, сдавленного и обычного в зависимости от дистанции. А вот за стенкой уже не выйдет сделать.
Ах да, было бы неплохо еще иметь крутилку для high pass и low pass, чтобы можно было их крутить как pitch и volume.
Дядя Миша писал: А теперь, товарищи, скажите мне, какие у вас соображения, по поводу всего вышенаписанного?
Я здесь вижу одну большую проблему. Что если у игры несколько озвучек на разных языках?
Цитата:
Дядя Миша писал: Вот как раз в этом посте и находится ответ на твой вопрос.
В простом варианте оно наверное и ок. Но с точки зрения стороннего пользователя это не читаемо. С точки зрения общего единства синтаксиса в конфигах движка, твой первый вариант был куда лаконичнее, хоть и избыточен. Ещё бы неплохо было бы добавить поле для ссылки для субтитров.
И сделать общий конфиг для всех игровых текстов который будет ссылать на эти ссылки.
Ещё как идея сделать физический блок для материала который содержит динамическое трение, статическое трение и боунс (прыгучесть).
__________________
У котёнка мокрый нос и гладенькая шерсть, у него забавный хвост и быстрых лапок шесть. Две задних, две средних и две передних лапы, такая многоножка получилася у папы.
Он ученый — папа мой — зверушек изучает, гуляет по помойкам, ловит крыс и чаек. Две крысы белокрылые и чайки две унылые покрытые пупырчатою кожей лягушат без пёрышек тоскуют и ускакать спешат.
А ещё есть муравей большой размером с гуся он пугает всех зверей, и я его боюся, когда он ковыляет на лапках на своих.
И в двери ударяет, и начинает стих: Я — муравей, воды налей! Не меньше ведра, напиться мне пора!
FiEctro писал: Я здесь вижу одну большую проблему. Что если у игры несколько озвучек на разных языках?
Смена языка это не только озвучка НПС, но и текстуры, декали, модели, текст
__________________
Kiss my ass if you don't like my Ford!
------------------------------------------ Game Area51 Update 1
First Person Shooter Released Jul 24, 2017
The game is a 3d shooter with the elements of the quest.
Aynekko писал: движку не составит труда воспроизвести звук с нужным эффектом по какому-то флагу
Я просто не представляю ситуации, когда такое может понадобится.
Какую бы аналогию привести. Ну это как если бы ты предлагал всё освещение запечь прямо на текстурах. И ещё сделать в движке настройку, чтобы он запекал какое-то освещение на текстуру при загрузке.