ID:151537
 
Would it be a better use of resources to use associative lists instead of variables for things such as player skills.

For example:

player
{
parent_type = /mob;
var
{
alchemy;
blackSmithing;
fishing;
poetry;
etc;
}
}


VS:

player
{
parent_type = /mob;
var
{
list
{
skills = list("alchemy" = 1, "blackSmithing" = 2, "fishing" = 1, "poetry" = 4, "etc" = 99);
}
}
}


If so would it be safe to say I could make a list of variables for each atom to save more resources?
A datum's variables are actually stored in an associative list already (datum.vars), so you would just be creating an extra list if you did that.

So from a purely resource perspective, you would be better off using separate variables instead of an associative list.
This really, really, really doesn't matter. Use whichever is easier to use.
In response to DarkCampainger (#1)
DarkCampainger wrote:
So from a purely resource perspective, you would be better off using separate variables instead of an associative list.

^ This is true.

Garthor wrote:
This really, really, really doesn't matter. Use whichever is easier to use.

In very minor usage situations it doesn't matter.

When you're talking about variables that are accessed multiple times per second, using actual variables instead of a list provides a vast advantage as far as efficiency is concerned.
Which method you use probably depends most on how much it will be used. If you define and initialize a list at compile-time, a copy of it will actually be made every time a new datum with that type is created. This is bad if you aren't going to be putting that list to use, but potentially good otherwise.

The var approach is pretty good too, since you can always refer to a var by name. However this does lack some flexibility and easy extensibility, so depending on the system a list may simply be better. For something like equipment I always prefer to go with lists.

Remember that you also have the option of not initializing a list at all, just defining a var that can be used only if it is needed, and left null at all other times. That's usually the best approach to any of these things.

Lummox JR
Personally, I'd only use the associated list if 1) I was actually using the list every time it was initialized and 2) if I needed my skills to be dynamic (ex. I can add new skills in game as I deem necessary; I've never seen this done).
In response to Jeff8500 (#5)
Okay, say I were adding skills during play. Would it be better to go with a list or a datum like so:

skill
{
var
{
name;
value;
}

New(n, v)
{
name = n;
value = v;
}
}

player
{
var
{
skill
{
list
{
skills;
}
}
}
}
In response to Librarian (#6)
Yes, using datums for this would be a great idea. I don't know if it is "better" since circumstances might not absolutely call for usage of an object, but using objects here will increase modularity (which makes it easier to make changes and create unique types with unique responses to input... and all that jazz).

FYI: That /skill modifier you are using in the list definition does absolutely nothing. var/skill/list/skills does not define a list of /skill datums, if that's what you think. BYOND does not have a method of specifically defining the type of data a list will contain. Just thought I'd mention it.
In response to Keeth (#7)
Actually, the skill modifier wasn't meant to be there. I originally had var/skill/skill1, var/skill/skill2, but then I was like wait I can use a list in this situation to cut down on having a bunch of confusing variables and forgot to delete the skill modifier.

I would add it to the list like so:

player
{
proc
{
new_skill(n, v)
{
src.skills += new/skill(n, v)
}
}
}


Say the player reads a book about poetry. I could then do something like src.new_skill("poetry", 1).

Then to edit the value, something like var/skill/s = src.skills[skill], s.value++. I'm not sure entirely how I would find the particular skill in the list, but it shouldn't be hard to figure out, possibly a for loop. If this would work of course.
In response to Librarian (#8)
While there isn't anything wrong with using a [skill_name] = [proficiency] system... since OOP is encouraged (being an OOP-language), using objects to determine all relevant data for skills wouldn't be such a bad idea.

Using objects, we can define one structure with all of the attributes and methods of the skill. We can define a name, description, display of the skill, actual usage of the skill, etc... right on the object itself. All we need is a template, and then we can build off of it. Makes adding new skills and changing old ones a breeze too.

For example:
skill
var
name // name goes here
desc // explain origins, general description of its function, etc...
proficiency // a percentage reflecting our mastery of this skill (1-100%)

// the New() parameter will set our new skill's proficiency.
// this'll be used for mobs learning skills, basically.
New(_proficiency) proficiency = _proficiency

proc
use()
// use me here


Then creating a new skill is a matter of building off of our template here, like so:
skill
roundhouse_kick
name = "Roundhouse Kick"
desc = "Invented by Chuck Norris. Roundhouse kick. What else can I say?"

use(mob/user, mob/target)
var/base_damage = user.strength
var/multiplier = 1 + (proficiency/100) + 0.25
var/damage = base_damage * multiplier
// basically, increase damage by 1% for every point of proficiency (and always add an extra 25%)

world << "[user] roundhouse kicked [target] for [damage] damage."
// deal damage here


Learning the skill would be a matter of implementing some functions like this:
// might want to separate this so only player mobs get it. if you want to implement this into NPC AI, then good on you.
mob
var
list/skills = new // list of skills we know

proc
has_skill(skill_type) return locate(skill_type) in skills // grab the skill (if we know it)

learn_skill(skill_type, proficiency=1)
var/skill/skill = new skill_type(proficiency)
skills += skill
return skill // return the skill object we just created

forget_skill(skill_type)
var/skill/skill = has_skill(skill_type)
if(!skill) return // we don't know this skill

// get rid of the skill
skills -= skill
return skill


And having some kind of tutor mob that trains certain skills to people who have met the criteria for them:
mob
chuck_norris
some_interaction_function(mob/interacter)
if(interacter.has_skill(/skill/roundhouse_kick))
interacter << "Dude, you already know how to roundhouse kick."
return

// all young grasshoppers have access to the roundhouse kick!
interacter.learn_skill(/skill/roundhouse_kick)
interacter << "You are now trained in the ways of the roundhouse. Make me proud."


If you want to, you can go ahead and create some kind of tutor mob that has an automated method of teaching people skills (like a list of skills they teach paired with criteria required to learn the skills. could even use objects for that!).

Using a skill could be a matter of using a verb, typing the name of the skill, or clicking a graphical display. Implementing something like this (dynamic skill definition) with something like verbs (constant and unchanging action) is probably just gonna end badly. BYOND actually has a method of renaming a function/verb at runtime, but the method is very gross and probably will also end just as badly (I recall trying to implement this very system and ended up sacking it because of some serious inconvenient problems I was having). I'd stick with graphical displays of some kind 100% of the time in graphical games.

Anyway yeah. Sorry for the whole big block. I'm not exactly an expert here (and I wrote this in notepad), but I think this is at least a decent demonstration of object-oriented programming in use with something like skills.