12 Oct, 2011, plamzi wrote in the 21st comment:
Votes: 0
@teqneek

Setting aside for a moment whether a database will be fast enough for real-time lookups, can we go back to the question of what you're trying to achieve exactly? I'm still trying to understand why you would ever have an object and a mobile in the same index/list. I understand that you're deriving everything from an "entity" class, but your database schema doesn't have to mirror your class hierarchies. The more disparate things you try to stick in the same table, the more inefficient it will become, not just in terms of record size. For instance, if you have players in the same table as mobiles, and you want to set a max number of mob instances in existence, you'll be adding a column that no player record actually needs.

As for what to look up in database and what to load in memory, I would just use my judgment, keeping in mind quixadhal's earlier point about a MUD server generally under-utilizing machine resources. I would point all relatively simple lookups to stuff that's in the memory. I would also load up stuff that needs to be accessed at 10-20 times per second, unless it's much easier to do that particular kind of lookup via a query. While a database can handle that frequency if it comes from a single session (your game), it seems to me that you'd be squandering its capacity.

What I mean by squandering relates to Rarva's point about concurrency. Regardless of where you are now with your project, if things go well, you'd want to be able to open up the database to interfaces other than the game, e. g. a website, or maybe a web client, etc. At that point, concurrent access may cause lag spikes that in a real-time game will be noticeable to players.
12 Oct, 2011, David Haley wrote in the 22nd comment:
Votes: 0
I'm a little amused and bemused that people are comparing the performance needs of a MUD to the performance needs of, um, Google, or automated trading systems that process tens of thousands of trades a second with millisecond-level latency. Like Quix said, those are some seriously heavy performance systems and being just a little slow can mean millions of dollars. Anyhow, the point here is that you are exaggerating your need for performance or perhaps not seeing the bigger picture. Your enemy here is not performance: you can work around performance. Obviously you won't make an external process call for every single piece of information. You can still use it as a storage device.

I'm not entirely sure what the big issue here is, to be honest. You would want everything to be in the same table if you view all of your in-game entities as interchangeable. If an actor is really an object that happens to move around and do stuff, it makes sense to treat it the same as an object with some extra properties. Whether or not you do this depends on what your goals are. Do you want objects that behave like actors? What about actors that behave like objects?

If your entities are cleanly divisible into categories like "actor", "object" and "room" (etc.) then you really have no reason to store it all in one table, and in fact, you have several reasons not to. Performance is an example; keeping your indexes small and to-the-point will make queries faster.

As for numeric IDs, I don't think you should worry about recycling. Use a big enough number field, like a 64 bit number. That gives you 1.844674407370955e+19 numbering possibilities. If you were creating a million things a second, it would take 18,446,744,073,709 seconds to exhaust the ID space. That many seconds is 584,942 years, by the way. So… just use an ever-increasing 64-bit number, and the chances of you ever having to care are infinitesimal.

Don't solve a problem until you've established that it truly is a problem. Unless you are so memory-constrained that a 64-bit number per object is expensive (99.999% chance that you aren't), the issue of dealing with unique IDs goes away without anything more complicated than a sequence number.

plamzi said:
At that point, concurrent access may cause lag spikes that in a real-time game will be noticeable to players.

No matter how you're storing your data, if disparate systems need read-write access and therefore you need lock control, you will have these spikes if you're not careful. Database vs. file is irrelevant as soon as you have competing concurrent access.
12 Oct, 2011, plamzi wrote in the 23rd comment:
Votes: 0
David Haley said:
I'm a little amused and bemused…
Don't solve a problem until you've established that it truly is a problem. Unless you are so memory-constrained…
plamzi said:
At that point, concurrent access may cause lag spikes that in a real-time game will be noticeable to players.

No matter how you're storing your data, if disparate systems need read-write access and therefore you need lock control, you will have these spikes if you're not careful. Database vs. file is irrelevant as soon as you have competing concurrent access.


If in your experience, concurrency never created any issues, it's not safe to assume that it will never be a problem for anyone else, either. I have established for myself that it is a problem, which is why I brought it up. I run my own server with 6GB RAM and generous caching and I've still seen some issues. For one, at some points there can be 6 instances of the server (builder instance, staging instance + individual developer instances) some of which go frequently up and down (the dev ones) even if they don't have actual players, and at boot-up reading is very intense (the dev instances load 400+ areas). I'm glad I didn't play fast and loose with runtime database lookups.

I wasn't comparing a database to flat file access in terms of concurrency. In fact, I haven't mentioned flat file access at all because it doesn't sound like the OP is asking us whether to go with one over the other.
12 Oct, 2011, David Haley wrote in the 24th comment:
Votes: 0
plamzi said:
If in your experience, concurrency never created any issues

Sorry, but I'm not sure where I said that concurrency never created any issues. I believe I said the opposite, in fact.
12 Oct, 2011, plamzi wrote in the 25th comment:
Votes: 0
David Haley said:
plamzi said:
If in your experience, concurrency never created any issues

Sorry, but I'm not sure where I said that concurrency never created any issues. I believe I said the opposite, in fact.


I misunderstood the point you were trying to make in your first paragraph. Upon re-reading, it seems like we're on the same page.
13 Oct, 2011, teqneek wrote in the 26th comment:
Votes: 0
quixadhal said:
Most games I've seen (outside the tinker-toy realm of MUD's, most of which are written by hobbyists) that use SQL do, in fact, store ALL the game data in SQL. The advantages far outweigh the limitations, but it does require you design for the fact.

