Введение в программировние для Source SDK

Что это такое?

Возможно вы новичок и не имеете представления что такое программирование на C++ и что стоит за этими всеми названиями: «компиляция», «класс», «интерфейс» и так далее, в таком случае, вы должны приобрести базовые навыки программирования на языке C++, после чего можно будет полноценно выполнять поставленные задачи перед программистом мода.
Source SDK предоставляет исходный код для модификации движка игры.
Это означает что вы обладая определенными знаниями и инструментами можете при наличии у вас этого исходного кода внести в него нужную вам функциональность.
Что такое движок?
Например есть некая игра которую вы запускаете на вашем компьютере.
Игра состоит из программного кода и файлов с данными.
Файлы с данными нетрудно понять что это — то из чего строится игровой мир, графика, модели карты, и т. д.
А код — это то что выполняется процессором, грубо говоря, чтоб эти файлики могли отображаться на экране, двигаться и звучать.
Эту программную часть и называют «движок».
Движок состоит из нескольких систем, каждая отвечает за свою задачу (рендеринг графики, работа с файлами, обработка комманд, работа с сетью, организация игровой сцены, игровые объекты…)

С чего начать?

Что понадобиться чтобы модифицировать игру?
1. Знание С++. Некоторые полезные ресурсы посвященные программированию:
http://firststeps.ru
http://sources.ru
http://rsdn.ru
http://codenet.ru
http://msdn.microsoft.com

2. Исходники из Source SDK. Скачать всегда можно при помощи Steam.

3. Microsoft Visual Studio 7.1. Работа над кодом производится в данной среде для работы с проектами Visual С++ 7.1 от фирмы Microsoft.
Возможно есть другие пути компиляции проектов Visual С++ но это отдельная тема.

4. Знание как устроен Source SDK.
Часто программисту нужно самому менять те данные которыми оперирует код и знать каким образом эти данные организуются.
Для этого необходимо:
— изучить документацию по Source SDK: http://www.valve-erc.com/srcsdk;
— знать какие есть команды и настройки консоли для разрабочиков модов;
— понимать как создаются карты (bsp);
— понимать как создаются материалы (vmt/vtx);
— понимать как создаются модели (mdl);
— понимать как создаются звуковые скрипты и ресурсные файлы.
Эти вопросы рассматриваются в других туториалах. 5. Игра Half-Life для запуска вашего собственного мода.

После того как вы создали новый мод (Play Games -> Tools/Source SDK -> Create a Mod -> Modify Half-Life 2) открываем файл src/Game_sdk.sln
Файл sln — это Solution — решение, такой вот термин в Visual Studio. Почему не называют его проектом как в Visual Studio 6?
Решение (.sln) состоит из нескольких проектов (.vcproj), которые можно генерировать все сразу или по отдельности.
Данный файл решения состоит из двух проектов:
client — клиент
hl — сервер
Зачем их два, а если у нас например, не будет мультиплеера в игре?
В любом случае, будь то мультиплеер или синглплеер движок будет состоять из двух частей. Это обясняется тем что сам механизм имитации игрового мира разделен на две зависящие друг от друга стороны.
Что делает сервер, а что клиент, в чем их разница?
Сервер выполняет имитацию виртуальной реальности в реальном времени позволяя синхронизировать различные игровые объекты;
к серверу присоединяются клиенты которые тоже являются этими объектами, один или несколько, вообще в движке Source может быть до 255 клиентов.
В случае сетевой игры через интерент или локальную сеть, запускается общий сервер который синхронизирует всех клиентов, а в одиночной игре работают только свой локальный сервер и клиент.
За что отвечает клиент? Он выполняет ввод управления от игрока и вывод информации в том числе поступившей от сервера. Тоесть он реализует интерфейс с игроком.
Обычно все что невозможно (нет надобности) каким-либо образом выводить для игрока не выполняется на клиенте.
Вообщето клиент имитирует примерно то же что и сервер, но не может превышать больше полномочий чем сервер. Поэтому для сервера важно только то что клиент может передавать состояние игрока, и может вносить разные настройки сервера, предусмотренные разработчиками.

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

В результате компиляции этого кода получается два DLL модуля (клиент и сервер).

Серверный код находится в директории src/dlls.
В нем содержится иерархия серверных классов, в котором одни классы являются базовыми для порождаемых дочерних классов. При проектировании классов все общие свойства нескольких дочерних классов содержатся в родительском.
Серверные классы обычно имеют имена подобные CИмя (CBaseEntity, CBasePlayer).
Сервер отвечает за суть происходящего в игре, для него не важно как это нужно отображать на экране игрока, важна сама логика происходящего.
В результате сборки проекта src/dlls/hl_sdk.vcproj получается файл server.dll.

Код клиента находится в директории src/cl_dll.
Содержит иерархию клиентских классов. Классы клиента обычно имеют имена подобные C_Имя (C_BaseEntity, C_BasePlayer). Все классы игровых объектов которые участвуют в имитации мира имеют соответствующий класс на стороне сервера.
Здесь содержится код управлющий рендерингом моделей, озвучкой, обработка GUI-интерфейса, вывод текстовых сообщений, обработка ввода клавиатуры и мыши и т. д.
В результате сборки проекта src/cl_dll/client_sdk.vcproj получается файл client.dll.
Если поместить DLL файлы клиента и сервера в директорию bin вашего мода, движок сможет их подключить при запуске.

