12 Nov, 2008, David Haley wrote in the 261st comment:
Votes: 0
The problem is when people store the index instead of the pointer to the data structure. The latter is what's important; the former is pretty much immaterial and "noise" as far as the user is concerned.

There's a strong argument to be made in favor of container encapsulation and data hiding here. :shrug:
14 Nov, 2008, quixadhal wrote in the 262nd comment:
Votes: 0
So, today's little mini-project is to implement the non-functional auto-god system that currently only exists as a couple of variables and not much else. In looking at how the player load/save system works, I reordered the directories a little bit so that players/ and gods/ now have the 26 alphabetic subdirs. That should help keep the directories from becoming so gigantic. I know even on a small MUD, unless you have registration, people make tons of alts and trial characters that just sit there as clutter. :)

Anyways, currently the system reads and writes your player data to players/q/Quixadhal, for example. If I make myself immortal, it makes a worthless entry in gods/q/Quixadhal, which is never accessed by anything in the game, in any way.

How about this. When you log in, the game looks for you in gods/f/Foo, and if that loads, you are an immortal. If that fails, it looks in players/f/Foo, and if that loads you are NOT an immortal (the code specifically would cap you at LEVEL_HERO). The save code would choose which directory to save you in, based on your level.

Thus, if you promote someone to godhood, it forces a save and they now use the file in gods/ from now on. If you later decide to demote them, you (or the code) just removes that file. Now they are right back where they were just before they got promoted. Of course, you probably have to kick them off and THEN yank the file, so they don't just re-save themselves, but you get the idea.

Otherwise, just yanking the whole "gods" directory seems reasonable, since – it isn't used for anything!

All this came about because in order to properly do the "first login becomes admin" thing, we need a file that enumerates players, which will not exist the first time you run the game. It could be an empty file, but why not make it useful? I think a list of players that's just name, last login, maybe class/level – just enough to make a who entry. That way one can lookup when the last time their friends were on without having to poke into the player files, an external web server could use that to build a who list, and admins could use it to decide when/if to archive idle players.
14 Nov, 2008, David Haley wrote in the 263rd comment:
Votes: 0
FWIW I don't really like the idea of a file that enumerates players; that sounds like you're introducing redundancy because all of that information is already available. If the goal here is to let people create admins as the first characters, there are other, simpler ways of going about this. The first that comes to mind is a flag on the command-line that makes all new characters immortals. You could turn on the server with that flag, log in, and then reboot without the flag. Surely this is much less work than maintaining some kind of player database separate from the file list.
14 Nov, 2008, quixadhal wrote in the 264th comment:
Votes: 0
It is redundant, but it's because anyone who wants to provide that information via a web browser probably does NOT want to implement load_char_obj() in php, or perl. It would also be faster if an in-game lookup wanted to find out the last time someone logged in, rather than reading the whole pfile, or a whole set of pfiles.

If I wanted to take the dirt-simple route, I'd just "touch" a file after creating the first character. File present, normal.. file absent, next login becomes admin. Using states that don't rely on user input is more idiot-proof. ;)
14 Nov, 2008, David Haley wrote in the 265th comment:
Votes: 0
But you don't have to implement something as complex as load_char_obj to display it. Besides, even if you did, arguably you are compensating for laziness (it's not that hard to write a pfile parser, especially if your pfile format is sane to begin with) by introducing a whole new level of complexity on the C/C++ side. In other words, to avoid potential work for some hypothetical web site developer, you're adding real work to a non-hypothetical person now. :wink:


EDIT:
And if your file really does have info on all characters, why is it any faster to get one person's information from there than just their pfile? Seems like the pfile would be faster.

Also, what happens if you want to store more information in that file? Do you regenerate it from scratch, do you allow for partial records, etc.
14 Nov, 2008, quixadhal wrote in the 266th comment:
Votes: 0
grep, said the frog. :)

In both perl and php, I can do a one-liner to pull a player's info if it's stored in a single file, then it's just picking out the fields and (possibly) translating them. To parse player save files, I have to actually do some work… and that work gets repeated as the game's file formats evolve.

I also think it might be advantageous to store a minimal set of info in memory, for the MUD to use. If you kept a list of all players and their last login times, that could probably be loaded at boot time and not only be useful for finger/who/last type commands (no file access required), but also handy for new player logins… a binary search of said array would probably be faster than doing file I/O to see if the pfile in question exists.
14 Nov, 2008, David Haley wrote in the 267th comment:
Votes: 0
Well, I probably didn't make this explicit enough above, but if the formats are written correctly from the get-go, you shouldn't actually have to change the parsing routines as more data fields get added. You'd only have to adapt if you wanted to pay attention to new fields or something like that.

I guess I'm just not seeing this use case as warranting all the extra complexity of creating and maintaining the single file.

I mean, sure, searching in memory will be "much" faster (i.e. less than 1ms as opposed to however many ms, probably not a whole lot at all, it takes to hit the disk), but it's not something you would really do a lot. Premature optimization and all that.
260.0/267