Version


🚀 Benchmarks 🚀

⚙️ Unity module ⚙️

❗️ Гайд миграции с версии 1.0.x на 1.2.x ❗️

Static ECS - C# Binary Entity component system framework

  • Легковесность
  • Производительность
  • Отсутствие аллокаций
  • Без Unsafe
  • Основан на статике и структурах
  • Типобезопасность
  • Бесплатные абстракции
  • Мощный механизм запросов
  • Минимум болерплейта
  • Совместимость с Unity с поддержкой Il2Cpp и Burst
  • Совместимость с другими C# движками
  • Совместимость с Native AOT

Оглавление

Контакты

Установка

Библиотека имеет зависимость на StaticPack версии 1.0.6 для бинарной сериализации, StaticPack должен быть так же установлен

  • В виде исходников

    Со страницы релизов или как архив из нужной ветки. В ветке master стабильная проверенная версия

  • Установка для Unity

    • Как git модуль в Unity PackageManager
      https://github.com/Felid-Force-Studios/StaticEcs.git
      https://github.com/Felid-Force-Studios/StaticPack.git
    • Или добавление в манифест Packages/manifest.json
      "com.felid-force-studios.static-ecs": "https://github.com/Felid-Force-Studios/StaticEcs.git"
      "com.felid-force-studios.static-pack": "https://github.com/Felid-Force-Studios/StaticPack.git"

Концепция

StaticEcs — новая архитектура ECS, основанная на инвертированной иерархической bitmap модели. В отличие от традиционных фреймворков ECS, которые полагаются на архетипы или разреженные наборы, в этой конструкции используется инвертированная индексная структура, в которой каждый тип компонента владеет масками активных сущностей, а не сущности хранят маски компонентов. Иерархическая агрегация этих масок обеспечивает логарифмическое индексирование блоков сущностей, что позволяет осуществлять фильтрацию блоков O(1) и эффективную параллельную итерацию с помощью битовых операций. Этот подход полностью устраняет миграцию архетипов и sparse set индирекцию, предлагая прямой доступ к памяти в стиле SoA с минимальным количеством промахов кэша. Модель обеспечивает до 64 раз меньшее количество запросов к памяти на блок и линейно масштабируется с количеством активных наборов компонентов, что делает ее идеальной для крупномасштабных симуляций, реактивного ИИ и открытых миров.

  • Основная идея данной реализации в статике, все данные о мире и компонентах находятся в статических классах, что дает возможность избегать дорогостоящих виртуальных вызовов, иметь удобный API со множеством сахара
  • Данный фреймворк нацелен на максимальную простоту использования, скорость и комфорт написания кода без жертв в производительности
  • Доступно создание мульти-миров, строгая типизация, обширные бесплатные абстракции
  • Система сериализации
  • Система отношений сущностей
  • Многопоточная обработка
  • Низкое потребление памяти
  • Основан на Bitmap архитектуре, нет архетипов, нет sparse-set
  • Фреймворк создан для нужд частного проекта и выложен в open-source.

Быстрый старт

using FFS.Libraries.StaticEcs;

// Определяем тип мира
public struct WT : IWorldType { }

// Определяем типы-алиасы для удобного доступа к типам библиотеки
public abstract class W : World<WT> { }

// Определяем тип систем
public struct SystemsType : ISystemsType { }

// Определяем тип-алиас для удобного доступа к системам
public abstract class Systems : W.Systems<SystemsType> { }

// Определяем компоненты
public struct Position : IComponent { public Vector3 Value; }
public struct Direction : IComponent { public Vector3 Value; }
public struct Velocity : IComponent { public float Value; }

// Определяем системы
public readonly struct VelocitySystem : IUpdateSystem {
    public void Update() {
        foreach (var entity in W.Query.Entities<All<Position, Velocity, Direction>>()) {
            entity.Ref<Position>().Value += entity.Ref<Direction>().Value * entity.Ref<Velocity>().Value;
        }
        
        // Или
        W.Query.For((ref Position pos, ref Velocity vel, ref Direction dir) => {
            pos.Value += dir.Value * vel.Value;
        });
    }
}

public class Program {
    public static void Main() {
        // Создаем данные мира
        W.Create(WorldConfig.Default());
        
        // Регистрируем компоненты
        W.RegisterComponentType<Position>();
        W.RegisterComponentType<Direction>();
        W.RegisterComponentType<Velocity>();
        
        // Инициализируем мир
        W.Initialize();
        
        // Создаем системы
        Systems.Create();
        Systems.AddUpdate(new VelocitySystem());

        // Инициализируем системы
        Systems.Initialize();

        // Создание сущности
        var entity = W.Entity.New(
            new Velocity { Value = 1f },
            new Position { Value = Vector3.Zero },
            new Direction { Value = Vector3.UnitX }
        );
        
        // Обновление всех систем - вызывается в каждом кадре
        Systems.Update();
        // Уничтожение систем
        Systems.Destroy();
        // Уничтожение мира и очистка всех данных
        W.Destroy();
    }
}

Лицензия

MIT license