ID:272977
 
I'm currently trying to learn how to use a datum, what situations they would be useful in, and why to use them instead of /atom, /mob, /obj, etc.

I've read the Dream Makers Article and the Reference, but was wondering if anyone knew of any other sources I could look at, or if they could be so kind as to answer my questions for me here?
It's very simple.

Whenever you want to create an OBJECT (not /obj) and it DOESN'T need to be an atom of some kind (you don't intend on it being on the map or in an atom's contents, for example), then you'd use a datum.

Here's an example... say you want a system of guilds. Each guild has a bunch of information associated with it. A name, a description of its purpose (if you want something like that), a list of members (and their rank), a list of ranks, a list of leaders, and the like.

In this case, you'd create some kind of datum prototype:
guild
var
name
desc
list/ranks = list("Private", "Private First Class", "etc...")
list/members = new
// etc...


Now that this is done, you want a place to store all of them so you can easily access them. A global variable called guilds, for example. And then you can add a method of creating NEW guilds, assigning it the basic information, then a method for adding people to the guild and such. Then you'd save the list when the world closes and reload the list when the world opens.

That's just one example (I figured I'd use something that people would in general find a use for...). People use datums for all sorts of things. Even if they just want an object to hold two values, they would make a datum (which is much better than creating an atom with all sorts of useless information).

Here's something I made:
calendar
var
// decides how time passes for us...
seconds_per_minute = 1 // how many seconds in a minute?
minutes_per_hour = 60 // how many minutes in an hour?
hours_per_day = 24 // how many hours in a day?

// our units of time
SECOND = (10) // 1 second in-game = 1 second real-time
MINUTE = (SECOND*seconds_per_minute) // 1 minute in-game = 1 second real-time
HOUR = (MINUTE*minutes_per_hour) // 1 hour in-game = 1 minute real-time
DAY = (HOUR*hours_per_day) // 1 day in-game = 24 minutes real-time

elapsed_time = HOUR
// added to world.time, this is the total amount of seconds passed since
// the world first started up (with an hour added)

// days in our calendar
list/days = list(
"Day of Shirke",
"Day of Karledbolg",
"Day of Serin",
"Day of Jae Hyuk",
"Day of Jae Hyun",
"Day of Depore",
"Day of Xix",
"Day of Zizz II",
"Day of Gram",
"Day of Saturday",
)

// months in our calendar
list/months = list(
/*
month name = days in the month
*/

"Month of the Serpent"=25,
"Month of the Demon"=20,
"Month of the Mahou"=28,
"Month of the Vision"=23
)

// names of the years
list/years = list(
"Dawning Year",
"Year of Intensity",
"Dusking Year",
)

// when does the year start?
base_year = 1


It's a calendar with all of the necessary information to generate a date and time using world.time and some other information. In datum format, it is easily modifiable and creating multiple instances (say I want different calendars in different parts of the world?) is as easy as creating a new calendar object and changing some fields.
/datum is the topmost ancestor of (most) DM types (and so properties defined on it are shared by most objects). Like /turf is a descendant of /atom, /atom is actually a descendant of /datum. So, the full, "true" path to say, /mob is essentially /datum/atom/movable/mob.
The above means /datum is the most basic, stripped class available - it's the basic ancestor of everything, so it has as little stuff defined of it as possible. A datum is essentially like any other object, only without extra 'baggage', if you will. You could use, say, an /obj or /mob (or what have you) instead of every datum you use, but then your objects will just be bloated with extra data they don't need.
Also, dunno if you've read this[link] post I've recently made, a bit of it may be helpful.
In response to Kaioken (#2)
Okay.

From what I've deduced, if you wanted to make a big game which used almost no elements of a turf or obj, would it be possible to instead replace their use with your own turf or obj using datums?
In response to Demon_F0rce (#3)
No, not really. Being mappable and having an appearance (which includes having an icon, and more) are really features built into the language (and the /atom) type, and in fact the whole point of using datums is to have abstract objects which have no appearance nor location/map-spot - if you had wanted to make your own mappable object, you'd have subtyped it under /atom, not /datum.
You've already received some pretty decent examples. Another common use for using your own datums would be stuff like stats and health for a typical RPG.

Lets say the typical BYOND RPG designed by a novice programmer has something set up like this:

mob/var
HP //current HP
maxHP //maximum HP
bonusHP //HP mod from equipment/skills
MP //current MP
maxMP //maximum MP
bonusMP //MP mod from equipment/skills
strength //base strength
bonusStrength //strength bonus from equipment/skills
agility //base agility
bonusAgility //agility bonus from equipment/skills


You could instead do something like this:
Pools
var
cur //current value for the pool
max //maximum value for the pool
bonus //Bonus for the pool (added to max)
New(X) //When the pool is first created, set it's max and current values equally.
cur = X
max = X

Stats
var
base //base value for a stat
bonus //bonus value for a stat
New(X) //When the stat is first created, set it's base value.
base = X

mob/var
Pools/HP //HP pool
Pools/MP //MP pool
Stats/strength //Strength stat
Stats/agility //Agility stat

mob/player
New()
..()
//Assign starting health, MP, agility, strength
//to new players
HP = new(50)
MP = new(20)
strength = new(10)
agility = new (10)

verb/heal()
if(MP.cur >= 3)
MP.cur -= 3
src << "You cast a healing spell!"
HP.cur = HP.max + HP.bonus
else
src << "You need at least 3 MP to cast heal, you currently have [MP.cur] out of [MP.max + MP.bonus] MP."