Upload
forkconf
View
214
Download
6
Embed Size (px)
DESCRIPTION
Citation preview
О докладчике
Якимец Максим
C# на сервере
Entity Component System
Использование
при разработке игр.
Структура доклада
• Что предлагает ООП• Различные Entity Component Systems• Выбор Artemis• Описание игрового мира. Примеры• AI, Scripting• Физика• Сеть• Tips & Tricks
Что предлагает ООП?
• Множественное наследование• Множество классов• Композиция• Типажи (traits)• АОП• Паттерн “Стратегия”
Множественное поведение
Entity Component Systems
UnityAshEmberArtemisApollo
Artemis
Entity System Framework
Entity Component System
Artemis• Entity - ID.• Components - данные• Systems - логика, поведение• Managers - управление данными, запросы
Data Oriented Design
Artemis
var world = new EntityWorld(initializeAll: true);
Entity entity = world.CreateEntity();entity.Add(new Transform(100, 100));entity.Add(new Velocity(1, 1));
Artemis
var frameTime = watch.Elapsed - currentTime;accumulator += frameTime;
while (accumulator >= minDelta){
entityWorld.Update(minDelta);accumulator -= minDelta;
}
currentTime = watch.Elapsed;
MovementSystem
[ArtemisEntitySystem]public class MovementSystem : EntityProcessingSystem{
public MovementSystem(): base(Aspect.All(typeof(Transform), typeof(Velocity)))
{}...
}
MovementSystem
public override void Process(Entity entity){
var velocity = entity.Get<Velocity>();var transform = entity.Get<Transform>();
var seconds = this.EntityWorld.Delta.TotalSeconds;
transform.X += velocity.X * seconds;transform.Y += velocity.Y * seconds;
}
[ArtemisEntitySystem]public class AfterlifeSystem : EntityProcessingSystem{
public event Action<Entity> EntityVanishing;
public AfterlifeSystem(): base(Aspect.All(typeof(KilledComponent)))
{}
public override void Process(Entity entity){
var expiresComponent = entity.Get<ExpiresComponent>();if (expiresComponent == null || expiresComponent.IsExpired){
this.OnEntityVanishing(entity);entity.Delete();
}}
private void OnEntityVanishing(Entity entity){
var handler = this.EntityVanishing;if (handler != null){
handler(entity);}
}}
Position (Transform)Velocity (Movement)Lifetime (Expires)Health (Destroyable)Attack (Damager)Dead (Killed)GoldBountyRewardBonusInputControllerAnimationColliderPhysics
MovementSystemExpirationSystemAttackSystemAfterlifeSystemBonusSystemBountyRewardSystemAnimationSystemRenderSystemPhysicsSystem
Описание игрового мира
CellPositionScreenPositionDamagerTimedEffectSpreadableDestroyableCollidableBombLayerPowerup
Описание игрового мира
Описание игрового мира
EnemyComponentExpiresComponentHealthComponentWeaponComponentTransformComponentVelocityComponentSpatialFormComponent
EnemyComponentExpiresComponentHealthComponentWeaponComponentTransformComponentVelocityComponentSpatialFormComponent
Описание игрового мира
EnemyShipMovementSystem ExpirationSystemEnemyShooterSystem PlayerShipControlSystemCollisionSystemMovementSystemRenderSystemHudRenderSystemEnemySpawnSystem
Scripting
public class ScriptComponent: IComponent{ public IScript Script { get; set; }}
public interface IScript{ void Init(EntityWorld world, Entity entity); void Update();}
Scripting
ScriptComponent (IScript) + ScriptSystem
vs
BehaviorXComponent + BehaviorXSystemBehaviorYComponent + BehaviorYSystem
AI: BehaviorLibrary
public class AIComponent: IComponent{ public Behavior Behavior { get; set; }}
public class AISystem : EntityProcessingSystem{ public override void Process(Entity entity) { entity.Get<AIComponent>().Behavior.Behave(); }}
Физика
PhysicsComponent: Body
PhysicsSystem: OnAdded -> physicsWorld.Add(body) OnRemoved -> physicsWorld.Remove(body)
ProcessEntities -> physicsWorld.Step();
Физика: Position
PositionComponent
PhysicsComponent:Body (Position + Form)
Сеть
• ECS на сервере и на клиенте• ECS на сервере, ООП на клиенте
Сеть
foreach (Entity player in this.players){ float gold = player.Get<Gold>().Value;
if (this.playersGold[player.Id] != gold) { this.playersGold[player.Id] = gold; this.RaiseGoldChangedEvent(gold, player); }}
Tips & tricks
Взаимодействиемежду частями Entity System
Entity-EntityComponent-ComponentEntity-Component
System-System
Tips & tricks
• Порядок срабатывания систем• Удаление/добавление Component• Удаление Entity
Tips & tricks
Pooling• entity pool• component pool
Проблема с переиспользованием Entity.Id
Tips & tricks
Карта - это Entity? Component?
Tips & tricks
Связи между Entity:• references• IDs• Managers• System data
Пример: инвентарь
public class InventoryComponent: IComponent{ public List<Entity> Items { get; set; }}
public class InventoryItemComponent: IComponent{ public Entity Inventory { get; set; }}
public class InventoryManager{ private Dictionary<Entity, List<Entity>> inventories;}
Пример: Заклинания
• Удар молнии = Position + Damage + Attacking• Камнепад = Position + Damage + AoE + Attacking• Мина = Position + Damage + AoE• Бомба с фитилем = Position + Damage + AoE +
Expires + AttackOnExpires• Болото = Position + AoE + Expires + BuffSource• Усиление = Position + AoE + Expires(0) + BuffSource
Пример: неуязвимость
Неуязвимость
HealthComponentDefenseComponent
“Build games, not engines”
“Build games, not elaborate component systems!”
“Entity Systems are the future of MMOs”
“A game is just a real-time database with a pretty graphical front end.”
“Do not try and bend the spoon - that's impossible. Instead, only try to realize the truth… There is no spoon.”