C# и архитектура Space Station 14: От новичка до контрибьютора

Этот курс обучает основам языка C# через призму движка Robust Toolbox и архитектуры ECS, используемых в Space Station 14. Вы научитесь создавать игровые объекты, писать логику систем и работать с клиент-серверной частью игры.

1. Настройка среды разработки, Git и структура проекта Space Station 14

Настройка среды разработки, Git и структура проекта Space Station 14

Добро пожаловать в курс «C# и архитектура Space Station 14: От новичка до контрибьютора». Это первая статья, и она станет фундаментом для всего вашего дальнейшего пути. Прежде чем мы начнем писать код, создавать новые предметы или механики, нам необходимо подготовить рабочее место.

Space Station 14 (SS14) — это сложный проект с открытым исходным кодом, в котором участвуют сотни разработчиков. Чтобы стать одним из них, недостаточно просто знать язык программирования C#. Нужно понимать инструменты, которые используются в команде, и архитектуру, на которой строится игра.

Почему C# и что такое RobustToolbox?

Space Station 14 написана на языке C# с использованием игрового движка RobustToolbox. В отличие от Unity или Unreal Engine, RobustToolbox был создан специально для нужд SS14. Это означает, что он оптимизирован для тайловой 2D-графики, сложной симуляции атмосферы и клиент-серверной архитектуры, способной поддерживать сотни игроков одновременно.

Выбор C# не случаен. Это строго типизированный язык с мощными возможностями для объектно-ориентированного программирования и отличной производительностью благодаря платформе .NET. Если вы пришли из мира Python или JavaScript, C# может показаться более строгим, но именно эта строгость помогает избегать множества ошибок в крупном проекте.

Шаг 1: Установка необходимых инструментов

Для работы над SS14 вам понадобится «джентльменский набор» разработчика. Давайте разберем каждый компонент.

1. Git: Система контроля версий

Git — это машина времени для вашего кода. Она позволяет сохранять историю изменений, возвращаться к прошлым версиям и, самое главное, объединять работу множества людей в один проект. Без Git разработка SS14 была бы невозможна.

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

2. .NET SDK

Так как SS14 написана на C#, вам нужен .NET SDK (Software Development Kit). Это набор библиотек и компиляторов, необходимых для сборки игры. На момент написания этой статьи проект активно использует .NET 8. Убедитесь, что вы скачиваете именно SDK, а не Runtime (последний нужен только для запуска, но не для разработки).

3. IDE: Среда разработки

Это ваш главный инструмент, верстак, за которым вы будете проводить 99% времени. В сообществе SS14 есть негласный стандарт:

* JetBrains Rider — наиболее рекомендуемая IDE. Она платная, но имеет бесплатную версию для студентов и разработчиков open-source проектов. Rider лучше всего понимает специфику C# и имеет отличную интеграцию с Git. * Visual Studio (не путать с VS Code) — классический выбор для C# разработчиков на Windows. Мощная, но тяжеловесная. * Visual Studio Code — легкий редактор кода. Его можно настроить для работы с C#, но для крупного проекта вроде SS14 он может быть менее удобен из-за отсутствия продвинутых инструментов рефакторинга «из коробки».

> Мы настоятельно рекомендуем использовать JetBrains Rider, так как большинство гайдов и плагинов сообщества ориентированы именно на него.

Шаг 2: Клонирование репозитория

Здесь многие новички совершают первую ошибку. Репозиторий Space Station 14 содержит подмодули (submodules). Движок RobustToolbox находится в отдельном репозитории и подключается к игре как подмодуль. Если вы просто скачаете код как ZIP-архив или сделаете обычный клон, папка с движком окажется пустой, и проект не соберется.

Правильная команда для клонирования выглядит так:

Флаг --recursive говорит Git'у: «Скачай не только этот проект, но и все вложенные в него проекты (движок)». Если вы уже клонировали проект без этого флага, исправить ситуацию можно командой:

Шаг 3: Структура проекта

Открыв проект в IDE, вы увидите множество папок. Не пугайтесь. Архитектура SS14 построена на четком разделении ответственности между клиентом и сервером. Это критически важно для многопользовательской игры, где нельзя доверять клиенту.

!Диаграмма взаимодействия клиентской, серверной и общей частей кода

Давайте разберем основные директории решения (Solution):

Content.Client

Здесь находится код, который выполняется только на компьютере игрока.

