Skip to content

Custom Types

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

Custom Types and Generics Guide

This guide covers working with custom types, generics, structs, enums, and complex data structures in Atomic files.

πŸ“¦ Supported Type Categories

Primitive Types

values:
    # Numeric types
    ByteValue: byte
    ShortValue: short
    IntValue: int
    LongValue: long
    FloatValue: float
    DoubleValue: double
    DecimalValue: decimal
    
    # Boolean and character
    IsActive: bool
    Initial: char
    
    # String
    Name: string

Unity Types

imports:
    UnityEngine

values:
    # Vectors and rotation
    Position: Vector3
    Direction: Vector2
    Rotation: Quaternion
    EulerAngles: Vector3
    
    # Colors and graphics
    Color: Color
    Tint: Color32
    Material: Material
    Texture: Texture2D
    Sprite: Sprite
    
    # Components
    Transform: Transform
    Rigidbody: Rigidbody
    Collider: Collider
    Animator: Animator
    
    # Other Unity types
    Bounds: Bounds
    Rect: Rect
    AnimationCurve: AnimationCurve
    Gradient: Gradient

Collection Types

imports:
    System.Collections.Generic

values:
    # Lists
    Inventory: List<Item>
    Waypoints: List<Vector3>
    ActiveEffects: List<StatusEffect>
    
    # Arrays
    SkillSlots: Skill[]
    TeamMembers: IEntity[]
    
    # Dictionaries
    Attributes: Dictionary<string, float>
    Cooldowns: Dictionary<int, float>
    ItemStacks: Dictionary<Item, int>
    
    # HashSets
    UnlockedAbilities: HashSet<int>
    VisitedLocations: HashSet<string>
    
    # Queues and Stacks
    ActionQueue: Queue<Action>
    StateHistory: Stack<GameState>

🎯 Custom Structs

Defining Custom Structs

Create your struct in C#:

namespace Game.Data
{
    [System.Serializable]
    public struct CharacterStats
    {
        public int strength;
        public int agility;
        public int intelligence;
        public float critChance;
        public float attackSpeed;
        
        public CharacterStats(int str, int agi, int intel)
        {
            strength = str;
            agility = agi;
            intelligence = intel;
            critChance = agi * 0.01f;
            attackSpeed = 1f + (agi * 0.02f);
        }
    }
}

Using in Atomic Files

imports:
    Game.Data

values:
    BaseStats: CharacterStats
    ModifiedStats: CharacterStats
    EquipmentStats: CharacterStats

Generated Methods

// Get/Set struct
public static CharacterStats GetBaseStats(this IEntity entity);
public static void SetBaseStats(this IEntity entity, CharacterStats value);

// Check existence
public static bool HasBaseStats(this IEntity entity);

// Try pattern
public static bool TryGetBaseStats(this IEntity entity, out CharacterStats value);

πŸ”’ Enums

Defining Enums

namespace Game.Enums
{
    public enum ElementType
    {
        None = 0,
        Fire = 1,
        Water = 2,
        Earth = 3,
        Air = 4,
        Light = 5,
        Dark = 6
    }
    
    [Flags]
    public enum StatusFlags
    {
        None = 0,
        Poisoned = 1 << 0,
        Burning = 1 << 1,
        Frozen = 1 << 2,
        Stunned = 1 << 3,
        Invisible = 1 << 4,
        Invulnerable = 1 << 5
    }
}

Using Enums in Atomic

imports:
    Game.Enums

values:
    Element: ElementType
    ResistantTo: ElementType
    WeakTo: ElementType
    StatusEffects: StatusFlags
    Immunities: StatusFlags

Working with Flag Enums

// Set multiple flags
entity.SetStatusEffects(StatusFlags.Poisoned | StatusFlags.Burning);

// Check for specific flag
var status = entity.GetStatusEffects();
if ((status & StatusFlags.Poisoned) != 0)
{
    // Entity is poisoned
}

