Still looking for a Ruby MUD client

Sy wrote:

Perhaps what I could do is to try out everyone's entry and do a little
writeup on my experiences. Does anyone do this sort of thing for
these quizes?

Yes.

1) The Quiz is posted on Friday.
2) Solutions are allowed to be submitted from 24 hours after the quiz is
published.

One minor correction. 24 should be 48.

3) Somebody inspects the entries and produces a "summary" before Friday,
looking at one or more approaches to the problem, usually highlighting
interesting implementation details.

See http://www.rubyquiz.com for FAQ.

See Ruby Quiz - Drawing Trees (#40) for an example summary.

James would undoubtedly appreciate your writing the week's summary.

Always! Be sure and let me know if you intend to do this.

James Edward Gray II

···

On Aug 31, 2005, at 10:46 AM, Dave Burt wrote:

"Dave Burt" wrote:

(I wish I could find a function that would be like "Okay, give me *everything* that I could read from the
socket right now." Or even just a way to check how
much is waiting on the socket... Pretty much everything
I've
ever tried to do with sockets would be easeir with
that.)

socket.read will do that.

Socket < BasicSocket < IPSocket < IO

Are you sure about this?

I just did a little code in a couple irb windows to test this. socket.read
called with an argument doesn't seem to return until it gets as many
characters as the argument specified. And without an argument, it
doesn't seem to return... ever. (Or at least, not until I tell my server to
close the socket. Which kind of defeats the purpose.)

Now, socket.recv, that's a method I've managed to make some use of,
since it'll come back with what it has if I call it with a number larger than
the amount of data available. There are still times when "get everything"
would be nice though, and that doesn't supply it.

-Morgan

···

agemoagemo@yahoo.com wrote:

--
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.344 / Virus Database: 267.10.17/85 - Release Date: 08/30/2005

Sy wrote:

> The only way around this I see would be to make some
> sort of "universal" set of codes for describing colors
> and such, convert all the MU* output types to that,
> then pass it to the GUI which handles it as necessary.

You're describing the beginnings of a new telnet/mudding protocol?

Not necessarily a new one, but for an arrangement like this to
work there has to be a consistent way for information to pass
through the system.

MXP is probably versatile enough to do the job, but as mentioned
before, I don't like it. :wink: In particular, I'm not happy about something
using a delimiter character that can appear in normal MUD output.
I ran into issues before on a certain MUSH where the way certain
things were normally output got interpreted as MXP commands,
and would just disappear.

It should also be noted that a system for internal communication
within the client doesn't *have* to be something that could easily
be transmitted over a socket. It just has to work consistently and
do the job.

I didn't realise it could be such a nightmare for the different gui
toolkits to deal with things.

Well, I don't know about "nightmare", but there are some distinct
differences.

Looking at vwmc, for instance, adding a line of relatively normal
colored text (no blink or underline) uses this command:

self.outputBuffer.insert(self.iter,ci[:text],"deffont",fg,bg)

where fg and bg are values representing the text and background
colors respectively. (I'm not sure what the self.iter is for, but that
doesn't appear to be important - it looks like something that's
totally internal to the gui.)

Whereas to do something similar in Fox's FXText widget, I set
up a FXHiliteStyle object (conceptually similar to the structure
vwmc defines in parseansi.rb, though not containing the text) for
each color combination I'll be using, put them in an array, give
that to the FXText object, then use something like

thisFXText.appendStyledText(text, indexInTheStyleArraySortOf)

I don't believe this means I have to make an array of all possible
styles before I start doing anything. (Though it might be easier to
do it that way anyway... take about 64k of memory I think.) Still,
it's a distinctly different sort of process from what's being used in
the GTK program.

> > > I already see various distinctions:
> > > * The GUI
> > > * The console app
> > > * The mud-scripting engine
> > > * the underlying mud-telnet library
>
> I don't quite see the seperation between GUI and
> console app. To me, running in an ordinary prompt
> window or something is just another GUI (albeit one
> with some rather strict limitations).
>
> For the rest, I'm kind of trying to keep things
> distinct when I can, but I'll probably place getting
> the thing working at a higher priority. ^_^;;

Yeah, making it work should always be a priority, but sometimes one
can plan just a little to make life easier for the eventual rewrite.

Hmmm. Currently, my code is littered with the remnants of things
I've tried and had them not work. ^_^;; Once I find something that does,
I'll sift through it and clean things out.

I too don't really separate the console and the GUI.. but once you
start thinking about things like sending certain output to certain
separate buffers it gets wierd. I personally don't see anything
special about a GUI app at *all* until you start talking about
interaction with the mouse (or graphics, and maybe not even then).
Frankly, I never really got to like mice anyways..

Extra windows to capture certain information and certain ways of
viewing scrollback are my main issues. Also, configuration is
generally much easier.

The user would care about two things:

* The UI
* The scripting they'd have to learn

The UI can be separate from mud client to client. The scripting
engine should be *the exact same* to reduce the overhead of porting
scripts, learning new skills etc.

To at least partly help with this, I've been thinking about a way to support
at least a significant subset of tintin commands. (Which seems to be what
most of zmud's script language is.) The system translates those commands
into ruby code, to speed up execution.

(Not that I've written that part, mind you. But I think I know how to do it.)

It may not be "that hard" for simple scripts, but more complex scripts
that do wierd things like yank out a previous command from the command
history aren't exactly portable concepts.

I'm not quite sure why you'd want to do that, let alone how. `.`;

> Do any MUDs really use that height/width stuff?

I personally feel that height and width should be irrelevant to the
server itself. It should just throw streams of information and the
client should handle pauses and line breaks. It's not that hard.

Personally, I find aardwolf's scroll setting to be useful sometimes,
but of course that's something that people can disable if they don't
want.

World-builders should, of course, still worry about certain standards,
which is a rant I won't get into here.. but long descriptions should
never be hand-wrapped. That's just stupid.

My experience with OLC suggests that the designers disagree with
you. `.`

> A library to handle MCCP would be a nice thing.

I agree. Looking at the mccp stuff, it looks like it hasn't been
developed much in some years. =/

Apparently the person who originally came up with it disappeared
or something. <.< It seems to work quite well in the version
available now though, and since there's a zlib library for ruby
it ought to be possible.

> > * A library for strings w/ markup, and manipulating
>
> This could probably be useful for things other than
> MUDs as well, if you could configure it to handle
> multiple types of markup. (Which I'd guess you could.)
> The question is, how do you do it? I can think of a
> few
> ways, but nothing I can't think of a way to break too.

Thinking about it more, how difficult this would be depends
on what things you want to work across tags.

Say, something like this. (MXP, even though I don't like it.)

something = "A <C red>red</C> and <C blue>blue</C> baseball bat."

something.reverse should give:
".tab llabesab <C blue>eulb</C> dna <C red>der</C> A"

However, what a normal reverse gives is:
".tab llabesab >C/<eulb>eulb C< dna >C/<der>der C< A"

If we unreverse the tags, we get:
".tab llabesab </C>eulb<C blue> dna </C>der<C red> A"

Still not quite right. Switch each pair of tags, and then you've got it.

But let's suppose you only wanted to reverse part of it. Well, you're
in trouble now...

something.somehow_reverse_just_the_part_thats_like("d and b") =>
"A <C red>re</C><C blue>b</C> dna <C red>d</C><C blue>lue</C> baseball bat."

In conclusion, you're in trouble now.

Of course, to do this you need a way of pattern matching across tags. Well,
that might actually be relatively simple...

Okay, let's try it on some ANSI.

For the moment, we'll pretend that + represents the escape character,
since I'm too lazy to write it out properly for this.

something = "A +[31mred+[39m and +[34mblue+[39m baseball bat."

This would actually work about like the MXP example...

So let's do something that doesn't.

something = "A +[31mred, +[32mgreen, +[39m and +[34mblue +[39mbaseball bat."

something.reverse should give us:
".tab llabesab+[34m eulb+[39m dna+[32m neerg+[31m der+[39m A"

And what does reversing just part of it look like?

It looks like Morgan fleeing in terror, that's what.

Now, I still don't know why you'd want to reverse anything. So, let's come
up with some ludicrous example for gsub, which was also mentioned.

something = "A <C red>red</C> and <C blue>blue</C> baseball bat."

something.gsub("red and blue", "ostrich") should give us something like...
"A ostritch baseball bat."

... But which parts are red and which parts are blue?

In conclusion, you're in big trouble.

Okay. The thing making this difficult is handling things that span across
tags. Running a gsub that matches something entirely within a single
tag won't produce problems, nor will reversing it, nor will anything else
you do to it that I can think of. Matching a pattern across tags I'm
pretty sure can be done, but it'll probably be a pain to do, and I'm starting
to wonder if there's any point to it. Substitution across tags is probably
doable if you can solve the pattern matching problem, but how do you
decide sensibly what ends up in what tag?

In conclusion,...

-Morgan.sendToWorld("flee\nflee\nflee\nflee\nflee\n")

···

On 8/31/05, agemoagemo@yahoo.com <agemoagemo@yahoo.com> wrote:

--
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.344 / Virus Database: 267.10.17/85 - Release Date: 08/30/2005

A solution, similar to that employed by ncurses and many other UI
systems, is to use the concept of an extended character. Each
character in the string is flagged with applicable attributes.
Translating marked up ASCII to a list of extended characters is easy
enough: maintain a bitmask of attributes and turn them on/off as you
encounter tags; apply the current bitmask to each character
encountered.

Translating back from an extended character string to ascii markup can
be accomplished with an algorithm like the following (I'm using an
array instead of bitmask for readability):

def encode( extended_chars, start_flags=, clean=0 )
  current_flags = start_flags
  encoded_ascii = ''
  extended_chars.each do |char|
    (current_flags - char.flags).each do |flag|
      encoded_ascii << flag.close_tag
    end
    (char.flags - current_flags).each do |flag|
      encoded_ascii << flag.open_tag
    end
    current_flags = char.flags
    encoded_ascii << char.ascii_char
  end
  if clean
    current_flags.each do |flag|
      encoded_ascii << flag.close_tag
    end
    current_flags =
  end
  return (encoded_ascii, current_flags.clone)
end

Ideally, the list of encoded characters would be encapsulated in an
object that acts like a string (implementing gsub, reverse, etc.) The
operations would rearrange/remove individual extended characters from
the object without changing any of the flags associated with any one
character.

As an example application, your string would decode as follows:

something = decode("A <C red>red</C> and <C blue>blue</C> baseball bat.")
# => A, ' ', r|red, e|red, d|red, ' ', a, n, d, ' ', b|blue, l|blue,
u>blue, e|blue, ' ', b, a, s, ...

The regex /red and blue/ would match this substring
# r|red, e|red, d|red, ' ', a, n, d, ' ', b|blue, l|blue, u|blue, e|blue

That substring is replaced with the substring (since it wasn't encoded):
# o, s, t, r, i, c, h

And the result is:
# A, ' ', o, s, t, r, i, c, h, ' ', b, a, s, ...

Obviously, no part is red or blue. Assume we'd actually marked up "ostrich" as
# "<C red>os</C>tri<C green>ch</C>"
# => o|red, s|red, t, r, i, c|green, h|green

And matched against the shorted substring "d and bl" then the result would be:
# A, ' ', r|red, e|red, o|red, s|red, t, r, i, c|green, h|green,
u>blue, e|blue, ' ', b, a, s, ...
# => "A <C red>reos</C>tri<C green>ch</C><C blue>ue</C> baseball bat."

Jacob Fugal

DISCLAIMER: None of the above is intended to be complete, bug-free or
efficient. An actual implementation would need all of those. This is
just meant to be an example algorithm that would make the discussed
operations possible.

···

On 9/1/05, Morgan <taria@the-arc.net> wrote:

Okay. The thing making this difficult is handling things that span across
tags. Running a gsub that matches something entirely within a single
tag won't produce problems, nor will reversing it, nor will anything else
you do to it that I can think of. Matching a pattern across tags I'm
pretty sure can be done, but it'll probably be a pain to do, and I'm starting
to wonder if there's any point to it. Substitution across tags is probably
doable if you can solve the pattern matching problem, but how do you
decide sensibly what ends up in what tag?

Sy wrote:
>It may not be "that hard" for simple scripts, but more complex scripts
>that do wierd things like yank out a previous command from the command
>history aren't exactly portable concepts.

I'm not quite sure why you'd want to do that, let alone how. `.`;

I can have the scripting notice if I was afk or sleeping or whatever,
and automatically perform an action and then repeat the command. So I
can "look" while sleeping and it'll notice that I'm asleep and wake up
to perform the action.

For mmucl, it is:
parse [lindex [cline history] end]

This functionality has been remarkably valuable to me. I hate going
"whoops, was afk.. afk <cursor-up> <enter>".. it's a small thing,
but very handy imo.

>World-builders should, of course, still worry about certain standards,
>which is a rant I won't get into here.. but long descriptions should
>never be hand-wrapped. That's just stupid.

My experience with OLC suggests that the designers disagree with
you. `.`

Well if I ever meat them in a dark alley, I'll punch their lights out.
A lot of these old fashioned "standards" are just leftovers from more
shortsighted days. Like, oh, email wrapping settings. Geeze, offline
mail readers from the BBS days had it right, email clients these days
are just pathetic.

Okay. The thing making this difficult is handling things that span across
tags. Running a gsub that matches something entirely within a single
tag won't produce problems, nor will reversing it, nor will anything else
you do to it that I can think of. Matching a pattern across tags I'm
pretty sure can be done, but it'll probably be a pain to do, and I'm starting
to wonder if there's any point to it. Substitution across tags is probably
doable if you can solve the pattern matching problem, but how do you
decide sensibly what ends up in what tag?

That was some awesome description for reversing..

and it went sailing over my head.. whoa. I see some of the problems
which people face with string manipulation like this.

But as a user, I could live without any kind of reversing
functionality.. I could live without matching by-colour in fancy ways.
Substitution can be based on matching the plain text.. that's just
fine.

···

On 9/1/05, Morgan <taria@the-arc.net> wrote:

Jacob Fugal wrote:

A solution, similar to that employed by ncurses and many other UI
systems, is to use the concept of an extended character. Each
character in the string is flagged with applicable attributes.
Translating marked up ASCII to a list of extended characters is easy
enough: maintain a bitmask of attributes and turn them on/off as you
encounter tags; apply the current bitmask to each character
encountered.

Seems reasonable, but I do wonder how efficient the process would be.
Something like that on each character makes me nervous. `.`

As an example application, your string would decode as follows:

something = decode("A <C red>red</C> and <C blue>blue</C> baseball bat.")
# => A, ' ', r|red, e|red, d|red, ' ', a, n, d, ' ', b|blue, l|blue,
u>blue, e|blue, ' ', b, a, s, ...

The regex /red and blue/ would match this substring
# r|red, e|red, d|red, ' ', a, n, d, ' ', b|blue, l|blue, u|blue, e|blue

That substring is replaced with the substring (since it wasn't encoded):
# o, s, t, r, i, c, h

And then you'd get a bug report about how your replace is dropping color...

At least, the behavior I would expect is to preserve the existing coloration.
(Of course, then I specifically picked an example where there's no obvious
sensible way to do that. Still, I think keeping the color would generally be
expected.)

-Morgan

···

--
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.344 / Virus Database: 267.10.17/85 - Release Date: 08/30/2005

This is getting to be a long conversation that's diverging from Ruby and
onto more generic mud-related topics. But anyway:

Whoops, I seem to have caused some confusion in my last reply. There's
two things I had in mind here while writing that:

1) I verged off a bit and discussed both client and server bits.
(i.e: MXP, and having MXP deal with markup - and this includes color,
html-like clickable links, even urls to sound files, etc.)

2) I'm from a PennMUSH background. I used to be big on Smaug, Rom and
other Diku-Derivatives up until I discovered Penn. Now I won't go back.
:D. (Can you play scrabble, all forms of poker, boggle, chess, bridge,
and many, many more games on a Diku? How about writing 'softcode'
on-game to make almost anything imaginable?)

MUSHes (PennMUSH, TinyMUSH, and Muxes) are not only entirely created
online, but also entirely scripted online. They provide a very powerful
scripting engine to its users that fairly resembles what you'd get if
you had lisp with string interpolation and function(...) rather than
(function,...) The "programming" available on Diku derivatives is like
using old Apple ][e BASIC for making websites in comparison.)

On protocols:

This is important to both the server and the client. Many users or
clients would enjoy an ability to have certain lines of input flagged as
for a certain purpose. For you mudders, this may be "shout"s or "OOC" or
other channels. For MUSHers, we have explicit channels that begin with
<channelname>

Now suppose your client wanted to filter shouts into a separate window
so you can follow a global conversation while you're hacking a hundred
monsters to bits. It would miss multi-line shouts:

Joe the Slayer shouts, "This is a
shout with more
than one line!"

Your shout window would catch: 'Joe the slayer shouts, "This is a'

Not too fun. Having some form of protocol *available* to (but not forced
upon) the user is a Good Idea (tm). i.e:

<Chat: Shout>Joe the slayer shouts, "This is a
shout with more
than one line!"</Chat>

On text manipulation:

MUSHes provide ways for world-builders to customize the description of
all the rooms at the same time. You can write "who" listings, combat
systems, and more - all through string manipulation. String manip in
'mushcode' is considerably easier to deal with than Ruby.

For example, a common 'room parent' would be:

@descformat room parent=[repeat(-,10)]r[wrap(%0,10)]%r[repeat(-,10)]

@desc room 1=This is a fairly long description that is wrapped at 10 characters.

look

···

----------
This is a
fairly
long
descriptio
n that is
wrapped at
10
characters
.
----------

Toss in ansi hilighitng, and it can get messy fast, especially when you
have columns of things, etc.

Terminal settings, or: "Why we should send width and height"

As for the terminal sending its width/height: users can access each
other's terminal sizes by using width(<user>) and height(<user>). Plug
that in to the above @descformat and use:

repeat(-,sub(width(%#),2))%r[wrap(%0,sub(width(%#),2))]%r[repeat(-,sub(width(%#),2))]

And all your rooms will have their descriptions cleverly hard-wrapped to the
user's terminal size.

- Greg. aka Walker @ M*U*S*H

(If you're interested in taking a look at PennMUSH, btw - feel free to
check out M*U*S*H: http://mush.pennmush.org - I'm Walker on there.)

Sy wrote:

I can have the scripting notice if I was afk or sleeping or whatever,
and automatically perform an action and then repeat the command. So I
can "look" while sleeping and it'll notice that I'm asleep and wake up
to perform the action.

For mmucl, it is:
parse [lindex [cline history] end]

This functionality has been remarkably valuable to me. I hate going
"whoops, was afk.. afk <cursor-up> <enter>".. it's a small thing,
but very handy imo.

Oh, I see. Not something I would want to do, but I can see how it would
be done... once I implement a command history. `.` (Which you've just
saved from being done purely gui-side.)

> >World-builders should, of course, still worry about certain standards,
> >which is a rant I won't get into here.. but long descriptions should
> >never be hand-wrapped. That's just stupid.
>
> My experience with OLC suggests that the designers disagree with
> you. `.`

Well if I ever meat them in a dark alley, I'll punch their lights out.
A lot of these old fashioned "standards" are just leftovers from more
shortsighted days. Like, oh, email wrapping settings. Geeze, offline
mail readers from the BBS days had it right, email clients these days
are just pathetic.

Still, when one is writing a mud client, one must deal with what the mud
that exists is going to output. And I don't think it's unreasonable for the
server to expect at least a certain width. Be impossible to make a good
score display otherwise...

But as a user, I could live without any kind of reversing
functionality.. I could live without matching by-colour in fancy ways.
Substitution can be based on matching the plain text.. that's just
fine.

Even then it could still be a real pain to do.

I'm not sure I even want to try coding for substitution until I can find
a clean way of handling this.

-Morgan

···

--
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.344 / Virus Database: 267.10.17/85 - Release Date: 08/30/2005

Jacob Fugal wrote:
>A solution, similar to that employed by ncurses and many other UI
>systems, is to use the concept of an extended character. Each
>character in the string is flagged with applicable attributes.
>Translating marked up ASCII to a list of extended characters is easy
>enough: maintain a bitmask of attributes and turn them on/off as you
>encounter tags; apply the current bitmask to each character
>encountered.

Seems reasonable, but I do wonder how efficient the process would be.
Something like that on each character makes me nervous. `.`

Hence my disclaimer. :slight_smile: I'm just demonstrating that it's possible,
making it efficient will be a big project.

>As an example application, your string would decode as follows:
>
>something = decode("A <C red>red</C> and <C blue>blue</C> baseball bat.")
># => A, ' ', r|red, e|red, d|red, ' ', a, n, d, ' ', b|blue, l|blue,
>u>blue, e|blue, ' ', b, a, s, ...
>
>The regex /red and blue/ would match this substring
># r|red, e|red, d|red, ' ', a, n, d, ' ', b|blue, l|blue, u|blue, e|blue
>
>That substring is replaced with the substring (since it wasn't encoded):
># o, s, t, r, i, c, h

And then you'd get a bug report about how your replace is dropping color...

At least, the behavior I would expect is to preserve the existing coloration.
(Of course, then I specifically picked an example where there's no obvious
sensible way to do that. Still, I think keeping the color would generally be
expected.)

Well, once possible workaround for this is to pass initial state when
decoding raw ascii. However, as you state, this example is ambiguous.
Assume we replaced the shorter substring "d and bl" with the raw
"ostrich", using this technique. We'd end up with something like:

"A <C red>reostrich</C><C blue>ue</C> baseball bat."

This is because the raw string "ostrich" was passed char.flags as its
initial flags (where char is the extended char object for the 'd' in
red, the first character in the replaced substring) rather than an
empty mask.

Jacob Fugal

···

On 9/1/05, Morgan <taria@the-arc.net> wrote:

This is getting to be a long conversation that's diverging from Ruby and
onto more generic mud-related topics. But anyway:

*shrug* I'm not sure. I know I'm still looking at all of this with the intent
of learning things to help me write the client I'm working on. And since
it's in Ruby... `.`

Whoops, I seem to have caused some confusion in my last reply. There's
two things I had in mind here while writing that:

1) I verged off a bit and discussed both client and server bits.
(i.e: MXP, and having MXP deal with markup - and this includes color,
html-like clickable links, even urls to sound files, etc.)

Yeah. Personally, I'm a little too old-fashioned for that stuff (despite
not being that old). Colored text is about fancy enough for mud output
for me.

(Now, since we're already getting sidetracked... ^_- )
(For reference puproses, pretty much the only MU* I've found that I'm
willing to spend time on is Aardwolf, so most of my experience will
relate to it.)

2) I'm from a PennMUSH background. I used to be big on Smaug, Rom and
other Diku-Derivatives up until I discovered Penn. Now I won't go back.
:D. (Can you play scrabble, all forms of poker, boggle, chess, bridge,
and many, many more games on a Diku? How about writing 'softcode'
on-game to make almost anything imaginable?)

Would I *want* to play those things on the MU* is what I'd ask. `.`
Most times I'd rather use other specialized programs for those things.
(Also why I don't have much interest in social MUSHes - I consider
IRC more suitable for socializing.)

MUSHes (PennMUSH, TinyMUSH, and Muxes) are not only entirely created
online, but also entirely scripted online. They provide a very powerful
scripting engine to its users that fairly resembles what you'd get if
you had lisp with string interpolation and function(...) rather than
(function,...) The "programming" available on Diku derivatives is like
using old Apple ][e BASIC for making websites in comparison.)

I've actually tried doing some mush coding. It's pretty powerful, but
it didn't seem possible to do the things I wanted to without horrifying
monstrous long constructions with a few dozen brackets here and
there. I could have made what I wanted easier in mIRC script...

Not being familiar with Diku olc, I don't really know what it's like. (I'm
under the impression that Aardwolf's is fairly different. Not surprising
given that it's three generations descended from Diku...)

On protocols:

This is important to both the server and the client. Many users or
clients would enjoy an ability to have certain lines of input flagged as
for a certain purpose. For you mudders, this may be "shout"s or "OOC" or
other channels. For MUSHers, we have explicit channels that begin with
<channelname>

Aardwolf's mostly look like
<playername> <channelname>: <message>

A few are more complicated, but mostly that's it.

Now suppose your client wanted to filter shouts into a separate window
so you can follow a global conversation while you're hacking a hundred
monsters to bits. It would miss multi-line shouts:

Joe the Slayer shouts, "This is a
shout with more
than one line!"

Do many MUs send them as actual multiple lines? On Aard, it appears
that most such things are sent as single long lines, to be wrapped at the
clients discretion. (Which is distinctly different from the way room
descriptions are done; I believe hardwrapping those is pretty much obligatory.)

(I think the only thing I've seen on a channel that uses hard-wrapping is
that imm-only curse-only social with the ascii art of the raised middle
fingers...)

Your shout window would catch: 'Joe the slayer shouts, "This is a'

Not too fun. Having some form of protocol *available* to (but not forced
upon) the user is a Good Idea (tm). i.e:

<Chat: Shout>Joe the slayer shouts, "This is a
shout with more
than one line!"</Chat>

Maybe a nice idea, but probably something that needs to be taken up
on MU* design MLs before here. No point in writing a client to implement
it before there's someone who'll write a server to use it.

On text manipulation:

MUSHes provide ways for world-builders to customize the description of
all the rooms at the same time. You can write "who" listings, combat
systems, and more - all through string manipulation. String manip in
'mushcode' is considerably easier to deal with than Ruby.

For example, a common 'room parent' would be:

@descformat room parent=[repeat(-,10)]r[wrap(%0,10)]%r[repeat(-,10)]

Morgan.sendToWorld("flee\nflee\nflee\n")

I'm not sure I could figure out what that did... ever, if I didn't already know.

[snip]
Terminal settings, or: "Why we should send width and height"

I was really more asking "Does anyone want us to", but this answers
that too...

As for the terminal sending its width/height: users can access each
other's terminal sizes by using width(<user>) and height(<user>). Plug
that in to the above @descformat and use:

repeat(-,sub(width(%#),2))%r[wrap(%0,sub(width(%#),2))]%r[repeat(-,sub(width(%#),2))]

And all your rooms will have their descriptions cleverly hard-wrapped to the
user's terminal size.

Hmmm. And that's done with standard telnet control codes, I believe?
Difficult to do with the current telnet implimentation. I don't believe there's
any way to tell it to respond to additional telnet commands other than the
ones that are built in.

What, I wonder, would something coded the way you describe do if the
client is unwilling or unable to provide that information?

And what happens if the size of their terminal changes?

-Morgan, fails saving throw to resist making a comment about how she
isn't sure she wants people to be able to see her sizes so easily...

···

At 05:33 PM 09/01/2005, you wrote:

--
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.344 / Virus Database: 267.10.17/85 - Release Date: 08/30/2005

Jacob Fugal wrote:

Hence my disclaimer. :slight_smile: I'm just demonstrating that it's possible,
making it efficient will be a big project.

It'd be something interesting to see at any rate, even if it weren't
as efficient as possible immediately. It's another of those things I'm
not sure I'm up to programming myself though. ^_^;

As I understand it, each color would have it's own bit, right?

So for ansi color that'd be 8 bits for basic colors, and a bit each for
bold, italic, underline, and strikethrough. What else other protocols
might need I'm not sure about, which is probably one of the things
complicating this...

A user might also find it desirable to be able to define their own
desired coding to be put into the text, to simplify later use. (As in,
why shouldn't I be able to tell it "when it changes to bold blue text,
send me this" and so forth, instead of sending me some other set
of tags that I then have to figure out how to parse?)

For that matter, I'm wondering just how configurable it could be made
without impacting speed. After all, such a thing could have uses other
than this MUD stuff...

> At least, the behavior I would expect is to preserve the existing coloration.
> (Of course, then I specifically picked an example where there's no obvious
> sensible way to do that. Still, I think keeping the color would generally be
> expected.)

Well, once possible workaround for this is to pass initial state when
decoding raw ascii. However, as you state, this example is ambiguous.
Assume we replaced the shorter substring "d and bl" with the raw
"ostrich", using this technique. We'd end up with something like:

Doing it that way I think would make more sense. In most sensible
applications that's probably the behavior you'd want, and as for
insensible applications... well, sometimes you can protect the user
only so much.

-Morgan

···

--
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.344 / Virus Database: 267.10.17/85 - Release Date: 08/30/2005

Well, you'd have one bit region for color. Colors are mutually
exclusive: you can't have text that's red and green at the same time.
So, for 8 ANSI colors as you said, the color bit region would be 3
bits.

On top of that, though, I'm of the camp that any markup should be
semantic, as opposed to immediate. Rather than marking a chunk of text
as "red", I'd prefer to mark it as, for instance "noun", and then the
client is at liberty how to display nouns (eg. by coloring them red).

One way to make this extensible is for the server to send a header
(once, on login) which defines the possible semantic flags and their
corresponding bit regions. That way one mud server can have one set of
flags, another have other sets of flags, or the same flags serialized
differently, and my client can interpret each appropriately.

This type of markup wouldn't handle the idea of embedded links very
well (it is possible though, ask if you want to know how) since it's
pretty much the equivalent of an XML tag with no attributes. But for
simple semantic markup it could work.

Jacob Fugal

···

On 9/1/05, Morgan <taria@the-arc.net> wrote:

As I understand it, each color would have it's own bit, right?

So for ansi color that'd be 8 bits for basic colors, and a bit each for
bold, italic, underline, and strikethrough. What else other protocols
might need I'm not sure about, which is probably one of the things
complicating this...