reckfellENGINE

C#: Inspector and prefab properties

Export, private fields, Range, persistence and value validation in a complete example.

On this page

Run the example

Add the five files below to a Reckfell 1.0.0 C# project and build. Create a level rooted at Entity2D, attach ManagedDataDemo2D to the root and run F6. Code creates the children. Ammo starts at 5; Fire once changes it to 4.

ShotSettings.cs
C#
using Reckfell;

[GlobalClass]
public partial class ShotSettings : Resource
{
    [Export] public string DisplayName { get; set; } = "Pulse";
    [Export(PropertyHint.Range, "1,100,1")] public int Damage { get; set; } = 12;
    [Export] public Reckfell.Collections.Array<string> Tags { get; set; } = new() { "weapon" };

    public bool TryGetDamage(out int damage)
    {
        damage = 0;
        if (Damage < 1 || Damage > 100) return false;
        damage = Damage;
        return true;
    }
}
ExportedWeapon.cs
C#
using Reckfell;

public partial class ExportedWeapon : Entity
{
    [Signal] public delegate void FiredEventHandler(int damage);
    [Export] public ShotSettings? Settings { get; set; }
    [Export(PropertyHint.Range, "0,99,1")] private int _ammo = 5;
    public int Ammo => _ammo;
    public int TransientValue { get; set; } = 3;

    public bool TryFire()
    {
        if (_ammo <= 0 || !ReckfellObject.IsInstanceValid(Settings) ||
            !Settings!.TryGetDamage(out int damage)) return false;
        _ammo--;
        EmitSignal(SignalName.Fired, damage);
        return true;
    }
}
InventoryLedger.cs
C#
using System;
using System.Collections.Generic;

public sealed class InventoryLedger
{
    private readonly Dictionary<string, int> _counts = new(StringComparer.Ordinal);

    public int CountOf(string item) => _counts.TryGetValue(item, out int count) ? count : 0;

    public bool TryAdd(string item, int amount)
    {
        if (string.IsNullOrWhiteSpace(item) || amount <= 0) return false;
        int current = CountOf(item);
        if (current > int.MaxValue - amount) return false;
        _counts[item] = current + amount;
        return true;
    }

    public Reckfell.Collections.Dictionary<string, int> Snapshot() => new(_counts);
}
VariantCounter.cs
C#
using Reckfell;

public static class VariantCounter
{
    public static bool TryRead(Variant value, out int count)
    {
        count = 0;
        if (value.VariantType != Variant.Type.Int) return false;
        long raw = value.AsInt64();
        if (raw < 0 || raw > 999) return false;
        count = (int)raw;
        return true;
    }
}
ManagedDataDemo2D.cs
C#
using Reckfell;

public partial class ManagedDataDemo2D : Entity2D
{
    public ExportedWeapon Weapon { get; private set; } = null!;
    public InventoryLedger Inventory { get; } = new();
    public Label Readout { get; private set; } = null!;
    public Button FireButton { get; private set; } = null!;
    private bool _ru;

    public override void _Ready()
    {
        _ru = TranslationServer.GetLocale().StartsWith("ru");
        var title = new Label { Position = new Vector2(28, 24), Text = _ru ? "C#: настройки и данные" : "C#: settings and data" };
        title.AddThemeFontSizeOverride("font_size", 26);
        AddChild(title);
        AddChild(new Label { Position = new Vector2(28, 74), Text = _ru ? "Resource → свойство → игровая проверка" : "Resource → property → gameplay validation" });
        Readout = new Label { Position = new Vector2(28, 126) };
        AddChild(Readout);
        Weapon = new ExportedWeapon { Settings = new ShotSettings() };
        AddChild(Weapon);
        Inventory.TryAdd("pulse", 2);
        FireButton = new Button { Position = new Vector2(28, 260), Size = new Vector2(230, 48), Text = _ru ? "Сделать выстрел" : "Fire once" };
        FireButton.Modulate = new Color(0.35f, 0.55f, 1);
        FireButton.Pressed += Fire;
        AddChild(FireButton);
        AddChild(new Label { Position = new Vector2(28, 336), Text = _ru ? "Range — подсказка. TryFire проверяет данные." : "Range is a hint. TryFire validates the data." });
        Refresh();
    }

    private void Fire()
    {
        Weapon.TryFire();
        Refresh();
    }

    private void Refresh()
    {
        Variant sample = 25L;
        VariantCounter.TryRead(sample, out int count);
        Readout.Text = _ru
            ? $"Урон: {Weapon.Settings!.Damage}\nБоезапас: {Weapon.Ammo}\nВ инвентаре: {Inventory.CountOf("pulse")}\nVariant.Int: {count}"
            : $"Damage: {Weapon.Settings!.Damage}\nAmmo: {Weapon.Ammo}\nInventory: {Inventory.CountOf("pulse")}\nVariant.Int: {count}";
    }
}

Running C# fixture after firing once

What Export stores

ExportedWeapon.Settings is a Resource reference. The private _ammo field is exported too: private limits C# access, not persistence. Packing this object with _ammo = 9 restores 9. The unexported TransientValue = 42 returns to its initializer 3 in a new instance. Get/Set accessibility alone does not establish persistence.

Level/prefab persistence also follows Owner and PackedEntity rules. Export neither creates a disk savegame nor automatically writes runtime instance changes back to the source asset.

A hint and validation are separate

Range supplies Inspector metadata. Assigning Damage = 1000 or using Set to put −2 in _ammo is not clamped by that range. TryGetDamage and TryFire explicitly reject invalid state before consuming ammo or emitting a signal. Do not use a slider as validation for files, network input or your own code.

Export Variant-compatible fields or readable/writable instance properties. List<int> does not replace Reckfell.Collections.Array<int>. Static, readonly and unsupported types produce RF0101, RF0103 and RF0102 respectively. A Resource cannot export an Entity reference: RF0107; place that reference on an Entity component.

After changing fields, build the C# project first. If Inspector is stale, check build errors, the attached script and exact class/file names. Native persistence and metadata were tested; Inspector mouse actions and saving through its window were not.

Reckfell Engine documentationBack to top ↑
QUICK LINKSGetting startedEntity hierarchyC# & .NET 10Scenes and prefabs
Reckfell guides and full API K
reckfellENGINE
RECKFELL ACCOUNT

Sign in

Sign in to your Reckfell account.

One account for the entire Reckfell platform.