Общий код лежит в директориях src/public и src/game_shared.

В директории linux_sdk содержатся файлы для создания специального для этой платформы файла компиляции — Makefile, если вы занкомы с Unix, то уже догадались что он нужен для компиляции порта сервера под Linux.

Кроме того в Source SDK есть разные вспомогательные исходники, которые непосредственно не относятся к движку игры, их можно найти в директории src/utils
Это различные утилиты, ну например вы решили сделать какойто свой редактор для файлов в форматах движка Source, вам могут потребоваться такие исходники.

Вникаем в подробности

Для начала сделаем первый шаг в программировании мода.
Открываем файл src/dlls/hl2_dll/hl2_player.cpp
Находим реализацию метода PlayerUse, который отвечает за нажатие на клавишу USE
void CHL2_Player::PlayerUse (void)
Добавим после строки
CBaseEntity *pUseEntity = FindUseEntity ();
строку
if (pUseEntity && (m_afButtonPressed & IN_USE)) Msg («Hello MOD!\\n»);
Перед началом сборки следует обратить внимание на конфигурацию.
Заходим в Build -> Configuraion Manager… -> Active Solution configuration.
У проектов есть две конфигурации Release HL2 и Debug HL2.
В результате и первой и второй получаются файлы server.dll и client.dll, но в чем различия Release и Debug?
Debug предназначен для отладки (содержит отладочную информацию для отладчиков) и обычно более медленно работает, Release — создает оптимизированный код для окончательной версии мода.
Поскольку покачто это не имеет большого значения, можно выбрать Release.
Проверьте в какую директорию будут записаны файлы полученные при сборке проектов.
Для этого кликните правой кнопкой в Solution Explorer на client и выберите Properties, затем Configuration properties->Custom Build Step->General, В поле Command Line должно содержаться примерно следующее
if exist «путь_к_моду/bin/client.dll» attrib -r «путь_к_моду/bin/client.dll»
copy «$(TargetDir)"client.dll «путь_к_моду/bin»
if exist «путь_к_моду/bin/client.pdb» attrib -r «путь_к_моду/bin/client.pdb»
if exist «$(TargetDir)"client.pdb copy «$(TargetDir)"client.pdb «путь_к_моду/bin/client.pdb»
В поле Outputs (выбрать <Edit…>)
путь_к_моду/bin/client.dll
путь_к_моду/bin/client.pdb
Кроме DLL, студия также сохраняет специфические .PDB файлы, которые содержат информацию которая нужна для отдладки.
То же самое выполнить и для проекта hl.
Правой кнопкой в Solution Explorer на client, затем Properties->Configuration properties->Custom Build Step->General
Установки аналогичны толко для файла server.dll.

Сборка файлов выполняется коммандой Build -> Build Solution.
В окне вывода (Output) мы можем видеть вывод процесса сборки:

------ Build started: Project: client, Configuration: Release HL2 Win32 ------

Compiling…

Первая компиляция может занимать довольно много времени.
Если сборка произошла удачно, в самом конце вывода будет сообщено:

---------------------- Done ----------------------

Build: 2 succeeded, 0 failed, 0 skipped

Сгенерированные в результате файлы автоматически копируются в директорию bin вашего мода (в соответствии установкам Custom Build Step).

Теперь если запустить игру с нашими изменениями при использовнии каких-либо предметов (поднимите какойто предмет клавишей USE) мы должны видеть сообщение «Hello MOD!».
Запускать мод можно с помощью файла run_mod.bat в директории вашего мода.

Рассмотрим подробнее параметры командной строки для запуски собственных модов.
Вот пример:
hl2.exe -steam -dev -condebug -developer 2 -ent_messages_draw 1 -game NAME_OF_MOD
hl2.exe -steam — это запуск игры (изменять не нужно)
-dev (или -console) — включить командную консоль
-condebug — запись лога сообщений из консоли в файл console.log
-developer 1 или 2 — уровень отладки
-ent_messages_draw 1 — отобржать сообщения о происходящие работе сообщений
-game NAME_OF_MOD — какой мод запускать (указывается имя директории мода в директории Half-life2) Копаем глубже…

Запомните одну из очень ценных возможностей имеющуюся в Visual Studio — это поиск в файлах с кодом.
Find in Files — поиск в файлах или Ctrl+Shift+F с клавиатуры.
С помощью поиска вы можите исследовать исходный код, и находить самые важные для вас места для модификации.

Первым делом следует рассмотреть базовые вещи с которых нужно начинать знакомство с устройством движка.
Серверу и клиенту предоставляются различные программные интерфейсы которые предоставляют огромный список различных возможностей.
Например,
IPhysics — обработка физики;
IMaterial — огранизация системы материалов;
ICommandLine — работа с коммандами консоли;
IBaseFileSystem — запись/чтение файлов;
IEngineSound — вывод звука;
IInput — ввод клавиатуры или мышки;
и так далее…
Этот список довольно длинный, детальное рассмотрение требует большего объема чем данный туториал.

Чтобы в определенном месте кода сделать проверочный вывод информации на экран например чтобы проконтролировать как выполняется код — используйте вспомогательные функции:
UTIL_ClientPrintAll, ClientPrint или Msg

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

Автор: DarkLight.
18 февраля 2005, 17:05