20 Sep, 2008, David Haley wrote in the 61st comment:
Votes: 0
By compression I mean gzip etc. By terseness I mean what the uncompressed file looks like. Something that makes gains by taking shortcuts in the "plain text" version is very likely to cause pain later on, whereas making gains by using gzip etc. is basically transparent and causes no harm.
20 Sep, 2008, Lobotomy wrote in the 62nd comment:
Votes: 0
DavidHaley said:
By compression I mean gzip etc. By terseness I mean what the uncompressed file looks like. Something that makes gains by taking shortcuts in the "plain text" version is very likely to cause pain later on, whereas making gains by using gzip etc. is basically transparent and causes no harm.

I see, and you're absolutely right. Now that I have the gzip functions working for file saving and loading (and I'm rather happy with the results so far), I'll likely do away with my former system and change my bitvectors to output the flags in plaintext; leaving it up to the compression to get the space saving I desire. :smile:

quixadhal said:
You could easily use gzip (or bzip2) by just adding the gzip library to your dependancies (-lz), and then using gzopen/gzclose instead of fopen/fclose. The price you pay is more CPU use when accessing files, and you lose the ability to randomly seek in your files, but that ability hasn't been used since we went away from indexing directly.

One thought I have is that I may set up my use of gzip to vary based on whether the amount of text to be saved exceeds 4k. I.e, if it's greater than 4k, use compression, otherwise don't. Although on the whole I don't think the performance hit from gzip will really be all that much. I could be wrong, though, as I've no idea how I would go about tracking the time it takes for a function to finish running so that I could compare the results of the two methods side by side.
20 Sep, 2008, David Haley wrote in the 63rd comment:
Votes: 0
Well, keep in mind that the performance hit for gzip only occurs when you read or save areas – a relatively infrequent operation. Of course, if it's only saving 4k, then arguably the real worry is whether the programmer time was worth it.
20 Sep, 2008, Lobotomy wrote in the 64th comment:
Votes: 0
DavidHaley said:
Well, keep in mind that the performance hit for gzip only occurs when you read or save areas – a relatively infrequent operation. Of course, if it's only saving 4k, then arguably the real worry is whether the programmer time was worth it.

Well, I was speaking in terms of all file types (character, system, othersuch), but I suppose that's detracting from the subject matter of the thread. :thinking:
21 Sep, 2008, Sandi wrote in the 65th comment:
Votes: 0
Darva said:
*laughs* So from the discussion i'm guessing named flags in area files is one thing we need to put on the list.

So the current list goes:

Hunt and squash bugs (obviously)
Unlimited bit system.
Named flags in area files.
Finishing the Material system.

What else should we be looking at? Most of the things that I keep thinking of are relativly minor changes: Centralize the channel system, change the affect structure to have a dispellable boolean so you can remove the long list of spell checks in spell_dispel_magic and new affects work automatically.

I'm getting lost, here. Are you suggesting this as Version #1 or Version #2? I'd be okay with that list as version #1.
21 Sep, 2008, quixadhal wrote in the 66th comment:
Votes: 0
Lobotomy said:
Well, I was speaking in terms of all file types (character, system, othersuch), but I suppose that's detracting from the subject matter of the thread. :thinking:


Just a quick note before we get back on track…. :)

If you use zlib and the gz-family of functions (gzopen/gzprintf/etc), all reads work transparently, regardless of whether the file is compressed or not. If you open the file for writing, it will be compressed. Not sure what happens if you open it for both and it wasn't compressed before.

If you did a search/replace on your code so all calls to fopen/fclose became a macro (FOPEN/FCLOSE), you could #define it to be gzopen if zlib is available, or plain fopen otherwise.

Note that filenames won't automatically get a .gz extension… which doesn't matter to unix people so much, but windows people will be unhappy… well, more unhappy than normal. :)
21 Sep, 2008, Darva wrote in the 67th comment:
Votes: 0
Sandi: I'm just trying to compile a list of changes that seem to get enough of a response that they seem like a good idea, and those were the things discussed so far.
22 Sep, 2008, Skol wrote in the 68th comment:
Votes: 0
On the room flags thing btw, I'd done that a while back (feel free to let me know if I'm doing anything wrong btw, still expanding my C knowledge).

