sprintf(buf, "Well hello %s, i see you have your handy %s with you.", ch->name, obj->short_descr);
/* Example CSS */
.farsight name { fgcolor: blue; }
.farsight .room { text-align: right; }
players = me.area.players # find everyone in my area
list = TableNode.new(:class => "farsight")
players.each_with_index do |player, i|
list[i, 0] = NameNode.new(player.name, :class => "name")
list[i, 1] = TextNode.new(player.room.name, :class => "room")
end
render list
chardata string { color: white;} /* all string attributes of the character display as white */
chardata #name { color: blue;} /* but name cascades (overrides) to display as blue */
/* these will cascade towards the bottom. */
#mensers-awesome-area npc { color: green;} /* match all npcs in that area */
#mensers-awesome-area npc:first { color: grey;} /* matches the first npc rendered in a buffer*/
#mensers-awesome-area npc:last { color: purple;} /* matches the last npc rendered in a buffer */
#mensers-awesome-area genie {color: yellow;} /* match all genie in this area, assuming it's implemented as a type */
#mensers-awesome-area room > genie {color: blue; } /* match genies directly nested in a room. */
#mensers-awesome-area genie.asleep {color: grey;} /* match all genies that have asleep flag set */
#mensers-awesome-area item genie {color: red;} /* match all genies contained in any item */
#mensers-awesome-area item.lamp genie {color: silver;} /* match all genies contained in any item with lamp flag */
#mensers-awesome-area npc #short_desc { mxp-font-weight: bold;} /* match all npc short descriptions in mensers-awesome-area*/
# room with a player in it, in an area
player = Player.new
room = Room.new(player)
area = Area.new(player)
# print the rendering out, respecting the css rules of course.
puts player.render("Retnur is standing here.", :with_bounding_box=>true)
<area>
<room>
<player>
Retnur is standing here.
</player>
</room>
</area>
<area>
<room>
<player>
<long_desc><name>Retnur</name> is standing here.</long_desc>
</player>
</room>
</area>
puts player.render("<long_desc><name>Retnur</name> is standing here.</long_desc>", :with_bounding_box=>true)
/* every player */
player { width: 80;}
/* every player inside of a room (any nesting level) */
room player {
align: right;
mxp-color: navy; /* example of something not supported on all clients and how it can fall back */
}
/* players directly nested in a room. */
room > player { height: 3; }
/* every room */
room { align: right;}
/* this rule isn't matched against */
player room { something: irrelevant;}
[ Retnur is standing here.]
[ ]
[ ]
Area.new(Room.new(player = Player.new))
player.name = "Retnur"
puts player.name.render()
player name {
align: center;
width: 13;
}
<% "score".to_tag do %>
Your score sheet:
<% player.to_tag do %>
name: <%= player.name.to_tag {player.name } %>
hp: <%= player.heath.to_tag {player.health } %>
moves: <%= player.moves.to_tag {player.moves} %>
<% end %>
<% end %>
score { color: red; } /* entire score defaults to red */
score player { color: blue; } /* any field of a player is blue in a score*/
score player name { color: yellow; } /* except the name, we want that yellow */
[class speech]Bubba says, "Hi Biffy"[/class]
[class description]The sword has a ruby encrusted hilt.[/class]
style_table = {
"speech" =>"[color fuchsia on blue]%%[/color]",
"description" =>"[color blue][size +3][font wingdings]%%[/font][/size][/color]"
}
having a framework that could be used to accomplish heavy lifting for new developers.
I think it could even benefit from using a MVC design as far as game objects go. […]
Full disclosure. This is moving away from the idea of a framework and towards the idea of a pattern. And that pattern is, as mentioned, MVC. I've been mulling over this for a month or two, and I think a way to accomplish the MVC pattern can be found by looking at html/css and js. In properly designed html, html would be the model, css the view, and js the controller. After considering this, I thought it might be interesting to use css as the missing link in a mud on the server-side.
So, what's the point? Well, the point is it's much cleaner we've found in HTML/Css/js to separate these three things. Writing inline styles in html is absolutely gross and not maintainable. Writing js inline isn't much better, but at least it's segregated by virtue of technology. In a mud we typically combine all 3 of these things, because there's no virtue of different technology. And we don't see the benefits of centralizing styles and keeping them away from the data, but make no mistake. There's big gains to be had. It can turn around a mess and make it very manageable. There's a lot of muds out there separating the controller and model, the view is the part that is up in the air. I'd like to talk about a proposal to do that using CSS.
Basically, it would require either writing a css parser (which is more work than I'd be willing to do.) or just using one written for us. Here's an example of one written for us.
Before I elaborate, I should make it clear…the client wouldn't use the css. The server would. It makes no sense for the server to use the css, you say? Well, it also makes no sense for the server to be a renderer for the client…yet muds generally all do it. So following this pattern, the renderer, no matter where it may be, can make use of css.
In addition to that, I am not proposing using html. CSS is a technology separate from html. In fact, the css related to a mud wouldn't even need to use the same attributes as you'd expect from html. CSS is rather agnostic about that. Instead we could write css like this:
In this example, all genies are blue. All genies in a bottle have 10 characters left padding.
The renderer would generate a line of text like this based on the rules like this:
[[color=royalblue] A genie is trapped in this bottle![/color]]
You can ignore the []'s. I'm using them just to show where the bounding box is.
Relating the html model to the mud model, generally you can compare tags to classes. For example, where you might have a <body> tag containing a <div> in html. And that div may contain many other tags. So in the mud world you might have a Room containing a Player. And a Player containing many Items.
So where does the css concept of classes and id's come into play? A great comparison for classes is actually flags. So this css rule could match a player that's dead:
In that example, we want players who are dead to be displayed in red.
In normal css w/html you could expect something like this:
And a great example of id is simply the vnum! If your mud uses a vtag system, even better, as long as it's unique. :)
A quick example of matching just my vtag of alucard-the-vampire-king:
Switching gears back to the player red rule. Consider the following html. It has a class (poorly named red) that can be matched against to make the content red.
But this markup isn't really useful for our mud world. Our mud worlds model is a little more complex. So… Let's consider the 'markup' for our mud world.
And the flag itself can act as the class. Making the previous example match it great. The point I'm trying to make is that the html is just a scaffold for the data.
It's important to mention that these are naive examples of what css can do. The real power is localizing css. You could have a global style sheet, sure. We've been doing that in these examples. But things might get interesting when a builder puts a style sheet in their area. Maybe for some reason all demon npcs short descriptions are styled differently in this zone. This builder decides just the short descriptions, where-ever they appear in this zone should cascade and override the global style sheet. This is the real power of css.
Here's a quick and interesting example I made scaffolding html:
http://jsfiddle.net/T8sUD/3/
I want to stress, the html isn't important. What's important is that css can match against a model. I repeat, the html isn't important.
If you look at the example, however, there's two distinct blocks being rendered. Both are in response to commands. You can think of this just like web-page requests. In a website, generally, the client "clears" the screen. So imagine if your mud client cleared the screen after it received any block of text. It doesn't, but it *could*. Not that we want it to. But this helps us consider each block of text received as a new view based on a route. In this case the route was "look" and "look at retnur". In http we might consider this to be /look/ and /look/at/retnur/ since we're restful around here.
Fallback Mechanisms
The style could have properties that can't be used because the client connected won't support it. Like, for example, changing the font face. But there are technologies and clients that the server and client may be in agreement to use to make it possible. So the answer is simple. Just as in web clients, you use what style the client understands. If you're using MXP and you know you can change the font face, then that's a valid style. If it's not valid, just don't use it. That would be done in the renderer implementation.
I admit, this is a bit of an academic discussion…because I'm not willing to come outfit YOUR mud with this system. I may implement something in my codebase just as a test bed. But I think this type of design would be a huge step forward. I think the first step in this direction is just starting small and implementing a few attributes, then going from there. The applications as I see it could work in just about any mud, though.
I've already tl;dr'd this out, but I'll probably post more ideas since I didn't go over it all as I consider it more (or maybe actually have a working implementation to show.)
Here's a link for more information regarding CSS for beginners. It uses html to teach it, but just learning how the css rules work is what's important in this context.
http://www.w3.org/Style/Examples/011/fir...