@Thenomain said in Dealing with Staff:
... resurgence of Rhost as apparently Ashen has become utterly insane and entirely off his meds.
But in a good way.
... Honest.
@Thenomain said in Dealing with Staff:
... resurgence of Rhost as apparently Ashen has become utterly insane and entirely off his meds.
But in a good way.
... Honest.
@thenomain said in Mux Logger Objects:
Yes.
Don't you mean maybe to the 99.9999999999999999999999999% of yes?
@arkandel said in Do we need staff?:
True, but there's no way to systematize right.
No, I have to argue with this.
The way to 'systematize' right is frankly up to the people running the game.
If it's not right for you (the queen's you) then it's none of your damn business. Leave them have their right and go somewhere else.
Too many people try to force their version of right on everyone else, and then we wonder why the hell we have problems.
Coding isn't hard, but good coding is.
Things to remember when you mush code. And this applies to all mush flavors (Penn, TinyMush, MUX, Rhost, etc)
@emit 123 -- This is a single queue stack. @emit pushes '123' onto the queue stack and pops it. One level.
@switch 1=1,@emit 123 -- This is a DOUBLE stack. @switch compares 1=1, finds that to be 'true' and then pushes '@emit 123' onto the stack. This is a command, so when it pops it from the queue stack it evaluates @emit 123 as the second queue stack.
This is very important, because how things are pushed and pulled from the command queue stack depends on how things evaluate. For example
@wait 0={@emit 123;@emit 456;@emit 789}
returns:
123
456
789
However...
@wait 0={@emit 123;@switch 1=1,@emit 456;@emit 789}
returns:
123
789
456
WAIT... WTF? you're asking yourself. It's actually asking yourself. Well, consider what I said before about evaluation. @switch is an evaluation, then what it calls is ALSO an evaluation. While each @emit itself is an evaluation.
So it was processing that command chain as:
@wait 0 -- One evaluation
@emit 123 -- One evaluation
@emit 456 --One evaluation
@emit 789 -- One evaluation
@switch 1=1 -- One evaluation
So, to put this in perspective:
@wait 0={@emit 123;@switch 1=1,@emit 456;@emit 789}
^^^^1 ^^^^2 ^^^^2 ^^^^3 ^^^^2
1 is evaluated first. The {}'s mean everything inside that is passed to that one argument
2 is evaluated next.
3 is evaluated last.
It's all based on how things are pushed and pulled from the command queue.
Functions. Functions are not commands. They are used within commands and are intended to manipulate the stateful data of a given command. They tend to be used to manipulate input and output of those commands and format, redirect, or in some way alter what a user enters to what they ultimate see returned. Functions can mimic commands like @set via set() and are called side-effects. They are called side-effect as the function itself doesn't really return anything but in fact acts as an 'aside' for a different purpose. The arguments that the functions use lead up to
Arguments. Arguments are called via %0 (or [v(0)]) to %9 (or [v(9)]) through an interpreted parser. By using the v() function, you can access arguments past 9, usually up to 30 by default. So v(10), v(11), and so forth. Penn, MUX, and Rhost have very similar parsers but they do have some small differences in evaluation that can annoy people who are used to one parser or another. MUX and Rhost for example will require additional escapes of backslashes ()'s while Penn tends to nerf ['s and have some significant issues with stacking functions. Each can be worked around, but they can be annoying when you're neck deep in complex code. How evaluation works leads to...
Parsing. Parsing is done when you enter text into a command or function. Depending on how many times you call that text and how many times you act upon it, you could, potentially, double, triple or even more a segment of text. Generally, this can lead to all sorts of security risks, since some strings you do NOT want to double parse, as it opens up possibilities to execute code that you may not necessarily want to execute. This leads us to
Security. Security in mush is a very hard animal to understand if you're not familiar with the language. If you have a string [add(1,1)] as a literal string, it will be passed as that. However, if it evaluates, it will return '2'. This isn't that big a deal. But let us assume you have [add(1,1)] in an attribute. You have [get(myobj/attribute)]. It evaluates and returns the raw string [add(1,1)] which you want. But you mistakenly use this and evaluate it again, so now you have '2' being passed, which is not what you wanted. This could, potentially, be a nested evaluation that causes unforseen evaluation. So when you code, always test against evaluation. Make sure you are not mistakenly double evaluating anything, and never, ever, just evaluate values that you can not guarantee will have a value you expect. Such as an attribute off a player that they can change. There are functions (like objeval(), secure(), escape(), and so forth) that you can use to lock down and limit evaluation issues, but each one should be a case by case basis on your needs and desires. This leads to how commands and evaluation is chained together by...
user defined commands. These are also commonly called $-commands because these start with an identifier of a '$'. They allow globbing wildcards (* and ?) by default, and most modern and current mush codebases allow the optional REGEXP flag to allow regular expression (PCRE -- perl's contribution) matching for the commands. This allows some fairly consistent flexibility in convenience and while an interpreted language will never be faster than a byte compiled or compiled language, hitting hundreds of thousands of evaluations a second isn't too hard a thing to accomplish. Put plainly, the built in interpreted language of mush is powerful, complex, and while a far cry from a mature language, isn't something to just sneer at either. You can store values in various ways that lead us to...
Static storage. This tends to be attributes or if you have it configured sql databases or other methods. The common method, however, is attribute storage. This is done through the @set command (short-hand of '&') or using a sideeffect function like set(). These are considered static (or permanent) storage because it is written to the database on consistent physical storage on a physical harddrive. So they will remain during shutdowns, restarts, migrations, etc until you modify or delete it. Static storage can be fetched through the get() function or evaluated and fetched via the u() function. There are a slew of other functions you can use to fetch and evaluate, but are generally based off the theme of get() and u(). get() takes it raw, u() evaluates. You also have the capability of having...
Dynamic storage. These tend to be called registers and will last until the command (or command sequence) is completed. Once the command chain is completed, the dynamic storage (registers) are gone. This is handy when you want to store temporary values, function returns, or essentially complex parsing or processing that you wish to recall or re-use later in the command sequence. This not only allows for better readable code, but speeds up processing since a set of complex code doesn't have to be re-processed as you already have the result stashed away into a register. There are a limited number of registers on mushes (generally 36 depending on the codebase), which I find more than sufficient for most needs. Registers are gotten through the %q substitution or r() function. They can be set with the setq() or setr() function. Dynamic storage also leads to...
percent substitutions. These are pretty much dynamic and are intended as a 'substitution' value fro when something parses. For example, %n is 'name'. It will be replaced with the name of the executor that evaluates that string. There's a large number of useful substitutions on mushes and you should practice and experiment with how they parse. Registers, dynamic, and static values can be utilized using...
Data Objects. Objects can be referenced by name or by dbref#. A dbref# is essentially a unique index assigned to each item in the database. While dbref#'s can be recycled, they will be unique for that item until destroyed (recycled). When you storage attributes, they are stored based on the object.
Now you can put this all together, so without further adoo....
This leads us to some fun examples in putting this all together...
&AN_ATTRIBUTE -- This is an attribute called 'an_attribute' that is a static (permanent) value.
&A_STRING - This is an attribute called 'a_string' that is a static (permanent) value.
[setq(0,My Value)] -- This stores 'My Value' into a register of '0'.
[r(0)] -- return the value of register '0' (you can also use %q0)
#12345 -- This is a dbref# specifying an object in the database
[get(#12345/a_string)] - fetches the contents of the variable 'a_string' from object #12345
@emit foo -- This is the command '@emit' with the argument 'foo'
$mycommand * -- this is a user defined command called 'mycommand' that takes a single argument (the '*')
To put this all together:
&A_STRING #12345=This is a string
&AN_ATTRIBUTE #12345=$mycommand *:@emit %0 [setq(0,get(#12345/a_string))];@emit Register was: [r(0)]
If you typed:
mycommand abc
You would see returned:
abc
Register was: This is a string
This is by far not a complete document, but hopefully it'll give you some understanding of the guts and garters of mushing. Some day I should sit down and write a manual, but honestly I'm being bum-gammed with real life and work, so maybe for 2017
Ok peeps.
This is something I've rolled around in my head, and figured I"d put it out there for everyone else to talk about and debate.
To make a good game that people want to build, one of the important things is to have a back--end engine, weither that is mush, mud, muse, moo, evennia, muck, or other that works best for matching your dreams.
What I want to bring up to you guys (and girls) is this:
What is your favorite mu* engine, the pros you like the most with it, and the cons that you wish it could do.
I have an alternative motive with this, as I plan to take anything and everything said to help make RhostMUSH even better, but beside this, I'm hoping this will bring to light to everyone, developers, game admins, and players alike, to what is really desired today in a gaming engine.
Also, to highlight some things that's currenty in the works with RhostMUSH so those of you can bring up info on that as well or pros/cons, here is where we are:
That's currently what's cooking with RhostMUSH.
For all other people, please let everyone know their favorite codebase and pros/cons to those and let's discuss how to make our love even better.
@icanbeyourmuse said in Room parent / exitformat weirdness:
The exit owner did not matter but when i owned the room and set the attribute it went where it should. Even if @Cobaltasaurus owned the exit.
Double check to see if you, yourself, are not inherit.
If a player is set inherit, it assumes inherit on anything they own.
DO NOT DO THIS.
Another option is setting the exits, rooms, etc with a @power of see_all (I think it is?) which also can be somewhat abusive. Other than that, I'm unfamiliar with anything in MUX that would grant one player full access to everything w/o an inherit for darkish things.
Best bet is what is suggested earlier, just make a central builder character and chown all rooms and exits to them.
Not only does it allow the ownership and permissions to match up, it also keeps things less cluttered as you know who owns what and why they own it.
@Cobaltasaurus said in TinyMUX: How to set default player attributes?:
Create a character parent, and then in the server set the player_parent to that dbref. So all players are automatically parented to it.
That'd honestly be the best solution, but barring that like you mentioned something in the starting room when they do ACCEPT or maybe the master room when a player connects check the existence of the attribute, if it doesn't exist, set it.
Times like this makes me kinda wish MUX had some more features from (shudder) TinyMUSH3 or RhostMUSH.
Basically a global_clone_<type> so when a new type of that type is created, all attributes are copied from the clone to the target. I think Penn has work arounds with their action lists and other methods, but with MUX you're more limited by options.
So off the top of my head with MUX you're limited to:
And with MUX2 (the latest) that... would be about it.
@skew said in IC Message Code/Alternative to @mail:
And I'm going to keep yammering...
Any chance anyone has the help files for Brandy Mailer? They're not on the MUSH code website. It has you create the help file, but doesn't give you any actual stuff to put into it.
I did a few google searches, but didn't find anything.
There you go.
Figure I'll keep this in this thread as it talks about 'Codebase Pot Pie' just as well as adding a new thread.
First, Rhost 4.0 supports full unicode. Have fun those who are on Rhost 4.0.
Second, I'm working on a somewhat passible STEP API into the mush.
Essentially, using curl, you will be able to submit GET and POST responses to the mush to push and pull entries to and from the mush queue and return them to the outside application.
You should be able to use this in junction with execscript() and interactively as it pushes and pulls right from the queue itself.
The goal for this is to allow outside applications full reign into the mush engine to pass any data async into it.
It obviously won't be the fastest thing in the world as, hey, it's an API engine, but it should allow unlimited flexibility into the mush.
The reason of bringing it up here, other than the obvious of giving people a heads up what may be coming down the line with Rhost, is ideas and interfaces you would like to see on the API as it's being built. It's in the design stages right now (I have a working PUSH/PULL engine, still have to build the parser around it).
So, anyone interested to dive on the band wagon, feel free. All constructive ideas are welcome.
An example of the interface will be:
curl --user "#dbref:password" -H "Exec: commands-go-here" -H "Parse: no/yes/strip" http://mymush.is.here:API-PORT
The 'password' will be generated per-dbref# (non-player allowed!) in a SHA2 hash.
@faraday said in UX: It's time for The Talk:
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.
Made this possible with Rhost with dynamic help files you can create on the fly then access with textfile(), dynhelp() or @dynhelp in your code.
You just need to create two server side files to make it happen.
whatever.txt and then mkindx it for a whatever.indx.
There's also a corresponding mkhtml that you can convert a whatever.txt and a whatever.indx file into an HTML translated file with built in indexing.
I've always believed the solution for the nitch environment is providing an environment that is flexible, that can be easily maintained, and easily modular to go in nearly any direction the admin want it to go.
We're close to that end point, and it's a moving target so I doubt we'll ever reach it. But it's been a fun ride getting there and every day we think of new things to add for modularity and configuration control.
With how the world is going with direction with containers, cloud computing, virtualization, dynamic start-ups and any number of other things, environments and codebases generally have to follow the pattern at the back-end or frankly be left behind as people choose things that will do it.
It's a tough target to keep up with.
@rook said in Alternative Formats to MU:
Unless you are actively participating in a development effort (like Griatch and team seem to be), I wouldn't hold my breath. Seems like something that will eventually go the way of pay-to-play, and you'll lose a lot of the current crowd with that.
Exactly this.
I and others have worked on RhostMUSH for, what will by start of 2019 be 30 years.
Moving MUSH into mainstream runs into some very real issues. They are (but not limited to):
To make changes to that we have:
This is why you won't see much effort.
The majority of mud developers (like myself) are frankly burnt out, jaded, and cynical.
We've been doing this for 30 years, half our lives, and likely longer than a fair portion of you have been alive. We're tired.
We did what we did for the love of it. Not for what people may or may not appreciate, love, or hate. We did it for our own love and interest. We did it because we hoped others would find the same love in it we did.
We would love to take mudding to the next level, but did I mention we are tired?
So if you all want to see it happen, you all are going to have to help us with it. We just don't have the time we used to. We have families now, some of us have grandchildren. I myself have great-great-nephews and nieces. I find staying up after 10pm is hard as hell now, where when I originally wrote on Rhost I could do 48 hour stints with a glass of mountain dew and some anime on TV and maybe a bucket of hot wings.
Frankly put, we just can't keep up anymore.
To quote Futurama: Our minds are willing, but our bodies are weak and flabby.
Always wanted to start a mush based on H. G. Wells Time Machine.
With realities and zones handling each different 'timezone' and having the 'past' effect the future, the possibilities would be fun.
Same with a Doctor Who mush.
Maybe one based on TRON with some fun virtual reality.
Then of course, Guardians of the Galaxy.
And to throw one out there that will make people lynch me and beat their heads to remove the imagery:
Smurfs Vs My Little Pony -- The apocolypse death battle.
@theonceler said in Yes! More Micro-transactions! (Activision, WB Games and EA appreciation thread):
The games you want just don’t make enough money.
Boy it’d be nice to embed a tweet right here, but whatever, read this tweet storm from game biz journo Mike Futter. He does a good job of running down the changes that are getting single player buy-and-done games canceled while P2P goes on strong. The gist is that $60 per person just isn’t enough these days and season passes patched the problem for a while but now even they aren’t doing it anymore.
This is like saying all those poor multi-billion dollar companies don't make enough on their web sites so need to just apply those billions of ad-spaces to make up for their losses.
Yea, pull the other one. It's got bells on it.
@Thenomain said in Information Storage Question:
I don't know why anyone would suggest not using 64k buffers. I can't code without at least 16 anymore, or at least SQL which is preferable but not universal.
It's not so much that mush can't handle 64K buffers or more, it's that older routing and TCP buffers have issues with it.
Some systems cap TCP buffers at 32K which can cause a retry and a retransmit on packets over that 32K, which depending on your network latency and reliability could potentially mean lost packets (seemingly information being cut off).
Sometimes this is in relation to the receive window size being set to a ceiling of 32K, so any packets over 32K requires an acknowledgement before sending the remainder of packets. In around-robin TCP single-threaded engine, this could cause potential of issues and would likely require some back-end handling for additional buffering of packets not sent. Theory, as I've not researched it overly much on send/receive TCP window size alterations.
When I played with 64K lbufs it seemed to work fine with people with fat network systems but those who were on older ISP's and slower networks occasionally complained about information being cut off.
So it's why I usually suggest not going over 32K lbufs.
@ominous said in Dies Irae: Paid Positions for Coder:
@thenomain The stock market is not hard to game-ify. Many board games have done it. It's just a really big auction house. People are selling X at Y price and other people are buying A at B price. Once these people meet and agree to Z price, that sets the new value of the stock. That is a very simplified version, but a MU* only needs a simplified version.
And for all that's holy, try to code it so that a group of people can't nerf the system by cornering the market in attempts to sell 'a common rock' for like 10k a pop?
I've been on MMPORGS that had markets that didn't protect against this which absolutely ruined the game because the people who played the system essentially owned the game.
@Ominous said in MU Flowchart:
@Ashen-Shugar Since he asked for 'the good old flowchart' rather than 'a good old flowchart,' I am assuming he is referring to some specific one that may be an old joke/meme.
Ah, in that case, this is the one I used to pin up in my cubicle a lot.
This is the one I recently got for my work days.
Works well for my needs.
https://redhat.corpmerchandise.com/ProductDetail.aspx?did=26009&pid=200696
Hey all, is it possible to - in TinyMUX - set a conditional lock that prevents me from seeing someone's poses/says/@emits when in certain rooms? I want to block any incoming stuff from people in certain OOC rooms but not interfere in their input elsewhere.
Or am I just gonna have to do this through hella LUA scripting?
You gotta do this through client side gagging. And separating it out from IC vs OOC rooms is a little hard to the point at at midnight I can't think of a way to actually accomplish it off the top of my head.
Actually have an idea.
MUX2 does have Reality Levels.
Set up a unique reality level for yourself and just put the room in that reality and make sure you're -not- in that reality, but everyone else is, then they see as normal, but to you they don't even exist to you while in that room.
@Sunny said in MU Flowchart:
Also
https://see.stanford.edu/Course/CS106A
It will not teach you mush code, but the Stanford class (it's free) should get the concepts across enough for you to teach yourself the mush stuff using helpfiles, dissecting other peoples' code, and asking for the occasional bit of help. Very few of the mush coders I know are anything but mostly self-taught.
There's also Amberyl's Mush Manual
15+ years outdated, but the base ideas and core features are still valid today.