IgdrasilCore — Основной модуль движка

Обзор

IgdrasilCore — ядро движка Igdrasil. Содержит:


GameObject

Базовый класс, от которого наследуются все игровые объекты.

Основные свойства

public class GameObject
{
    public Guid GUID { get; set; }  // Уникальный идентификатор
}

Использование

// Создать новый объект с автогенерируемым GUID
var obj = new GameObject();

// Или с заданным GUID
var obj2 = new GameObject(new Guid("..."));

// Сравнение по GUID
if (obj == obj2) { /* ... */ }

Особенности


Сериализация и AssetBundle

AssetBundle

Контейнер для хранения сериализованных объектов с поддержкой типов, ссылок и иерархических структур.

var bundle = new AssetBundle();

// Сериализовать объект (используется GUID объекта)
var obj = new MyObject();
bundle.Serialize(obj);

// Или с явным GUID
bundle.Serialize(someGuid, obj);

// Получить объект по GUID
var retrieved = bundle[guid];

// Удалить
bundle.Remove(guid);

// Количество блоков
int count = bundle.Length;

Загрузка и сохранение

var bundle = new AssetBundle();
bundle.Serialize(player);

// Использовать сериализатор для преобразования
var serializer = new AssetBundleJsonSerializer(prettyPrint: true);
byte[] data = serializer.Serialize(bundle);

// Сохранить на диск
await File.WriteAllBytesAsync("bundle.json", data);

// Загрузить с диска
byte[] loaded = await File.ReadAllBytesAsync("bundle.json");
var deserializedBundle = serializer.Deserialize(loaded);

Интеграция с пользовательскими типами

public class MyObject : GameObject
{
    [SerializableField]
    public string Name { get; set; }
    
    [SerializableField]
    public int Health { get; set; }
}

// Автоматически регистрируется при сериализации
var bundle = new AssetBundle();
bundle.Serialize(myObject);

Утилиты

Random — Xoroshiro128+

Детерминированный генератор случайных чисел на основе Xoroshiro128+.

// Глобальный экземпляр
var rng = Random.Shared;

// Новый генератор с seed
var rng = new Random(42);

// Случайные числа
ulong ul = rng.NextULong();                 // 0 .. ulong.MaxValue
long l = rng.NextLong();                    // long.MinValue .. long.MaxValue
float f = rng.NextFloat();                  // [0, 1)
int i = rng.NextInt(100);                   // [0, 100)

// В диапазоне
int range = rng.NextInt(10, 20);            // [10, 20)
float fRange = rng.NextFloat(1.5f, 3.5f);   // [1.5, 3.5)

// Вероятность
if (rng.NextBool(0.7f)) { /* 70% шанс */ }

// Выбрать случайный элемент
T item = rng.PickRandom(collection);

EncryptionHelper

Шифрование AES, RSA и создание ключей.

// Создать ключ из пароля
byte[] key = EncryptionHelper.AesCreateKey("mypassword");
byte[] iv = EncryptionHelper.AesCreateIV("mypassword");

// Сгенерировать случайный ключ
byte[] randomKey = EncryptionHelper.AesGenerateKey(32); // 32 байта = 256 бит

// Зашифровать и расшифровать
byte[] encrypted = EncryptionHelper.AesEncrypt(dataBytes, key, iv);
byte[] decrypted = EncryptionHelper.AesDecrypt(encrypted, key, iv);

// RSA (асимметричное шифрование)
(byte[] publicKey, byte[] privateKey) = EncryptionHelper.GenerateRsaKey();
byte[] encrypted = EncryptionHelper.RsaEncrypt(data, publicKey);
byte[] decrypted = EncryptionHelper.RsaDecrypt(encrypted, privateKey);

HashHelper

SHA-1/256/384/512 хеширование.

// От строки
string hash1 = HashHelper.GenerateSha1("hello");
string hash256 = HashHelper.GenerateSha256("world");

// От массива байт
byte[] data = Encoding.UTF8.GetBytes("data");
string hash = HashHelper.GenerateSha256(data);

// От потока (файл и т.д.)
using var file = File.OpenRead("largeFile.bin");
string fileHash = HashHelper.GenerateSha256(file);

// CRC и Adler
ushort crc16 = CRC16.Calculate(data);
uint crc32 = CRC32.Calculate(data);
ushort adler16 = Adler16.Calculate(data);
uint adler32 = Adler32.Calculate(data);

CompressionHelper

Сжатие Deflate, GZip, Brotli, LZMA.

byte[] data = Encoding.UTF8.GetBytes("Hello, World!");

// Deflate
byte[] compressed = CompressionHelper.DeflateCompress(data, CompressionLevel.Optimal);
byte[] decompressed = CompressionHelper.DeflateDecompress(compressed);

// GZip
byte[] gzipped = CompressionHelper.GZipCompress(data);
byte[] ungzipped = CompressionHelper.GZipDecompress(gzipped);

// LZMA
byte[] lzmaCompressed = CompressionHelper.LzmaCompress(data);
byte[] lzmaDecompressed = CompressionHelper.LzmaDecompress(lzmaCompressed);

// Асинхронно
byte[] compressedAsync = await CompressionHelper.DeflateCompressAsync(data, CompressionLevel.Optimal);

UID

Генерация уникальных идентификаторов.

// Новый UID
var uid = UID.New();

