Как стать автором
Обновить

Source Modding — Часть 1 — Основы основ

Время на прочтение 6 мин
Количество просмотров 19K

В мире существует множество игровых движков, но нет ни одного движка, похожего на Source своей историей и особенностями.


В этом (пилотном) уроке мы разберем простейшие действия с исходными кодами SDK, а также внесем наше первое изменение в код Half-Life 2.



Вступление


Немножко терминов


Сам по себе Source SDK — набор утилит и программ, помогающих в разработке собственных уровней и модификаций для игры, а также исходные коды Half-Life 2 и эпизодов.


Игра/Мод (Для сурса нет никакой разницы, игра это или мод :p) — скомпилированные исходные коды SDK.


Так почему же именно Source?!


  1. Модульность. Это может показаться минусом для некоторых, но почти все подсистемы движка вынесены в отдельные модули, каждый из которых может быть заменен без пересборки всего движка.
  2. Чрезвычайная гибкость. При достаточном количестве усилий вы можете сделать на Source игру абсолютно любого жанра.
  3. Движок и SDK разрабатывались огромным количеством людей, поэтому код SDK (а также утекший в сеть три раза код движка разных версий, но об этом позже ( ͡° ͜ʖ ͡°) ) состоит из множества разных стилей программирования! Я почти уверен, что именно работа с Source SDK подарила мне умение (но не желание...) читать чужой код.
  4. Порог вхождения. Он не слишком низок и не слишком высок. Достаточно знать C++ и уметь вчитываться в документацию!
  5. К моменту появления идеи о написании туториала у автора попросту не было новой версии юнити.

Что нам необходимо?


  1. Ну прежде всего хотя бы базовые знания C++ (Достаточно знать его на уровне Си с классами).
  2. Любая Microsoft Visual Studio с Multibyte MFC Library и Microsoft Build Tools 2013 (v120/v120_xp). Чтобы не морочить себе голову, можно просто установить VS2013.
  3. Git for Windows или любой другой.
  4. Steam с установленным Source SDK Base 2013 [Single|Multi]player (также необходимо в свойствах "игры" установить бета-версию upstream, иначе мод будет падать)
  5. В будущем также знание HLSL, но не сейчас :)

Введение в сурс дела


Репозиторий


Исходный код SDK находится в репозитории на GitHub. Склонируйте его в любое удобное для вас место:


git clone https://github.com/ValveSoftware/source-sdk-2013.git

Выбор ветки


Если вы хотите написать свой первый мод для Half-Life 2/Episode 1/2, то используйте директорию sp/ и Source SDK Base 2013 Singleplayer.


Если же вы извращенец и хотите написать свой первый мод для Half-Life 2: Deathmatch, то используйте директорию mp/ и Source SDK Base 2013 Multiplayer.


ВАЖНО: Туториал будет рассматривать программирование под ветку SP, поэтому пути, содержащие hl2 в пересчете на MP могут содержать hl2mp вместо hl2!!!


Стиль кода


Клиентские (client.dll) классы именуются с префиксом C_, а серверные (server.dll) — с префиксом C:


// client.dll
class C_BaseWeapon { ... };
// server.dll
class CBaseWeapon { ... };

Поля класса именуются с префиксом m_, использование венгерской нотации рекомендуется (на то есть свои причины, которые здесь обсуждать нет смысла):


class C_SomeClientClass {
private:
    float m_flTime = 0.0;
};
extern float g_flSomeFloat;
static float s_flSomeStaticFloat;
void SomeFunction(float flValue);

Структура кода


SDK, так же как и движок, разделён на несколько частей.


Список проектов сгенерированных проектов
  • client.dll
    Клиентская часть игры.
    Отвечает за рендеринг, предсказания и ввод.
    Расположена: src/game/client/
  • server.dll
    Серверная часть игры.
    Отвечает за игровую логику, ИИ и т.д.
    Расположена: src/game/server/
  • tier1.lib
    Библиотека, содержащая в себе множество полезных фич, например UTL ("валвовская" версия STL), interface convention и т.д.
    Расположена: src/tier1/
  • raytrace.lib
    Библиотека, внезапно содержащая в себе функции и типы, предназначенные для рейтрейсинга. Честно говоря, я так и не понял, что библиотека для компиляторов делает здесь.
    Используется компилятором vrad и, судя по утечкам исходных кодов, редактором уровней Valve Hammer Editor.
    Расположена: src/raytrace/
  • mathlib.lib
    Библиотека, содержащая в себе множество типов и функций, используемых в "повседневной" математике Source.
    Расположена: src/mathlib/
  • vgui_controls.lib
    Библиотека, содержащая в себе реализации разных элементов (кнопки, панели) VGUI2.
    Используется почти повсеместно.
    Расположена: src/vgui2/vgui_controls/

VPC


Source SDK имеет свой генератор проектов (sln, Makefile, etc.) с блэкджеком и… кхм…
Называется он Valve Project Creator и находится в src/devtools/bin.


Проекты генерируются автоматически с использованием специальных .VPC файлов. Синтаксис этих файлов прост до безобразия — простой набор пар ключ-значение.


Вот пути до некоторых таких файлов:


src/game/client/client_episodic.vpc
src/tier1/tier1.vpc
src/utils/vrad/vrad_dll.vpc

