Введение
Прототипы - это фундаментальный механизм Space Station 14 для определения данных игры в YAML-файлах, которые затем загружаются и используются движком Robust Toolbox. Они помогают отделить логику от данных: например, если вы хотите изменить внешний вид или характеристики предмета, вам не нужно перекомпилировать весь код - достаточно изменить соответствующий YAML-прототип.
Основные концепции
1. Что такое прототип?
Прототип - это шаблон или описание игрового объекта (или другого элемента игры), написанный в YAML-формате. Каждый прототип имеет:
- Уникальный идентификатор (ID) - по нему код находит и использует прототип
- Набор свойств - определяют, как будет выглядеть и вести себя объект в игре
- Возможность наследования - прототип может взять свойства от одного или нескольких других прототипов (как класс в программировании)
2. Что такое компонент?
Компонент - это модуль функционала для сущностей. Каждый компонент добавляет определённую способность сущности:
Sprite- добавляет спрайт (графику)Physics- делает сущность физическим объектом (с массой, гравитацией)Item- делает объект поднимаемым и переносимымDamageable- позволяет сущности получать урон
Сущность - это собрание компонентов. Без компонентов сущность не будет ни видно, ни взаимодействовать с миром.
3. Ключевые интерфейсы
В Robust Toolbox существуют два основных интерфейса для работы с прототипами:
IPrototype
Базовый интерфейс для всех прототипов. Определяет обязательное свойство ID.
public interface IPrototype
{
string ID { get; }
}
IInheritingPrototype
Расширение IPrototype, позволяющее прототипу наследовать свойства от родительских прототипов.
public interface IInheritingPrototype
{
string[]? Parents { get; }
bool Abstract { get; }
}
Структура YAML-прототипа
Общий формат
- type: <тип_прототипа>
id: <уникальный_идентификатор>
<свойство1>: <значение1>
<свойство2>: <значение2>
Пример: EntityPrototype (Сущность)
Сущности - это основные игровые объекты. Они описываются с помощью компонентов.
- type: entity
id: BaseControllable
abstract: true
save: false
components:
- type: Sprite
noRot: true
drawdepth: Mobs
- type: GravityAffected
- type: Physics
- type: Fixtures
fixtures:
fix1:
shape: !type:PhysShapeCircle
radius: 0.35
density: 50
mask: [MobMask]
layer: [MobLayer]
Основные типы прототипов
EntityPrototype (Сущности и предметы)
Сущность - это основной игровой объект: моб, предмет, устройство, стены и т.д.
Пример: Простой предмет (гаечный ключ)
- type: entity
name: wrench
parent: BaseItem
id: Wrench
description: "A common tool for assembly and disassembly."
components:
- type: Sprite
sprite: Objects/Tools/wrench.rsi
state: icon
- type: Item
size: Small
- type: Tag
tags:
- Wrench
- type: MeleeWeapon
wideAnimationRotation: 135
attackRate: 1.5
damage:
types:
Blunt: 4.5
- type: Tool
qualities:
- Anchoring
useSound:
path: /Audio/Items/ratchet.ogg
TagPrototype (Теги)
Теги используются для классификации сущностей и создания белых/чёрных списков.
- type: Tag
id: Airlock
SoundCollectionPrototype (Звуковые коллекции)
- type: soundCollection
id: MetalThud
files:
- /Audio/Effects/metal_thud1.ogg
- /Audio/Effects/metal_thud2.ogg
- /Audio/Effects/metal_thud3.ogg
Наследование прототипов
Базовое наследование
Прототипы могут наследовать свойства от других прототипов, используя поле parent.
- type: entity
id: BaseMob
abstract: true
parent: BaseControllable
components:
- type: MobCollision
- type: Physics
bodyType: KinematicController
Множественное наследование
Для множественного наследования используется массив в parent.
- type: entity
id: ComplexMob
abstract: true
parent: [BaseMob, MobDamageable, MobCombat]
components:
- type: CustomComponent
customProperty: "value"
Абстрактные прототипы
Абстрактные прототипы не могут быть использованы напрямую, только наследованы. Они используются для создания базовых шаблонов.
- type: entity
id: BaseControllable
abstract: true
save: false
components:
- type: Sprite
- type: Input
Создание собственного типа прототипа
Если вам нужен новый тип прототипа, создайте класс в C#:
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Shared.MyModule
{
[Prototype("customItem")]
public sealed class CustomItemPrototype : IPrototype
{
[IdDataField]
public string ID { get; private set; } = default!;
[DataField("name")]
public string Name { get; private set; } = "Неизвестный предмет";
[DataField("price")]
public int Price { get; private set; } = 0;
[DataField("modifiers")]
public ItemModifiers Modifiers { get; private set; } = new();
}
public sealed class ItemModifiers
{
[DataField("fireDamage")]
public int FireDamage { get; private set; } = 0;
[DataField("attackSpeedBonus")]
public float AttackSpeedBonus { get; private set; } = 0f;
}
}
Теперь создайте YAML-файл с прототипами:
- type: customItem
id: CustomSword
name: custom-sword-test
price: 50
modifiers:
fireDamage: 10
attackSpeedBonus: 0.2
Спавн сущностей в коде [C#]
Для спавна сущностей используйте IEntityManager:
using Robust.Shared.Prototypes;
using Robust.Shared.Map;
public class MySystem : EntitySystem
{
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
public void SpawnItemAtLocation(string prototypeId, EntityUid targetEntity)
{
var transform = _entityManager.GetComponent(targetEntity);
var item = _entityManager.SpawnEntity(prototypeId, transform.Coordinates);
}
}
Практические советы для новичков
1. Как начать с прототипов?
- Сначала изучите существующие прототипы в
/Resources/Prototypes/ - Создайте копию простого прототипа
- Измените его свойства (имя, спрайт, компоненты)
- Проверьте, работает ли ваш прототип
2. Пример: Создайте простой предмет "Моя Лампа"
- type: entity
id: MyLamp
name: "Моя Лампа"
description: "Простая лампа, которую я создал!"
components:
- type: Sprite
sprite: Objects/Lights/table_lamp.rsi
state: icon
- type: Item
size: 1
- type: Physics
bodyType: Dynamic
- type: Fixtures
fixtures:
fix1:
shape: !type:PhysShapeAabb
bounds: "-0.25,-0.25,0.25,0.25"
density: 5
- type: PointLight
color: "#ffffaa"
radius: 3
energy: 0.8
3. Советы по организации
- Уникальные ID: Используйте описательные названия (
Wrench,TableLamp) - Абстрактные прототипы: Используйте их для шаблонов
- Наследование: Максимально используйте для уменьшения дублирования
- Комментарии: Добавляйте комментарии для пояснения
FAQ - Часто задаваемые вопросы
Как добавить спрайт к предмету?
Используйте SpriteComponent и укажите путь к RSI-файлу:
- type: Sprite
sprite: Objects/MyCustomItem.rsi
state: icon
Как сделать предмет поднимаемым?
Добавьте ItemComponent:
- type: Item
size: Small # Tiny, Small, Normal, Large, Huge
Как добавить свет к сущности?
Используйте PointLightComponent:
- type: PointLight
color: "#ffffff"
radius: 5
energy: 1.0
Важные директории
/Resources/Prototypes/- Основная директория с прототипами/Resources/Prototypes/Entities/- Прототипы сущностей/Resources/Prototypes/Entities/Mobs/- Прототипы мобов/Resources/Prototypes/Entities/Objects/- Прототипы объектов