REDIT( redit_rlist )
{
ROOM_INDEX_DATA *pRoomIndex;
AREA_DATA *pArea;
char buf[MSL];
char arg[MIL], arg2[MIL];
bool fAll, found;
int vnum, colsp, savesp, col;
char buffer[MSL], spaces [24]; // For tidy listings

argument = one_argument( argument, arg );
argument = one_argument( argument, arg2);

pArea = ch->in_room->area;
fAll = !str_cmp( arg, "all" );
found = FALSE;
col = 0;

send_to_char ("{rREDIT: {yRlist - ", ch);

if (arg[0] == '?' || is_name (arg, "options"))
{
send_to_char ("Options{x\n\r", ch );
send_to_char ("Exitsizes, Elevations, Sizes, Health, Mana\n\r"
"All, Sector (type/all), Flags (type/all), room names\n\r", ch);
return FALSE;
}

if (is_name (arg, "flags"))
{
BUFFER *output;
bool showdisroom;

output = new_buf();

sprintf (buf, "Flags{x '%s'\n\r", arg2[0] == '\0' ? "All" : capitalize(arg2));
send_to_char (buf, ch);
for ( vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++ )
{
showdisroom = FALSE;
if ((pRoomIndex = get_room_index(vnum)) != NULL)
{
if (is_name (arg2, flag_string( room_flags, pRoomIndex->room_flags)))
showdisroom = TRUE;
if (arg2[0] == '\0')
showdisroom = TRUE;
}
else
continue; // Room doesn't exist, or has normal exits/elevations
if (showdisroom)
{
sprintf (buf, "%-14.13s", capitalize( pRoomIndex->name ));
spaces[0] = '\0';
for (colsp = savesp = get_color_changes (buf); colsp > 0; colsp –)
strcat (spaces, " ");

sprintf( buf, "[%5d] %-14.13s%s{x- %8.8s ", pRoomIndex->vnum, capitalize( pRoomIndex->name ),
savesp > 0 ? spaces: "", flag_string( room_flags, pRoomIndex->room_flags) );
add_buf( output, buf );
if ( ++col % 3 == 0 )
add_buf( output, "\n\r" );

}
}

// End Room Flags
page_to_char (buf_string(output), ch);
free_buf(output);
return FALSE;
}


BUFFER *buf1;
buf1 = new_buf();

if (fAll)
send_to_char ("{x 'All'\n\r", ch);
else
{
sprintf (buf, "{x'%s'\n\r", arg[0] == '\0' ? "Used Rooms" : arg);
send_to_char (buf, ch);
}
for ( vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++ )
{
if (fAll) // to show ALL vnums.
{
pRoomIndex = get_room_index(vnum);

sprintf (buf, "%-17.16s", pRoomIndex != NULL ? capitalize( pRoomIndex->name ) : "— unused —");
spaces[0] = '\0';
for (colsp = savesp = get_color_changes (buf); colsp > 0; colsp –)
strcat (spaces, " ");
found = TRUE;
sprintf( buf, "[%5d] %-17.16s%s{x",
vnum, pRoomIndex != NULL?capitalize( pRoomIndex->name ) :
"— unused —", savesp > 0 ? spaces: "" );
add_buf( buf1, buf );
if ( ++col % 3 == 0 )
add_buf( buf1, "\n\r" );
}
else if ( ( pRoomIndex = get_room_index( vnum ) ) != NULL )
{
if ( arg[0] == '\0' || is_name( arg, smash_color(pRoomIndex->name)))
{
sprintf (buf, "%-17.16s", capitalize( pRoomIndex->name ));
spaces[0] = '\0';
for (colsp = savesp = get_color_changes (buf); colsp > 0; colsp –)
strcat (spaces, " ");

found = TRUE;
sprintf( buf, "[%5d] %-17.16s%s{x",
pRoomIndex->vnum, capitalize( pRoomIndex->name ), savesp > 0 ? spaces: "" );
add_buf( buf1, buf );
if ( ++col % 3 == 0 )
add_buf( buf1, "\n\r" );
}
}
}

if ( !found )
{
send_to_char( "Room(s) not found in this area.{x\n\r", ch);
return FALSE;
}

if ( col % 3 != 0 )
add_buf( buf1, "\n\r" );

page_to_char( buf_string(buf1), ch );
free_buf(buf1);
return FALSE;
}
22 Sep, 2008, Skol wrote in the 69th comment:
Votes: 0
I've actually done similar things with most of my OLC editor lists.

// This from redit_mlist
if (arg[0] == '?' || is_name (arg, "options"))
{
send_to_char ("Options{x\n\r", ch );
send_to_char ("All, Act, Act2, Race, Form, Parts\n\r"
"Imm, Off, Size, Spec (add NOT for excluding those)\n\r", ch);
return FALSE;
}


// redit_olist options
send_to_char ("{rREDIT: {yOlist - ", ch);
if (arg[0] == '?' || is_name (arg, "options"))
{
send_to_char ("Options{x\n\r", ch );
send_to_char ("Wear, Extra, Material, Type, Level (exact)\n\r"
"Levels/Range # # (items in level range)\n\r"
"(add NOT for excluding those)\n\r"
"All, Affected (hitroll/damroll etc)\n\r", ch);
return FALSE;
}

Really helps builders to be able to find things, and Imps or head builders to find 'wtf' moments when walking an area before porting.
22 Sep, 2008, Fizban wrote in the 70th comment:
Votes: 0
Looks similar to what I did with mlist on tbaMUD, you can type mlist level # or mlist flags # to list mobs based on characteristics in addition to the traditional listing by zone or vnum range.
06 Jan, 2015, koqlb wrote in the 71st comment:
Votes: 0
I can agree with everyone on this post, but honestly as a MUD owner, I've discovered that if you have a higher max mortal level, you want some areas that other MUDs do have (say Underdark or Dante's Inferno)… And, there are a lot of custom areas that people have shared over the years (some are on here) and though they're compatible with QuickMUD, or stock Rom, they are not compatible with Unlimited Bits. And I wish they were. It takes a LOT to convert these areas over with the way the areas are. And god forbid if you have a new do_areas system, which I have thanks to the awesome snippet by Hades_Kane (has Finished flags, which I've modified, so that players can't see Immortal areas in the area list, as well as players not being able to access areas that are not "Finished" yet).
60.0/71