What to choose GodotObject/RefCounted?

Godot Version 4.2.1 Mono (C#)

Question

I want to create classes to store game session and game information:

Constants
Session Statistics
Session state

And I have now written the first two classes that I inherited from RefCounted and wondered if it would be better to inherit from GodotObject (Object). Here are the two classes I wrote:

SessionStats.cs

using Godot;

namespace Game.Data
{
    public partial class SessionStats: GodotObject
    {
        /// <summary>
        /// Called when the value of money, experience or level is changed 
        /// so that the GUI will request the new information to display correctly.
        /// </summary>
        [Signal] public delegate void ChangeValuesEventHandler();

        /// <summary>
        /// Called each time the level is changed to bring up the new skill selection window.
        /// </summary>
        /// <param name="_previousLevel"></param>
        /// <param name="_currentLevel"></param>
        [Signal] public delegate void ChangeLevelEventHandler(int _previousLevel, int _currentLevel);

        private int _currentMoney = 0;
        private int _currentExperience = 0;
        private int _currentLevel = 1;

        public int CurrentMoney
        {
            get
            {
                return _currentMoney;
            }
            set
            {
                _currentMoney = value;
                EmitSignal(SignalName.ChangeValues);
            }
        }
        public int CurrentExperience
        {
            get
            {
                return _currentExperience;
            }
            set
            {
                _currentExperience = value;
                int bufferLevel = CurrentLevel;
                for (int i = bufferLevel; ;i++)
                {
                    if (_currentExperience > bufferLevel * 50)
                    {
                        _currentExperience -= bufferLevel * 50;
                        bufferLevel += 1;
                    }
                    else
                    {
                        break;
                    }
                }

                if (bufferLevel > CurrentLevel)
                {
                    CurrentLevel = bufferLevel;
                }

                EmitSignal(SignalName.ChangeValues);
            }
        }
        public int CurrentLevel
        {
            get
            {
                return _currentLevel;
            }
            set
            {
                EmitSignal(SignalName.ChangeLevel, _currentLevel, value);
                _currentLevel = value;
            }
        }  

        public int GetMoney()
        {
            return CurrentMoney;
        }

        public int GetExperience()
        {
            return CurrentExperience;
        }

        public int GetLevel()
        {
            return CurrentLevel;
        }

        /// <summary>
        /// Adds money to the current money.
        /// </summary>
        /// <param name="what">
        /// Number of money to be added.
        /// </param>
        public void AddMoney(int what)
        {
            CurrentMoney += what;
        }

        /// <summary>
        /// Adds XP to the current experience.
        /// </summary>
        /// <param name="what">
        /// Number of XP to be added.
        /// </param>
        public void AddExperience(int what)
        {
            CurrentExperience += what;
        }

        /// <summary>
        /// Adds level to the current level.
        /// </summary>
        /// <param name="what">
        /// Number of levels to be added.
        /// </param>
        public void AddLevel(int what)
        {
            CurrentLevel += what;
        }
    }
}

Constants.cs:

using Godot;

namespace Game.Data
{
    public partial class Constants : GodotObject
    {
        public const short limitHealth = short.MaxValue;
        public const short limitSpeed = short.MaxValue;
        public const short limitDamage = short.MaxValue;
    }
}

Keep them RefCounted if you don’t want to serialize them to file system. Use Resource if you want to save them to file system. There’s no need to use Object for this scenario.

More information can be found here:

I want to create new instances of these classes at session startup to write new data to them. Also, I’m currently writing a SkillParameters file that takes data from a JSON file and lets me work with it. Now in SkillParameters I want to take data at creation, I started to write _ready function and realized that it just does not exist :slight_smile: good thing there is a constructor, in which I will write all the good. Thanks for the advice and information, for now I will start from RefCounted.

RefCounted is just Object with a pseudo garbage collector (is not a garbage collector, is just reference counted object that gets deleted when nobody points at it). You can threat it as if it were an object without created leaked instances.

If you need to inspect these in editor, and/or create instances of them from/to disk, use Resources.

So… yeah, RefCounted is a good start.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.