16 Oct, 2008, David Haley wrote in the 101st comment:
Votes: 0
Isn't the whole point of using transactions to do things atomically? If you are happy with only completing half of your operation, are transactions really appropriate? I suppose they give you a nice property of things not changing in the middle, but still…

And there's no way of asking the DB to not throw away a particular aborted transaction? I suppose that depends on the DBMS API…
16 Oct, 2008, quixadhal wrote in the 102nd comment:
Votes: 0
Nope, there's no way to NOT discard incomplete transactions. You could set the connection to not use transactions, but then every single statement IS a transaction, and that causes far more pain and suffering than it solves (unless you really do have a database just for logging).

It's probably just me being overly cautious… from my days of programming on systems without hardware memory management (where if you didn't free memory when you exited, it was lost until you rebooted).
16 Oct, 2008, David Haley wrote in the 103rd comment:
Votes: 0
This isn't hardware memory management, it's the OS cleaning up for you. When a process exits, all of its memory is freed, all of its file descriptors are closed, etc. I've actually never heard of hardware memory management, unless you're talking about the hardware page table cache.

Of course, that is quite different from wanting to control how a descriptor is closed. You might want to clean up differently, or send some kind of "oh no, panic" message to let the other side do something before closing it. You mentioned a case involving several commands where this could be appropriate.
16 Oct, 2008, Caius wrote in the 104th comment:
Votes: 0
quixadhal said:
Actually, splitting the random number generator off into its own file would make it pretty simple to allow the end user to select which one they want. I'll probably change some of the low level function names to be more useful (leaving #defines for those that insist that number_mm is somehow intuitive), and then we can just make #defines to point to the set you want to use.

Or you could allow the user to change the strategy at runtime, for instance using function pointers. It wouldn't be that much work to create a little infrastructure so that you could use different random generators for different parts of the game.

quixadhal said:
It's probably just me being overly cautious… from my days of programming on systems without hardware memory management (where if you didn't free memory when you exited, it was lost until you rebooted).

Tell me about it. I still do a little Amiga programming now and then. And it's not just memory. ALL resources must be freed. Try exiting your program before all child tasks are in a safe state, and very bad things can happen (a Task is like a thread, for you Amiga-illiterates out there).
16 Oct, 2008, Caius wrote in the 105th comment:
Votes: 0
DavidHaley said:
This isn't hardware memory management, it's the OS cleaning up for you. When a process exits, all of its memory is freed, all of its file descriptors are closed, etc. I've actually never heard of hardware memory management, unless you're talking about the hardware page table cache.

I think he's referring to a memory management unit (MMU), without which things like resource tracking and memory protection is very awkward.
16 Oct, 2008, David Haley wrote in the 106th comment:
Votes: 0
Yes, that's what I meant when I mentioned the page table handling. I'm not sure what that has to do with resource tracking, though. And for that matter, memory protection is also typically handled in the OS by limiting which processes can read/write a given page. I think that the MMU just takes care of mapping page tables to physical memory addresses.
16 Oct, 2008, elanthis wrote in the 107th comment:
Votes: 0
DavidHaley said:
Well, sure, but I'd assume that people have seen dice before and realize that you can get the same number in a row…


Two numbers in a row on a single die is pretty obvious – I didn't disagree on that point. Logically, when thinking about it, most people realize that two (or even three or four) in a row is quite possible. When actually playing a game, however, where the outcome of those dice rolls have some kind of effect on the player, they become very sensitive to anything that they can perceive as an advantage or disadvantage. If they never roll the same number twice, they aren't going to notice. If they roll the same number twice, it's going to stand out. If it happens several times in a row, they are going to start praising their luck (if the rolls were fortunate for them) or getting upset at the machine (if the rolls were unfortunate for them).

If there's absolutely no recognizable pattern, they trust in the randomness. If there is a pattern, they begin to notice and wonder. Just how people are. Whether they logically understand that it's possible isn't the question in these circumstances, because they're more concerned about winning the game of chance than they are about observing natural probability.

Quote
elanthis said:
TTTTTHHHHH
TTHHTTHHTT
THHTTHTTHH
HHHHHHHHHH

The correct answer is of course that all 4 sequences are equally likely to happen. :)

