Skip to content

Properties #165

@exectails

Description

@exectails

Intro

Early in Melia's life, it became obvious that we'd need some kind of property system, because basically anything in ToS has properties, a collection of named values. The whole game is made up of them. Actually, even more so than I thought back then, which is why our current property system is a little lackluster.

Properties

In game development, properties often times receive special handling. You might have a container that manages an object's properties, and a series of property classes, like PropertyInt, PropertyString, etc, that are used to set up an object, and which can then be used by querying that property with an id.

player.Properties.Add(new PropertyInt(Property.Level, 9001));
player.Properties.Add(new PropertyInt(Property.MaxHp, 20));

var level = player.Properties.GetInt(Property.Level);
player.Properties.SetInt(Property.Level, level + 1);

This has its advantages and disadvantages. Particularly, it takes more effort to set up and isn't nearly as comfortable to use as a simple C# property. However, you gain the ability to add, remove, and modify properties without affecting packet structures, because you can simply iterate over all existing properties. You can also add additional features to the property classes, like clamping the values or adding OnChange events.

Melia

Since we were coming from a game where this property situation wasn't nearly as bad, we figured we'd implement a hybrid between C# properties and a proper property system for Melia, because we thought it would be comfortable to use and flexible enough. Basically, we would keep using C# properties, but create reference properties, that point to these values.

this.Properties.Add(new RefFloatProperty(PropertyId.PC.STR, () => this.Str));

This allowed you to simply use player.Str to modify someone's strength, but also put that property "on the map" for packets that need a character's properties.

Problem

Now the problem is, that there are just way. too. many. properties in ToS. Hundreds of player properties, hundreds of item properties, hundreds of guild properties, and thousands more. If we were to apply our hybrid design to those, the respective classes would become a mess of properties. They'd be thousands of lines long, just for the properties and to set them up.

Solution

My proposed solution: Go from hybrid with focus on C# properties, to hybrid with focus on property collections. Create property containers, potentially specialized ones, and add C# properties for commonly used fields. For example, in a more recent project of mine, I have a CharacterParameters class, which is such a property collection, and on it, I also have a few C# properties, for quick access and for properties that are made up of multiple other properties.

void InitParameters()
{
	this.Add(new ParameterFloat(ParameterType.Mana, DefaultMana, min: 0, max: DefaultMana));
	this.Add(new ParameterFloat(ParameterType.ManaMaxBase, DefaultMana));
	this.Add(new ParameterFloat(ParameterType.ManaMaxMod, 0));
	// ...
}

public float Mana => this.GetFloat(ParameterType.Mana);
public float ManaMax => this.SumFloat(ParameterType.ManaMaxBase, ParameterType.ManaMaxMod);

This removes the hundreds and thousands of lines of code for the properties from classes like Character, embraces the property design that ToS is so fond of, and still keeps the ability to easily access common properties easily.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions