MudBytes
» MUDBytes Community » Coding Discussions » Coding and Design » data structures in C
Pages: << prev 1, 2 next >>
data structures in C, prototype stuctures
JohnnyStarr
Wizard






Group: Members
Posts: 550
Joined: Feb 14, 2009

Go to the bottom of the page Go to the top of the page
#1 Posted Jun 30, 2009, 6:10 pm

This is taken from merc.h in ROM

So, the following is for Objects, but there is the same for Rooms and Mobs,
Now, is this a way of making hash tables as far as "index" is concerned?

If so, how do these compare to eachother, is it that the "one object" structure is
just to create an object, then the object_index is the structure that is a global list
of them? if so that makes sense, but at the same time its kinda weird, (to me) why
the need to make 2 structures, is it due to the fact that C is more 'bare bones'?

Code (text):
1
2
3
4
5
6
7
8
9
10
11
 
Prototype for an object. 
 
struct    obj_index_data
 
One object.
 
struct    obj_data
 
.........................
Current Development: Lunacy (a Lua powered Merc project)

David Haley
Wizard






Group: Members
Posts: 5,730
Joined: Jun 30, 2007

Go to the bottom of the page Go to the top of the page
#2 Posted Jun 30, 2009, 6:22 pm

I'm not sure I follow your question... the "bare-bonesedness" of C has little to do with what kind of structures you write in it...?

The idea here in any case is that for every (game) object, you have a "prototype", or canonical/template/standard/whatever, version of the (game) object. But when the (game) object is instantiated into (code) objects, the fields are copied from the prototype (game) object.

If you really want to you can think of the obj_index_data as the "class" and the obj_data as the "instance" of that class, but this is a little too much meta and gets confusing pretty quickly...
.........................
-- d.c.h --
BabbleMUD Project (custom codebase)
Legends of the Darkstone (head coder)
http://david.the-haleys.org
.........................

JohnnyStarr
Wizard






Group: Members
Posts: 550
Joined: Feb 14, 2009

Go to the bottom of the page Go to the top of the page
#3 Posted Jun 30, 2009, 7:55 pm

What i meant by the term 'bare bones' more or less meant that I've never seen this done in newer languages and was wondering if it is sort of a workaround or compromise due to the limited use of high-end programming in C.

So, that makes sense, its just kind of weird for me. but thank you very much  :smile:

So, if i'm right, if i were to try to loop through the global (game) object list, i would be searching through the object_index?
.........................
Current Development: Lunacy (a Lua powered Merc project)

Last edited Jun 30, 2009, 8:02 pm by staryavsky
David Haley
Wizard






Group: Members
Posts: 5,730
Joined: Jun 30, 2007

Go to the bottom of the page Go to the top of the page
#4 Posted Jun 30, 2009, 8:01 pm

You would or could do the exact same thing in any language... the concept being implemented here is orthogonal to the language itself. You might be getting hung up on the fact that it has the word 'index' in it.

In fairness, have you seen whole MUDs implemented in newer languages to make a good comparison? :wink:
.........................
-- d.c.h --
BabbleMUD Project (custom codebase)
Legends of the Darkstone (head coder)
http://david.the-haleys.org
.........................

JohnnyStarr
Wizard






Group: Members
Posts: 550
Joined: Feb 14, 2009

Go to the bottom of the page Go to the top of the page
#5 Posted Jun 30, 2009, 8:13 pm

David Haley said:

In fairness, have you seen whole MUDs implemented in newer languages to make a good comparison? :wink:


Ok, i said "limited use of high-end programming in C" which I've read all over the place, including this site. So, I'm just trying to learn here  :smirk: I'm not trying to step on anyones toes.
.........................
Current Development: Lunacy (a Lua powered Merc project)

Runter
Wizard






Group: Members
Posts: 1,074
Joined: Jun 1, 2006

Go to the bottom of the page Go to the top of the page
#6 Posted Jun 30, 2009, 8:39 pm

Just thought I would point out It would have also been fairly easy to simply use obj_data for both prototypes and instantiated objects from those prototypes.  Depending on how your own personal implementation it could mean having useless fields in both but not necessarily.  I think someone, like David pointed out, wanted a metaclass.  And it made sense to create a physical separation of (meta)class from instance.
.........................
-Heath

For once you have tasted flight Ruby you will walk the earth with your eyes turned skywards,
for there you have been and there you will long to return. --
                                              Leonardo Da Vinci Yukihiro Matsumoto

Last edited Jun 30, 2009, 8:42 pm by Runter
Tyche
Wizard






Group: Members
Posts: 1,059
Joined: May 23, 2006