// Из существующего значения
var uid2 = new UID(12345);

// Конверсия
int value = uid.AsInt;
string str = uid.ToString();

StringUtils

Работа со строками.

// Проверки
bool isEmpty = StringUtils.IsEmpty(str);
bool isNullOrEmpty = StringUtils.IsNullOrEmpty(str);
bool isNumber = StringUtils.IsNumeric(str);

// Преобразования
string upper = StringUtils.ToUpperFirst(str);
string lower = StringUtils.ToLowerFirst(str);

ReflectionUtils

Работа с рефлексией.

// Получить все свойства с атрибутом
var props = ReflectionUtils.GetPropertiesWithAttribute<SerializableFieldAttribute>(obj.GetType());

// Проверить наличие атрибута
bool hasAttr = ReflectionUtils.HasAttribute<MyAttribute>(typeof(MyClass));

// Вызвать метод по имени
object result = ReflectionUtils.InvokeMethod(obj, "MethodName", params);

ComparisonUtils

Сравнение с допуском.

// Сравнить float с допуском
bool equals = ComparisonUtils.NearlyEqual(a, b, 0.0001f);

// Клип в диапазон
int clamped = ComparisonUtils.Clamp(value, min, max);

// Lerp
float interpolated = ComparisonUtils.Lerp(start, end, t);

IO — Форматы сериализации

JSON

var obj = new MyObject { Name = "Test", Health = 100 };

// Сериализовать в JSON
string json = JsonUtils.Serialize(obj);

// Десериализовать из JSON
MyObject loaded = JsonUtils.Deserialize<MyObject>(json);

XML

// Сериализовать в XML
string xml = XmlUtils.Serialize(obj);

// Десериализовать из XML
MyObject loaded = XmlUtils.Deserialize<MyObject>(xml);

YAML

// Сериализовать в YAML
string yaml = YamlUtils.Serialize(obj);

// Десериализовать из YAML
MyObject loaded = YamlUtils.Deserialize<MyObject>(yaml);

Бинарные потоки

Для эффективного сохранения и загрузки больших объёмов данных.

var reader = new BinaryReaderWithEndians(stream);
var writer = new BinaryWriterWithEndians(stream);

// Чтение/запись с контролем порядка байт
int value = reader.ReadInt32(Endianness.BigEndian);
writer.WriteInt32(value, Endianness.LittleEndian);

Editor — Атрибуты

SerializableField

Отмечает поле для сериализации.

public class MyObject : GameObject
{
    [SerializableField]
    public string Name { get; set; }
    
    [SerializableField]
    public int Value { get; set; }
}

ShowInInspector

Отображает поле в редакторском инспекторе.

public class MyObject : GameObject
{
    [SerializableField, ShowInInspector]
    public float Speed { get; set; }
}

Space / Header

Добавляет визуальные разделители в инспектор.

public class MyObject : GameObject
{
    [Space(10)]
    [Header("Physics")]
    [SerializableField, ShowInInspector]
    public float Mass { get; set; }
}

LimitCount

Ограничивает количество элементов в коллекции.

[SerializableField, LimitCount(5)]
public List<GameObject> Children { get; set; }

Иерархия данных — Tree

Древовидная структура для организации данных.

var root = new Tree<string>("root");

// Добавить узлы
root.AddChild("child1");
root.AddChild("child2");

// Получить детей
foreach (var child in root.Children)
{
    Console.WriteLine(child.Value);
}

// Навигация
var parent = root.Parent;
var firstChild = root.Children.FirstOrDefault();

Практика и примеры

Полный пример: сохранение и загрузка игрового объекта

// 1. Определить класс объекта
public class Player : GameObject
{
    [SerializableField, ShowInInspector]
    public string Name { get; set; }
    
    [SerializableField, ShowInInspector]
    public int Level { get; set; }
    
    [SerializableField]
    public List<string> Inventory { get; set; } = new();
}

// 2. Создать и заполнить
var player = new Player { Name = "Hero", Level = 5 };
player.Inventory.AddRange(new[] { "Sword", "Shield", "Potion" });

// 3. Сохранить в AssetBundle
var bundle = new AssetBundle();
bundle.Serialize(player);
await bundle.SaveAsync("player.igb");

// 4. Загрузить
var loadedBundle = await AssetBundle.LoadAsync("player.igb");
var loadedPlayer = loadedBundle[player.GUID] as Player;
Console.WriteLine($"{loadedPlayer.Name} (Level {loadedPlayer.Level})");

Безопасное хранение с шифрованием

var bundle = new AssetBundle();
bundle.Serialize(sensitiveData);

// Сохранить с шифрованием
byte[] bundleBytes = await bundle.SaveBytesAsync();
byte[] key = EncryptionHelper.AesCreateKey("secretPassword");
byte[] iv = EncryptionHelper.AesCreateIV("secretPassword");
byte[] encrypted = EncryptionHelper.AesEncrypt(bundleBytes, key, iv);
await File.WriteAllBytesAsync("secure.igb", encrypted);

// Восстановить
byte[] encryptedData = await File.ReadAllBytesAsync("secure.igb");
byte[] decrypted = EncryptionHelper.AesDecrypt(encryptedData, key, iv);
var loadedBundle = await AssetBundle.LoadFromBytesAsync(decrypted);

Производительность и рекомендации


© 2026 Igdrasil Project. Все права защищены.