Skip to content

Tutorial

Yaroslav Sarchuk edited this page Aug 29, 2025 · 1 revision

Tutorial: Building Your First Atomic Project

This step-by-step tutorial will guide you through creating a complete game component system using the Atomic Plugin.

๐Ÿ“š What You'll Learn

  • Creating and configuring .atomic files
  • Generating extension methods for entities
  • Using generated code in your game
  • Working with tags and values
  • Optimizing with advanced features

๐ŸŽฎ Project Overview

We'll build a simple RPG character system with:

  • Character entities with health, mana, and stats
  • Inventory system with items
  • Combat system with damage calculation
  • Buff/debuff system

Step 1: Project Setup

1.1 Create Unity Project

  1. Open Unity Hub
  2. Create new 3D project named "AtomicRPG"
  3. Install Atomic Framework:
    # In Unity Package Manager, add from git URL:
    https://github.com/StarKRE22/Atomic.git

1.2 Open in Rider

  1. Open the project in JetBrains Rider
  2. Verify Atomic Plugin is installed (see Installation)
  3. Create folder structure:
    Assets/
    โ”œโ”€โ”€ Scripts/
    โ”‚   โ”œโ”€โ”€ Atomic/         # Your .atomic files
    โ”‚   โ”œโ”€โ”€ Generated/      # Generated extension methods
    โ”‚   โ””โ”€โ”€ Game/          # Your game logic
    

Step 2: Create Character System

2.1 Create Character Atomic File

  1. Right-click on Scripts/Atomic/ folder
  2. Select New โ†’ Atomic File
  3. Name it Character.atomic

2.2 Configure Character Entity

Edit Character.atomic:

entityType: "IEntity"
namespace: "RPG.Characters"
className: "CharacterExtensions"
directory: "Scripts/Generated/Characters"
aggressiveInlining: true
unsafe: false

imports:
    System
    UnityEngine
    RPG.Core
    RPG.Stats

tags:
    Player
    Enemy
    NPC
    Ally
    Boss
    Dead
    Stunned
    Invulnerable

values:
    # Core Stats
    Health: int
    MaxHealth: int
    Mana: float
    MaxMana: float
    Level: int
    Experience: int
    
    # Attributes
    Strength: int
    Agility: int
    Intelligence: int
    
    # Combat
    Damage: float
    Defense: float
    CritChance: float
    AttackSpeed: float
    
    # References
    Transform: Transform
    Animator: Animator
    CharacterModel: GameObject

2.3 Generate Extension Methods

  1. Open Character.atomic
  2. Press Ctrl+Shift+G to generate
  3. Check Scripts/Generated/Characters/ for CharacterExtensions.cs

Step 3: Create Inventory System

3.1 Create Inventory Atomic File

Create Inventory.atomic:

entityType: "IEntity"
namespace: "RPG.Inventory"
className: "InventoryExtensions"
directory: "Scripts/Generated/Inventory"
aggressiveInlining: true

imports:
    System
    System.Collections.Generic
    UnityEngine
    RPG.Items

tags:
    HasInventory
    InventoryFull
    InventoryLocked

values:
    # Inventory Data
    Items: List<Item>
    MaxSlots: int
    Gold: int
    
    # Equipment
    Weapon: Item
    Armor: Item
    Accessory: Item
    
    # Item Management
    SelectedItem: Item
    LastPickedItem: Item
    ItemFilter: ItemType

3.2 Generate and Test

  1. Press Ctrl+Shift+G in Inventory.atomic
  2. Verify generation in Scripts/Generated/Inventory/

Step 4: Implement Game Logic

4.1 Create Character Controller

Create Scripts/Game/CharacterController.cs:

using UnityEngine;
using RPG.Characters;
using Atomic.Entities;

public class CharacterController : MonoBehaviour
{
    private IEntity characterEntity;
    
    void Start()
    {
        // Create entity for this character
        characterEntity = new Entity();
        
        // Initialize character stats
        characterEntity.SetMaxHealth(100);
        characterEntity.SetHealth(100);
        characterEntity.SetLevel(1);
        characterEntity.SetStrength(10);
        
        // Add player tag
        characterEntity.AddPlayerTag();
        
        // Set Unity references
        characterEntity.SetTransform(transform);
        characterEntity.SetAnimator(GetComponent<Animator>());
    }
    
    public void TakeDamage(int damage)
    {
        if (characterEntity.HasInvulnerableTag())
            return;
            
        int currentHealth = characterEntity.GetHealth();
        int defense = (int)characterEntity.GetDefense();
        
        // Calculate actual damage
        int actualDamage = Mathf.Max(1, damage - defense);
        int newHealth = Mathf.Max(0, currentHealth - actualDamage);
        
        characterEntity.SetHealth(newHealth);
        
        if (newHealth <= 0)
        {
            characterEntity.AddDeadTag();
            OnDeath();
        }
    }
    
    public void Heal(int amount)
    {
        if (characterEntity.HasDeadTag())
            return;
            
        int currentHealth = characterEntity.GetHealth();
        int maxHealth = characterEntity.GetMaxHealth();
        int newHealth = Mathf.Min(maxHealth, currentHealth + amount);
        
        characterEntity.SetHealth(newHealth);
    }
    
    void OnDeath()
    {
        // Handle death logic
        Debug.Log("Character died!");
        characterEntity.GetAnimator()?.SetTrigger("Death");
    }
}

4.2 Create Inventory Manager

Create Scripts/Game/InventoryManager.cs:

using System.Collections.Generic;
using UnityEngine;
using RPG.Inventory;
using RPG.Items;
using Atomic.Entities;

public class InventoryManager : MonoBehaviour
{
    private IEntity inventoryEntity;
    
    void Start()
    {
        inventoryEntity = new Entity();
        
        // Initialize inventory
        inventoryEntity.SetItems(new List<Item>());
        inventoryEntity.SetMaxSlots(20);
        inventoryEntity.SetGold(100);
        inventoryEntity.AddHasInventoryTag();
    }
    
    public bool AddItem(Item item)
    {
        if (!inventoryEntity.HasHasInventoryTag())
            return false;
            
        var items = inventoryEntity.GetItems();
        int maxSlots = inventoryEntity.GetMaxSlots();
        
        if (items.Count >= maxSlots)
        {
            inventoryEntity.AddInventoryFullTag();
            return false;
        }
        
        items.Add(item);
        inventoryEntity.SetLastPickedItem(item);
        
        // Remove full tag if it was set
        if (inventoryEntity.HasInventoryFullTag() && items.Count < maxSlots)
        {
            inventoryEntity.DelInventoryFullTag();
        }
        
        return true;
    }
    
    public void EquipWeapon(Item weapon)
    {
        if (weapon.Type != ItemType.Weapon)
            return;
            
        // Unequip current weapon
        if (inventoryEntity.TryGetWeapon(out var currentWeapon))
        {
            AddItem(currentWeapon);
        }
        
        // Equip new weapon
        inventoryEntity.SetWeapon(weapon);
        
        // Remove from inventory
        var items = inventoryEntity.GetItems();
        items.Remove(weapon);
    }
}

Step 5: Advanced Features

5.1 Create Combat System

Create Combat.atomic:

entityType: "IEntity"
namespace: "RPG.Combat"
className: "CombatExtensions"
directory: "Scripts/Generated/Combat"
aggressiveInlining: true
unsafe: true  # Enable for performance-critical combat

imports:
    System
    System.Collections.Generic
    UnityEngine
    RPG.Skills

tags:
    InCombat
    Attacking
    Defending
    Casting
    Channeling
    Interrupted

values:
    # Combat State
    Target: IEntity
    LastAttacker: IEntity
    CombatStartTime: float
    
    # Damage Tracking
    DamageDealt: float
    DamageTaken: float
    LastDamageTime: float
    CriticalHits: int
    
    # Skills
    ActiveSkills: List<Skill>
    SkillCooldowns: Dictionary<int, float>
    CurrentCast: Skill
    CastProgress: float

5.2 Create Buff System

Create Buffs.atomic:

entityType: "IEntity"
namespace: "RPG.Buffs"
className: "BuffExtensions"
directory: "Scripts/Generated/Buffs"
aggressiveInlining: true

imports:
    System
    System.Collections.Generic
    UnityEngine

tags:
    Buffed
    Debuffed
    Poisoned
    Burning
    Frozen
    Blessed
    Cursed

values:
    ActiveBuffs: List<Buff>
    ActiveDebuffs: List<Debuff>
    BuffStacks: Dictionary<int, int>
    DebuffResistance: float
    StatusEffectDuration: Dictionary<string, float>

Step 6: Optimization

6.1 Enable Aggressive Inlining

For performance-critical systems, enable aggressive inlining:

aggressiveInlining: true  # Compiler optimization hint

Generated methods will include:

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetHealth(this IEntity entity) { ... }

6.2 Use Unsafe Code for References

For hot paths, enable unsafe code:

unsafe: true  # Enables ref returns

This generates additional methods:

public static ref int RefHealth(this IEntity entity) { ... }

Usage:

ref int health = ref entity.RefHealth();
health += 10;  // Direct modification, no method call

Step 7: Testing Your System

7.1 Create Test Scene

  1. Create new scene "TestArena"
  2. Add character GameObject with CharacterController
  3. Add UI for health/mana display
  4. Create enemy spawner

7.2 Test Combat

public class CombatTest : MonoBehaviour
{
    public CharacterController player;
    public CharacterController enemy;
    
    void Start()
    {
        // Test damage calculation
        player.TakeDamage(20);
        
        // Test healing
        player.Heal(10);
        
        // Test death
        enemy.TakeDamage(999);
    }
}

Step 8: Best Practices

8.1 Organization

  • Keep .atomic files organized by system
  • Use consistent naming conventions
  • Group related tags and values

8.2 Performance

  • Enable aggressiveInlining for frequently called methods
  • Use unsafe only when necessary
  • Cache entity references

8.3 Maintainability

  • Document complex values in comments
  • Use meaningful tag names
  • Keep atomic files focused (single responsibility)

๐ŸŽฏ Challenge Exercises

Exercise 1: Add Magic System

Create a magic system with:

  • Spell casting with mana cost
  • Elemental damage types
  • Spell combos

Exercise 2: Quest System

Implement quests with:

  • Quest progress tracking
  • Rewards system
  • Quest dependencies

Exercise 3: Multiplayer Support

Extend for multiplayer:

  • Network synchronization tags
  • Player ownership values
  • Server authority checks

๐Ÿ“š Further Learning

๐Ÿ†˜ Getting Help


Congratulations! You've completed the Atomic Plugin tutorial. You now know how to create entity systems using .atomic files and the generated extension methods.

Navigation

๐Ÿ“š Documentation

๐Ÿ“– Reference

โ“ Help

๐Ÿ”— Links

Clone this wiki locally