ВАЖНО: При внесении ЛЮБЫХ изменений в VPC файл решение должно быть заново перегенерировано!


Генерация проектов


Проекты генерируются вызовом скрипта, расположенного в директории src/.
В самом простом случае — достаточно просто открыть src/creategameprojects.bat.
После генерации в src/ будет находиться games.sln.



Исключение HL2


SDK имеет внутри себя также разделение на HL2 и Episodic. Использование второго позволит нам иметь некоторые фичи, например отдельную от стамины шкалу заряда фонарика.


И поэтому, чтобы не компилировать лишний код, мы можем просто исключить HL2 из скриптов:


  1. Откройте src/creategameprojects.bat в любом текстовом редакторе.
  2. Удалите из командной строки часть /hl2
  3. Сохраните файл и сгенерируйте проект.

Другие скрипты


Рядом с creategameprojects.bat также лежит его клон для bash а также два интересных файла — createallprojects.bat и его клон для bash.


Эти два скрипта заставляют VPC создавать проекты не только для чистых библиотек мода, но и для различных утилит, таких как vrad (Radiosity!) или height2normal.


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


Первичная сборка и запуск


Сборка


Чтобы удостовериться, что вы всё сделали правильно, необходимо собрать всё сгенерированное решение. Итак, собираем (вы же ведь открыли решение в IDE?):


  1. Переключите конфигурацию в Release.
    ВАЖНО: При сборке в Debug мод крайне нестабилен!!!
  2. Соберите ВСЁ решение (F6)
  3. Если сборка закончилась с ошибками, повторите шаг 2.
  4. Если ошибки повторяются, пересоздайте проекты (creategameprojects) и повторите все шаги начиная с 1.

После сборки в папке game/mod_hl2/bin/ или game/mod_episodic/bin/ должны появится наши клиентская и серверная библиотеки!


Запуск — Способ 1 — Steam


  1. Копируем нашу папку mod_xxx в путь/до/Steam/steamapps/sourcemods/
  2. Перезапускаем Steam (либо запускаем, если еще этого не сделали...)
  3. Ищем в библиотеке "My First Episodic Mod" или "My First HL2 Mod"
  4. В свойствах устанавливаем дополнительные параметры командной строки:
    -dev -console
  5. Запускаем, в консоли запускаем карту sdk_vehicles (SP) или dm_lockdown (MP)

Запуск — Способ 2 — Visual Studio


Я рекомендую использовать именно этот способ — не копировать же бинарники мода каждый раз после сборки!


  1. Заходим в свойства проекта (не решения!!!) во вкладку Debugging
  2. В поле Command вписываем:
    путь/до/steam/steamapps/common/Source SDK Base 2013 XXXX/hl2.exe
  3. В поле Working Directory вписываем:
    путь/до/steam/steamapps/common/Source SDK Base 2013 XXXX/
  4. В поле Command Arguments вписываем:
    -game "путь/до/репо/xx/game/mod_xxx/" -debug -dev -console
  5. Сохраняем, запускаем (F5)!
  6. Запускаем, в консоли запускаем карту sdk_vehicles (SP) или dm_lockdown (MP)

Если карта загрузилась и вы можете передвигаться и двигать камеру мышью — сборка успешна!



Первая модификация в коде


Функции семейства Msg()


Функции Msg(), DevMsg(), Warning(), DevWarning() и ConColorMsg() являются чем-то вроде классического printf(), но в мире программирования под Source SDK. Эти функции так или иначе выводят какой-то текст в консоль разработчика и debug output.


// somewhere in tier0/dbg.h
void Msg( const tchar* pMsg, ... );

// somewhere in code
Msg( "This is a message! %d\n", 42 );

Говорящий пистолет!


Давайте научим пистолет писать сообщение с количеством патронов в магазине:


  1. Откройте src/game/server/hl2/weapon_pistol.cpp (Server (Episodic/HL2)/HL2 DLL/weapon_pistol.cpp)
  2. Найдите там метод void CWeaponPistol::PrimaryAttack( void ) (Где-то вокруг строки 255)
  3. Аккурат после строчки BaseClass::PrimaryAttack(); добавьте какое-нибудь сообщение, например:
    BaseClass::PrimaryAttack(); // где-то на строке 251
    Msg( "weapon_pistol: m_iClip1 = %d\n", m_iClip1 );
  4. Соберите мод, запустите и откройте карту
  5. Поскольку мы писали в аргументы -dev, чит-команды включены по умолчанию, поэтому пишите в консоль пресловутый impulse 101 и пробуйте стрелять из пистолета!


Заключение


Чему мы научились?


[Я надеюсь, что] из данного урока мы выяснили:


  • Что вообще такое Source SDK и с чем его едят
  • Как генерировать проекты используя VPC
  • Как печатать что-то в консоль разработчика

Что дальше?


Во второй части мы разберем систему сущностей Source SDK.


Полезные ссылки


Теги:
Хабы:
+12
Комментарии 6
Комментарии Комментарии 6

Публикации

Истории

Работа

Ближайшие события

PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн
Weekend Offer в AliExpress
Дата 20 – 21 апреля
Время 10:00 – 20:00
Место
Онлайн