UX: It's time for The Talk
-
@Ganymede said:
I know. When I'd roll, though, I'd just type "+roll <sum of my relevant dots and bonuses>." And if someone asked: "Gany, why did you roll <sum of my relevant dots and bonuses>?", I would reply with "because that's the sum of my relevant dots and bonuses."
Hmmm.. Hang on. I'm trying to follow this... So when you roll <sum of relevant dots and bonuses>, what you're REALLY saying is that you're rolling the <sum of relevant dots and bonuses>? I'm confused.
( This reminds me of the SNL skit "St. Valentine's Day Massacre" )
-
I use numbers to roll.
-
@Ganymede said in UX: It's time for The Talk:
I use numbers to roll.
Ganymede says: That's just how I roll.
-
@Thenomain said in UX: It's time for The Talk:
Ganymede says: That's just how I roll.
Damn right, son.
-
@Groth said in UX: It's time for The Talk:
Sidenote: @WTFE strictly speaking and syntaxical sugar aside. Mushcode has the same lamba support as any other string based scripting language as it can pass along arbitrary strings and call eval()
So leaving aside the part that makes lambdas useful (and you haven't addressed closures) it's just like having lambdas!
Lua:
function addxplus3(x) local z = x + 3 return function (y) return z + y end end add5plus3 = addxplus3(5) print(add5plus3(3)) -- 11 x = 100 -- what happens when we change "x"? print(add5plus3(3)) -- 11
MUSHcode:
???
From my reading of it, there's no convenient way to do the equivalent in MUSHcode. Doing that code in MUSHcode would be about as painful and as error-prone as doing the equivalent in, say, Rexx or in C. It's doable in both those languages because ANYTHING you can express in one Turing-complete language can be expressed in another modulo hardware limitations, etc. (if you'd like I'll put up the Rexx version), but it's painful, it's error-prone, and thus it's something that's going to be avoided as a result.
"Store this function as a string and call eval()" (roughly how I'd do the Rexx equivalent) is theoretically very similar to the above, but its the very lack of that syntax sugar is why nobody would ever actually use it.
Syntax is nothing. Syntax is everything. Both statements are true.
-
@faraday said in UX: It's time for The Talk:
-
Sensible Command Names - Why is the OOC profile command named +finger? Or the build command 'dig'? Or the private chat command 'page'?
-
Consistency - The mixed up mash of coded systems on most MUs often leads to bizarre inconsistencies - like one command uses
subject=message
and another usessubject/message
. -
Redundancy - +help versus help or +desc versus @desc anyone? MU systems overlay on the base hardcode implementation, so you end up with multiple ways to do similar things. Which is sort of related to...
-
Command Prefixes - Why is it @desc versus +where versus quit?
These. All of these right fucking here. And it goes far, far, far deeper than even that.
Another (non-MUSH) example of shitty UX despite having decent functionality: Git. For many of the same reasons here.
Now I personally know that a lot of this stuff has historical roots. +finger from the unix command, @/+ prefixes for softcode vs hardcode. But when you look at it as an outsider it's un-intuitive, needlessly complex, and just plain goofy.
The @ vs. + vs. . vs bare thing never had an excuse except POSSIBLY the hardcode vs. softcode divide if there's no way to override hardcode commands in softcode. But ... a few questions even if that hardcode/softcode divide needs to be kept:
- Why prefixes at all? Why is it so necessary to TELL people that they're using soft-coded commands instead of hard-coded? Is it really so necessary to have
+finger
instead offinger
? What does the "+" add there at all? - I can see, if I squint right, how @desc me=foo makes sense to distinguish a property from a command, but why is it @ for some and & for others? Pick one and stick with it, dammit! Or even better just make setting a command!
set <property> <target> <foo>
. And to read itget <source> <property>
and to read it in codeget(<source>, <property>)
and so on.
@Derp is right in that there is a certain level of complexity you cannot reduce below. But that's the essential complexity of a problem domain. What's at issue in shitty UXes (like that of MUSHing) is the unnecessary incidental complexity typified by unexpected naming, unnecessary duplication, bizarre naming schemes, etc.
Nobody (sane and/or knowledgeable) is clamouring for a reduction of essential complexity (because this is impossible). But there's a whole lot of work that could be done to eliminate the incidental complexity of MU*ing, even sticking with the servers as-is.
But I do agree with @HelloProject that you can make at least the basic versions simple.
And that's the other issue in UX design. Identifying the most common use cases and streamlining it for those to be efficient and simple. If 99.44% of the time an attack is roll d20 add attack subtract defense, that should be what happens when you type the
attack
command by itself. If you have to add modifiers for uncommon situations, a rawattack
should still work exactly as the most common circumstance holds.The same is true for all parts of the MU: chat systems, bulletin boards, jobs systems, scene management, etc.: the common should be the default.
-
-
@Bobotron said in UX: It's time for The Talk:
@Rook
Movement aside, everything else is just 'effects' to put into play, insofar as code is concerned. Cover mechanics, reduced armor, increased/decreased anything...I'm sure this has been mentioned but I haven't finished the thread again. It exploded on me.
Every 'effect' is another layer of complexity to the code that has to be input and thus removing the 'simplicity' of automated code.
As to why + commands work, not only are we A) used to them but B) Nobody starts a pose with +. So it's a lot harder to accidentally run a fucking command when just trying to RP.
-
@WTFE Seems to be much better at articulating this topic than me.
-
@Lithium said in UX: It's time for The Talk:
As to why + commands work, not only are we A) used to them but B) Nobody starts a pose with +. So it's a lot harder to accidentally run a fucking command when just trying to RP.
This is almost certainly a retroactive explanation.
ahelp anews brief DOING drop examine enter events follow get give go index leave LOGOUT look move news page pose QUIT read rules say score teach think unfollow use whisper WHO with
Any of those look familiar?
"QUIT IT, you moron!
Accidentally forget the opening quote and ... oh, right. Nothing happens. Except a badly uninformative error message. Because commands have syntax and the odds of you matching that syntax in a random pose are negligible.
-
The @ vs. + vs. . vs bare thing never had an excuse except POSSIBLY the hardcode vs. softcode divide if there's no way to override hardcode commands in softcode. But ... a few questions even if that hardcode/softcode divide needs to be kept:
- Why prefixes at all? Why is it so necessary to TELL people that they're using soft-coded commands instead of hard-coded? Is it really so necessary to have
+finger
instead offinger
? What does the "+" add there at all?WTFE
Because people need to know where the documentation for this command lives. It's really that simple. That + distinguishes it as a custom command that did not come in the box, so they need to look in the help files for commands that did not come in the box. Mu games are a class of games, with some universal and some custom elements. It is important to keep those distinct, both for players who will go to new games on the same platform and for people wanting to learn the code. +posebreak is nice, but if I want to make a game, I need to either find it, make it, or steal it. That prefix conveys a lot of info. New players might not get that, but older players and coders do. Learning curve.
- I can see, if I squint right, how @desc me=foo makes sense to distinguish a property from a command, but why is it @ for some and & for others? Pick one and stick with it, dammit! Or even better just make setting a command!
set <property> <target> <foo>
. And to read itget <source> <property>
and to read it in codeget(<source>, <property>)
and so on.
NOW you are doing what @HelloProject was talking about. This is thinking like a coder. New players have no way to know what those properties are. These commands exist, with their own help files, to explain that. Plenty of us use &whatever me=stuff, but a newbie doesn'the necessarily know what properties the hardcode already knows versus arbitrary attributes. Those files go a long way in helping that.
As for the 'common being the default', in many ways, this is already the case. Many of us use myrrdin's bb system, anomalyjobs, etc. They are common to the point of being default. But they got that way by convention. Most MU systems are not this way. There is no 'common' except as the most basic of systems, and often just a barebones command will give you the most common thing players use it for '+equip bringing up inventory/equipped gear, for instance'. So this is in and of itself pretty arbitrary if more people spend time buying equipment than changing it. What is 'common' to one player is wholly subjective and vastly different depending on experience and investment.
- Why prefixes at all? Why is it so necessary to TELL people that they're using soft-coded commands instead of hard-coded? Is it really so necessary to have
-
@Derp said in UX: It's time for The Talk:
Because people need to know where the documentation for this command lives. It's really that simple.
This flies directly in the face of several games I've played where
help
gave you help for all the commands. Including the built-in ones. And where +help gave you exactly the same help files.- I can see, if I squint right, how @desc me=foo makes sense to distinguish a property from a command, but why is it @ for some and & for others? Pick one and stick with it, dammit! Or even better just make setting a command!
set <property> <target> <foo>
. And to read itget <source> <property>
and to read it in codeget(<source>, <property>)
and so on.
NOW you are doing what @HelloProject was talking about. This is thinking like a coder. New players have no way to know what those properties are.
New players shouldn't have to know. That's the entire fucking point! They should know that if they want to have a description for their character they
set description me I'm too sexy for my shirt.
This can be documented. In about the same way that@desc
is, in fact. New users will have a general idea of what "setting" something means. They've "set" the time on their phone or their computer or their VCR if they're really advanced. None of them will know what@desc me=
means.These commands exist, with their own help files, to explain that.
And you can document
set
andget
as well. And you can documentdescription
andcharacter generation
and a whole host of other stuff in ways that are actually useful. I mean seriously, do you believe new users who've never MUSHed before will think "I know, I'll just typehelp @desc
so I can figure out how to describe my character!"Plenty of us use &whatever me=stuff, but a newbie doesn'the necessarily know what properties the hardcode already knows versus arbitrary attributes.
help attributes
help universal attributes
help basic commands and attributes
help newbies
help new to MUSH
.
.
.Any one of which is better than
help @desc
.As for the 'common being the default', in many ways, this is already the case.
And in most ways that you encounter when first thrown into a MUSH it is not.
What is 'common' to one player is wholly subjective and vastly different depending on experience and investment.
What is "common" is something that can be trivially identified by monitoring command usage and seeing which patterns show up most often. HCI 101 stuff here, now.
- I can see, if I squint right, how @desc me=foo makes sense to distinguish a property from a command, but why is it @ for some and & for others? Pick one and stick with it, dammit! Or even better just make setting a command!
-
@WTFE said in UX: It's time for The Talk:
@Groth said in UX: It's time for The Talk:
Sidenote: @WTFE strictly speaking and syntaxical sugar aside. Mushcode has the same lamba support as any other string based scripting language as it can pass along arbitrary strings and call eval()
So leaving aside the part that makes lambdas useful (and you haven't addressed closures) it's just like having lambdas!
Lua:
function addxplus3(x) local z = x + 3 return function (y) return z + y end end add5plus3 = addxplus3(5) print(add5plus3(3)) -- 11 x = 100 -- what happens when we change "x"? print(add5plus3(3)) -- 11
MUSHcode:
???
From my reading of it, there's no convenient way to do the equivalent in MUSHcode. Doing that code in MUSHcode would be about as painful and as error-prone as doing the equivalent in, say, Rexx or in C. It's doable in both those languages because ANYTHING you can express in one Turing-complete language can be expressed in another modulo hardware limitations, etc. (if you'd like I'll put up the Rexx version), but it's painful, it's error-prone, and thus it's something that's going to be avoided as a result.
"Store this function as a string and call eval()" (roughly how I'd do the Rexx equivalent) is theoretically very similar to the above, but its the very lack of that syntax sugar is why nobody would ever actually use it.
Syntax is nothing. Syntax is everything. Both statements are true.
It's one of the reasons I introduced execscript() to Rhost so that you could execute external scripts, schema, binaries, programs, executeables, or whatever and feed back the result as a native function. To bypass some syntactical hell that's prevalent in mush code. While it's powerful, it does have serious limitations when all you can do is feed it a block of crap and split up the args based on pre-built filters and handlers.
I mean sure, I've added dynamic functions, variables, declarations, redefinitions, empowerment and depowerment localization of variables, syntax, and functions, and a global handler of the same. But boil it down, and it's still mush code and still has the limitations of the interpreted parser.
The beauty of execscript() is it lets you step out of the box and do... anything else.
I'm currently working on a STEP-like API so that you could actually do curl/web calls right from the shell to execute code within the mush to both send and receive results.
Goal is to be able to do low-level cross-platform/cross-software plugins that work right into the mush.
It's always possible to work around limitations, it just sometimes takes a hell of a lot of scotch to do it.
-
@Rook said in UX: It's time for The Talk:
That's a miss on the coder's part. The room, when dropped into combat, should have had an @oleave/@otport set and the player should have had an @omove set to leave the combat.
Would that even have helped? I could see like half a dozen ways a player object could end up outside the combat room without triggering any of those triggers. The MUSH engine is just not built to handle states, any attempt to make it run a state based combat engine is likely to end up in a clusterfuck.
@WTFE said in UX: It's time for The Talk:
The @ vs. + vs. . vs bare thing never had an excuse except POSSIBLY the hardcode vs. softcode divide if there's no way to override hardcode commands in softcode. But ... a few questions even if that hardcode/softcode divide needs to be kept:
- Why prefixes at all? Why is it so necessary to TELL people that they're using soft-coded commands instead of hard-coded? Is it really so necessary to have
+finger
instead offinger
? What does the "+" add there at all? - I can see, if I squint right, how @desc me=foo makes sense to distinguish a property from a command, but why is it @ for some and & for others? Pick one and stick with it, dammit! Or even better just make setting a command!
set <property> <target> <foo>
. And to read itget <source> <property>
and to read it in codeget(<source>, <property>)
and so on.
There doesn't exist any command which uses & as a prefix. The & is a shortcut to the @set command(which does exist, so does @get). It is possible to override most of the hardcoded commands but it's inadvisable, being consistent about the +prefix makes things relatively intuitive.
- Why prefixes at all? Why is it so necessary to TELL people that they're using soft-coded commands instead of hard-coded? Is it really so necessary to have
-
@WTFE If we're starting from scratch, there's no need for command prefixes at all. Ares doesn't use them and it works just fine.
For the existing servers, though, there are real limitations based on the hardcode/softcode divide.
Just one small example: My Penn softcoded +help is searchable, does partial command matches, the help files are editable in-game, and I have an API function for installing/uninstalling help files that supports my install manager. There's no way to do any of that with the hardcoded 'help' system (without forking the hardcode). Conversely, I don't think it's beneficial to clutter up +help with the 5 bazillion built-in help entries for MU functions and useless commands just to unify the systems. I'm not even sure you can disable built-in help and have a softcoded 'help' command. (though maybe you can; it's been awhile)
So yes, it sucks. But I really don't see a good solution that doesn't involve gutting the way the hardcode works. That's something the hardcode devs can help with, but it's beyond the reach of the average game admin/coder.
-
@WTFE said in UX: It's time for The Talk:
Or even better just make setting a command!
set <property> <target> <foo>
. And to read itget <source> <property>
and to read it in codeget(<source>, <property>)
and so on.For your command there, is
property
allowed to have spaces? Istarget
? If they are, am I required to put quotes around them? That's not going to be super-intuitive to a lot of non-coders (or at least, people who aren't used to UNIX shells) either.The problem is that computers aren't people. To us, if you have "Captain Aardvark" as a character, and want to set the 'approved' value to 'true' on Cap,
set Captain Aardvark approved true
makes sense. But the computer's going to see that as settingAardvark
toapproved true
on the characterCaptain
, which may not work so well for your chargen approval code.So you go, well, I'll separate the
property
andtarget
... let's doset <target>=<property> <foo>
. But now what if you wanted a space in that property? Well, let's separate THOSE too, and... hey, hang on, now we haveset <target>=<property>:<foo>
, which is the actual MUSH syntax (minus the @ on the front).It's a terrible syntax, but it arises to solve genuine parser problems.
Now, there's probably better methods to do this than stateless single-line commands. You could have, for instance:
edit Captain Aardvark set approved to true set approver Sparks show save done
...which would be like opening a document, tweaking things, and then saving it
Part of the problem arises with MUSH, where commands and code are identical; you want
@set Captain Aardvark=approved:true
because it needs to be a command usable in code, not just for a user. That interactive session might be great for a user, but it's not so hot for code that's basically a glorified batch script.With newer stuff like Ares or Evennia, the code (in Ruby or Python) and the commands (actually entered by the user) are wildly different. That's where we get freedom to come up with wholly new commands and interaction models for even the lowest-level stuff. The problem is, the hobby is still made up of folks who are used to doing things a certain way, and many of us get grumpy when we discover that, hey, it's not
page WTFE=How are you doing?
anymore, but instead, say,tell WTFE Hey, how are you doing?
ortell "Captain Aardvark" Hey, were you up for that scene?
Heck, I've seen people get grumpy at Arx for requiring commas in the mail recipient list, when @mail/quick is otherwise more or less identical in syntax to MUX2.
-
Command: @amove[/<switch>] <object> = <command-list>
Attribute: AmoveSets the action to be taken by an object whenever it moves from one
location to another, whether by using an exit, entering or leaving an
object, teleporting, or going home.I said @omove, but it is definitely @amove. My mistake, but it should still trigger no matter how the person's location is updated/changed. The moment that object is moved from one location to another, the game will kick off that attribute.
-
Eh, I don't think that the hobby is suffering from people who don't understand the difference in command syntax. People only learn what they have to in order to play the game at the level they want.
If code exists that they want to use, they do. They learn it. Even if they have to ask someone for help. You see it all the time: "How do I put ansi/color in my comtitle?" and "How do I do building?" and people get help, it's part of the hobby. MOST people I've met delight at learning new things like this, so again, I don't think it drives people away.
What might drive people away is not enough front-loaded, immediately-available help and explanatory rooms when they first connect. We've gone from "This is how you page/channel for help" to "You must be this high to ride this ride" sorts of intro rooms... and that, I think, is where we can make strides to help non-MUSHers. If a MUDder drops into a MUSH and doesn't know how to look around, they won't, they disconnect.
I am betting that a huge majority of MUDders dropping into a MUSH will be prepared, at some level, to learn something new. Just as a MUSHer dropping into a MUD will need to learn. It's part of the hobby. If you want to play, you'll take steps to learn, and that goes for any game.
-
@WTFE said in UX: It's time for The Talk:
@Lithium said in UX: It's time for The Talk:
As to why + commands work, not only are we A) used to them but B) Nobody starts a pose with +. So it's a lot harder to accidentally run a fucking command when just trying to RP.
This is almost certainly a retroactive explanation.
Then let me explain from history: Because @commands.
I believe the very first +command was Firelizard Mail, an object-driven messaging system from before the days of a Master Room, before user-defined attributes. It was an amazing feat of coding in a limited system, and it eventually became +mail, especially when we got Brandymail.
So we have '@dig', '@link', and all those @-commands which have to do with server-changing functions. Then you have 'page' and 'move' and 'pose' which are all user-facing server commands. Perhaps '+mail' should have been one, but we created a third category: User-created commands.
It is unarguably good UX for users of an interface to be able to do whatever makes the most logical sense to them. '+command' meant 'softcoded command' for over a decade.
In part, I've invited this discussion. '+' is silly, but it's silly nowadays, not silly then. Things change. We should change with them, but getting people to change isn't as easy as saying things are wrong. This isn't a coder issue, it's a user issue. It won't change overnight.
"QUIT IT, you moron!
Accidentally forget the opening quote and ... oh, right. Nothing happens.
... I have no idea what you're talking about here. I suppose that no, this doesn't look familiar.
-
@Thenomain said in UX: It's time for The Talk:
This isn't a coder issue, it's a user issue. It won't change overnight.
Well I mean, you've gotta code it that way for users to get used to it. It has to start with coders, there's literally no other way to do it.
It's not exactly a chicken or egg scenario.
-
@HelloProject said in UX: It's time for The Talk:
@Thenomain said in UX: It's time for The Talk:
This isn't a coder issue, it's a user issue. It won't change overnight.
Well I mean, you've gotta code it that way for users to get used to it. It has to start with coders, there's literally no other way to do it.
You mean even you have ignored the twice where I've said I had, and gave you specific ideas on how to get people to transition over?
Just to be clear: I'm on it. Faraday is on it. Evennia is on it. This isn't just preaching to the choir, it's preaching to the Pope.