* За что отвечает: Отрисовка графики (спрайты, свет), воспроизведение звуков, интерфейс пользователя (UI), обработка нажатий клавиш. * Безопасность: Сервер никогда не доверяет данным, пришедшим отсюда, кроме команд управления.

Content.Server

Это «мозг» игры. Код отсюда выполняется на сервере.

* За что отвечает: Логика игры, сохранение в базу данных, взаимодействие с администраторами, истинное состояние мира. Если вы хотите, чтобы нажатие кнопки открывало шлюз, сама логика открытия должна быть здесь.

Content.Shared

Это связующее звено. Код в этой папке компилируется и в клиентскую, и в серверную сборку.

* За что отвечает: Сетевые сообщения, компоненты, которые должны быть видны обеим сторонам, и предсказание (Prediction). * Пример: Когда игрок идет по коридору, клиент не ждет ответа от сервера «ты сделал шаг», а сразу рисует движение (используя код из Shared). Сервер параллельно просчитывает то же самое движение (используя тот же код из Shared) и подтверждает его.

Resources

Здесь нет C# кода. Это папка с данными:

* Textures: Спрайты и иконки. * Prototypes: Самая важная часть для новичка. Это .yml файлы, описывающие сущности (предметы, стены, мобов). В SS14 используется подход «Data-Driven». Вместо того чтобы писать класс Apple.cs, вы создаете запись в YAML-файле, наделяя сущность компонентами «Еда», «Предмет», «Спрайт».

Шаг 4: Первая сборка и запуск

