Replies: 9 comments
-
Oh, and this should also be extended to the database, so you don't have to add a new field for every single property. |
Beta Was this translation helpful? Give feedback.
-
For me, this is exactly what a Dictionary should be. In some past Emulators, I left everything Dictionary related outside of the source code of the repository. Basically, you would have a dictionary that acts as Key-Value Dictionary (IdentifierString, NumericValue) It is mostly an INI file
And inside the Emulator, you have a Manager, that during the initialization it loads the Dictionaries. We could even have a command during execution time to reload the Dictionary if you make a change, or like for example, updating the Revision. So you could easily do something like: ParameterDictionary.get("IdentifierNumberOne"); This is just a different approach for at least mapping the Identifiers. But I definitely think your Solution is great. Also instead of an Ini file, it could be inside the Database. Whatever it's easier or better. |
Beta Was this translation helpful? Give feedback.
-
What I meant about it getting extended to the database, is that there should be a table for character properties for example, where you can simply dump and read all of their properties from. Instead of declaring a field for level, and one for HP, and one for stamina, etc. on the character table, you'd simply write the id, type, and value of every property, together with the character id into a property table. This way, when you declare a new property for a character, you don't have to update the database, it simply gets read and written together with the others. Similar to how we currently store scripting variables in the database. On that note, for future reference, when saving properties to the database this way, we should not use a property's integer id as the index, because those have had a tendency to change a lot in the past. Sometimes, after an update, all the property ids were suddenly different, which would completely break the data. We should either use an intermediary index, that we can make sure never changes, or use the property names instead. |
Beta Was this translation helpful? Give feedback.
-
We could also use the name of the property itself as the index. So the table structure would basically have the |
Beta Was this translation helpful? Give feedback.
-
Yea, I just thinking that we could probably generate indices based on the strings. Basically hashes. Not very intuitive if you look at the data in the database, but it would work. Or we create a lookup table, where we assign every property name a fixed id. |
Beta Was this translation helpful? Give feedback.
-
If our Database actually supports HashMaps that would actually be quite fast :) |
Beta Was this translation helpful? Give feedback.
-
We don't need hashmaps, we could just use tables with 'id'(entry_id), 'attrb_name', 'value'. |
Beta Was this translation helpful? Give feedback.
-
nvm the json field, we are using mysql, so json is not an option |
Beta Was this translation helpful? Give feedback.
-
We started implementing this a while ago and it's working relatively well, though there will be another refactoring of it soon. Regardless, the proposed solution is in use and we will keep using it, because anything else would be madness in this game. |
Beta Was this translation helpful? Give feedback.
-
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.
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 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.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.
Beta Was this translation helpful? Give feedback.
All reactions