// Add flag
var current = entity.GetStatusEffects();
entity.SetStatusEffects(current | StatusFlags.Frozen);

// Remove flag
current = entity.GetStatusEffects();
entity.SetStatusEffects(current & ~StatusFlags.Frozen);

🧬 Generic Types

Simple Generics

imports:
    System.Collections.Generic
    Game.Core

values:
    # Generic collections
    ComponentList: List<IComponent>
    EventQueue: Queue<GameEvent>
    
    # Nullable types
    OptionalTarget: IEntity?
    LastDamageTime: float?
    
    # Custom generic types
    Pool: ObjectPool<GameObject>
    StateMachine: FSM<PlayerState>

Complex Generic Constraints

Define complex generic types:

namespace Game.Systems
{
    public class StateMachine<T> where T : IState
    {
        private T currentState;
        private Dictionary<Type, T> states;
        
        public void AddState(T state) { }
        public void TransitionTo<TState>() where TState : T { }
    }
    
    public interface IState
    {
        void Enter();
        void Update();
        void Exit();
    }
}

Use in Atomic:

imports:
    Game.Systems

values:
    PlayerStateMachine: StateMachine<PlayerState>
    AIStateMachine: StateMachine<AIState>

πŸ—οΈ Complex Data Structures

Nested Types

public class Quest
{
    public class Objective
    {
        public string description;
        public bool completed;
        public int progress;
        public int required;
    }
    
    public string name;
    public List<Objective> objectives;
    public Reward reward;
}
imports:
    Game.Quests

values:
    ActiveQuest: Quest
    CompletedQuests: List<Quest>
    CurrentObjective: Quest.Objective

Tuples

imports:
    System

values:
    # Named tuples
    DamageInfo: (float amount, ElementType type, IEntity source)
    GridPosition: (int x, int y, int z)
    
    # Value tuples
    MinMax: ValueTuple<float, float>
    Coordinate: ValueTuple<int, int>

Usage:

// Set tuple
entity.SetDamageInfo((50f, ElementType.Fire, attackerEntity));

// Get tuple
var (amount, type, source) = entity.GetDamageInfo();

// Access tuple elements
var damage = entity.GetDamageInfo();
Debug.Log($"Took {damage.amount} {damage.type} damage from {damage.source}");

πŸ”„ Type Conversion and Casting

Implicit Conversions

values:
    # These will auto-convert
    HealthFloat: float
    HealthInt: int
// Automatic conversion in generated code
entity.SetHealthFloat(100);  // int to float
entity.SetHealthInt(entity.GetHealthFloat());  // float to int (truncated)

Interface Types

imports:
    Game.Interfaces

values:
    Weapon: IWeapon
    CurrentItem: IItem
    ActiveAbility: IAbility
public interface IWeapon : IItem
{
    float Damage { get; }
    void Attack(IEntity target);
}

// Usage
var weapon = entity.GetWeapon();
if (weapon is Sword sword)
{
    sword.SpecialAttack();
}

🎨 Custom Type Validation

Validation Attributes

using System.ComponentModel.DataAnnotations;

public struct ValidatedStats
{
    [Range(0, 100)]
    public int level;
    
    [Range(0f, 1f)]
    public float healthPercent;
    
    [StringLength(20)]
    public string playerName;
}

Custom Validation in Generated Code

The plugin respects validation attributes:

public static void SetValidatedStats(this IEntity entity, ValidatedStats value)
{
    // Validation occurs automatically
    if (value.level < 0 || value.level > 100)
        throw new ArgumentOutOfRangeException();
        
    entity.Set("ValidatedStats", value);
}

πŸ“ Type Aliases

Using Type Aliases

// Define aliases in C#
using EntityId = System.Int32;
using PlayerId = System.String;
using Timestamp = System.Int64;
imports:
    System
    Game.Types

values:
    Id: EntityId
    OwnerId: PlayerId
    CreatedAt: Timestamp
    LastModified: Timestamp