You're worrying about a few thousand records, at a lookup speed of a few dozen a second? Even in the 1980's, that was easily doable. I've worked on systems with millions of rows, updating a hundred thousand entries an hour, and had front-end interfaces that would retrieve the data in tenths of a second. The high volume trading systems David mentioned are indeed real-time. You will never convince investors that "a few seconds" is adequate responsiveness, because "a few seconds" might make the difference between selling at $400/share and selling at $150/share.

As for increasing ID numbers. I wouldn't worry about it until and unless you see it as a problem. With a 32-bit integer you have 2 billion to work with. If your maximum number starts getting upwards of a billion, you probably still have some time to think about how to recycle old ones. As an added bonus, if you design your database with the appropriate triggers on updates, you could simply change the ID of an item to a lower-value previously deleted one and have all the data change with it.

Note that being able to do that does mean you have to work out a cache system which respects changes of that nature, so your game code also adjusts accordingly.

Much of the "slowness" in web applications comes from the fact that they often run as one-off scripts which have to connect and tear-down the database connection every time they run. That stuff does indeed take time, but a normal game won't do that. It will connect at bootup and hold the connection open until shutdown.


This i do not get… yes many large scale games do store all of their game data in SQL just as most muds now a days store their data in a flat file system… In no way do these large scale mmos pull directly ALL of their data from the SQL database in real time, nor do muds do this with their flatfile systems.

Unfortunately this topic got a little derailed, the whole real point was just the numeric ID system, something alternative to a vnum system (Tyches article link was a very good read for those of you who havent taken a peek)
13 Oct, 2011, teqneek wrote in the 27th comment:
Votes: 0
David Haley said:
I'm a little amused and bemused that people are comparing the performance needs of a MUD to the performance needs of, um, Google, or automated trading systems that process tens of thousands of trades a second with millisecond-level latency. Like Quix said, those are some seriously heavy performance systems and being just a little slow can mean millions of dollars. Anyhow, the point here is that you are exaggerating your need for performance or perhaps not seeing the bigger picture. Your enemy here is not performance: you can work around performance. Obviously you won't make an external process call for every single piece of information. You can still use it as a storage device.

I'm not entirely sure what the big issue here is, to be honest. You would want everything to be in the same table if you view all of your in-game entities as interchangeable. If an actor is really an object that happens to move around and do stuff, it makes sense to treat it the same as an object with some extra properties. Whether or not you do this depends on what your goals are. Do you want objects that behave like actors? What about actors that behave like objects?

If your entities are cleanly divisible into categories like "actor", "object" and "room" (etc.) then you really have no reason to store it all in one table, and in fact, you have several reasons not to. Performance is an example; keeping your indexes small and to-the-point will make queries faster.

As for numeric IDs, I don't think you should worry about recycling. Use a big enough number field, like a 64 bit number. That gives you 1.844674407370955e+19 numbering possibilities. If you were creating a million things a second, it would take 18,446,744,073,709 seconds to exhaust the ID space. That many seconds is 584,942 years, by the way. So… just use an ever-increasing 64-bit number, and the chances of you ever having to care are infinitesimal.