В вашей IDE (например, Rider) вы увидите конфигурации запуска. Обычно их две основные:

  • Content.Server
  • Content.Client
  • Чтобы протестировать игру локально:

  • Запустите Content.Server. Откроется консольное окно сервера. Дождитесь надписи, сообщающей о том, что сервер запущен (обычно [INFO] SAW: Started).
  • Запустите Content.Client. Откроется окно игры.
  • В меню игры нажмите «Connect to Local» или введите адрес localhost.
  • Если вы видите своего персонажа в лобби — поздравляем! Вы успешно настроили среду разработки.

    ECS: Краткое введение

    Space Station 14 использует архитектурный паттерн ECS (Entity Component System). Мы будем подробно разбирать его в следующих статьях, но сейчас важно понять суть, чтобы не потеряться в структуре папок.

    * Entity (Сущность): Просто ID объекта (например, EntityUid 105). Сама по себе сущность ничего не делает и не имеет свойств. * Component (Компонент): Данные. Например, компонент PhysicsComponent хранит массу и скорость, а SpriteComponent хранит путь к картинке. * System (Система): Логика. PhysicsSystem берет все сущности с PhysicsComponent и двигает их.

    В структуре проекта вы часто будете видеть папки Systems и Components внутри Client, Server и Shared. Это и есть реализация ECS.

    Решение типичных проблем

    При первой настройке часто возникают ошибки. Вот самые популярные:

    Ошибка: "The type or namespace name 'Robust' could not be found"*. * Решение: Вы забыли --recursive при клонировании. Движок не скачался. Выполните git submodule update --init --recursive. Ошибка: "SDK not found"*. * Решение: Проверьте версию установленного .NET SDK командой dotnet --version в терминале. Она должна соответствовать той, что указана в файле global.json в корне репозитория. * Ошибка: Долгая компиляция. * Решение: Первый билд всегда долгий. Последующие будут быстрее, так как пересобираются только измененные файлы.

    Заключение

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

    В следующей статье мы погрузимся в мир YAML и Прототипов, чтобы создать ваш первый игровой предмет, не написав ни строчки кода на C#. Готовьтесь, будет интересно!

    2. Основы C# и глубокое погружение в архитектуру Entity-Component-System (ECS)

    Основы C# и глубокое погружение в архитектуру Entity-Component-System (ECS)

    В предыдущей статье мы подготовили рабочее место: установили Git, .NET SDK и IDE, а также клонировали репозиторий Space Station 14. Теперь, когда у вас есть инструменты, пришло время разобраться, как ими пользоваться.

    Space Station 14 (SS14) — это не просто набор скриптов. Это сложная инженерная система, построенная на архитектурном паттерне ECS (Entity-Component-System). Чтобы писать качественный код для SS14, вам нужно не только знать синтаксис C#, но и перестроить свое мышление с классического объектно-ориентированного подхода (ООП) на компонентный.

    Экспресс-курс C# для разработчика SS14

    Язык C# огромен, но для старта в SS14 вам нужно глубокое понимание нескольких ключевых концепций. Мы не будем разбирать циклы for или if, так как предполагается, что вы знакомы с основами программирования. Сосредоточимся на том, что критически важно для движка RobustToolbox.

    Ссылочные типы и значимые типы (Class vs Struct)

    В C# все типы данных делятся на две категории:

  • Reference Types (Ссылочные типы): Это class. Когда вы передаете объект класса в метод, вы передаете ссылку на него. Изменение объекта внутри метода отразится на оригинале. В SS14 Компоненты (Components) и Системы (Systems) — это классы.
  • Value Types (Значимые типы): Это struct (и примитивы вроде int, float). Они хранят данные непосредственно. При передаче они копируются. В SS14 События (Events) и EntityUid — это структуры.
  • Понимание этого различия критично. Если вы попытаетесь изменить поле в структуре-событии после того, как передали ее в функцию, оригинал не изменится, и ваша логика не сработает.

    Дженерики (Generics)

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

    Пример из движка:

    Здесь метод GetComponent — обобщенный. Мы говорим ему: «Верни мне компонент именно типа PhysicsComponent».

    Атрибуты (Attributes)

    Атрибуты — это метаданные, которые мы добавляем к классам и полям. В SS14 они играют огромную роль для сериализации (сохранения/загрузки) и сетевого взаимодействия.

    Без атрибута [DataField] движок не узнает, что переменную Color нужно загружать из файлов прототипов.

    Архитектура ECS: Смена парадигмы

    Если вы пришли из Unity (до DOTS) или классического ООП, забудьте про наследование. В классическом ООП, чтобы создать «Фонарик», вы бы сделали класс Flashlight, который наследуется от Item, который наследуется от GameObject.

    В ECS наследования сущностей не существует. Вместо глубокой иерархии мы используем композицию.

    !Сравнение иерархии наследования в ООП и композиции в ECS

    Три кита ECS

    Архитектура держится на трех понятиях: Entity (Сущность), Component (Компонент) и System (Система).

    #### 1. Entity (Сущность)

    Сущность в SS14 — это ничто. Буквально. Это просто уникальный идентификатор, число (EntityUid).

    У сущности нет методов. У нее нет полей «Здоровье» или «Имя». Сущность — это просто ID, к которому мы можем «приклеить» данные. Думайте об этом как о ключе в базе данных.

    #### 2. Component (Компонент)

    Компонент — это данные. Только данные и никакой логики.

    Компонент DoorComponent не знает, как открывать дверь. Он просто хранит состояние: «Открыта» или «Закрыта». Компонент DamageableComponent не знает, как умирать. Он просто хранит число: «Урон: 50».

    Пример правильного компонента:

    #### 3. System (Система)

    Система — это логика. Системы обрабатывают данные компонентов.

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

    Пример логики системы (псевдокод):

  • Игрок нажимает на дверь.
  • DoorSystem ловит событие нажатия.
  • DoorSystem проверяет, есть ли у этой сущности DoorComponent.
  • Если есть, система меняет IsOpen с false на true.
  • Система просит визуальную систему обновить спрайт.
  • Почему ECS круче для SS14?

  • Производительность: Данные одного типа (например, физика) лежат в памяти рядом. Процессору гораздо быстрее обрабатывать массив однотипных данных, чем прыгать по ссылкам разных объектов.
  • Гибкость: Хотите сделать банан, который стреляет лазером? В ООП вам пришлось бы создавать ужасного мутанта LaserBanana, наследуясь от Food и Weapon. В ECS вы просто берете сущность и вешаете на нее два компонента: FoodComponent и GunComponent. Всё. Это работает автоматически.
  • Событийно-ориентированная архитектура

    Системы в SS14 общаются друг с другом и с миром через События (Events). Это позволяет снизить связность кода (Decoupling).

    Вместо того чтобы InteractionSystem напрямую вызывала метод DoorSystem.Open(), она выбрасывает событие ActivateInWorldEvent.

    DoorSystem заранее «подписывается» на это событие для всех сущностей, у которых есть DoorComponent.

    Это означает, что вы можете добавить новую механику (например, бомбу, которая взрывается при нажатии), просто создав ExplosiveComponent и подписавшись на то же самое событие ActivateInWorldEvent. Вам не нужно менять код системы взаимодействия.

    Внедрение зависимостей (Dependency Injection)

    В SS14 широко используется паттерн IoC (Inversion of Control). Вам не нужно создавать экземпляры менеджеров вручную (через new). Движок сам предоставит их вам.

    Для этого используется атрибут [Dependency].

    Это упрощает тестирование и управление глобальными сервисами, такими как аудио, сеть или интерфейс.

    Практический пример: Анатомия предмета

    Давайте соберем ментальную модель простого предмета в игре — Красного ящика с инструментами.

    В мире ECS это EntityUid (например, 1042), к которому прикреплен список компонентов:

  • SpriteComponent: Содержит путь к текстуре toolbox_red.rsi.
  • ItemComponent: Помечает сущность как предмет, который можно положить в инвентарь. Содержит размер предмета.
  • PhysicsComponent: Определяет, что предмет имеет массу и сталкивается со стенами.
  • TransformComponent: Хранит координаты X, Y и карту, на которой лежит ящик. (Этот компонент есть у всех сущностей в мире).
  • StorageComponent: Позволяет хранить внутри другие предметы.
  • Если мы захотим сделать этот ящик съедобным, мы просто добавим FoodComponent. Нам не нужно переписывать код ящика.

    Заключение

    Переход на ECS может быть болезненным для новичков. Главное правило: разделяйте данные и логику. Если вы пишете метод внутри класса компонента — остановитесь, вы делаете ошибку. Перенесите метод в Систему, а данные оставьте в Компоненте.

    В этой статье мы разобрали теоретический фундамент. Вы узнали, что Entity — это ID, Component — это данные, а System — это логика. Мы также затронули события и внедрение зависимостей.

    В следующей статье мы перейдем к практике и научимся описывать эти сущности и компоненты, не написав ни строчки C# кода — с помощью YAML и системы Прототипов.

    3. Создание контента: Работа с прототипами YAML и сериализация данных

    Создание контента: Работа с прототипами YAML и сериализация данных

    Добро пожаловать обратно, кадет! В предыдущей статье мы разобрали архитектуру ECS (Entity-Component-System) и выяснили, что сущности — это просто идентификаторы, а компоненты — это данные. Но остался один важный вопрос: как именно мы «собираем» эти сущности? Неужели нам нужно писать C# код каждый раз, когда мы хотим добавить в игру новый вид отвертки или пончика?

    К счастью, нет. Space Station 14 использует подход Data-Driven (управляемый данными). Это означает, что большая часть игрового контента определяется не в коде, а в специальных файлах конфигурации. В SS14 для этого используется язык разметки YAML.

    В этой статье мы научимся читать и писать прототипы, поймем, как магическим образом данные из текстового файла попадают в переменные C#, и создадим ваш первый игровой объект.

    Что такое Прототип?

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

    Прототип — это шаблон, описывающий сущность. Он говорит движку: «Когда нужно создать объект с ID Crowbar, создай новую сущность и прикрепи к ней компоненты SpriteComponent, ItemComponent и PhysicsComponent с вот такими настройками».

    Все прототипы хранятся в папке Resources/Prototypes. Они имеют расширение .yml.

    Почему YAML?

    YAML (YAML Ain't Markup Language) был выбран за его человекочитаемость. В отличие от JSON или XML, здесь минимум скобок и кавычек. Структура определяется отступами (пробелами).

    > Важно: В YAML запрещено использовать табуляцию (Tab). Используйте только пробелы (обычно 2 пробела на уровень вложенности). Если вы используете IDE вроде Rider, она сама заменит Tab на пробелы.

    Анатомия Прототипа

    Давайте взглянем на типичный прототип предмета. Это реальный пример того, как может выглядеть лом (Crowbar) в файлах игры:

    Разберем каждое поле:

  • - type: entity: Это объявление начала нового прототипа. Мы говорим, что описываем именно сущность (бывают и другие типы прототипов, например, рецепты крафта).
  • id: Crowbar: Уникальный идентификатор. Именно по этому ID мы будем спавнить предмет в игре или обращаться к нему в коде.
  • name и description: Имя и описание, которые увидит игрок, наведя курсор на предмет.
  • components:: Самая важная часть. Это список компонентов, из которых состоит сущность.
  • Внутри списка components мы перечисляем типы компонентов (например, Sprite, Item) и настраиваем их поля (sprite, size).

    !Визуализация того, как текстовый файл превращается в игровой объект через менеджер сериализации

    Магия Сериализации: Связь C# и YAML

    Как движок понимает, что строчка size: Small в YAML должна попасть в переменную Size в классе ItemComponent? Этот процесс называется сериализацией (или маппингом данных).

    В SS14 за это отвечает мощная система атрибутов. Чтобы поле C# класса можно было настроить через YAML, его нужно пометить атрибутом [DataField].

    Взглянем на код компонента (упрощенно):

    Когда игра загружается, SerializationManager читает YAML-файлы. Он видит поле size в прототипе, ищет в коде компонента поле с атрибутом `[DataField(

    4. Программирование игровой логики: Взаимодействие Систем, Компонентов и Событий

    Программирование игровой логики: Взаимодействие Систем, Компонентов и Событий

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

    Чтобы вдохнуть жизнь в объекты Space Station 14, нам нужно спуститься в машинное отделение — в код C#. В этой статье мы разберем, как заставить сущности реагировать на действия игрока, используя триаду ECS: Entity, Component, System.

    Разделение ответственности: Кто за что отвечает?

    Прежде чем писать код, давайте вспомним золотое правило архитектуры RobustToolbox:

    > Компоненты хранят данные. Системы выполняют логику.

    Это самая частая ошибка новичков. Если вы пишете метод Open() внутри класса DoorComponent, вы нарушаете принципы ECS. Компонент должен быть глупым контейнером данных. Вся магия происходит в Системах.

    Пример задачи

    Допустим, мы хотим создать «Шумный ящик». Когда игрок кликает по нему пустой рукой, ящик должен издавать забавный звук.

    Для этого нам понадобятся:

  • Компонент (NoisyComponent): Будет хранить имя звукового файла.
  • Система (NoisySystem): Будет слушать клики игрока и воспроизводить звук.
  • Шаг 1: Создание Компонента (C#)

    Мы уже касались компонентов в статье про YAML, но теперь создадим свой собственный класс. В папке Content.Shared (так как звук должны слышать все, и логика предсказания важна) создадим файл NoisyComponent.cs.

    Обратите внимание на partial. В современных версиях C# и RobustToolbox это позволяет движку генерировать дополнительный код для сетевой синхронизации, если это потребуется.

    Теперь, когда у нас есть C# класс, мы можем добавить его в YAML-прототип нашей сущности:

    Шаг 2: Создание Системы (C#)

    Теперь самое интересное. Нам нужен «мозг», который заставит это работать. Создадим файл NoisySystem.cs в той же папке Content.Shared.

    Системы в SS14 наследуются от класса EntitySystem.

    Внедрение зависимостей (Dependency Injection)

    Чтобы проиграть звук, нам нужен доступ к аудиосистеме движка. Мы не создаем её через new AudioSystem(). Движок уже создал её за нас. Мы просто просим ссылку на неё с помощью атрибута [Dependency].

    Шаг 3: События — нервная система игры

    Как система узнает, что игрок нажал на ящик? Через События (Events).

    Когда вы кликаете по объекту в игре, движок создает событие (например, ActivateInWorldEvent) и «рассылает» его всем системам, которые подписались на это событие для конкретного компонента.

    [VISUALIZATION: Схема потока данных слева направо. 1. Иконка курсора мыши нажимает на иконку коробки. 2. Стрелка ведет к блоку

    5. Сетевое взаимодействие и создание пользовательского интерфейса (UI)

    Сетевое взаимодействие и создание пользовательского интерфейса (UI)

    Приветствую, коллеги! Мы продолжаем наш курс «C# и архитектура Space Station 14». В прошлых лекциях мы научились создавать сущности, наделять их данными через компоненты и оживлять с помощью систем. Мы даже заставили коробку издавать звуки. Но есть одна проблема: Space Station 14 — это многопользовательская игра.

    Если вы запустите наш «Шумный ящик» на сервере, один игрок может нажать на него, но увидит ли (и услышит ли) это другой игрок? И как нам показать игроку красивое окно с кнопками и текстом, если он взаимодействует с компьютером или торговым автоматом?

    Сегодня мы разберем две фундаментальные темы: Сетевое взаимодействие (Networking) и Пользовательский интерфейс (UI). Мы свяжем их вместе через мощную абстракцию движка RobustToolbox, называемую BoundUserInterface (BUI).

    Архитектура Клиент-Сервер: Кто здесь главный?

    Space Station 14 использует архитектуру с авторитарным сервером. Это означает, что истина существует только на сервере. Клиент — это просто «терминал», который отправляет нажатия клавиш и получает картинку мира.

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

    !Диаграмма авторитарной архитектуры: сервер управляет состоянием, клиенты отправляют запросы и получают обновления.

    Синхронизация Компонентов

    В предыдущих статьях мы создавали компоненты в папке Content.Shared. Это позволяет и клиенту, и серверу видеть класс. Но данные внутри них не синхронизируются магическим образом.

    Чтобы переменная в компоненте обновлялась у клиентов при изменении на сервере, нужно сделать три вещи:

  • Добавить атрибут [NetworkedComponent] к классу компонента.
  • Пометить поля атрибутом [DataField] (или [ViewVariables]).
  • Использовать метод Dirty() в Системе.
  • Пример компонента:

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

    Без вызова Dirty(), клиенты будут продолжать видеть старое значение 100, даже если на сервере оно уже 50.

    Пользовательский интерфейс (UI): XAML и Контролы

    Интерфейс в SS14 строится не на HTML/CSS и не на WinForms. Движок RobustToolbox использует свою систему, вдохновленную WPF и Avalonia, основанную на XAML.

    XAML — это язык разметки, похожий на XML. Он описывает структуру окна: где находятся кнопки, надписи и картинки. Каждый XAML-файл имеет связанный с ним C# класс (Code-behind), который управляет логикой этого окна.

    Анатомия UI

    UI находится исключительно в проекте Content.Client. Сервер не знает о существовании кнопок и шрифтов.

    Давайте создадим простое окно для нашего устройства. Нам понадобятся два файла:

  • MyWindow.xaml (Внешний вид)
  • MyWindow.xaml.cs (Логика отображения)
  • Пример MyWindow.xaml:

    Пример MyWindow.xaml.cs:

    BoundUserInterface (BUI): Мост между мирами

    Теперь у нас есть логика на сервере и красивое окно на клиенте. Но как их соединить? Как серверу сказать окну «Откройся» или «Обнови заряд»? И как кнопке сказать серверу «Меня нажали»?

    Для этого используется паттерн BoundUserInterface.

    !Структура BoundUserInterface: Сервер отправляет State, Клиент отправляет Message, всё это связано через общий ключ Enum.

    Этот процесс состоит из 4 шагов.

    Шаг 1: Общие определения (Content.Shared)

    Нам нужно определить «язык», на котором будут общаться клиент и сервер. Создадим enum для идентификации интерфейса и класс для передачи состояния.

    Обратите внимание на атрибут [NetSerializable]. Он обязателен для всего, что летит по сети.

    Шаг 2: Серверная часть (Content.Server)

    На сервере мы должны добавить компонент, который умеет «держать» интерфейс. Обычно используется стандартный ActivatableUIComponent для простых вещей, но мы пойдем через ServerUserInterfaceComponent для понимания сути.

    В нашей Системе (MyMachineSystem) при инициализации:

    Шаг 3: Клиентский BUI (Content.Client)

    Это самый неочевидный момент. Нам нужен класс-посредник, который наследуется от BoundUserInterface. Он живет на клиенте, получает данные от сервера и управляет окном.

    Шаг 4: Связывание в YAML

    Последний штрих. Нам нужно сказать сущности, что у неё есть этот интерфейс, и связать Enum ключ с клиентским классом BUI.

    В прототипе сущности:

    Заключение

    Поздравляю! Вы только что прошли через одну из самых сложных тем для новичков в SS14. Мы создали полный цикл взаимодействия:

  • Игрок кликает на объект в мире.
  • Сервер открывает сессию UI.
  • Клиент создает окно (XAML).
  • Сервер отправляет данные (State).
  • Клиент обновляет окно.
  • Игрок жмет кнопку, Клиент шлет сообщение (Message).
  • Сервер обрабатывает логику.
  • Это фундамент для создания компьютеров, консолей, PDA и любых сложных механизмов. В следующей статье мы отойдем от кода и поговорим о том, как создавать красивые карты и работать с тайлами в редакторе маппинга.