ID:266049
 
Good day people. I come today seeking knowledge on the practicality of the parent_type variable specifically within use on datums


Monster
parent_type = /mob
name = "Tiberath"
var/Health = 10


What would be the point in doing that over this:

mob/Monster
name = "Tiberath"
var/Health = 10




Or am I missing the point entirely?
El Wookie wrote:
Good day people. I come today seeking knowledge on the practicality of the parent_type variable specifically within use on datums


> Monster
> parent_type = /mob
> name = "Tiberath"
> var/Health = 10
>

What would be the point in doing that over this:

> mob/Monster
> name = "Tiberath"
> var/Health = 10
>

Or am I missing the point entirely?

The fact that you made Tiberath the monster does nothing short but bring tears to my eyes. parent_type is useful in scenarios where you have types defined three or four nodes deep and it's starting to look ugly, or you just want to improve your organization.
In response to Audeuro
Lets say you have lots of objects and you can't find what you want you need when you are mapping. So, with use of parent_type you can organize everything to make mapping easier. Here's example:
obj/furniture/doors
obj/machinery/traps
turfs/walls
turf/ground
obj/plants
obj/mineral

area//I put everything under areas because I nearly never use them.
Dungeon
Doors
parent_type = /obj/furniture/doors
Normal_door
//add all stuff you need here
Locked_door

Master_door
Traps
parent_type = /obj/machinery/traps
Poison_gass

Spike

Falling_floor

Walls
parent_type = /turfs/walls
Normal

Cracked

Castle
Doors
parent_type = /obj/furniture/doors
Normal_door

Locked_door

Walls
parent_type = /turfs/walls

Normal

Outside
Fields
Ground
parent_type = /turf/ground
Grass

Path
Plants
parent_type = /obj/plants
Tree

Bush

Other
Rock
parent_type = /obj/mineral


Because you can't place datums, I made all of these objects area type. Of course, you can make them another type, but I usually don't use areas, so I thought I could use them for that.

EDIT: Wait, you asked about use within datums? Well, I don't actually know. As I said datums can't be placed in the map editor, so my idea won't work on them...
In response to Martys1103
You can place "datums" on the map if they aren't actually datums. You'll have to check the "Show all nodes" option in the map editor though.

Also,
http://files.byondhome.com/DreamMakers/ iainperegrine.2007-1116/parent_type.html
It looks like you're missing the point. One of the uses both I and IainPeregrine use in Casual Quest is when creating skills that are very similar.

For example, the Flame Arrow has a parent_type of the regular arrow. However, we overrode one of it's procedures to produce the flame effect.

arrow {
icon = 'arrow.dmi'
behavior() {
go_forward()
}
}

fire_arrow {
parent_type = /arrow
icon_state = "fire"
behavior() {
. = ..()
do_fire_effect()
}
}


Something like that. Obviously this was made on the spot.
In response to CauTi0N
In this case it's probably best to put that type of stuff as a child of /arrow. Using parent_type is most ideal for this stuff when it's saving you from crazy long typepaths, but /arrow/fire_arrow isn't very long, and it's quite a bit more informative at a glance than /fire_arrow, because you know right away it's a child of /arrow instead of having to check the code for its parent_type.
In response to Kaiochao
"One of the first big ideas a programmer new to DM has to learn is the difference between the usr and src vars. Both of these variables hold a mob as their value"

Isn't this strictly wrong? Since src can be anything as opposed to a mob. (Reading onwards now, sorry if he covers that later)
In response to Nadrew
So it's purely for code management, and can easily be avoided to use. I wonder because long ago I used to never use datums, and since then I have started to extensively use them and I wonder of all the times that they would of saved my life. I don't want parent_type to be another of these cases, since it's (as far as I know) the only method in BYOND I'm still uncomfortable with.
In response to El Wookie
I sort of agree with what Nadrew and some others have said, but I wouldn't encourage using parent_type as a way of shortening long type paths - instead I'd question why the type paths got so long in the first place.

One way I use parent_type is to create a new subset of atoms you can easily iterate over. For example, suppose you're making an RTS where each client has a mob but it's not a unit in the game - the mob is there and it moves around just so the map scrolls. If you do this in a unit's AI routine:

for(var/mob/m in oview(4,src))
attack(m)


You might accidentally attack the mob that belongs to a player but isn't an actual unit.

If you do this instead, you won't have that problem:

unit
parent_type = /atom/movable

proc/ai()
for(var/unit/u in oview(4,src))
attack(u)


Using parent_type to obscure what type an object inherits from is a bad idea. In Caution's post ([link]) you need to know that the fire arrow attack is actually a child of the regular arrow attack. If you're not aware of this you'll make changes to /arrow that'll unintentionally affect the fire arrow attack too.
In response to Nadrew
Nadrew wrote:
In this case it's probably best to put that type of stuff as a child of /arrow. Using parent_type is most ideal for this stuff when it's saving you from crazy long typepaths, but /arrow/fire_arrow isn't very long, and it's quite a bit more informative at a glance than /fire_arrow, because you know right away it's a child of /arrow instead of having to check the code for its parent_type.

Right, I should have specified it.

To Forum_account, one use I've noticed is useful for us is when we are creating summons that are inherent for a specific character. For example, we have custom characters which follow a path similar to

game/hero/custom/cauti0n {
parent_type = /game/hero/soldier
// extra information here
}


