Atomic is an architectural framework for game development in Unity and C#, built around the Entity–State–Behaviour
pattern and using Atomic elements for data organization.
- Requirements
- Installation
- Using Odin Inspector
- Using Atomic Plugin for Rider
- Key Concepts
- Documentation
- Unity Quick Start
- CSharp Quick Start
- Game Examples
- Best Practices
- Performance
- License
- Contacts
The Atomic Framework requires Unity 6 or .NET 7+. Make sure your development environment meets these requirements before using the framework.
- Option #1. Download source code with game examples
- Option #2. Download Atomic.unitypackage or AtomicNonUnity.zip from release notes
- Option #3: Install via Unity Package Manager using the Git
URL:
https://github.com/StarKRE22/Atomic.git?path=Assets/Plugins/Atomic
For better debugging, configuration, and visualization of game state, we optionally recommend using Odin Inspector. The framework works without Odin, but Odin makes inspection and tweaking much easier.
🔌 Using Plugin for Rider (Read More)
For better code generation and more convenient workflow in Rider IDE, we highly recommend installing
the Atomic Rider Plugin from Jetbrains Marketplace
or GitHub Repository . By default, the code generation works with
Unity, but with the plugin, development experience in Rider IDE become
smoother and more powerful than in Unity.
- Entity — a container holding a set of data (
State) and logic (Behaviour), kept strictly separate. - State — a collection of
atomiccomponents defining the entity's parameters. - Behaviour — controllers that operate on the entity’s
Statethey are attached to.
Any game object, system, AI, or UI can be represented as a composition of data and logic, making systems modular and predictable.
Complex systems should be built from atomic elements.
Instead of creating large, monolithic objects, entities’ State can be composed of small, reusable atomic elements.
This ensures data remains modular, predictable, and reusable, while behaviours act on these well-defined building blocks.
Game development often involves highly interactive systems. Traditional Object-Oriented Programming (OOP) can struggle to model these interactions cleanly, creating unnecessary complexity.
Atomic Framework encourages a procedural approach, leveraging static methods and a centralized data registry
instead of tightly coupled objects.
This approach simplifies interactions, improves maintainability, and scales well for large entity-driven projects.
Atomic Framework consists of two main modules, each serving a distinct role in how you structure and build your game:
⚛️ Atomic.Elements (Read More)
A library of atomic elements for constructing complex game objects and systems in Unity and C#. The solution includes constants, variables, reactive properties, collections, events, and actions, enabling developers to quickly assemble any game entity like a LEGO constructor.
🧩 Atomic.Entities (Read More)
A framework implementing the Entity–State–Behaviour pattern in Unity and C#. In addition to basic entities and
behaviours, the solution provides factories, pools, worlds, filters, and a separate UI layer if Unity is used
as the presentation layer.
- Entities
- Behaviours
- Installers
- Aspects
- Factories
- Baking
- Pooling
- Collections
- Worlds
- Registry
- Filters
- Triggers
- Lifecycle
- Views
- Names
- API Generation
Below is the process for quickly creating a character entity in Unity
// Controller that moves entity by its direction
public sealed class MoveBehaviour : IEntityInit, IEntityFixedTick
{
private Transform _transform;
private IValue<float> _moveSpeed;
private IValue<Vector3> _moveDirection;
// Called when MonoBehaviour.Start() is invoked
public void Init(IEntity entity)
{
_transform = entity.GetValue<Transform>("Transform");
_moveSpeed = entity.GetValue<IValue<float>>("MoveSpeed");
_moveDirection = entity.GetValue<IValue<Vector3>>("MoveDirection");
}
// Called when MonoBehaviour.FixedUpdate() is invoked
public void FixedTick(IEntity entity, float deltaTime)
{
Vector3 direction = _moveDirection.Value;
if (direction != Vector3.zero)
_transform.position += _moveSpeed.Value * deltaTime * direction;
}
}//Populates entity with tags, values and behaviours
public sealed class CharacterInstaller : SceneEntityInstaller
{
[SerializeField] private Transform _transform;
[SerializeField] private Const<float> _moveSpeed = 5.0f; //Immutable variable
[SerializeField] private ReactiveVariable<Vector3> _moveDirection; //Mutable variable with subscription
public override void Install(IEntity entity)
{
//Add tags to a character
entity.AddTag("Character");
entity.AddTag("Moveable");
//Add properties to a character
entity.AddValue("Transform", _transform);
entity.AddValue("MoveSpeed", _moveSpeed);
entity.AddValue("MoveDirection", _moveDirection);
//Add behaviours to a character
entity.AddBehaviour<MoveBehaviour>();
}
}
Below is the process for quickly creating an entity in plain C#
//Create a new entity
IEntity entity = new Entity("Character");
//Add tags
entity.AddTag("Moveable");
//Add properties
entity.AddValue("Position", new ReactiveVariable<Vector3>());
entity.AddValue("MoveSpeed", new Const<float>(3.5f));
entity.AddValue("MoveDirection", new ReactiveVariable<Vector3>());//Controller that moves entity by its direction
public sealed class MoveBehaviour : IEntityInit, IEntityTick
{
private IVariable<Vector3> _position;
private IValue<float> _moveSpeed;
private IValue<Vector3> _moveDirection;
//Called when Entity.Init()
public void Init(IEntity entity)
{
_position = entity.GetValue<IVariable<Vector3>>("Position");
_moveSpeed = entity.GetValue<IValue<float>>("MoveSpeed");
_moveDirection = entity.GetValue<IValue<Vector3>>("MoveDirection");
}
//Called when Entity.OnUpdate()
public void Tick(IEntity entity, float deltaTime)
{
Vector3 direction = _moveDirection.Value;
if (direction != Vector3.zero)
_position.Value += _moveSpeed.Value * deltaTime * direction;
}
}entity.AddBehaviour<MoveBehaviour>();// Initialize the entity -> Calls IEntityInit
entity.Init();
// Enable the entity for updates -> Calls IEntityEnable
entity.Enable();
// Update your entity while game is running
const float deltaTime = 0.016f; // 60 FPS
while(isGameRunning)
{
entity.Tick(deltaTime); // Calls IEntityTick
System.Threading.Thread.Sleep(16); // deltaTime * 1000
}
// Disable entity for updates -> Calls IEntityDisable
entity.Disable();
// Dispose entity resources -> Calls IEntityDispose
entity.Dispose();This section presents three sample projects, each demonstrating a different level of complexity and use case of the
framework.
All examples are available inside Assets/Examples.
- Beginner Sample — a simple 2-player mini-game showcasing the core principles of the framework.
- Top-Down Shooter Sample — a more advanced, modular game architecture suitable for mid-sized projects.
- RTS Sample — a large-scale simulation demonstrating high-performance entity management with thousands of units.
A simple 2-player mini-game designed to introduce the fundamental ideas behind the Atomic framework. Link to the sample.
This sample represents the most basic foundation of the Atomic framework with Unity. It demonstrates how to build
gameplay using a universal SceneEntity, showing three minimal entities:
GameContextCharacterCoin
Everything here is intentionally kept as simple and transparent as possible, focusing on the core idea of the atomic approach — how logic can emerge from the composition of small, modular elements.
The project uses code generation in Unity and serves as a minimal example for rapid prototyping within the Atomic ecosystem.
- Players: Two players share a single arena.
- Goal: Collect more coins than your opponent within a limited time.
- Controls:
- Player (Blue): Arrow keys
- Player (Red):
W,A,S,D
- Creating and configuring Entity objects in Unity.
- Structuring a project using the Entity–State–Behaviour pattern.
- Using atomic elements to drive logic and interaction.
- Applying code generation for fast and clean iteration.
The Top-Down Shooter demonstrates a more sophisticated and scalable game architecture, suitable for mid-size projects. Link to the sample.
- Players: Two players in a shared arena.
- Objective: Eliminate your opponent more times than they eliminate you, within a time limit.
- Controls:
- Player (Blue): Arrow keys to move,
Spaceto shoot - Player (Red):
W,A,S,Dto move,Qto shoot
- Player (Blue): Arrow keys to move,
- Mechanics:
- Movement: Kinematic character movement with
Rigidbody.SweepTestcollision handling. - Combat: Independent weapon entities firing physical projectiles.
- Projectile: Kinematic object with trigger collisions and limited lifetime.
- Respawn: Units reappear at random points after death.
- Time Limit: The match ends when the timer expires.
- Movement: Kinematic character movement with
- Visualization:
- Animated characters with sound and VFX.
- UI displays kills and time remaining.
- Scenes:
Bootstrap— initializes and loads the game.Menu— the main navigation scene.- Levels: three stages featuring player and enemy spawning.
- Save System: Remembers the last completed level.
- Loading Tree: Hierarchical scene-loading sequence for structured bootstrapping.
- Designing a complete, scalable game architecture.
- Implementing an application context using the Entity–State–Behaviour pattern.
- Building procedural menu systems.
- Managing complex loading flows with a Loading Tree.
- Saving and restoring persistent game data.
- Turning entities into fully featured game objects with animation, VFX, and audio.
- Managing projectile pools efficiently.
- Structuring a modular project file system.
The RTS Sample showcases high-performance entity management — running thousands of active units in real time with minimal overhead. Link to the sample.
- Armies: Two large armies automatically engage in battle — each consisting of infantry, tanks, and buildings.
- Buildings: Have health points and serve as static defense or production units.
- Infantry: Possesses health, performs melee attacks, and seeks the nearest enemy.
- Tanks: Fire projectiles and detect enemies within range.
- Projectiles: Travel toward targets with limited lifetime and cause impact damage.
- CameraControls:
- Movement: WASD
- Zoom: Mouse Scroll
- 5000 Units Scene — 5,000 visualized GameObjects for real-time simulation.
- 10000 Units Scene — 10,000 entities simulated without visualization for performance benchmarking.
- Entity Baking Scene — demonstrates converting Unity scene objects into pure C# entities for simulation.
- Running complete game logic in pure C#, using Unity solely for visualization.
- Employing
EntityWorld,EntityFactory,EntityPool,EntityFilter, andEntityTriggers. - Using
EntityView,EntityViewPool, andEntityCollectionViewfor rendering and synchronization. - Managing 5,000–10,000 active objects efficiently on a single thread.
- Baking Unity objects into a pure data-driven simulation architecture.
This section outlines recommended approaches and patterns when working with the library. Following these practices will help you write modular, testable, and high-performance code, whether you’re developing single-player or multiplayer games.
- Architecture
- File System Organization
- Prefer Atomic Interfaces to Concrete Classes
- Flyweight Pattern for Constants
- Request-Condition-Action-Event (RCAE) Flow
- Modular EntityInstallers
- Upgrading EntityFactory to the Builder
- Combine EntityPool with EntityFactory
- Building Entity System with Model & View Separation
- Overriding EntityFactories with EntityBakers
- Optimization
- Features
- InlineActions with Entities
- InlineFunctions with Entities
- Events with Entities
- Requests with Entities
- Requests vs Actions
- Cooldown with Entities
- Timer vs Cooldown
- Expressions with Entities
- Setters with Entities
- Uninstall Method for EntityInstallers
- DisposeComposite in EntityInstallers
- PlayMode & EditMode for EntityInstallers
- Optional with EntityInstallers
- Extensions
This section focuses on runtime efficiency within the framework. It provides detailed benchmarks, comparisons, and implementation notes that highlight how different systems and data structures perform under real-world conditions.
- Atomic.Entities
- Atomic.Elements
This project is licensed under the MIT License.
MIT License
Copyright (c) 2025 Igor Gulkin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Author: Igor Gulkin
Telegram: t.me/starkre22
Email: gulkin.igor.developer@gmail.com

