Advertisement

Items in MMORPG

Started by April 21, 2005 12:22 PM
30 comments, last by hplus0603 19 years, 9 months ago
Here is my idea. Okay, since you can easily find out who owns the items, start there.

During a trade, just change item owner's name and remove from old owners inventory.

For a dropped item, maybe use a item status column allowing you to limit queries only to dropped items.

Can't help too much more than that since I haven't ever made one. Good luck with your project.

P.S. Mind starting up the server for me?
There are two ways of doing it:

1) make items entirely data-instanced: a big table or array defines what each item is and does for you, and the per-player data is simply a pair of <item-kind,count> for how many of each you own.

2) make items have identify of their own: each item has an object ID just like players, mobs, etc. Items can be customized, but making storage and networking efficient is harder.

The typical FPS and RPG way of doing it is 1); the typical virtual-world way of doing it is 2).

In the end, distributing items and their properties isn't all that different from distributing other facts about the world: "there's a monster here".
enum Bool { True, False, FileNotFound };
Advertisement
I'd also like to add that with option 2, you're usually better off basing each item on a template, and only store the changes from the base tempalte in the actual item; this makes for easier management, upgrading, and transmission.
enum Bool { True, False, FileNotFound };
Hi,

Thank you all for the replies.

@acraig

OK, that's pretty simple and straight forward... but just one question, doesn't your system use a lot of memory unnessasarily since you have one giant class with all the possible fields in it? It seems like this would use a lot of memory...

@hplus

If you don't mind, could you explain what 2) is a little more? Im assuming that 1) is the system acraig is describing? Or maybe im just misunderstanding both of you [grin].

With number 2), you treat an item as a unique object then? Couldn't you use this system to kind of prevent duping completely? But what did you mean by "Items can be customized"? Why couldn't they with 1)? I guess im a little confused on what the difference is exactly between 1) and 2)... are you saying that 2) is kind of like a relational database in that you store a big table of items which have ID's, and then your player has a std::set<Item_ID> for an inventory instead of a std::map<Item,int> for an inventory? (Item_ID would just be an enum type).

Thanks again for any help.
FTA, my 2D futuristic action MMORPG
I'd like to suggest taking a look at this GameDev article. Don't know if it will be of any use, but I stumbled upon it when looking though the archices.
Quote:
With number 2), you treat an item as a unique object then? Couldn't you use this system to kind of prevent duping completely?


Yes, with such a system, duping because of bugs becomes much less of a problem. However, there might still be bugs that magically create items, or that sell items for way under-price, or buy items for way over-value, so it's not an entire panacea.

With option 1, you cannot customize an item, because ALL the stats of an item have to live in a well-known, pre-determined item record. You could create item records for "Sword," "+1 Sword," "+2 Sword," and "Flaming Sword" and allow the user to take action that consumes a "Sword" and produces a "+1 Sword". However, with system 1, assuming this is the data you have, you can't take a "+2 Sword" and turn it into a "+2 Flaming Sword" -- because there is no such item pre-determined.

With option 2, you probably still have templates, but you then store a list of overrides for each item. You also have to store the identity of each item -- each item has an entity Id, whereas with option 1, there are just item kinds, and the player has 0 or more instances of that item kind.

Option 1 will usually lend itself to explicitly storing all the various parameters as columns in a table; Option 2 will usually lend itself to store parameters about an item (or about an item template) as key/value pairs that you union together to get the entire item.

Option 2 is heavier server-side, for sure, and may be heavier network-wise, but gives you more flexibility. There's no right or wrong answer on which way to go. For example, creating 40 separate Entities just to fill a magazine of a rifle with bullest is probably a bad idea -- but if your rifle object only has an "ammo count" value, how can you load it with silver bullets to hunt vampires, or load every 5th bullet with tracer for night-time hunting?
enum Bool { True, False, FileNotFound };
Advertisement
Quote:
Original post by graveyard filla
@acraig

OK, that's pretty simple and straight forward... but just one question, doesn't your system use a lot of memory unnessasarily since you have one giant class with all the possible fields in it? It seems like this would use a lot of memory...


Well, it ( the server ) would normaly only have 1 copy for each item stat. Ie many items would share a pointer that describe the details of an axe. We are also in the process of refactoring this class a little bit so we can probably do some better packing of the data. But in the end we want to keep it nice a general and try treat all items the same. Otherwise we could get into trouble if we decide we want a new item type or want to blend several types together.
That was me by the way, I suddenly got logged out half way through posting.

Mark
Quote:
It should be trivial to ensure that items can't be duped, because they can obviously only be in one place at a time.


The trick is in persisting that fact to disk. When you're using item counts for inventory, moving an item from place A to place B really destroys the item and re-creates it in the other place, so it doesn't model what happens in real life. Here are two examples I've heard of from operating games (not our system, luckily :-):

1) User A gives stuff to user B. Server crashes when both users have accepted, but only user B has yet been updated (there's an update pending for user A). After re-start, stuff is duplicated because both user A and user B has it (requires the item-count way of doing inventory). This is bad if there's some bug that lets players crash servers on demand...

2) User hands in items for quest, and receives reward. User immediately logs out. Turns out, checkpointing for the reward happened right away, but checkpointing for the quest consumables was lost due to a bug, and that loss would only checkpoint if something else changed in inventory after that.

When you have "item counts" inventory, you have to make sure that everything commits as one transaction, or you have possible dup bugs. When you have unique items, you can form "your inventory" using "select * from items i where i.owner = 'You'", and ONE class of dup bugs goes away -- but others still remain, as long as you don't have a system for reliable, durable, sequenced transactions.
enum Bool { True, False, FileNotFound };
In our system we just change the ownership of the item so there is very little chance of duplication since the item is never really destroyed. There is the potential for the item to not end up in the right hands but that is a different matter. We also do a database hit whenever the ownership changes just to make sure we limit loss on a server crash ( which we still have, /me shakes fists at bugs ). For trading we place all the items in a 'special' area and only re-assign ownership after both parties accept. So even if the server crashes in the middle of the exchange they should not lose their items. The *only* time I can see possible duplication is when splitting a stack of items, this does create a new item in the world.

I'm sure if we find any duping we will come down hard on it ( as we already have on a few players for exploiting a quest).

This topic is closed to new replies.

Advertisement