The interesting thing about this is that the equal likeliness is only the case if you take them as sequences. Taken as a collection of occurrences, the probabilities are not equal at all. That's tricky to wrap your head around the first time you encounter it…


The original source (Which I can't find) made sure to use sequences comprised exactly of five heads and five tails, making them equally likely that way as well – my mistake for not following their example. Asking the question of occurrences, many people are still likely to pick the one in which looks like a random jumble of H's and T's, because most people don't have any real knowledge of probability. I know most high schools don't teach anything beyond the bare basics, and the probability courses I took in college were all level 400+. It's just not something that's taught to most people, and "common sense" dictates that randomness precludes any sort of recognizable pattern.

Quote
Why do you need to worry about closing handles?
When the process dies, those will all disappear. I suppose that you might have to worry about corrupting the database's state, but shouldn't it handle that when a connection suddenly dies?


Depends on the database. Not all databases are RDBMS. SQLite, for example. Or Berkeley DB. Or any custom file-based database. Any of those may be in an inconsistent state and requires shutting down. (I'm too lazy to read up through the thread and check to see if the DB in question is an RDBMS or not. ;) )

Quote
I'm also worried that if you're already in a Very Bad State, it's unclear that you'll be able to clean up properly anyhow.


Gotta love those MUDs that install a SIGSEGV handler that tries to immediately save all game state and then hot reboot into a new instance, eh? ;)
16 Oct, 2008, David Haley wrote in the 108th comment:
Votes: 0
elanthis said:
If there's absolutely no recognizable pattern, they trust in the randomness. If there is a pattern, they begin to notice and wonder. Just how people are. Whether they logically understand that it's possible isn't the question in these circumstances, because they're more concerned about winning the game of chance than they are about observing natural probability.

Point taken. I mean, you're right, I just have trouble relating to this attitude personally. :wink:

elanthis said:
Depends on the database. Not all databases are RDBMS. SQLite, for example. Or Berkeley DB. Or any custom file-based database. Any of those may be in an inconsistent state and requires shutting down. (I'm too lazy to read up through the thread and check to see if the DB in question is an RDBMS or not. ;) )

I'm guessing you mean something more than just a relational database in the general sense when you say RDBMS, right?
16 Oct, 2008, quixadhal wrote in the 109th comment:
Votes: 0
Without an MMU, it's pretty close to impossible to isolate processes the way we do now. The Amiga had no MMU (pre 68010 anyways), and so you could write to any bit of memory in the system. The OS would try to clean up after you, but if you crashed and corrupted parts of the stack or heap, the OS wouldn't be able to track what you'd allocated and what you hadn't.

Of course, the C64 before it didn't even bother trying… anyone could use any or all memory. There wasn't any need to free resources, since there wasn't any process space… just a program counter, a few registers, and a bunch of RAM. :)
16 Oct, 2008, David Haley wrote in the 110th comment:
Votes: 0
Sure, the MMU is an enabler, I just wasn't sure what you meant by "hardware memory management" since the MMU is just a map from virtual to physical address, that the OS happens to change every time the active memory context changes – and the OS just happens to set things up so that memory isn't shared across processes (well, unless you ask it to…).
21 Oct, 2008, quixadhal wrote in the 111th comment:
Votes: 0
I'm having fun. I'm in the middle of indentifying (word soon to be copyrighted) the source, and of course that means I need to hand-walk each file to be sure it didn't screw anything up, and to see if I can hand-fix it in such a way that running it through indent again won't screw it up again. :)

Anyways, the "gem" of the morning is this comment by Furey, in do_mfind().

Quote
/*
* Yeah, so iterating over all vnum's takes 10,000 loops.
* Get_mob_index is fast, and I don't feel like threading another link.
* Do you?
* – Furey
*/


Of course, he really means it takes 2 billion loops, because everyone always applies the 2 billion vnum patch, and then makes some stupid immortal-only chewtoy mob whose vnum IS 2000000000, just to prove it's working.

So, no, I don't FEEL like threading another link, and in fact I also don't feel like redoing the whole vnum system so it's less convoluted (yet), but…. this is something to come back to in the near future. If you've ever typed "mfind orc" and watched the mud stall for 5 seconds, this is probably why. :)
21 Oct, 2008, David Haley wrote in the 112th comment:
Votes: 0
What is meant by "threading a link" in this case?