Don't solve a problem until you've established that it truly is a problem. Unless you are so memory-constrained that a 64-bit number per object is expensive (99.999% chance that you aren't), the issue of dealing with unique IDs goes away without anything more complicated than a sequence number.

plamzi said:
At that point, concurrent access may cause lag spikes that in a real-time game will be noticeable to players.

No matter how you're storing your data, if disparate systems need read-write access and therefore you need lock control, you will have these spikes if you're not careful. Database vs. file is irrelevant as soon as you have competing concurrent access.


Some how this topic got into me storing all my data (that normally resides in memory) in an sQL table.. heh, definitely not where I was trying to go. As far as storing all my entities in one "Table" I was referring more to the Code side as a STL Map, in a sense my objects can act like creatures, and a creature could act like an object. The idea of the design was that a "thing" could do the very basis of what a object in real life could do… Move, Walk, Talk, Access various data from the world, etc. These issues seem pretty trivial to me in the end especially for a mud.. Again I was trying to just seek better ways to handle a VNUM system, with a better instance tracking system (vs the standard way that Diku does its)

Glad we have some discussion going though!
13 Oct, 2011, Idealiad wrote in the 28th comment:
Votes: 0
teqneek said:
Unfortunately this topic got a little derailed, the whole real point was just the numeric ID system, something alternative to a vnum system (Tyches article link was a very good read for those of you who havent taken a peek)


One thing I didn't understand in Tyche's article that I'm wondering if someone can clear up is this:

Quote
Consider the problem with @rename $orc $troll. I could have lots of references out there using the symbol $orc. To cycle through all the objects and all their naughty parts updating the symbols is completely unacceptable. However since they all use the same subscript in symbol_table all I have to change is the string there and viola. It's almost too easy.


I think it's related to this (?):

Quote
Now at the risk of further confusion maybe a few words about how symbol tables are designed. Forget about OIDs for the moment. The dirty little secret is that symbols are also stored as numbers internally! It might be helpful to grab a compiler design book and read about the various algorithms used to create, store and retrieve symbols, and the reasoning behind them. I use at least three different algorithms depending on the scope and use of the symbol, whether it's scoped globally, at the object level, or at method level (functional scope). The symbols I've been describing are globally scoped, and used when referencing objects.


Just to clarify, is Tyche saying that builders can write $orc when scripting a bunch of different objects, then @rename $orc $troll, and when they go back to look at those other objects they now see $troll – and this happened without going through all those objects to update $orc to $troll, because internally it's just using a number that references the symbol in the symbol table?
13 Oct, 2011, David Haley wrote in the 29th comment:
Votes: 0
Quote
These issues seem pretty trivial to me in the end especially for a mud.. Again I was trying to just seek better ways to handle a VNUM system, with a better instance tracking system (vs the standard way that Diku does its)

Then I'm not sure what your question is, or what issues you have with the various proposals that have been given.

You need a way to identify prototypes and a way to have instances. You can give prototypes unique names or numeric IDs. Many people think names are clearer. You can then give your instances unique numbers and a reference to the prototype ID.

I guess I'm not sure what question is remaining? Was there something wrong with the approaches given?

Idealiad said:
Just to clarify, is Tyche saying that builders can write $orc when scripting a bunch of different objects, then @rename $orc $troll, and when they go back to look at those other objects they now see $troll – and this happened without going through all those objects to update $orc to $troll, because internally it's just using a number that references the symbol in the symbol table?

Basically he's saying that you use the numeric ID of the element in the symbol table, and the name is secondary.

So whenever you would store the symbol, you store the symbol id, and look up the name when you display it. It would be relatively rare when the name is the important piece of data rather than a reference to the symbol itself.
13 Oct, 2011, Runter wrote in the 30th comment:
Votes: 0
Sorry for the late response. I've been a little busy.

Quote
There seems to be alot of reference to web based applications in the database, alot of queries and return to a website take around .005 to .01 for execution times in the query. To use that kind of look up in a game even with proper indexes and caching, and doing that lookup several times a second… seems inefficent.


I don't want to beat a dead horse, but even with your admission here of .005 to .01.. let's just say .01. And several times a second. Several taken to mean "Consisting of a number more than two or three but not very many". Let's just go ahead and give you a good number above several. So let's say 10 @ 10 ms each. Assuming no caching at all, that's only 0.1 seconds total. Most muds sleep longer than this every 4 pulses. Now assume caching, and suddenly only the first access of a specific datum is 10 ms. Even using the most naive caching strategy most of the requests are centralized around players currently in the game. Like hitting their hp over and over. Or their current armor class. Stuff like this performs fantastic with any sane caching strategy. And most ORMs give you it for free, even if they don't you can encapsulate it in your own system. Just to be clear, I think even without caching you'd have a hard time noticing any performance hit. Btw, database lag isn't really a performance deal. It's more of a synchronization/blocking deal. Even if you had so many database hits that your game was laggy, it wouldn't be using a crippling amount of CPU.

So when would this not be appropriate? Well, it wouldn't be appropriate once your game has thousands of concurrent users. Given that I don't know a single mud in existence with several thousand concurrent users, I'm going to go ahead and say it'll probably be fine forever. But if it's not, once you get several thousand concurrent users you can either do what big MMOs do and shard your server (the easy way) or you can just redesign it to handle more users. But don't make the mistake of thinking that big MMOs aren't using direct access to databases. For a lot of reasons, they often will be.

Unless you're making your game have database driven neural networks, a MMO where time can run backwards, and cryogenically frozen ninjas thawed to save the world, I don't see any reason to rock the boat of a proven strategy at the expense of convenience to you. Besides, a heavy database strategy gives you advanced features, too. Like full persistence whenever and wherever you choose.
13 Oct, 2011, Runter wrote in the 31st comment:
Votes: 0
Btw, just for the heck of it I decided to write a little test using sqlite3. This is not an in memory database.

To insert (create)
~ (0.000848) INSERT INTO "entries" ("field") VALUES (691)

And to access.
~ (0.000017) SELECT "id", "field" FROM "entries" ORDER BY "id" LIMIT 1

so 0.0017 ms to access.

How about getting the field from every single existing record? (5000)

~ (0.000028) SELECT "id", "field" FROM "entries" ORDER BY "id"

0.028 ms for all of them.

And finally updating.
~ (0.000872) UPDATE "entries" SET "field" = 99999 WHERE "id" = 11

Again, not in memory. But I decided to do in memory database just for the hell of it.
~ (0.000026) INSERT INTO "entries" ("field") VALUES (807)
~ (0.000029) SELECT "id", "field" FROM "entries" ORDER BY "id" LIMIT 1
~ (0.000036) SELECT "id", "field" FROM "entries" WHERE "field" = 10 ORDER BY "id" LIMIT 1
~ (0.000041) UPDATE "entries" SET "field" = 99999 WHERE "id" = 11

So the milage will vary depending on some factors, but I think it's pretty clear that assuming 10 ms per operation is magnitudes wrong.

Code can be found here: https://gist.github.com/1285812
13 Oct, 2011, David Haley wrote in the 32nd comment:
Votes: 0
Runter said:
But don't make the mistake of thinking that big MMOs aren't using direct access to databases. For a lot of reasons, they often will be.

As a data point that might be interesting, where I used to work (a financial firm) we stored basically all interesting information in databases. Any program that did anything interesting would be hitting the DB over and over again. A fairly clever caching system had been developed so that DB hits would go in-memory when possible and to the DB when necessary; various hooks were written so that when a write occurred, caches were intelligently invalidated and so forth.

This is mainly an interesting point if you're going to Go Big, like Runter said. For a MUD, your performance needs will be rather small – the day that you have thousands of concurrent users needing realtime servicing, come back to us and we'll talk performance then. :wink:
14 Oct, 2011, Tyche wrote in the 33rd comment:
Votes: 0
Idealiad said:
Just to clarify, is Tyche saying that builders can write $orc when scripting a bunch of different objects, then @rename $orc $troll, and when they go back to look at those other objects they now see $troll – and this happened without going through all those objects to update $orc to $troll, because internally it's just using a number that references the symbol in the symbol table?


Yes. This works for me because the script code isn't stored in source form, it's compiled to byte code, and decompiled to source code when you want to edit it.
If you wanted to use 'symbols' in Merc MobProgs, Circle DG scripts, or Mush code, you would have to, at the minimum, store them in a "tokenized" format to avoid search and replace.
Doing that has it's own benefits, like speeding up parsing when running them. I think one of Scandum's mud releases tokenizes script code ("Lola").
14 Oct, 2011, Tyche wrote in the 34th comment:
Votes: 0
I've always thought that making the builder/wizard use or remember 'vnums' or 'dbrefs' on dikus and tinys to be very annoying.
Typically on a Diku you assign a range of vnums to a builder for a zone/area and they create their objects/rooms/whatnot by creating them using their assign numbers.
The you have to remember which vnums are what when you write your scripts or are looking for things. On a tiny you create an object and get back a dbref and then
use that in all you commands to build/program it. You could redesign and use symbols, but typically what's been done is to create search commands for the wizard.
ColdMud, which I modeled my design after, incorporated both, a mechanism to use either symbols or dbrefs, plus it has a @find/@grep command which searches fields
on an object, like short/long description.
14 Oct, 2011, Rarva.Riendf wrote in the 35th comment:
Votes: 0
Considering lag, and talking about vnums, (meaning an old codebase) you will have it in your engine way before the database can be a problem.
Just try to simply code a command that slay all your mobs at once, (including corpse creation running through mprog death etc).
That is where you can have lag problems. Already, and even with everything in memory. (and I only have around 9k mobs).
Database hypothetical lag is the least of your concern.
14 Oct, 2011, quixadhal wrote in the 36th comment:
Votes: 0
teqneek said:
This i do not get… yes many large scale games do store all of their game data in SQL just as most muds now a days store their data in a flat file system… In no way do these large scale mmos pull directly ALL of their data from the SQL database in real time, nor do muds do this with their flatfile systems.


Tell the EVE-Online people that, since they worked directly with IBM to engineer one of the first terabyte solid-state disk arrays to do exactly that. You assume because the data is in SQL that every access will always be a disk hit. Most RDBMS's are pretty good about caching rows and/or tables that get hit frequently, even if you don't cache things at the application layer.

As for muds, that depends too. DIKU muds typically don't. But many others will flush seldom used objects to disk and load them on demand, and that's usually not noticeable to the players.
14 Oct, 2011, teqneek wrote in the 37th comment:
Votes: 0
People are still going all over on the DB speed thing, that wasnt even what this topic was about lol. Thanks for all the previous posts and suggestions, im slowly moving fwd on a blend of the ideas ive read in this topic about a a ID/Tag system.
14 Oct, 2011, teqneek wrote in the 38th comment:
Votes: 0
Regardless… using an MMO period is a bad example.. Great EVE uses technology most of us dont have access to.. and SSD bridges the huge gap in performance between RAM and Disk, they have their game spread over 100 SOL Blade servers, 100 Proxy servers, and over 5 database clusters. All using stacklesse python, and SSD access. :P

Oh and they are noted as having the largest super computer in the gaming industry :P
14 Oct, 2011, Runter wrote in the 39th comment:
Votes: 0
teqneek said:
People are still going all over on the DB speed thing, that wasnt even what this topic was about lol. Thanks for all the previous posts and suggestions, im slowly moving fwd on a blend of the ideas ive read in this topic about a a ID/Tag system.


Sure it is. If you proselytize based on falsehood then it's certainly more than on topic for people to dispute said false information. Without this, threads could do more harm to readers when taken for granted that those false statements had undisputed merit. Furthermore, any type of claims that are questionable, even those not related to the topic at hand, has to be disputed for the same reason.
teqneek said:
Regardless… using an MMO period is a bad example.. Great EVE uses technology most of us dont have access to.. and SSD bridges the huge gap in performance between RAM and Disk, they have their game spread over 100 SOL Blade servers, 100 Proxy servers, and over 5 database clusters. All using stacklesse python, and SSD access. :P

Oh and they are noted as having the largest super computer in the gaming industry :P

I generally agree with you that eve online is a bad example, because it gives you too many outs like the ones you are using here. Why do you think using Python gives you speed unachieved in C or C++ or any other language for that matter? Yes, it's a great technology, but that's not the reason they're using python. You make it sound like the reason they're using all of this expensive technology is because they foolishly decided use a database. Madness, indeed. You haven't really responded to my previous post, and I'm the only person here who has actually posted benchmarks and actual factual data. I wasn't running on a solid state, server cluster or on a super computer. I ran it on my laptop with a normal hard drive.
14 Oct, 2011, David Haley wrote in the 40th comment:
Votes: 0
They used Python for reasons quite unrelated to performance.

And the performance comparison is quite unfair and misleading because frankly a MUD simply does not service the kind of load that EVE does.
20.0/51