-
Notifications
You must be signed in to change notification settings - Fork 0
Custom Types
Yaroslav Sarchuk edited this page Aug 29, 2025
·
1 revision
This guide covers working with custom types, generics, structs, enums, and complex data structures in Atomic files.
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
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
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>
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);
}
}
}imports:
Game.Data
values:
BaseStats: CharacterStats
ModifiedStats: CharacterStats
EquipmentStats: CharacterStats
// 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);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
}
}imports:
Game.Enums
values:
Element: ElementType
ResistantTo: ElementType
WeakTo: ElementType
StatusEffects: StatusFlags
Immunities: StatusFlags
// 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);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>
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>
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
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}");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)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();
}using System.ComponentModel.DataAnnotations;
public struct ValidatedStats
{
[Range(0, 100)]
public int level;
[Range(0f, 1f)]
public float healthPercent;
[StringLength(20)]
public string playerName;
}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);
}// 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
[Serializable]
public class SaveData
{
public string version;
public DateTime timestamp;
public Dictionary<string, object> data;
}values:
SaveState: SaveData
Checkpoint: SaveData
// Custom types with JSON attributes
public class InventoryData
{
[JsonProperty("items")]
public List<ItemData> Items { get; set; }
[JsonIgnore]
public int InternalId { get; set; }
}imports:
Game.Factories
values:
EntityFactory: IEntityFactory<IEntity>
ItemFactory: IFactory<Item>
EffectFactory: Func<string, IEffect>
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);
});-
ref structtypes - Pointer types (except in unsafe context)
- Open generic types without concrete type arguments
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>
- Group related types in namespaces
- Use meaningful type names
- Document complex types
- Prefer structs for small data (< 16 bytes)
- Use classes for complex objects
- Consider memory alignment for structs
- Use enums instead of magic numbers
- Leverage strong typing
- Validate input data
- Keep types simple and focused
- Use interfaces for flexibility
- Document type constraints
The plugin resolves types in this order:
- Fully qualified types
- Types in imported namespaces
- System namespace types
- Unity types (if in Unity project)
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.