MU Soapbox

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Muxify
    • Mustard
    1. Home
    2. Ashen-Shugar
    3. Posts
    • Profile
    • Following 2
    • Followers 3
    • Topics 15
    • Posts 272
    • Best 116
    • Controversial 0
    • Groups 3

    Posts made by Ashen-Shugar

    • RE: Dreams to Reality

      @Chime said in Dreams to Reality:

      It's very pretty-- but it's a perfect example of what I was trying to avoid. I've been a UNIX person since 1995. I really do want just bare autoconf so that I can automate and do CI testing more easily.

      Well, that's the brilliant part of it. It makes a dynamic file called 'custom.defs' in the src directory that has the Makefile variables. So you could use CLI and generate it in a batch or on the fly just fine. The menu is just an interface to generate the custom.defs file, that's it.

      Unix guy here since 1985 (AT&T SYS3/SYSV on a 3B2), so I am all for the mighty CLI 😉

      That said-- it is really nice to have all of those configurable features. Ideally they should become config options in the game conf file rather than compile-time features, but I understand quite well how big a pain that is.

      Yup, we have a ton of customizations that way. All the mysql is in a rhost_mysql.conf, again, the Makefile menu interfaces with it.

      The only compile times are those that make huge differences in the code itself, and again is just populated as DEFS's in the custom.defs file. So entirely CLI capable with batch processing. Yay is the UNIX.

      Admittedly, a lot of my customizations to MUX were to remove a lot of #ifdefs for obsolete crap.

      Take your MUX inc()/dec() option. What's the harm in having that always enabled?

      Yea, some of these things we likely will re-visit to change from compile time to just conf parameters, most of it however was due to speed/performance considerations at the time.

      [X] 26. SHA512 Passwords
      

      I hope those are still salted?

      Absolutely. 10 character randomized seeding per password encryption.
      No rainbow table decryption for our baby 😉

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Dreams to Reality

      @Griatch said in Dreams to Reality:

      Thanks for the elaboration!

      My pleasure 🙂

      So to translate to terms I'm more familiar with, you will offer one sequential in-process call (which is blocking I presume) and also one asynchronous version involving a call to python running in a subprocess (or even launching a new python instance per call?) with a callback for whenever it returns. Sounds good!

      As far as I'm aware, that's what the plan is. The async will essentially run a separate thread for each python call, so each async call runs its own sandboxed process.

      Eventually what I would love to do with this as well is once we got the environment set up to be able to work with Evennia and exchange python modules so that we could literally swap them on the fly between our codebases like plugins.

      But that's the distant future.

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Dreams to Reality

      @Griatch said in Dreams to Reality:

      @Ashen-Shugar

      python API -- Preliminary development. There's no real backend code for it yet but the design implementation is solid and we just have to do it. This will essentially do a multi-threaded API engine that will allow a server-side python scripting to be tagged and interpreted right into the core MUSH. So all the power of python with the pre-existing mush language.

      This sounds awesome, kudos for giving more Python to the people! It will be interesting to see how the Python API will look. Also, when you say "multi-threaded", how do you intend to do true multi-threading rather than asynchronous event-loops without hitting the GIL - or are you referring to launching multiple python interpreters in separate processes?

      ... but anyway, to stay on topic, I'm partial to Evennia but that's maybe not too much of a surprise to anyone. 🙂
      .
      Griatch

      Multi-threaded in that the python scripting will launch separately from the mush engine.

      So you submit a request to the API and it then goes off and executes its thing then when finished returns the values and results to the mush with a notification layer.

      There'll be two methods. A single-instance (works like a built in function) and a multi-instance (or multi-thread) that will work a bit like the built in semaphores.

      So one instance is layer -> python -> result

      The other instance is layer -> python -V -> continue -> python -^ -> result

      Where you start by (V) pushing out the request to the python, and at some later point you get a notification state (^) saying the result is complete.

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Dreams to Reality

      @Thenomain said in Dreams to Reality:

      @Ashen-Shugar

      Can I turn off the cutesy "Did you mean Help?" style error messages which, okay, I've always found demeaning. That's just me, mind you. Sometimes when I forget I'm logging into an Rhost that message set set me scrambling to remember what's a flag and what's a trigger and what knife at the dinner table is best to plunge into my eyeballs so I never had to see it again.

      Yup!

      > help vanilla_errors
      VANILLA_ERRORS TOGGLE
        Toggle: VANILLA_ERRORS
      
        When this toggle is set on an object, the mush will show that object
        the normal error message. Otherwise the mush will show something more
        creative.
      
      > @toggle me=vanilla_errors
      

      You can also globally modify the errors.txt file and either null it out (which defaults to the vanilla error) or modify what you want for it.

      Full compatibility is for the win 🙂

      Edit: Wellll.... the reason for the @toggles was two fold. It was intended for 'toggle' values that was meant to turn on/off features on the fly, and the other was we reached the maximum for internal flag markers for the word storage at the time. 😛

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Dreams to Reality

      @Chime

      Hey Chime. Rhost has grown a lot since you last played with it.

      To answer some of your questions in order...

      • No unicode support (apparently fixed in beta?)
        -- Correct. This is fixed in a 'Kage' branch which is undergoing final testing. It uses a markup language similar to how ansi works.

      • Zenty's color implementation
        -- This has gotten a lot more transparent and become integrated in a lot of commands and functions. So it's a lot cleaner than it used to be. Still no HTML color but we do full XTERM 256 color and it allows ansi(<R G B>,foo) encoding and downtalks to 256 color (fully MUX/Penn ansi() compatible).

      • Loss of the original project repo, issue tracking
        -- Oh yes this sucked so hard. I went through and backtracked as many changes and suggestions that I could, and it's now part of the main distro and online help in 'help revis' shows all the changes that I was able to back port since version 1.0.0 in 1989. It's not perfect, but it's everything I could find 🙂

      • @mail UI changes.
        -- We have wrappers for @mail now that will mimic MUX/TM3 or Penn's system fairly reliably. It's not 100%, but it's good enough that people seem comfortable with it.

      • The database used for disk storage
        -- QDBM is now the default database engine and we allow upwards to 64K LBUFS. In addition, you can increase -and- decrease the LBUF's in a live database without introducing corruption. It does auto-trimming. You would potentially lose data that was larger than the new buffer, but the db handles it fine w/o eating itself. We also natively support mysql and sqlite... at the same time optionally.

      • The method to compile Rhost. We now use a menu 🙂

                             RhostMUSH Source Configuration Utility
      
      ------------------------------------------------------------------------------
      [X]  1. Sideeffects        [X]  2. MUSH/MUX u()/zfun  [X]  3. MUX inc()/dec()
      [X]  4. Disabled Comsys    [#]  5. ANSI SUBS (menu)   [X]  6. crypt()/decrypt()
      [X]  7. +help hardcoded    [X]  8. MUX @program       [ ]  9. COMMAND flag
      [X] 10. ~/_ attributes     [X] 11. Reality Levels     [X] 12. a-z setq support
      [X] 13. Enhanced ANSI      [X] 14. Marker Flags       [X] 15. Bang support
      [ ] 16. Alternate WHO      [X] 17. Old SETQ/SETR      [X] 18. Secured Sideeffects
      [ ] 19. Disable DebugMon   [ ] 20. Disable SIGNALS    [ ] 21. Old Reality Lvls
      [ ] 22. Read Mux Passwds   [ ] 23. Low-Mem Compile    [ ] 24. Disable OpenSSL
      [X] 25. Pcre System Libs   [X] 26. SHA512 Passwords
      --------------------------- Beta/Unsupported Additions -----------------------
      [#] B1. MySQL Support      [ ] B2. Door Support(Menu) [X] B3. 64 Char attribs
      [ ] B4. SQLite Support     [X] B5. QDBM DB Support    [#] B6. LBUF Settings (Menu)
      ------------------------------------------------------------------------------
      
      Keys: [h]elp [i]nfo [s]ave [l]oad [d]elete [c]lear [m]ark [b]rowse [r]un [q]uit
            [x]tra default cores (MUX, TinyMUSH3, Penn, Rhost-Default)
            Or, you may select a numer to toggle on/off
      
      Please Enter selection:
      

      Rhost has grown up quite nicely from the fuzzy days of yonder-year.

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • Dreams to Reality

      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:

      • unicode/UTF8 -- Beta. It's already there in a branch (Kage) and just has to be final-tested and pushed into the main branch.
      • python API -- Preliminary development. There's no real backend code for it yet but the design implementation is solid and we just have to do it. This will essentially do a multi-threaded API engine that will allow a server-side python scripting to be tagged and interpreted right into the core MUSH. So all the power of python with the pre-existing mush language.
      • With the above, a future ruby, perl, and other possible scripting languages tied to the same (or similar) api will be possible.
      • HSpace and hopefully a sync of ASpace compatibility. HSpace is already working in a branch.

      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.

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Really wierd happening...

      @Lithium said in Really wierd happening...:

      @Thenomain I just tore it down and am rebuilding it from scratch. I didn't have a lot of code in there to really be a problem to redo it all. Will take a very short amount of time.

      Just don't know why it happened in the first place... Kind of frustrating. I'm just glad I don't have to much stuff on there right now. I kept flip flopping on systems so there wasn't a ton of code on the game at the moment.

      EDIT: Yes, I do do backups.

      I realize I'm doing a bit of a necro, but figured I would toss in a reason for why this happened so that if you or others run across this, you can realize what is going on.

      MUX, TinyMUSH3, Rhost, and in some ways Penn, based on how they do data storage have a structure based on the data type that is based on a bitwise mask.

      Penn because of how they write their data, funny enough, is not as vulnerable to this as they use a method similar to a wacky XML format, however, TinyMUSH3, MUX2, and Rhost can be vulnerable to this.

      This goes way back to MUX 1.x, TinyMUSH, TinyMUD and all the other old codebases that used to use GDBM database. GDBM used a 4096 buffer for the cache, including attribute reads and writes. The A_LIST (internal attribute keeper) for attributes would store the 4 byte integer value of the attribute followed by a seperator. This would mean that on any database using GDBM where you have a 4 byte int (and not, say, Tru64 which uses 8 bytes), you were limited to 4096/5 + 1 (for the null) attributes per object before the 4096 internal cache buffer had to be split and chunked into a new cache buffer. This was seen, by gdbm, as not an issue. The reason is because GDBM was smart enough to recognize it needed to cache up a new buffer. MUSH/MUX was smart enough to realize it's not a problem, because they knew that GDBM did so.

      But. There is a problem. GDBM didn't order how or when the cache tables were written. It would put a pointer marker of where and how it was written, but it would not necessarilly write them --in order--. This would mean you now have data written in a structure out of order, which, you guessed it, would corrupt your table. This means that you could, potentially, have values overwrite your structure data turning a data type of, oh say EXIT, into a ROOM, a player, or so forth. Have attributes randomly show up on other things. Attribute contents (greater than 4096 bytes) randomly show up on other attributes or disappear alltogether. This was a common occurance seen in older TinyMUSH and MUX 1.6 systems.

      Then MUX 2.0 came out and Brazil made a completely new backend db engine. The corruption suddenly 'went away'. Funny that.

      Rhost realized the limitations of GDBM and we hard-capped attribs to get around it until we went to QDBM which no longer had this issue.

      TinyMUSH 3.3+ now uses QDBM as well.

      Penn went to a new db format from 1.8.0+.

      So, you ask yourself, without GDBM, why do I get something that looks like this exact same db corruption?

      Well, glad you asked!

      There's still ways that every codebase can still get corruption. The most common are five ways:

      1. You suffered a backout or brownout while the database was being written so you have partial or corrupt data in your database.
      2. You suffered a quota exceed limit or the mount point on the disk is filled so it had no room to write the data to disk.
      3. You opened the database with another tool at the same time the mush was attempting to write the data to it which would cause some... issues... depending on the database being used (QDBM is notoriously nasty when you open it in write mode when it's currently open by the mush).
      4. The code you're running is buggy and has an overflow (stack or buffer) that is blowing away values in memory and/or disk before it's being written and overwriting values.
      5. You have a BIOS on your computer that's not 100% compatible with the disk you are using, or you're using a filesystem that doesn't fully support disk write-ahead and your disk is corrupting saves because of write-ahead, or your physical disk is failing.

      #4 is easy enough to identify because it likely will keep occurring when certain commands or functions are used.

      #1 is easy enough as you can check uptime to see if the server you're on has bounced.

      #2 and #5 are a bit harder to identify, especially if you do not have system administrator access on the system in question. If you do, refer to the /var/log/messages (or /var/adm/messages depending on the UNIX flavor) and see if you can find any I/O errors in the logs. df to see how much free disk space you have. usa 'quota' to make sure you don't run out of account quotas. When you run active backups and you have quotas enabled, it's quite easy to run out of disk without realizing it since backups can chew up disk space quicker than you expect.

      All this boils down to that the only way actively to change a data type in a mu* database is with db corruption. As soon as you ever see it in your database, the reliability of your database is now in question. At this point you should backup everything you want and then load in a backup database and load in everything you could save from the db in question.

      MUX2, Penn, and Rhost are very resiliant mush engines, but nothing can save against acts of God other than backups backups backups.

      Good luck, and hope your mush is doing good.

      And, again, I apologize for the necro.

      posted in Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Code Teachers?

      @Thenomain said in Code Teachers?:

      Perhaps the technical term is "two selection points"?

      Ah, ok, I grok what you're asking for.

      Yea, other editors do offer this as well, most not out of the box, but they do have plugins that will enable it.

      VIM is just one (https://github.com/terryma/vim-expand-region) emacs and other applications have varying plugins that allow the same thing.

      I think if you have a preferred editor, Theno, you can likely get a plugin that'll do what you want, but you seem pretty happy with your editor of choice, so it's likely moot 🙂

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Fallout/Wasteland existing code/snippets.

      @Chime said in Fallout/Wasteland existing code/snippets.:

      @Thenomain said in Fallout/Wasteland existing code/snippets.:

      TinyMUX doesn't have a 'nospoof' @pemit, so @nspemit --> @pemit will have to do.

      And yet I had a variety of code on The Reach @pemiting without nospoof tags, e.g. the posebreak stuff.

      Hint: just run the pemit as the target (see objeval) and no tags are printed.

      The only issue this runs across is if you restrict @pemit from players, then objevalling to the enactor breaks because pemit() inherits the @pemit restrictions.

      Brilliant idea, but gotta keep in mind games that may restrict commands down.

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Fallout/Wasteland existing code/snippets.

      @Thenomain said in Fallout/Wasteland existing code/snippets.:

      @Grindle

      A++, would upvote again. Thanks for tracking this down.

      Minor warning to other softcoders: This is PennMUSH code, and I haven't gone through to see what might be incompatible with TinyMUX (possibly) or Rhost (unlikely). Always validate code for your game before installing.

      Just did a quick eyeball, it should mostly work out of the box with Rhost, the only things that'd have to be changed are:

      @nspemit -> @pemit (Rhost's @pemit by default does spoofing for wiz and higher)
      table() -> columns()
      haspower(guest) -> hasflag(guest)

      The rest looked fine.

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Code Teachers?

      @Thenomain said in Code Teachers?:

      @Ashen-Shugar

      The only text editor I can use is TextWrangler/BBEdit from Bare Bones Software. It's Mac-only, more's the pity, but it does one thing that Sublime Text/Atom/et al. do not, and while it's difficult to explain why I can't live without it, @Chime assures me that I probably will not see it anywhere else.

      In selecting a function to cut out of the code, I must, must have the ability to strip the contents, parenthesis, and the function name itself. It's no good at all for me to select just the contents of a function, or even the contents and the parens/brackets/etc.

      TextWrangler allows me to select the contents and parens/etc. just like the others, but it also puts in two insertion points: One at each end of the selection so if I use the keyboard to shift-arrow backwards, it expands the selection backwards. All the other programming text editors I've tried put only one insertion point at the end.

      Not having this feature drives me so goddamn batty. I would love to use Sublime Atom, but I'm told that this behavior is not accepted text-editor behavior, so no can do. Thanks a freakin' lot, guys.

      Hummm... that almost sounds a bit like code-folding. VIM and emacs has a form of this, but I don't think it's as complex as you are alluding to with TextWangler.

      Emacs and VIM allow folding based on the line(s), not based on character position, which honestly is a freakingly wonderful feature that now that you mention it I can see some amazing uses for.

      Great, now I have to look up this editor and play with it. You're such a bastard.

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Code Teachers?

      @Tat said in Code Teachers?:

      @Taika said in Code Teachers?:

      @Lithium - Yeah, but if you can't think of how to get to that pretty chart you want to code (what attributes to pull, how to order them, adding commands to set new ones, etc), you won't get far either, I would think?

      I actually think that developing this - learning how to /design/ the code, how to break it into all the pieces you want, and conversely, learning how to troubleshoot it to find the pieces that are broken - is the hardest thing to teach when it comes to coding.

      There will always be some adjusting along the way, but if you can learn to tackle this early on, to design well, to think about your product in pieces and then to break those pieces down into pieces, you'll do much better. And it's much easier to tackle one cog than the whole machinery at once.

      The best way to learn to code, in my opinion, is to pick a project and start. Just go. Stare at other people's stuff, maybe start by making adjustments. Change a color, add a column, see what breaks and fix it. Then do a simple command. A +who, a +finger. It's impressive how fast it gets complicated.

      If you can find a mentor who you can ask questions of, even better. I often find that by talking someone else through my sticking point, I solve it myself (this is actually a thing - google 'Rubber Duck Debugging). Even typing up a post on a forum can help you find that spot. But it's also really useful to have someone who can point you in the direction of stuff you didn't know existed, or to just explain @switch to you in a way that makes sense, or whatever dumb (or not dumb) thing you need.

      But the vast majority of learning to code is just coding.

      Pro tip: Keep a copy of the old code until you're REALLY SURE nothing important is broken.

      This is one of the big reasons I'm trying to get the PennMUSH and MUX coders to add parenmatch() from Rhost to the codebases.

      It's exceptionally nice as it color-codes the parenthesis, braces, and brackets via matching, or red-highlights missmatches. It also has a pretty-print option that breaks up the commands and functionality to make it easier to walk the code in question.

      The first line is the contents of the 'VC' attribute.
      The second line is the output of [parenmatch(me/vc)]
      The third and later lines is the output of [parenmatch(me/vc,,1)]

      As for how I tend to code, I found this is the best method (for myself) and works well.

      Picture how you want the final product. The output, the user-interface, every aspect of it.

      Then you ask yourself these questions:

      1. How do I design this so that if I need to come back to it a year from now and add new features, it can be done with the least amount of work, because I'm a lazy bastard.
      2. How can I design this so that when I come back to it a year later, I can understand what the hell I was smoking when I wrote it and not have to spend much time to get re-acquainted with it, because again, I'm a lazy bastard.
      3. When I write my code, to get the end results, what is the functions and commands that I can use that will amount to the least work involved to design it, because I'm a lazy bastard.
      4. When I organize my code, it should be modular, so I should split commands, data, and functions likely on different objects so that I don't have to worry about cruft when future addons are done.
      5. The storage will likely change a lot, so I should prepare for methods to keep the data consistent and ways to clean out old or bad data.
      6. When I design the way the information is stored, I should always leave room to allow quick and easy changes, additions, and removals.
      7. The way everything works should be easy for someone else to pick up on, incase I get hit by a bus, or more importantly when Fallout 5 comes out and demands my attention from the horrors of dealing with whiney players and demanding co-staff... er... I mean when Fallout 5 comes out... cough.

      Basically, I work backwards, find out what I need or want to have happen, work up a list of all the features and functions and commands it'll take to get me there, then code backwards to get to the starting point. I find it easier that way.

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Code Teachers?

      @Lithium said in Code Teachers?:

      I keep wanting to ask you to code for me but I know how many games you are tied to and I should do it myself anyways.

      Well, real life and work has bit me hard, so I am taking a small vacation from mushing for a minimum of a few months to a maximum of a year. Soooo... if you're serious, hit me up toward the end of this year and I'll put you to the top of my free list and see if I can't lend a hand for any mush you want to start up.

      Long as you stick to MUSH I can help you. My MOO-fu, MUCK-fu, and Evennia-fu is weak 🙂

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Code Teachers?

      @Taika

      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)

      1. Everything in mush starts as a command. Think of each command as their own separate sandbox. Each command has it's own 'resources'. Each command is executed linearly in a single-thread. Each command is able to have their 'environment' modified by functions. Functions will, with few exceptions, manipulate that command and arguments to that command which brings up. You can chain commands one after the other with a ';'. Each time a command is executed, it pushes onto a command queue stack. If you have a command call a SECOND command. Then you have two levels of command queue stacks. So for example:
      @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.

      1. 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

      2. 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...

      3. 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

      4. 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...

      5. 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...

      6. 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...

      7. 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...

      8. 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...

      9. 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 🙂

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Dune Coda Stuff

      @Sunny said in Dune Coda Stuff:

      @Ataru

      There IS a way to fix it. I don't remember what it is, but it is possible, never fear. Somebody will be able to tell you how to do it, as someone was once able to tell me.

      Until then...someone else may have done this before. I feel your pain. ^^

      If it's a RhostMUSH, you can use a conf file parameter to reset #1's password.

      add to the netrhost.conf file:

      newpass_god 777

      It resets #1's password to the default 'Nyctasia'.

      Once you've @rebooted your system for this, you should naturally remove this entry from your netrhost.conf, or it'll keep repasswording #1 🙂

      posted in Mildly Constructive
      Ashen-Shugar
      Ashen-Shugar
    • Myrddin CRON - Fix for Possible Missed Trigger Events

      Myrddin's Cron is more or less the defacto standard for crons, however, it has a failure possibility of missing a triggering event if the time it's meant to trigger the mush happens to be lagging or, for example, the server hosting has ntpd running and skews the time where the mush is advanced a period of time.

      This will fix both of those issues and guarentee a per minute trigger, and the mush will play catchup in either case.

      This will only work with a codebase that handles @wait/until

      Please modify your myrddin cron with these entries:

      @startup mushcron=@trigger me/cron=[secs()]
      
      &CRON mushcron=@break [!$v(0)]=@pemit/list #1 %#=Must start up [name(me)] by triggering the startup.;@trigger me/cronjobs=%0; @wait/until [add(%0,60)]={@trigger me/cron=[add(%0,60)]}
      
      &CRONJOBS mushcron=@dolist [setq(8,convsecs(%0))][setq(1,extract(%q8,2,1))][setq(2,extract(%q8,3,1))][setq(3,extract(%q8,1,1))][setq(4,extract(extract(%q8,4,1),1,1,:))][setq(5,extract(convsecs(%0),2,1,:))][lattr(me/cron_time_*)]={@switch and(or(member(extract([setq(0,v(##))]%q0,1,1,|),%q1),not(strlen(extract(%q0,1,1,|)))),or(member(extract(%q0,2,1,|),%q2), not(strlen(extract(%q0,2,1,|)))),or(member(extract(%q0,3,1,|),%q3),not(strlen(extract(%q0,3,1,|)))), or(member(extract(%q0,4,1,|),%q4), not(strlen(extract(%q0,4,1,|)))),or(member(extract(%q0,5,1,|),%q5),not(strlen(extract(%q0,5,1,|)))))=1,{@pemit #1=Triggering CRON_JOB_[extract(##,3,1,_)]; @trigger me/cron_job_[extract(##,3,1,_)]=[setq(t,%0)][last(%q0,|)]}}
      
      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Trend Statistics for RhostMUSH

      @Thenomain said:

      Nah, what's going to suck is turning things like $-2s$-2s $-2s$-2s $-2s$-2s $-2s$-2s $-2s$-2s $-2s$-2s $-2s$-2s $-2s$-2s $-2s$-2s $-2s$-2s $-2s$-2s $-2s$-2s into English.

      Mmm, it's not that bad. It works a lot like the hardcoded printf() command.

      To break it down:

      $ means the start of a substitution
      -- means left justify (default is right justify)
      ^ means center justify
      2 means 2 character alignment (auto-cut's off unless specified otherwise)
      s means the end of the substitution.

      If no number is specified for the $s pair (ergo, you just have $s) it just prints the value without any justification.

      So putting it together $-2s means 'Start substitution, left justify to 2 characters'

      For every $...s pattern you have one argument.

      so:

      printf(|$-2s|$-5s|$^20s|$s|,arg 1, arg 2, arg 3, arg 4)
      

      Will return:

      |ar|arg 2|       arg 3        |arg 4|
      

      You get the hang of it when you work with it some.

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Rhost Setup

      @Vale said:

      I have a rather old Rhost flat file for a MU* I would like to bring up, but I don't have strong server side skills at all. It may be a simple install or possibly trickier, but I'll be happy just to see it working.

      Would anyone out there be willing to help me get this running?

      Put the flatfile where you know where it is. Let's say for giggles your home directory is:
      /home/farble

      The flatfile should be called netrhost.db.flat

      So the flatfile location will be /home/farble/netrhost.db.flat

      Pull the latest Rhost source:

      git clone https://github.com/RhostMUSH/trunk Rhost

      Compile the code:
      cd Rhost/Server
      make confsource

      This will pull up this menu:

                             RhostMUSH Source Configuration Utility
      
      ------------------------------------------------------------------------------
      [X]  1. Sideeffects        [X]  2. MUSH/MUX u()/zfun  [X]  3. MUX inc()/dec()
      [X]  4. Disabled Comsys    [#]  5. ANSI SUBS (menu)   [X]  6. crypt()/decrypt()
      [X]  7. +help hardcoded    [X]  8. MUX @program       [ ]  9. COMMAND flag
      [X] 10. ~/_ attributes     [X] 11. Reality Levels     [X] 12. a-z setq support
      [X] 13. Enhanced ANSI      [X] 14. Marker Flags       [X] 15. Bang support
      [ ] 16. Alternate WHO      [X] 17. Old SETQ/SETR      [X] 18. Secured Sideeffects
      [ ] 19. Disable DebugMon   [ ] 20. Disable SIGNALS    [ ] 21. Old Reality Lvls
      [ ] 22. Read Mux Passwds   [ ] 23. Low-Mem Compile    [ ] 24. Disable OpenSSL
      [X] 25. Pcre System Libs   [X] 26. SHA512 Passwords
      --------------------------- Beta/Unsupported Additions -----------------------
      [#] B1. MySQL Support      [ ] B2. Door Support(Menu) [ ] B3. 64 Char attribs
      [ ] B4. SQLite Support     [X] B5. QDBM DB Support    [#] B6. LBUF Settings (Menu)
      ------------------------------------------------------------------------------
      
      Keys: [h]elp [i]nfo [s]ave [l]oad [d]elete [c]lear [m]ark [b]rowse [r]un [q]uit
            [x]tra default cores (MUX, TinyMUSH3, Penn, Rhost-Default)
            Or, you may select a numer to toggle on/off
      
      Please Enter selection:
      

      It pulls up a nice menu and just selection various options you want. The default values are nice, but you likely want B3, B6 (drill down and select 8, 16, or 32K lbufs. 64k works, but can have issues as some older routers have a 32K tcp buffer and packets can be lost).

      Any other option should be fine to play around with but the rest are usually fine for defaults.

      Hit 'r' (run) to run with the options and compile the code.

      Once it's compiled, modify your netrhost.conf file to change the port, mud name, master room, and anything else you need to that matches up with your flatfile.

      Once you have modified your netrhost.conf file, you have two ways to load the flatfile.

      Option 1. (from the game directory)
      ./Startmush

      This will prompt you if you're starting a new game (as it detects no flatfile) and when you say 'Y" it will prompt you for the FULL PATH AND NAME of your flatfile. In the above example this would be /home/farble/netrhost.db.flat

      Option 2. (from the game directory)
      ./db_load data/netrhost.gdbm /home/farble/netrhost.db.flat data/netrhost.db.new
      ./Startmush

      Either option works, but for both instances you need to give it the full path to where you have the flatfile.

      It should automatically load your RhostMUSH flatfile regardless of the age it is. Rhost's db format hasn't changed in 25 years. We believe in backward compatibility.

      That should work! If you have issues, head to the RhostMUSH dev site and someone there (who's not idle * grin *) will be able to help you.
      Rhost devsite: iweb.localecho.net 4201

      Good luck!

      posted in MU Questions & Requests
      Ashen-Shugar
      Ashen-Shugar
    • RE: Trend Statistics for RhostMUSH

      @Thenomain said:

      @Ashen-Shugar

      That's what it looked like, it was just odd to see.

      It's the fprint() that is going to be so babies.

      Absolutely. Penn has the closest chance of making it work with align(), but sadly align() doesn't offer some things that printf() does, like having multi-char fillers for different columns in the same command. That's gonna suck. 😕

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • RE: Trend Statistics for RhostMUSH

      @Thenomain said:

      It looks at very first blush that the only block to getting this on Mux is the use of fprint(). I could not find the help file that explained 'and(!!$...)', but I can see how it's being used so can do the same thing with 'strcat()'.

      The !!$ can be reproduced likely with t(). It's a bit of pre-parser voodoo.

      BANG NOTATION
      Bang notation allows you to use '!' and '!!' in functions for 'not' and
      'not-not' functionality. This works similiarilly to the C equivelant of
      using 'bangs'. You may also specify '!$' and '!!$' for FALSE or TRUE
      conditions on functions that return string values. Finally, you may
      specify '!^' and '!!^' for true-boolean FALSE or TRUE conditions on
      functions that return true-boolean based on the function t()'.

      Example:
      > say match(one two three four five,four)
      You say "4"
      > say !match(one two three four five,four)
      You say "0"
      > say !!match(one two three four five,four)
      You say "1"
      > say !!$grab(this is a test,was)
      You say "0"
      > say !!$grab(this is a test,this)
      You say "1"
      > say !!^space(1000) (spaces are non-boolean strings)
      You say "0"
      > say !!$space(1000) (spaces are not-null strings)
      You say "1"

      posted in MU Code
      Ashen-Shugar
      Ashen-Shugar
    • 1
    • 2
    • 10
    • 11
    • 12
    • 13
    • 14
    • 13 / 14