11 Mar, 2009, JohnnyStarr wrote in the 1st comment:
Votes: 0
Ok, I don't want to bug anyone with my questions,
but I can't find documentation about YAML that would explain
in detail what I'm wanting to do for a MUD. I've looked at
Tyche's code for Ruby based muds (Teensy / Rocket)

I've noticed that these bases output the entire world into one .yml file.
It's a dump of all of the rooms, exits and objects.
I'm trying to figure out how this is done, or if thats the way i want to do it.

with ruby i'm taking advantage of the arraylists and making several of them to
manage Rooms, Objects, Mobs etc. So with the simplicity of the YAML load and dump methods i thought i might make Areas first class objects and contain all the rooms within the areas, all the mobs and items within the rooms etc.

This would create a more 'traditional' area building approach. As i said before, i'm not asking this to have someone write the code for me or anything, but i cant seem to find the kind of YAML support out there to point out the benefits / flaws of this approach.

Thanks again!
11 Mar, 2009, David Haley wrote in the 2nd comment:
Votes: 0
I have to admit that I don't really understand your question… What is it that you're expecting to find in YAML?
11 Mar, 2009, JohnnyStarr wrote in the 3rd comment:
Votes: 0
well david, i am not looking for anything other than an opinion on a good method for what i'm suggesting. I have found that i can use the LOAD and DUMP methods from the YAML module thats built into Ruby. If you have used it i think you would have noticed it cuts out allot of coding. So i was wondering if anyone else that has used this, what their suggestions are about dumping / loading arrays containing objects.
11 Mar, 2009, Barm wrote in the 4th comment:
Votes: 0
I'm not sure if this answers your question, but you can include more than one document in a YAML file by separating each with three dashes, '—'. Then end the stream of documents with three dots, '…'. So in your example, each room or object would be a subsection of YAML markup followed by three dashes.

I think you'd be happier writing the extra code to break each into it's own YAML file, though. I wrote a function that grabs the names of every "*.yml" file in the room directory and create an iterator that returns the contents of each file. Using a for loop, I pass these to functions that converts them to dictionaries (while catching YAML exceptions) and another that builds game objects from those dictionaries. Reading other types of objects was just a matter of cutting and pasting with some name changes.
11 Mar, 2009, JohnnyStarr wrote in the 5th comment:
Votes: 0
Cool, now thats a good idea.
See i'm thinking about grouping everything in a tree order with lists:

World
|
Area
|
Room
/ \
Item Mob
\
Equiped items

But it seems that although that would be a good way to dump the state of the
game, i'm trying to figure out how i would ballance having those resets and
having an actual Index list of items. Like in Diku where you have room / mob items
but you also have an index of in-game objects for refference.

so do you think it would be good to have a separate .yml file for each (circle mud style) area1.yml area1Mobs.yml area1Items.yml?
11 Mar, 2009, elanthis wrote in the 6th comment:
Votes: 0
Is this a from-scratch MUD or are you making heavy modifications to an existing Ruby codebase?

I would honestly just recommend avoiding the Diku-style resets and simplify the design heavily. Create a list of object templates (a separate file) that defines each object in your game world. Your "resets" then are just a small note in the room that says "spawn item type XYZ here," as are the mob item drop lists. The list of objects in the room is then unambiguous. It also helps centralize your object definitions, which makes maintenance a fair bit easier.

You shouldn't need multi-document support form YAML, just represent everything as a tree. I would usually recommend one file per area (just to avoid having one huge file… and in turn, if a file gets corrupted and you have no backups, you lose less of your MUD) and then a series of files for the object/mob templates.

Some people prefer to have "contexts" which are just a way of organizing related areas/mobs/objects. Those may just be represented as directories. So you might have a layout like:

root/
underworld/
area-cityofdead.yml
area-riverstyx.yml
area-bonepalace.yml
mob-template.yml
object-template.yml
stonekeep/
area-forest.yml
area-castle.yml
area-dungeon.yml
mob-template.yml
object-template.yml


etc. An area's name would be its context and name combined, e.g. underworld.cityofdead or stonekeep.forest. A room's name would be something like underworld.cityofdead.throneroom.

In a language like Ruby, dealing with a setup like that is far easier than in C or C++, so you might as well go for it. It's really as easy as having classes for Context, Area, Room, ObjectTemplate, and MobTemplate. Your area/room lookup methods would just split the string on the dot, look up the context object from the first item, the area from the second, and the room from the third. Similar behavior for template lookup.

When you get into making your nice OLC system, you'll find the hierarchy makes for a MUCH nicer browsing/lookup system.
11 Mar, 2009, Barm wrote in the 7th comment:
Votes: 0
Why do you want to dump the state of the game?

I'm picturing a setup where information flows the other way – you define rooms, items, mobs, etc as YAML files and then read those on game startup. The only data I'd save is character state, for which YAML would work but, IMHO, a database would be better.

I'd hate to try editing a single YAML file with thousands of objects. Imagine if you started making changes to your schema?
11 Mar, 2009, JohnnyStarr wrote in the 8th comment:
Votes: 0
hmm, good points :redface:

