Friflo ECS

repository·main·Indexed 20 days ago

https://github.com/friflo/friflo.engine.ecs

A high-performance, fully managed C# Entity Component System (ECS) designed for game engines and data processing. It provides C/C++/Rust-level performance without using unsafe code, featuring SIMD support, zero-allocation enumerators, and advanced querying. Supports .NET Standard 2.1, .NET 5-10, WASM, Unity, Godot, MonoGame, and Native AOT. Includes advanced data modeling such as indexing, relationships, and relations, with an optional Boost extension for further performance optimization via unsafe code.

Tokens
8.3K
Snippets
18
Records
29
Agent score
72%

What's inside Friflo.Engine.ECS

  1. Overview of Friflo.Engine.ECS

    main

    Friflo.Engine.ECS is a high-performance, high-security Entity Component System (ECS) for C#. It is designed for developers who want a simple, boilerplate-free API without sacrificing performance.

    Key characteristics include:

    • High Performance & Low Memory: Capable of creating 100,000,000 entities in 1.5 seconds with zero allocations once buffers are sufficiently sized.
    • Security: 100% secure C# implementation with no unsafe code, no native DLL bindings, and no access violations.
    • Advanced Features: Supports entity relationships, hierarchies, reactive entity events, command buffers for deferred operations, and SIMD support.
    • Broad Compatibility: Supports .NET Standard 2.1, .NET 5/6/7/8, WASM, Unity (Mono, AOT/IL2CPP, WebGL), Godot, MonoGame, and Native AOT.
  2. Core features of Friflo ECS

    main

    Friflo ECS is a high-performance, fully managed C# ECS library. Key features include:

    • Performance: C/C++/Rust-like speed and memory efficiency with SIMD support.
    • Reliability: Fully managed C# with no unsafe code, preventing memory corruption and access violations.
    • Core ECS Concepts: Components, tags, relations, and systems.
    • Advanced Querying: High-performance, type-safe, and efficient multithreaded queries.
    • Operations: Fast batch/bulk operations, command buffers (deferred operations), and entity cloning/copying.
    • Structure: Entity hierarchy (scene tree) and relationships.
    • Memory Management: Zero allocations after buffers are sufficiently large; allocation-free enumerators.
    • Integration: JSON serialization and automatic component type registration.
    • Compatibility: Supports .NET Standard 2.1, .NET 5-10, WASM, Unity (Mono, AOT/IL2CPP, WebGL), Godot, MonoGame, and Native AOT.
  3. What is Entity Component System (ECS)?

    main

    An ECS is a software architecture pattern used for high-performance data processing, common in the gaming industry. It provides two main strengths:

    1. Decoupled Code: Data is stored in Components which are assigned to Entities at runtime. Implementation is divided into pure data structures (Component types) and code (Systems) that process them.
    2. High Performance: Components are stored in continuous memory to leverage CPU caches (L1, L2, L3) and improve CPU branch prediction by minimizing conditional branches during tight loops.
  4. Core Concepts of Friflo ECS

    main

    Friflo ECS follows the standard Entity-Component-System architecture pattern to enable decoupled code and high-performance data processing:

    • Entities: Objects that exist at runtime to which data is assigned.
    • Components: Pure data structures (Component types) that are assigned to Entities.
    • Systems: The logic/code used to process the data stored in Components.

    By storing components in continuous memory, the engine leverages CPU caches (L1, L2, L3) and improves branch prediction, making it ideal for high-performance scenarios like game development.

  5. Understand Prefabs in friflo ECS

    main

    Prefabs are used to create multiple copies or variations of the same asset within a scene. They allow you to define a template (an asset file) and then instantiate it or modify specific parts of it in a parent scene.

    Key Capabilities

    • Modification: Add or modify components on an existing prefab entity.
    • Addition: Add new entities to a prefab instance.
    • Removal: Remove specific entities that belong to a prefab.
    • Performance: Designed to support millions of entities with minimal heap usage and efficient loading/saving.

    Usage Modes

    • Edit Mode: Used when loading a scene or applying changes to a prefab.
    • Play Mode: Used when loading a scene or creating a prefab instance during runtime.

    Important Constraints

    • Reloading: The system does not support reloading an already loaded scene into the same EntityStore. To reload a modified scene, you must remove the current EntityStore instance and create a new one.
    • Stability: Entity ids used in scenes are stable (permanent), ensuring that links to them remain valid.
  6. New features in v3.0.0: Indexing, Relationships, and Relations

    main

    Version 3.0.0 introduced several advanced data modeling features:

    • Index / Search: Allows searching for entities with specific component values in $O(1)$ time. Useful for looking up entities by specific IDs (e.g., Guid, long, or string) within a component.
    • Relationships: Enables creating links or connections between entities, allowing you to build directed graphs where entities are nodes and relations are edges (e.g., for pathfinding or social networks).
    • Relations: Allows adding multiple instances of the same component type to a single entity, which is useful for modeling one-to-many structures like inventories.
  7. Compare Friflo ECS with Unity and Godot

    main

    This comparison highlights the fundamental architectural differences between Friflo ECS (an Entity Component System) and traditional Object-Oriented Programming (OOP) engines like Unity and Godot.

    Key differences include:

    • Entity Type: In Friflo, an Entity is a lightweight struct, whereas in Unity and Godot, they are heavy classes (GameObject or Node).
    • Existence: Friflo entities are optional (can be null/non-existent), while Unity GameObjects are always present.
    • Components: Friflo uses IComponent structs and provides explicit methods for component management (AddComponent<T>, GetComponent<T>, etc.), whereas Unity uses a class-based approach.
    • Tags: Friflo uses ITag structs for type-safe tagging and provides methods like Entity.Tags.Has<T>(), compared to Unity's string-based tagging.
    • Hierarchy: Friflo provides direct access to child entities and IDs via Entity.ChildEntities and Entity.ChildIds.
  8. Install Friflo ECS via NuGet or dotnet CLI

    main

    You can add Friflo ECS to your C# project using the NuGet package manager or the dotnet CLI. It supports .NET Standard 2.1, .NET 5 through .NET 10, WASM, Unity, Godot, and MonoGame.

    dotnet add package Friflo.Engine.ECS
  9. Use Friflo.Engine.ECS.Boost for improved query performance

    main

    If you are experiencing performance bottlenecks during query execution in Friflo.Engine.ECS, you can use the Friflo.Engine.ECS.Boost extension.

    This extension improves performance by using unsafe code to elide array bounds checks during query execution. This is particularly effective for large query result sets, where it can provide a performance boost of approximately 30%.

    Warning: While the core Friflo.Engine.ECS library uses only verifiably safe code, Friflo.Engine.ECS.Boost utilizes unsafe code. While this is done to optimize performance, users should be aware that unsafe code can lead to access violation errors if bugs are present in the unsafe implementation.

  10. Generate API documentation using mddocs

    main

    The mddocs tool (via the Grynwald.MdDocs package) is used to generate API documentation as Markdown. It is preferred for its ability to combine overloaded methods into a single file and maintain stable file paths based on the namespace/class/[constructor|fields|methods|properties] structure.

    To generate documentation, you must point the tool to your compiled assembly (e.g., Friflo.Engine.ECS.dll) and provide a configuration file.

    # Install the tool globally
    dotnet tool install --global Grynwald.MdDocs
    
    # Generate documentation
    # Note: Run this from the directory containing your compiled DLL
    cd Tests/bin/Release/net8.0
    mddocs apireference --assemblies "Friflo.Engine.ECS.dll" --configurationFilePath ../../../../scripts/api-reference.json
  11. Create a 'Hello World' ECS setup

    main

    To get started with friflo ECS, you need to create an EntityStore (the world), create entities with components, and then use a Query to iterate over them. Components must implement the IComponent interface.

    For high-performance scenarios involving millions of entities, consider using optimized enumeration techniques like Enumerate Query Chunks, Parallel Query Job, or Query Vectorization (SIMD).

    public struct Velocity : IComponent { public Vector3 value; }
    
    public static void HelloWorld()
    {
        var world = new EntityStore();
        for (int n = 0; n < 10; n++) {
            world.CreateEntity(new Position(n, 0, 0), new Velocity{ value = new Vector3(0, n, 0)});
        }
        var query = world.Query<Position, Velocity>();
        query.ForEachEntity((ref Position position, ref Velocity velocity, Entity entity) => {
            position.value += velocity.value;
        });
    }
  12. Make libraries compatible with NativeAOT

    main

    To ensure compatibility with NativeAOT and suppress reflection-related trim warnings (such as IL2070), you can use the UnconditionalSuppressMessage attribute. This is useful when a method is intentionally not called during NativeAOT execution but would otherwise trigger a warning.

    [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070", Justification = "Not called for NativeAOT")]