Archive for category Kids

Results of more kids’ play

Well, this has been a long hiatus! I come and go in and out of hobbies. I may or may not be back here to stay for awhile; this may be just a dalliance, not sure.

This post is to point out a few things I had to fix after my kids played with the game a bit. They found the following three things that needed fixing.

Wait! First, let me point out that they were totally thrilled to be able to make their own realms, map them out on paper, and connect them with exits. They would ask one another where they were, and try to find one another. They could very easily get lost in their own, tiny, 6-room realms, because this text-based interface was all new to them. But they thought it was fun anyway.

So, the things I had to fix:

  1. They discovered that my teleport command didn’t work when they typed it with no arguments. Then I discovered, after fixing that, that I had fallen prey to the “variable declarations must go first in a function, always!” gotcha. Ayiyi, LPC.
  2. The telnet app I got for an iPad doesn’t echo the newlines at the end of their commands. So things ran together in an ugly way. I updated my user.c commandHook() to check for vt220 (what the iPad reports as) and add newlines after each command from the MUD’s end. The code looked like this.
        // my iPad connects with vt220 and doesn't use enough \n's, so add some:
        if ( this_user()->query_property( "termtype" ) == "vt220" )
            write( "\n" );
    
  3. They needed an easy way to get back to their home. The teleport command was too lengthy, so I added a home command. It had two uses: “home here” makes your home the room you’re in, and “home” takes you to your home, just like teleport would.

Those were the main things. There were other usability improvements I’d like to make based on my observing the kids’ playing with the MUD, but I haven’t had a chance yet. After I implement them, I’ll come and post here about it.

1 Comment

A unique take on rooms

Well, I’m not sure this is unique, because I haven’t played MUDs in a million years, and obviously never played them all. But I made it up, so it’s new and unique to me, but maybe someone else does something similar.

I wanted to make it easy for my kids to create new rooms. The problem is that the usual way to create rooms is to write code. I.e., you can’t make a room unless you can edit a file and balance quotes, parentheses, and curly brackets. My eight-year-old can’t do that. So I needed a different way.

How rooms load

Fortunately, when you’re making a MUDLib you control…well, everything. So I can control the process of how rooms are loaded from disk. What loads rooms? Well, the teleport command loads them if you try to teleport to a filename. And when we eventually add exits to rooms then rooms themselves will load their neighbors when you take an exit. But as I said, both of those things are under my control. So I do not have to just use load_object() to get the room to load from a file; I could do something else.

The way I chose to do it was to have rooms save their crucial data to .o files, specifically /data/rooms/[domain]/[shortdesc].o files. Each room comes with a short description and a domain. Domains include Backbone, plus a domain for each developer, and maybe others in the future. So for example, here are some rooms in our MUD.

  • /data/rooms/backbone/The_Clouds.o
  • /data/rooms/endad/The_Cave.o

When I issue a command, I can do “teleport The Clouds” and it will find the right room to teleport me into. It loads it by creating a generic instance of room.c and then calling restore_object(). Here is the code, stored in room.c, for doing this.

object find_room ( string dom, string sdesc )
{
    string filename;
    object room;
    // If this room has already been loaded, find the old version
    // and don't create another copy; that's not the intent:
    foreach ( room in children( ROOM_OB ) ) 
        if ( ( room->query_domain() == dom )
          && ( room->query_short_desc() == sdesc ) ) 
            return room;
    room = 0;
    // save_filename() is another method in the room object
    // it does things like escape bad characters, to turn things
    // like "The Clouds" into "The_Clouds", etc.
    filename = save_filename( dom, sdesc );
    // We leave open the possibility that someone may have
    // coded a room in LPC, though this is rarely the case:
    if ( file_size( filename + ".c" ) > 0 ) 
        room = load_object( filename + ".c" );
    // Here's what usually happens:  Make a new room
    // and restore its data from the .o file on disk:
    if ( !room ) { 
        load_object( ROOM_OB );
        room = new( ROOM_OB );
    }   
    if ( room )
        room->restore( dom, sdesc );
    return room;
}

Easy room editing

This enables all sorts of cool tricks. For instance, we can not only load rooms from .o files, but we can save them to .o files. In fact, I can create an easy-to-use developer command that lets you tweak aspects of the room your standing in, and it automatically saves your changes to disk while you’re standing there! For instance, you could type room name My Castle and it would execute some code like this.

    // assume arg is a string, the text following "name" in the above example
    room->set_short_desc( arg );
    write( "You changed the room's name to this: " + arg + "\n" );
    say( capitalize( this_user()->query_name() )
       + " changed this place's name.\n" );
    return 1;

And you can create all manner of other ways to use the room command, such as room addtodesc [lots of text], or room domain [newdomain].

This makes it easy for my children (or those of them who can spell, that is) to edit rooms. You can even create a room create command that clones a new instance of room.c, but doesn’t save it until you’ve specified a domain and short description.

Later we’ll make it so that this command can also connect rooms, but first we have to build exits. That will be the next post!

Leave a comment

Enter: The Kids

First off, I haven’t posted in two weeks because I had work, travel, etc., to deal with and couldn’t tinker with the MUD.  But this project is not dead; it’s just a hobby that gets time given to it when time is available.  In fact, I’ve done some development since my last post but haven’t had a chance to blog about it.  But now I do!

I showed my nascent creation to the kids about two weeks ago, right after my last post.  To keep this blog anonymous, I’ll call my children by the (yes, impersonal) names of Una (girl, 8) and Duo (boy, 6).  Duo reads a bit, when forced; Una reads like fish swim.  (That means “all the time” as opposed to “wiggling from side to side.”)  Both use the Chris Columbus typing method (discover, then land).

Their response was mixed.  They love getting their hands on technology, so that helped.  They enjoy experimenting with typing, so that helped.  But as you recall, so far all we have is a little chat room; you can’t do much of anything.  So as far as the “game” experience goes, they didn’t care much at all.

Duo did almost nothing but chat a few basics like “hello.”  Una was adept enough to type help and see the commands available to her.  So she already is getting a little bit of the Unix-like command-line experience that is one of the benefits I hope they’ll take away from this game experience.

Then I explained that this was an environment that I would be customizing to their preferences over time, and explained the concept of rooms you could walk around in, and even create and/or modify.  They found this promising, and so I asked what they’d like to see in it.  Duo wants pets, so they’re sure to come.  In retrospect, I forget what Una said she wanted.

So, it was time for me to add rooms to explore and customize.  Time to go back to development!  (Okay, as confessed above, I’ve already done the development I’m about to blog about…but the next few posts will be tutorials and challenges leading up to a room system.)

Leave a comment