Simple Syntax for DragonECS
July 29, 2026 · View on GitHub
Read
Warning
Simple Syntax is slower than the standard DragonECS API. It is convenient for small games, samples, and prototyping, but it is not recommended for performance-sensitive code.
This extension reduces boilerplate around entity access, masks, and simple iteration. It gives entlong a more object-oriented style and adds compact Inc/Exc, tuple-query, and lambda ForEach syntax.
Installation
Copy the scripts into the project. The extension types are internal, so they should not conflict with other assemblies.
Features
- Entity helpers:
Get<T>(),Add<T>(component),Has<T>(),Del<T>(). - Tag helpers:
Add<T>(),Set<T>(bool),Toggle<T>(),Has<T>(),Del<T>(). - Entity utilities:
Delete(),Clone(),Clone(toWorld),IsMatchesMask(mask),GetComponentsCount(). - Mask syntax:
Inc<A, B>.Exc<C>.m; generated masks support up to 8 included components and up to 4 excluded components. - Query syntax:
foreach (var e in (world, mask)). - Lambda iteration:
world.With<T>().Without<Tag>().ForEach(...);ForEachsupports up to 8 component refs, whileWith/Withoutbuilders support up to 4 types per call.
Get<T>() uses TryAddOrGet, so it creates the component if the entity does not have it yet. Use Has<T>() first when component presence must be checked without adding it.
ForEach adds lambda component types to the mask as Inc automatically. Use With<T>() for extra filters, such as tags or components that should not be passed by ref.
Examples
Mask field:
public class VelocitySystem : IEcsRun
{
Inc<Transform, Velocity>.Exc<FreezedTag> _mask;
[DI] EcsDefaultWorld _world;
[DI] TimeService _time;
public void Run()
{
foreach (var e in (_world, _mask))
{
e.Get<Transform>().position += e.Get<Velocity>().value * _time.DeltaTime;
}
}
}
Inline mask:
public class VelocitySystem : IEcsRun
{
[DI] EcsDefaultWorld _world;
[DI] TimeService _time;
public void Run()
{
foreach (var e in (_world, Inc<Transform, Velocity>.Exc<FreezedTag>.m))
{
e.Get<Transform>().position += e.Get<Velocity>().value * _time.DeltaTime;
}
}
}
Lambda iteration:
public class VelocitySystem : IEcsRun
{
[DI] EcsDefaultWorld _world;
[DI] TimeService _time;
public void Run()
{
_world.Without<FreezedTag>().ForEach((entlong e, ref Transform transform, ref Velocity velocity) =>
{
transform.position += velocity.value * _time.DeltaTime;
});
}
}
Entity and tag helpers:
if (e.Has<Health>())
{
ref var health = ref e.Get<Health>();
health.Value -= damage;
}
e.Add<FreezedTag>();
e.Toggle<FreezedTag>();
e.Del<FreezedTag>();
entlong copy = e.Clone();
e.Delete();
Standard DragonECS syntax
public class VelocitySystem : IEcsRun
{
class Aspect : EcsAspect
{
public EcsPool<Transform> transforms = Inc;
public EcsPool<Velocity> velocities = Inc;
public EcsTagPool<FreezedTag> freezedTags = Exc;
}
[DI] EcsDefaultWorld _world;
[DI] TimeService _time;
public void Run()
{
foreach (var e in _world.Where(out Aspect a))
{
a.transforms.Get(e).position += a.velocities.Get(e).value * _time.DeltaTime;
}
}
}
Open mask generator if the built-in number of generic parameters is not enough. The generated code can replace EntLongQueryExtensions.cs.
Читать
Упрощенный синтаксис для DragonECS
Warning
Упрощенный синтаксис работает медленнее стандартного API DragonECS. Он удобен для небольших игр, примеров и прототипирования, но не рекомендуется для кода, чувствительного к производительности.
Это расширение уменьшает бойлерплейт при работе с сущностями, масками и простой итерацией. Оно добавляет для entlong более объектно-ориентированный стиль, а также компактный синтаксис Inc/Exc, tuple-запросов и lambda ForEach.
Установка
Скопируйте скрипты в проект. Типы расширения имеют видимость internal, поэтому не должны конфликтовать с другими сборками.
Возможности
- Методы для сущностей:
Get<T>(),Add<T>(component),Has<T>(),Del<T>(). - Методы для тегов:
Add<T>(),Set<T>(bool),Toggle<T>(),Has<T>(),Del<T>(). - Утилиты сущностей:
Delete(),Clone(),Clone(toWorld),IsMatchesMask(mask),GetComponentsCount(). - Синтаксис масок:
Inc<A, B>.Exc<C>.m; сгенерированные маски поддерживают до 8 включенных компонентов и до 4 исключенных компонентов. - Синтаксис запросов:
foreach (var e in (world, mask)). - Lambda-итерация:
world.With<T>().Without<Tag>().ForEach(...);ForEachподдерживает до 8 компонент поref, аWith/Without- до 4 типов за один вызов.
Get<T>() использует TryAddOrGet, поэтому создает компонент, если у сущности его еще нет. Используйте Has<T>(), если нужно проверить наличие компонента без добавления.
ForEach автоматически добавляет типы компонентов из lambda в маску как Inc. Используйте With<T>() для дополнительных фильтров, например тегов или компонентов, которые не нужно передавать по ref.
Примеры
Маска в поле:
public class VelocitySystem : IEcsRun
{
Inc<Transform, Velocity>.Exc<FreezedTag> _mask;
[DI] EcsDefaultWorld _world;
[DI] TimeService _time;
public void Run()
{
foreach (var e in (_world, _mask))
{
e.Get<Transform>().position += e.Get<Velocity>().value * _time.DeltaTime;
}
}
}
Маска прямо в запросе:
public class VelocitySystem : IEcsRun
{
[DI] EcsDefaultWorld _world;
[DI] TimeService _time;
public void Run()
{
foreach (var e in (_world, Inc<Transform, Velocity>.Exc<FreezedTag>.m))
{
e.Get<Transform>().position += e.Get<Velocity>().value * _time.DeltaTime;
}
}
}
Lambda-итерация:
public class VelocitySystem : IEcsRun
{
[DI] EcsDefaultWorld _world;
[DI] TimeService _time;
public void Run()
{
_world.Without<FreezedTag>().ForEach((entlong e, ref Transform transform, ref Velocity velocity) =>
{
transform.position += velocity.value * _time.DeltaTime;
});
}
}
Методы сущностей и тегов:
if (e.Has<Health>())
{
ref var health = ref e.Get<Health>();
health.Value -= damage;
}
e.Add<FreezedTag>();
e.Toggle<FreezedTag>();
e.Del<FreezedTag>();
entlong copy = e.Clone();
e.Delete();
Стандартный синтаксис DragonECS
public class VelocitySystem : IEcsRun
{
class Aspect : EcsAspect
{
public EcsPool<Transform> transforms = Inc;
public EcsPool<Velocity> velocities = Inc;
public EcsTagPool<FreezedTag> freezedTags = Exc;
}
[DI] EcsDefaultWorld _world;
[DI] TimeService _time;
public void Run()
{
foreach (var e in _world.Where(out Aspect a))
{
a.transforms.Get(e).position += a.velocities.Get(e).value * _time.DeltaTime;
}
}
}
Открыть генератор масок, если не хватает встроенного количества generic-параметров. Сгенерированный код может заменить EntLongQueryExtensions.cs.