πŸ”Œ Serialization Support

Serializable Types

[Serializable]
public class SaveData
{
    public string version;
    public DateTime timestamp;
    public Dictionary<string, object> data;
}
values:
    SaveState: SaveData
    Checkpoint: SaveData

JSON Serialization

// Custom types with JSON attributes
public class InventoryData
{
    [JsonProperty("items")]
    public List<ItemData> Items { get; set; }
    
    [JsonIgnore]
    public int InternalId { get; set; }
}

πŸš€ Advanced Patterns

Factory Pattern with Types

imports:
    Game.Factories

values:
    EntityFactory: IEntityFactory<IEntity>
    ItemFactory: IFactory<Item>
    EffectFactory: Func<string, IEffect>

Delegate Types

imports:
    System

values:
    OnDamage: Action<float>
    OnHealthChanged: Action<int, int>
    CalculateDamage: Func<IEntity, IEntity, float>
    CanPerformAction: Predicate<ActionType>

Usage:

// Set delegate
entity.SetOnDamage((damage) => Debug.Log($"Took {damage} damage"));

// Invoke delegate
entity.GetOnDamage()?.Invoke(25f);

// Function delegate
entity.SetCalculateDamage((attacker, target) => 
{
    float baseDamage = attacker.GetDamage();
    float defense = target.GetDefense();
    return Mathf.Max(1, baseDamage - defense);
});

⚠️ Type Limitations

Unsupported Types

  • ref struct types
  • Pointer types (except in unsafe context)
  • Open generic types without concrete type arguments

Workarounds

For ref struct:

// Instead of ref struct
public ref struct SpanData { }  // Not supported

// Use regular struct
public struct SpanDataWrapper
{
    public byte[] data;
    public int start;
    public int length;
}

For open generics:

# Not supported
values:
    GenericList: List<>  # Error
    
# Supported - concrete type
values:
    IntList: List<int>
    EntityList: List<IEntity>

πŸ“š Best Practices

1. Type Organization

  • Group related types in namespaces
  • Use meaningful type names
  • Document complex types

2. Performance Considerations

  • Prefer structs for small data (< 16 bytes)
  • Use classes for complex objects
  • Consider memory alignment for structs

3. Type Safety

  • Use enums instead of magic numbers
  • Leverage strong typing
  • Validate input data

4. Maintainability

  • Keep types simple and focused
  • Use interfaces for flexibility
  • Document type constraints

πŸ” Type Resolution

The plugin resolves types in this order:

  1. Fully qualified types
  2. Types in imported namespaces
  3. System namespace types
  4. Unity types (if in Unity project)

πŸ“– Examples

Complete RPG Character System

entityType: "IEntity"
namespace: "RPG.Characters"
className: "CharacterExtensions"

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

values:
    # Identity
    Id: Guid
    Name: string
    Class: CharacterClass
    
    # Stats
    Stats: CharacterStats
    Modifiers: List<StatModifier>
    
    # Combat
    Element: ElementType
    Resistances: Dictionary<ElementType, float>
    StatusEffects: StatusFlags
    
    # Equipment
    Equipment: Dictionary<EquipmentSlot, IItem>
    WeaponSet: (IWeapon primary, IWeapon secondary)
    
    # Inventory
    Inventory: List<IItem>
    Currency: Dictionary<CurrencyType, int>
    
    # Abilities
    KnownAbilities: HashSet<AbilityId>
    AbilityCooldowns: Dictionary<AbilityId, float>
    
    # AI/Behavior
    BehaviorTree: IBehaviorTree
    CurrentState: IState
    
    # Unity
    GameObject: GameObject
    Transform: Transform
    Animator: Animator

Next Steps: Learn about Advanced Features or explore Performance optimizations for custom types.

Navigation

πŸ“š Documentation

πŸ“– Reference

❓ Help

πŸ”— Links

Clone this wiki locally