We have a procedure that loads custom characters by text2path() so it can load all characters by their ckey, but my custom character would follow all the traits of the soldier. In this case, it's particularly useful.
You use it to make a general type path more distinct from its parent type and also more notable in general. For example, you sometimes handle NPCs completely different from players, so it makes sense to attribute different type paths to them to emphasize the distinction.

I don't think it should be used to shorten type paths, because this would more often than not hinder the clarity of the code and obscure a close relation between an object and its superclass. The path <code>/obj/item/ammo/arrow/fire_arrow</code> gives me a lot more information about the nature of the object than <code>/fire_arrow</code> (rather, in this case it makes more sense to make /item a distinct path from /obj).
In response to CauTi0N
CauTi0N wrote:
To Forum_account, one use I've noticed is useful for us is when we are creating summons that are inherent for a specific character. For example, we have custom characters which follow a path similar to

> game/hero/custom/cauti0n {
> parent_type = /game/hero/soldier
> // extra information here
> }
>

We have a procedure that loads custom characters by text2path() so it can load all characters by their ckey, but my custom character would follow all the traits of the soldier. In this case, it's particularly useful.

Because you've committed yourself to using type paths so much (or because Iain committed you to using them), this does look like a way to simplify things but I doubt it's ideal. Making one object type a child of another lets you make use of inheritance, but with such a deep hierarchy I doubt that you're really using inheritance that much.

Inheritance isn't the only way to re-use code:

// you can do it this way:
mob
proc
attack(mob/target)
target.health -= 5

mob/soldier
attack(mob/target)
// do a regular attack and make the target bleed
..()
target.bleeding += 3

// or you can do it this way:
mob
proc
attack(mob/target)
target.health -= 5

soldier_attack(mob/target)
attack(target)
target.bleeding += 3
In response to Forum_account
To me that just sounds like an issue that came about via bad programming practice, any programmer that even encountered that problem would have a simple ten minute task of creating a sub type for the clients to initially handle, and it would take longer to change it to your parent_type suggestion, I believe.

All in all it still seems that whilst it apparantly does have some practical use, this variable can otherwise easily be avoided in favour of (What some might think is) a messier source.
In response to El Wookie
El Wookie wrote:
To me that just sounds like an issue that came about via bad programming practice, any programmer that even encountered that problem would have a simple ten minute task of creating a sub type for the clients to initially handle, and it would take longer to change it to your parent_type suggestion, I believe.

I'm not sure what you mean by that. It's not that you implement things that way to solve a problem after you've run into it, you implement things that way to avoid the problem completely.

I can't think of any situation where you'd have to use parent_type. There are many cases where it just causes confusion. You can use parent_type to make your own "basic" object types. In the case of my example, you could instead not use parent_type and just have players be instances of /mob/player and have units be instances of /mob/unit.

The reason you'd use parent_type to make /unit look like a basic type is because you will never say "for(var/mob/m in world)", you'll either iterate over player mobs or unit mobs, but not both. It's kind of like how /objs and /mobs are children of /atom/movable, but I rarely ever find myself writing things like "for(var/atom/movable/m in world)".

BYOND gives you basic object types (turf, obj, mob, etc.) but those aren't always sufficient for your project. You might use different types of objs to create environmental objects (rocks, trees, etc.) and items. To make the distinction clear you set their parent_type to /obj or /atom/movable to make them look like basic types. It's a way to organize your project, which is why you're wondering why it'd be necessary - organization is never necessary and it comes down to your style.
atom
var
loc

movable
proc
Move()

area
parent_type=/atom

turf
parent_type=/atom

obj
parent_type=/atom/movable

mob
parent_type=/atom/movable


Interesting, isn't it?

Making a tree structure and overriding the parent_type are used where we see fit.



Datums like /atom, /atom/movable and such solely exist for defining shared vars and procs.
You use such datums to organize things. For better organization, they better be presented in a tree structure format.

Observe the following code.

color

primary
parent_type=/color

secondary
parent_type=/color

red
parent_type=/primary

yellow
parent_type=/primary

blue
parent_type=/primary

green
parent_type=/secondary

orange
parent_type=/secondary

violet
parent_type=/secondary


There's really nothing wrong with it. However, the following code is better.

color
primary
red
yellow
blue
secondary
green
orange
violet


With just a glance, you could see how things are grouped together.



Whenever you feel lazy writing a long type path, you could just place the datum in the root and override the parent_type var.

/obj and /mob are good examples on when to override the parent_type. To make the code more organized, we could subdivide things. (i.e. having /obj and /mob have their own trees) See the following code.

obj
// parent_type=/atom/movable
furniture
chair
table
cabinet
wall
brick_wall
concrete_wall
fence
box
item


weapon
parent_type=/obj/item
needs_ammo
bow
gun
sword
knuckles

clothing
parent_type=/obj/item
head
hat
mask
body
armor
shirt

mob
// parent_type=/atom/movable
npc
player


Not only /weapon/sword is shorter, it is also easier to remember compared with /atom/movable/obj/item/weapon/sword.
In response to Jemai1
Jemai1 wrote:
Not only /weapon/sword is shorter, it is also easier to remember compared with /atom/movable/obj/item/weapon/sword.

I'd recommend keeping it as /item/weapon/sword. It's important that clothing and weapons are types of items, but it's not important that items are objs. Using parent_type obscures these relationships but the /item type isn't something you'd want obscured.
In response to Forum_account
That works too. I originally had that in mind but my lazy part took over.