On the other hand, it is a little unreasonable that it takes 5 seconds to iterate over all mobs. It shouldn't matter that there are 2B possibilities – the performance should depend only on the number of things actually there.
21 Oct, 2008, quixadhal wrote in the 113th comment:
Votes: 0
The traditional way DikuMUD's have done iteration has been adding linked list pointers into various data elements, so you can traverse them in several ways. I suspect that there are linked list pointers in place for traversing all the mobs in a given room (via the room structure), but to loop over them by zone or in their entirely, you have to walk the array they get loaded into at boot time.

If they did mobs like they did rooms, that's actually a set of hash buckets with linked lists for collisions.

So, to follow the traditional way Diku did things, you'd need to add a linked list structure somewhere, and probably add next/prev fields to the mob data structures themselves (I don't think they seperated container logic, I think the list pointers are just embedded into whatever was made into a list).

Yeah….

I like my balanced binary trees approach much better. :)
21 Oct, 2008, David Haley wrote in the 114th comment:
Votes: 0
So why is the cost of iterating over all mobs a factor of 2B, and not the number of loaded mobs?

Surely the number of buckets in the hash table is not 2B, and in fact much smaller (a few thousand perhaps). So iterating over all mob prototypes should be a question of going to each bucket, and iterating over the linked list in that bucket. You won't (or shouldn't) be seeing 2B items.
21 Oct, 2008, quixadhal wrote in the 115th comment:
Votes: 0
Because the code, as it stands, loops from 0 to top_mob_vnum and calls get_mob_index() on it…. THAT walks the buckets and returns the index on success, or -1 on failure.

So, if your game has two mobs, vnum 1 and vnum 2bn, you walk the buckets 2bn times trying to find all the values in between.

I can't make this stuff up, honestly. :)
21 Oct, 2008, David Haley wrote in the 116th comment:
Votes: 0
Oh. Well that's just dumb. Why not just walk the buckets from the get-go?

I mean, there already is a "list" of all available mobs in the form of the values stored in the hash table. So asking, for each possibility, "do we have this?" is incredibly wasteful when you could just loop over what you've got.

In any case solving this doesn't need a particularly clever redesign or usage of better data structures. Just use the one that's already there. :wink:

quixadhal said:
I can't make this stuff up, honestly. :)

I disbelieve!! :tongue:
25 Oct, 2008, quixadhal wrote in the 117th comment:
Votes: 0
I weep for the children….

/*
* hack to make new thalos pets work
*/
if ( ch->in_room->vnum == 9621 )
pRoomIndexNext = get_room_index( 9706 );
else
pRoomIndexNext = get_room_index( ch->in_room->vnum + 1 );
if ( pRoomIndexNext == NULL )
{
log_error( "Bad pet shop at vnum %d", ch->in_room->vnum );
send_to_char( "Sorry, you can't buy that here.\n\r", ch );
return;
}
25 Oct, 2008, Runter wrote in the 118th comment:
Votes: 0
So just put rooms/rooms/indexs into std::map which implements the binary tree for you.

Never mind. I forgot. It's important the project remakes circa 1990.

I'm probably being a little unfair. Oh well. :)
25 Oct, 2008, Runter wrote in the 119th comment:
Votes: 0
I've long thought that most of the coding conventions that rom employs is ridiculous. It's one of the reasons I was interested in working on this project. I've been over pretty much every inch of the rom codebase, and there are plenty of silly and ridiculous things all around. Hopefully that's what we are trying to change in retrospect.
25 Oct, 2008, quixadhal wrote in the 120th comment:
Votes: 0
Hehehe, I bet there's an STL container for sparse arrays too, eh? Or perhaps std::map is the name for that construct.

Anyways, for those who don't know what a sparse array is… it's one where only the elements actually assigned exist. Unlike a traditional (perl/LPC) mapping, the index is still an integer, and thus can still be iterated over the old-fashion way, but you could just store room[vnum] directly without any of this hash bucket nonsense.

You *could* do
for(i=0; i< INT_MAX; i++) if(exists(room[i])) poo(&room[i])…
but of course the more efficient way is to use iterators.

That's actually a bigger selling point for C++, to me, than std::string is.
Random Picks
100.0/267