Go to the bottom of the page Go to the top of the page
#7 Posted Jul 1, 2009, 12:27 am

staryavsky said:

So, the following is for Objects, but there is the same for Rooms and Mobs,
Now, is this a way of making hash tables as far as "index" is concerned?


No.
Note there isn't a room_data.

staryavsky said:

If so, how do these compare to eachother, is it that the "one object" structure is
just to create an object, then the object_index is the structure that is a global list
of them?


obj_index_data is the prototype structure used to create instances of objects which are obj_data.
obj_index_data is what is read in from the area files, and/or editted via olc.
obj_data is the actual objects that are created in the game via resets. 

.........................
http://jlsysinc.gotdns.com/ladybug_laugh2.jpghttp://jlsysinc.gotdns.com/teensymud_250x80.pnghttp://jlsysinc.gotdns.com/palin_calendar.jpg
For now we see through a glass, darkly; but then face to face: now I know in part; but then shall I know even as also I am known.


quixadhal
Wizard






Group: Members
Posts: 1,256
Joined: Oct 17, 2007

Go to the bottom of the page Go to the top of the page
#8 Posted Jul 1, 2009, 12:09 pm

To clarify on the history a bit.... In the original DikuMUD, there was a single file for each type of game entity.  So, all rooms were in tinyworld.wld, all objects in tinyworld.obj, etc.  There was no OLC.  When the game booted, it first generated an index of the byte positions within each file where each entry started (the #6320 lines).  When you loaded a new object, it did an fseek to that index in the object file and read in what was there, copying it into an obj_index_data structure.  At that point, it would allocate a new obj_data structure and do whatever transforms it needed to make it a useable in-game object.

At some point (Merc?) they did away with the indexing and just pre-loaded everything, but the name stuck.

You can watch the old behaviour if you boot up an old Diku, then modify the file while it's running.  You'll soon see string corrpution in anything that comes later than what you changed in the file, and eventually it will crash.

EDIT - Oh yeah, it wasn't due to a limit in the langauge... it was done that way because memory used to be extremely limited.  Fitting a whole game into less than 4 megs of RAM was a challenge, and it was easier to just keep the index values in memory, and pull them off disk again to do resets.
.........................
http://i302.photobucket.com/albums/nn96/quixadhal/Alelord_banner.png

Last edited Jul 1, 2009, 12:11 pm by quixadhal
JohnnyStarr
Wizard






Group: Members
Posts: 550
Joined: Feb 14, 2009

Go to the bottom of the page Go to the top of the page
#9 Posted Jul 1, 2009, 1:11 pm

Thanks quixadhal, that was very helpful. I appreciate you explaining the background as well. So with resets they would pull from disk aye? That
does explain the index, now it was stated by some that it was set up as a meta class, can anyone explain why this would be desired without loading from disk? As in if you were using only dynamic memory? Or is it like Runter pointed out just "personal implementation"?

EDIT:

Oh, ok, sorry i just read Tyche's response, So if the prototype is "Large Sword" That is the prototype that can be replicated into actual usable objects in obj_data. So, the reason there isnt a room_data structure because there's no reason to make instances of the rooms, there are just rooms. But if you have several versions or instances of mobs and objs then on RESET you would want to copy something from the original prototype IE obj_index.

That makes total sense. My bad...
.........................
Current Development: Lunacy (a Lua powered Merc project)

Last edited Jul 1, 2009, 1:20 pm by staryavsky
David Haley
Wizard






Group: Members
Posts: 5,730
Joined: Jun 30, 2007

Go to the bottom of the page Go to the top of the page
#10 Posted Jul 1, 2009, 1:22 pm

staryavsky said:
So, the reason there isnt a room_data structure because there's no reason to make instances of the rooms, there are just rooms. But if you have several versions or instances of mobs and objs then on RESET you would want to copy something from the original prototype IE obj_index.

Not just on reset, but yes, that's the idea.

You don't technically need the separation; you could have special instances that act as prototypes from which you copy values. My code doesn't distinguish between them, at least not as far as the general data structure is concerned.
.........................
-- d.c.h --
BabbleMUD Project (custom codebase)
Legends of the Darkstone (head coder)
http://david.the-haleys.org
.........................

Runter
Wizard






Group: Members
Posts: 1,074
Joined: Jun 1, 2006

Go to the bottom of the page Go to the top of the page
#11 Posted Jul 1, 2009, 1:29 pm


staryavsky said:

Oh, ok, sorry i just read Tyche's response, So if the prototype is "Large Sword" That is the prototype that can be replicated into actual usable objects in obj_data. So, the reason there isnt a room_data structure because there's no reason to make instances of the rooms, there are just rooms. But if you have several versions or instances of mobs and objs then on RESET you would want to copy something from the original prototype IE obj_index.

That makes total sense. My bad...


Keep in mind that usually involves having a go-between function that you have to maintain to generate the instance (obj_data) from the pattern (obj_index_data).  This technically could be accomplished easier by designing obj_data to dup obj_data's and using a single obj_data as a protected pattern.  The difference could simply be a state.  (This is particularly useful if you want to be able to use the same editor code on pattern and instantiations.) 
.........................
-Heath

For once you have tasted flight Ruby you will walk the earth with your eyes turned skywards,
for there you have been and there you will long to return. --
                                              Leonardo Da Vinci Yukihiro Matsumoto

Justice
Sorcerer




Group: Members
Posts: 310
Joined: May 14, 2006

Go to the bottom of the page Go to the top of the page
#12 Posted Jul 1, 2009, 5:52 pm

"index" is a bad term.  What is actually going on is the obj_index_data describes how an obj_data is instantiated.  While obj_data is a single "instance" of it.  While not a perfect match, the obj_index_data is sort of a prototype for obj_data.  It stores information about how an actual object is created and placed within the game.

You could say that it is somewhere between a prototype and a factory design pattern.

staryavsky said:

If so, how do these compare to eachother, is it that the "one object" structure is
just to create an object, then the object_index is the structure that is a global list
of them? if so that makes sense, but at the same time its kinda weird, (to me) why
the need to make 2 structures, is it due to the fact that C is more 'bare bones'?
.........................
In any sufficiently complex system, no one is smart enough to predict every consequence of a seemingly minor change.

Runter
Wizard






Group: Members
Posts: 1,074
Joined: Jun 1, 2006

Go to the bottom of the page Go to the top of the page
#13 Posted Jul 1, 2009, 6:21 pm


Justice said:
"index" is a bad term.  What is actually going on is the obj_index_data describes how an obj_data is instantiated.  While obj_data is a single "instance" of it.  While not a perfect match, the obj_index_data is sort of a prototype for obj_data.  It stores information about how an actual object is created and placed within the game.

You could say that it is somewhere between a prototype and a factory design pattern.

staryavsky said:

If so, how do these compare to eachother, is it that the "one object" structure is
just to create an object, then the object_index is the structure that is a global list
of them? if so that makes sense, but at the same time its kinda weird, (to me) why
the need to make 2 structures, is it due to the fact that C is more 'bare bones'?


The same thing can be accomplished with using the prototype and instances of the same type.  Eg obj_data for pattern and obj_data for instances. 
.........................
-Heath

For once you have tasted flight Ruby you will walk the earth with your eyes turned skywards,
for there you have been and there you will long to return. --
                                              Leonardo Da Vinci Yukihiro Matsumoto

Justice
Sorcerer




Group: Members
Posts: 310
Joined: May 14, 2006

Go to the bottom of the page Go to the top of the page
#14 Posted Jul 1, 2009, 6:34 pm

Runter said:

The same thing can be accomplished with using the prototype and instances of the same type.  Eg obj_data for pattern and obj_data for instances. 


Yes, that would be a true prototype, I've used this pattern for a GZ style mud.  However, that isn't how DIKU/Merc based muds are written.

That being said, you should consider that using a single class to represent the "factory" and "instance" has some issues.  A factory generates some values, and is not simply a prototype.  In this circumstance, the "instance" may have values that make no sense to the "factory", such as game state.  As such, the values that the factory uses to generate other values will not make sense to the instance.

This may or may not be of any relevance to a particular problem.  Additionally, SMAUG uses the "prototype" to store information globally without copying it to each instance.  This saves resources, although the effect is limited due to string hashing.

.........................
In any sufficiently complex system, no one is smart enough to predict every consequence of a seemingly minor change.

Runter
Wizard






Group: Members
Posts: 1,074
Joined: Jun 1, 2006

Go to the bottom of the page Go to the top of the page
#15 Posted Jul 1, 2009, 6:37 pm

It's already been made clear by 4 or 5 different people what the prototype code is.  I'm pointing out there are other options--and you can still write some function to transfer fields.  Yes, diku does a lot of things a certain way.  That doesn't discount other options.
.........................
-Heath

For once you have tasted flight Ruby you will walk the earth with your eyes turned skywards,
for there you have been and there you will long to return. --
                                              Leonardo Da Vinci Yukihiro Matsumoto

Pages:<< prev 1, 2 next >>

Valid XHTML 1.1! Valid CSS!