Well, its just a matter of getting my new code base set up. I've used RocketMud's sockets but everything else is from scratch so i want to start off right. I see what your saying, i didnt mean to say 'state', i mainly just meant the Objects. I do agree a database IS better, but i love the simplicity of yml. Maybe i'm tired of writing connection strings with SQL. Maybe its not the BEST way but its so nice to be able to focus on other stuff for now. I'm hoping to go back and redo the database, but for now i might wanna just do it this way.

elanthis said:
Quote
You shouldn't need multi-document support form YAML, just represent everything as a tree.


So when you say a tree, do you mean having a tree of arrays?
11 Mar, 2009, JohnnyStarr wrote in the 9th comment:
Votes: 0
Here's my schema, does this sound good?
I dont like having to have the indexes but cant think of a better way.
Any suggestions???


World Object:
| |
| AreaList[] # all areas within World
| |
| Area Object
| | RoomList[] # all Rooms in Area
| | RoomObject
| | CharacterList[] # all character's in the room (pcs, npcs)
| | ItemList[] # all in game items in the current room
| |
| MobIndex[] # an Index of all of the Mobs that originate in this area file
| |
| ItemIndex[] # an Index of all of the Items that originate in this area file
|
WorldItemIndex[] # A quick reference to all items
WorldMobIndex[] # A quick reference to all Mobs
WorldRoomIndex[] # A quick reference to all Rooms
11 Mar, 2009, Grimble wrote in the 10th comment:
Votes: 0
staryavsky said:
Here's my schema, does this sound good?
I dont like having to have the indexes but cant think of a better way.
Any suggestions???

This may sound ugly to some, but my first class objects are all stand-alone files organized in a meaningful hierarchy, and reference each other by their path/file (like a URL). There are no numeric object IDs. If you don't like having all those files, an alternative could be to group related objects in the same file (like the room objects of an area) and reference them by path/file/<object name or ID in the file>.
11 Mar, 2009, JohnnyStarr wrote in the 11th comment:
Votes: 0
Sounds nifty Grimble.

Could you provide a more visual example?
11 Mar, 2009, David Haley wrote in the 12th comment:
Votes: 0
I think he means that instead of giving things an ID, he gives them a path like in a file system, so that instead of mob 1234 which is the dark-haired villager in the town of FooTown, he'd have something like mob /Area/FooTown/Mobs/DarkHairedVillager. (Or whatever.)
11 Mar, 2009, Grimble wrote in the 13th comment:
Votes: 0
David Haley said:
I think he means that instead of giving things an ID, he gives them a path like in a file system, so that instead of mob 1234 which is the dark-haired villager in the town of FooTown, he'd have something like mob /Area/FooTown/Mobs/DarkHairedVillager. (Or whatever.)

Yes, that's right. I liked it because the reference formed by the path/file gave me, as the developer, immediate information about the object and made things like reviewing area files easier. With a numeric ID, I'd have to search for the object definition before knowing anything about it. Some may decry the inefficiency of string IDs, but I was happy with the trade-off.
11 Mar, 2009, Vassi wrote in the 14th comment:
Votes: 0
Grimble said:
I liked it because the reference formed by the path/file gave me, as the developer, immediate information about the object and made things like reviewing area files easier. With a numeric ID, I'd have to search for the object definition before knowing anything about it. Some may decry the inefficiency of string IDs, but I was happy with the trade-off.


Right on. The problem with numbers for everything is that they're meaningless to those that come after. Descriptive names make it easier to figure our what's what when you're looking through older (or someone else's) work.
11 Mar, 2009, David Haley wrote in the 15th comment:
Votes: 0
In fact, you can implement string IDs efficiently such that a comparison is extremely cheap (e.g., interning strings and then using pointer equality).
11 Mar, 2009, Davion wrote in the 16th comment:
Votes: 0
staryavsky said:
Maybe i'm tired of writing connection strings with SQL.


You are working with Ruby. You could probably use an ORM to avoid writing any sql. Probably save you a lot of time too.
11 Mar, 2009, Tyche wrote in the 17th comment:
Votes: 0
David Haley said:
In fact, you can implement string IDs efficiently such that a comparison is extremely cheap (e.g., interning strings and then using pointer equality).


Ditto. Ruby to YAML and back already does this for you with symbols. I tend to construct meaningful symbols :npc, :wizard, :big_monster, without quotes, which are trivial to morph in prettier strings, but there's nothing preventing you from interning any arbitrary string like :'hello, world!'. Ruby doesn't intern to pointers but to symbol table entries. Same concept though.

irb(main):012:0> 'big green troll'.intern
=> :"big green troll"
irb(main):013:0> :'big green troll'
=> :"big green troll"
irb(main):014:0> :'big green troll'.to_i
=> 24735
irb(main):015:0> :'big green troll'.to_yaml
=> "— :\"big green troll\"\n"

The intern value of a symbol is only meaningful during the run life of the program, like a pointer. So it must be saved in it's string form.
01 Apr, 2009, Grimble wrote in the 18th comment:
Votes: 0
David Haley said:
In fact, you can implement string IDs efficiently such that a comparison is extremely cheap (e.g., interning strings and then using pointer equality).

Just wanted to follow-up on this after noticing that Boost has a flyweight library that will do this in a nicely transparent way for strings and other datatypes. The performance data is worth a look. I was not aware of the copy-on-write optimization that GCC provides.
0.0/18