What is out there? Hard and soft codebases of choice.


  • Coder

    @Griatch said in What is out there? Hard and soft codebases of choice.:

    Allow me to update @Thenomain's list of "things". The list of things you need to know to be a beginner Evennia user is, IMO, as follows:

    [...]

    • You need to know how to use a text editor and how to switch between windows in your OS. For seeing the results in-game you need a web browser or telnet client of your choice.

    This is such a strange addition to the list, and I at first thought you were being a bit sarcastic and/or bitter. I'm pretty sure you're not, but, well, this is Soapbox. I never know.


    I did have one question: How easy is it to remove @ from some of the global commands? The more I purge '+' from my own code, the stranger it seems. I'm guessing "bloody easy".


  • Coder

    @Thenomain said in What is out there? Hard and soft codebases of choice.:

    @Griatch said in What is out there? Hard and soft codebases of choice.:

    Allow me to update @Thenomain's list of "things". The list of things you need to know to be a beginner Evennia user is, IMO, as follows:

    [...]

    • You need to know how to use a text editor and how to switch between windows in your OS. For seeing the results in-game you need a web browser or telnet client of your choice.

    This is such a strange addition to the list, and I at first thought you were being a bit sarcastic and/or bitter. I'm pretty sure you're not, but, well, this is Soapbox. I never know.

    The need for a text editor is a difference to what is needed for writing mushcode, hence the inclusion. I guess the need for the browser/telnet client is a bit superfluous though.

    I did have one question: How easy is it to remove @ from some of the global commands? The more I purge '+' from my own code, the stranger it seems. I'm guessing "bloody easy".

    It's normally easy to overload a default command by name. Since we in this case want to replace the default command with the same functionality but with a different name (key) we need to unload the old and then add it again with the new key.

    First overload the original implementation of, say @reload. All we need to change is the Command's key.

    # in, say your commands/command.py module
    from evennia import default_cmds
    class CmdReload(default_cmds.CmdReload):
        key = "reload"  # instead of @reload
    

    The @reload command is by default made available through the Player command set. So we remove the old command from the command set and add in our new renamed one. This file is already pre-filled when you install Evennia, we just have to add the lines doing what we want:

    # in commands/default_cmdsets.py 
    # [...]
    from commands import command
    class PlayerCmdSet(default_cmds.PlayerCmdSet):
        def at_cmdset_creation(self):
            # [...]
            # remove the default one, add our custom one:
            self.remove(default_cmds.CmdReload)
            self.add(command.CmdReload())
    

    Then do @reload (for the last time) and you will henceforth be using reload instead.
    .
    Griatch


  • Coder

    @Griatch said in What is out there? Hard and soft codebases of choice.:

    It's normally easy to overload a default command by name. Since we in this case want to replace the default command with the same functionality but with a different name (key) we need to unload the old and then add it again with the new key.
    [snip]

    Hum. While it does seem fairly straight forward, I can say without reservations that unless I had a fairly good grasp of how Evennia worked at the under-hood I would have spent some time digging into how to do this.

    How much harder would it be to overload a default command by evaluation?

    Say I want 'command' to do this 'other command' but only on these set of conditions?

    Is that possible or would it add a lot more complexity to this?


  • Coder

    @Ashen-Shugar said in What is out there? Hard and soft codebases of choice.:

    @Griatch said in What is out there? Hard and soft codebases of choice.:

    It's normally easy to overload a default command by name. Since we in this case want to replace the default command with the same functionality but with a different name (key) we need to unload the old and then add it again with the new key.
    [snip]

    Hum. While it does seem fairly straight forward, I can say without reservations that unless I had a fairly good grasp of how Evennia worked at the under-hood I would have spent some time digging into how to do this.

    Sure, this is why one of the first beginner tutorials cover how Commands and Command sets work and tie together. And if you just wanted to replace the functionality of the command (not change its main identifier) you wouldn't need to remove the old command but just add the new one - it will then simply replace the old same-named one.

    How much harder would it be to overload a default command by evaluation?

    With "evaluation", do you mean to overload it conditionally? This is one of the purposes of Command sets - you can add and remove them non-destructively to build up the set of commands a user have available at any given moment. To add a new command set (with any number of commands in it), to a character for example:

    character.cmdset.add("commands.command.myCmdSet")
    

    (rather than giving the path you could also add the actual cmdset if you have it imported). This you can put in a condition as you please.

    The commands in that command sets will now dynamically replace same-named commands already available to character. You can control this replacement in detail using different merge strategies and merge-priorities (often not needed though). An example is the tutorial Red Button, which when you press it blinds you (for a short while) by replacing your command set with one whose commands only echo back that you can't see anything.

    Say I want 'command' to do this 'other command' but only on these set of conditions?

    Is that possible or would it add a lot more complexity to this?

    You mean, having one Command fire up another Command? That is just a matter of using execute_cmd on the one using the command (self.caller) .

        from evennia import Command
        class ThisCmd(Command):
            key = "thiscmd"   
            def func(self):
                # if (say) our location has some
                # particular flag set, run another command
                if self.caller.location.db.do_othercmd:
                    self.caller.execute_cmd("othercmd") 
    

    Of course, func can hold any code. All details about the Command (like who called it, what string was used, its arguments etc) are set as properties directly on the Command at run-time, making them easily accessible without any boilerplate.
    .
    Griatch


  • Coder

    @Griatch said in What is out there? Hard and soft codebases of choice.:

    Say I want 'command' to do this 'other command' but only on these set of conditions?

    Is that possible or would it add a lot more complexity to this?

    You mean, having one Command fire up another Command? That is just a matter of using execute_cmd on the one using the command (self.caller) .

    Mmm, not exactly.

    I'm saying let's say you have a built in command called 'bob'.

    I want 'bob' to be available to everyone, as it's a built in.

    However, on the condition of a full moon, between the times of midnight and 3am, I want players with a race of 'WOLF' to do an entirely different feature set by typing 'bob' at the same time that everyone else can still use the normal 'bob', which, of course, returns to the normal 'bob' after the conditions have elapsed.

    How hard would something like this be?


  • Coder

    @Ashen-Shugar said in What is out there? Hard and soft codebases of choice.:

    However, on the condition of a full moon, between the times of midnight and 3am, I want players with a race of 'WOLF' to do an entirely different feature set by typing 'bob' at the same time that everyone else can still use the normal 'bob', which, of course, returns to the normal 'bob' after the conditions have elapsed.

    Figured this would be a good chance to contrast Evennia and Ares' philosophy for command handling.

    Ares has the Engine (which provides core services) and Plugins (which handle commands, events, and data storage).

    One of the core services provided by the Engine is command dispatching. When a player types a command, the Engine goes through each of the Plugins asking "do you want to handle this?" until it finds one that does. It then executes a Command Handler provided by the Plugin. If nobody wants the command, you get the usual "Huh?" message.

    Most Plugins implement a very straightforward if/else or case statement based on the command root and switch. For example:

    Who Plugin:

          case cmd.root
          when "where"
            return WhereCmd
          when "who"
            return WhoCmd  
          else
            return nil   # I don't want it, move on to the next plugin
          end
    

    Mail Plugin:

          case cmd.root
          when "mail"
            case cmd.switch
            when "send"
              return MailSendCompositionCmd
            when "start"
              return MailStartCmd
            ... etc ...
          else
            return nil   # I don't want it, move on to the next plugin
    

    But Plugins could also do more sophisticated dispatching. You could have a command that only got handled if the enactor is a Wolf character in the Special Room on a Tuesday.

    You can also do that sort of check inside the Command Handler itself. For example, you could have the BobCmd do something like:

    BobCmd handler:

    def handle
        if (you're a Wolf in the Special room on a Tuesday)
           do something
       else
          do something else
        end
    end
    

    It's not as elegant as Evennia's command sets, and it doesn't follow the old MU* strategy of letting you tie those command sets directly to rooms or characters, but I like to think it's pretty straightforward and easy to understand/extend. I hope?

    Two other things worth noting:

    • Ares by default ignores the prefix (+, @, &, /) in front of commands. So who is the same as +who is the same as @who.
    • ALL commands are handled by the plugins, even ones that were old-school 'hardcoded' commands like movement, pages, poses, help, etc. This allows you to override/replace/extend any game command without having to do who vs +who or help vs +help.

  • Coder

    @faraday said in What is out there? Hard and soft codebases of choice.:

    It's not as elegant as Evennia's command sets, and it doesn't follow the old MU* strategy of letting you tie those command sets directly to rooms or characters, but I like to think it's pretty straightforward and easy to understand/extend. I hope?

    Two other things worth noting:

    • Ares by default ignores the prefix (+, @, &, /) in front of commands. So who is the same as +who is the same as @who.
    • ALL commands are handled by the plugins, even ones that were old-school 'hardcoded' commands like movement, pages, poses, help, etc. This allows you to override/replace/extend any game command without having to do who vs +who or help vs +help.

    Meh, don't sell yourself short. I like the fact it's in a centralized place and allows full levels of overriding.

    What would be a consideration as you design is a plugin parser of sorts. So that someone that runs Ares who has this 'nifty neato code' can just give the module code for the override, and not the modified command-set itself.

    so something like oh...

    if cmd.blah
       when is module.cmdname
       do that command
    else if command is blah
       do this
    else if command is blah
       do that
    ...
    

    So essentially it checks a module name based on the command being executed as an override, then calls the file. This allows some customization and modular plugins that people can literally plug and play.

    And of course a method to call multiple modules for the same command based on conditions and so forth.

    I think something like that would be a great boon, as people from historical reasons really dislike hacking around the core code and much prefer to write external modules that they can just plug in and go as an override.

    Also excuse my example, I'm not a ruby-head :)


  • Coder

    @Ashen-Shugar Thanks. To your point, I think I left out something important: The game/plugins directory contains all of the plugin code. When you first install Ares, it has the default plugins. If you want to change one, you just... change it. Again, it's simplicity over elegance. Rather than "overriding" functionality, you just replace or change it directly.

    Also, the commands are handled within the plugins themselves so you can easily remove an entire swath of command handling just by disabling that plugin. More elaborate example: Mail Plugin vs Who Plugin.

    Edit to add due to reading comprehension fail: I get what you're saying about people being leery of hacking core code, but Ares is really designed with the intention that you will. If it really concerns you, though, you can absolutely just insert your own custom stuff at the beginning of a plugin's command dispatcher, effectively bypassing what was there to begin with.


  • Coder

    Ah, ok. So I'll give two possible ways to do this; first the in-command "head-on" way and then using cmdsets.

    Head on way - command with ifs

    This means simply that we create the command Bob and have it check if we are in the given time slot or not. Since presumably the Wolf race has unique features (code-wise) we assume it's created as a separate Python class (let's say its path is typeclasses.wolves.Wolf). If Wolves were, say, just members of some biker gang (so human like other humans, code-wise) we could have instead just used a Tag to tag them as "Wolf" to identify them.

    # in a module, say, "commands.bob.py"
    from evennia import Command
    from evennia.utils import gametime
    
    def check_full_moon():
        # let's assume every 30 days in game-time is a full moon
        # I can't be bothered doing the logics for limiting it to 0-3AM but
        # it would happen here.
        return (gametime.gametime() * 3600 * 24) % 30 == 0
    
    class CmdBob(Command):
        key = "bob"
        def func(self):
            if self.caller.is_typeclass("typeclasses.characters.Wolf") and self.caller.check_full_moon():
                # do Wolf stuff 
            else:
                # do non-Wolf stuff
    

    Next just add Bob to the Character Command set, which all characters start out having. Again, most of the code was already filled out by Evennia from the start, so one plugs in the command where indicated.

    from commands import bob
    class CharacterCmdSet(CmdSet):
        # [...]
        def at_cmdset_creation(self):
            # [...]
            self.add(bob.CmdBob())
    

    After a @reload the "bob" command is available and will behave differently for wolves. Now this is straight-forward and may well be enough for your needs. It has some maintenance problems though. Say you have other classes like Druid, Fae and Moon dragon that all have special things happen during a full moon. You now have to expand CmdBob to account for all those. What if it's not just bob, but a whole slew of commands that should change like this? You would need to update them all. So far it's certainly doable. But then what happens if Wolves lose their special Bob when someone casts a spell or hits them with silver? You would then have to expand on your if statements. To be clear - this may well be ok for your game. But it may also be easy to forget to update a particular condition and the code could become hard to read and maintain.

    CmdSet way

    This will instead implement two versions of the Bob command, the normal one and the Wolf one.

    # in a module, say, "commands.bob.py"
    from evennia import Command, CmdSet
    class CmdBob(Command):
        key = "bob"
       def func(self):
           # do normal bob stuff
            
    class CmdBobWolf(Command):
         key = "bob"
         def func(self):
             # do wolf-bob stuff
    
     class CmdSetWolf(CmdSet):
         def at_cmdset_creation(self):
             self.add(CmdBobWolf())
    

    Note that if CmdBobWolf shared a lot of features with the normal CmdBob we could have inherited from it and just replaced some things. We also create a new cmdset CmdSetWolf only holding this single command (for now). We add the normal CmdBob to the CharacterCmdSet as shown earlier.

    Next we will use a Script to track time. A Script is a sort of virtual object that has no existence in-game. It can store data etc like an in-game object but also has an in-built timer.

    from evennia import Script
    from typeclasses.wolves import Wolf 
    from commands import bob
    class  MoonScript(Script):
        key = "moonscript"
        interval = 60 * 60  # calls self.at_repeat every hour
        persistent = True # will survive a shutdown
        self.db.is_full_moon = False
    
        def at_repeat(self):
             # fires every self.interval seconds
             if check_full_moon():                
                if not self.db.is_full_moon:
                    self.db.is_full_moon = True
                    # find all wolves and let the wolf-bob cmdset merge onto
                    # the existing one. All this will do is to change how "bob" works.
                    for wolf in Wolf.objects.all():
                        wolf.cmdset.add(bob.CmdSetWolf)
            elif self.db.is_full_moon:
                # the full moon passed.
                self.db.is_full_moon = False
                for wolf in Wolf.objects.all():
                    wolf.cmdset.remove(bob.CmdSetWolf)
    

    So what the Script does is that it will check every hour if there is a full moon, and if so add the CmdSetWolf to all wolves in the game. When the check fails it removes it again, restoring the default "bob" command. In a real game you will probably let your Weather or Calendar script do this job, alongside announcing to the world that the full moon has risen.

    Using cmdsets rather than if statements in one command has the advantage of containment: You could store everything wolf-related in one place, in relative isolation from others. Sure, there may be details that still require some if checks but by replacing the entire command you could plug in the command in new situations without changing of the command code.

    So if a Druid casts a spell on the Wolf, all you now need to do is to call wolf.cmdset.remove(bob.CmdSetWolf) on the wolf to have it loose all its moon-given powers at once. Importantly, if the wolf meanwhile has sipped a magical potion having it gain the AwesomeFlyingCmdSet (giving say the "fly" and "leap" commands), removing the CmdSetWolf will only remove that cmdset. The normal "bob" command will be used but "fly" and "leap" will remain until the Druid uses their next spell ...

    This also exposes a limit with the CommandSet system - you operate on Cmdsets, not on individual Commands (one Command could go into many different cmdsets). So if you have many commands in CmdSetWolf but only wanted to remove one of them, you'd be out of luck. For that level of precision you'd either have to fall back to doing if-checks in the command, use cmdsets with one Command each or overload the cmdset anew with the changed command structure.
    .
    Griatch


  • Coder

    @Griatch

    So passive conditions can't trigger command assignment? Leading to a third answer: The coder creates a system that loads all the possible "bob" commands, via a walk thru of the directory looking for 'bob-Werewolf.py', etc., maintaining add-on flexibility. Even that leaves my mouth dry, but I can envision too many scenarios where waiting even one minute for a command to become available is a downfall.


  • Coder

    @faraday

    Going full-on global commands is an interesting take. The example looks very clean! The concept of looping over all commands to find one that matches is simple to explain and use; do you do any pre-parsing to weed the loop or is it simply so fast it doesn't matter (I presume the number of commands is not big enough to be a problem). Does the system complain if there are multiple same-named commands (in different plugins, say) or will it take the first one every time?

    Having people edit the core in-place makes me a little twitchy though I admit. Many years ago Evennia had things set up so it was natural for people to edit things in-place (the game folder was a part of our repo instead of being created on-demand). We found that we couldn't make changes to upstream without users seeing merge clashes all over and reporting errors we could not reproduce - since their version of core was slightly different from ours. These days we make things pluggable and tell people not to mess with core until they are making an Evennia PR. A lot less headaches for everyone involved.

    @Thenomain said in What is out there? Hard and soft codebases of choice.:

    @Griatch

    So passive conditions can't trigger command assignment? Leading to a third answer: The coder creates a system that loads all the possible "bob" commands, via a walk thru of the directory looking for 'bob-Werewolf.py', etc., maintaining add-on flexibility. Even that leaves my mouth dry, but I can envision too many scenarios where waiting even one minute for a command to become available is a downfall.

    The way to do this is to catch when the passive condition changes. Evennia has something called a MonitorHandler one could use for this, but here's a pure-Python solution, assuming the property in question is .wolf_form.

    from evennia import Character
    from commands.wolf import WolfCmdSet
    class Wolf(Character):
        # [...]     
       # create a property .wolf_form that updates the cmdset when assigned
        def _get_wolf_form(self):
            return self.cmdset.has(WolfCmdSet)
        def _set_wolf_form(self, do_swap):
            is_wolf = self.cmdset.has(WolfCmdSet):
            if do_swap:
                if not is_wolf:
                    self.cmdset.add(WolfCmdSet)                   
            elif is_wolf:
                self.cmdset.remove(WolfCmdSet)           
        wolf_form = property(self._get_wolf_form, self._set_wolf_form)
    

    You will now be able to do character.wolf_form = True/False and have the cmdset state swap on-demand for you. You will also be able to do stuff like if character.wolf_form: ... to check if they are currently in wolf form (that is, have the WolfCmdSet on them).

    Edit: But if with "passive condition" you mean something like "at the moment of entering bob, if this condition is True then get back this version of the command, otherwise this other version", then you need to do a little more work:

    You could solve this by adding all your conditional commands to the cmdset and tell them not to merge but to remain separate (but same-named) in the set. You then plug in your own MULTIMATCH_ERROR handler. When you use "bob" you will then get multiple possible command-matches. The normal result on a multimatch is to give you a list of commands and let you pick the one you want to use (it may matter if you are using the "push" command on the red or blue button after all). But your multimatch handler could instead check the condition and run only the command the condition dictates.
    .
    Griatch


  • Coder

    @Griatch Yeah, I did experiments with the command looping and performance was not an issue. The dispatcher goes with the first plugin that wants it, so it's on the coder to avoid command name duplication.

    As for merge conflicts - absolutely those can happen. But I think by making it pluggable you're just trading one kind of headache for another. For starters, it's more complexity for the designer to worry about. Also, if someone makes a custom version of the Bob command and you make an upstream change to the core Bob command, then they've got a philosophical merge conflict whether they've modified BobCmd or overridden it with MyBobCmd. Editing in place allows you to use the built-in git merge tools to resolve trivial conflicts automatically, and gives you help in resolving more complex ones.

    Also we've got different user bases. A lot of my target audience won't be modifying the commands at all (since they're using Ares because they lack a coder) or just won't bother upgrading. So it's quite possible that your strategy works best for Evennia. It's a question of tradeoffs.


  • Pitcrew

    As someone who has now used Evennia a good deal as a player on Arx and Ares a little bit as a brief player on Faraday's game, I'd LOVE if Evennia had the same thing as Ares where all the commands don't have prefixes. Like, even the basic globals set up in Evennia now have some with @ by default and some without. Just knock everything off. Why not at least standardize so they all start the same? There are some touches in Ares like that that really seem to be specifically about "Making things easier/simpler/more streamlined for the user."

    (Also, letting players set a color for quoted text like Ares officially does now would be the bEST.)


  • Coder

    @faraday said in What is out there? Hard and soft codebases of choice.:

    As for merge conflicts - absolutely those can happen. But I think by making it pluggable you're just trading one kind of headache for another. For starters, it's more complexity for the designer to worry about. Also, if someone makes a custom version of the Bob command and you make an upstream change to the core Bob command, then they've got a philosophical merge conflict whether they've modified BobCmd or overridden it with MyBobCmd. Editing in place allows you to use the built-in git merge tools to resolve trivial conflicts automatically, and gives you help in resolving more complex ones.

    Sure, I can see both points of that argument. I can certainly see a nice hacking potential your way (in a good way). The thing with the "philosophical" merge conflict is however that if there are things that don't work you can always revert to "vanilla" Evennia to figure out if the problem you are having is in your code or not. Likewise, since we offer (defacto) user help and support, it helps a lot to be able to say "I'm using the same Evennia version you are and I can't reproduce your problem" - and be sure of the boundaries between upstream and custom code.

    Also we've got different user bases. A lot of my target audience won't be modifying the commands at all (since they're using Ares because they lack a coder) or just won't bother upgrading. So it's quite possible that your strategy works best for Evennia. It's a question of tradeoffs.

    Certainly. Ares (from what I gather) uses a command syntax that your user base already knows and expects and may not be likely to change as you say. If you don't expect heavy customization of your command structure or syntax there is little need to cater for it.
    .
    Griatch


  • Coder

    @Roz said in What is out there? Hard and soft codebases of choice.:

    As someone who has now used Evennia a good deal as a player on Arx and Ares a little bit as a brief player on Faraday's game, I'd LOVE if Evennia had the same thing as Ares where all the commands don't have prefixes. Like, even the basic globals set up in Evennia now have some with @ by default and some without. Just knock everything off. Why not at least standardize so they all start the same?

    The default Evennia commands are inspired by MUX and that's where the @ comes from. Consistently, all commands related to building or administration use @ while in-game commands like look, get, inventory etc. do not. It would be simple to have the default commands accept both @ and -not though; just have an alias for the non-@ version. Does Ares list the commands with @ (but accept without too) or are they listed without @ (but accepts one anyway) ?

    There are some touches in Ares like that that really seem to be specifically about "Making things easier/simpler/more streamlined for the user."

    (Also, letting players set a color for quoted text like Ares officially does now would be the bEST.)

    The default Evennia commands are pretty low on coloration, admittedly. They are intentionally bland since they are intended to be customized per-game. So technically you should direct this request to @Tehom if you want it in Arx. :) But that said - since all is in place for allowing players to customize things like that, maybe it would be an idea to support it out of the box in vanilla Evennia too.
    ·
    Griatch


  • Pitcrew

    @Griatch said in What is out there? Hard and soft codebases of choice.:

    @Roz said in What is out there? Hard and soft codebases of choice.:

    As someone who has now used Evennia a good deal as a player on Arx and Ares a little bit as a brief player on Faraday's game, I'd LOVE if Evennia had the same thing as Ares where all the commands don't have prefixes. Like, even the basic globals set up in Evennia now have some with @ by default and some without. Just knock everything off. Why not at least standardize so they all start the same?

    The default Evennia commands are inspired by MUX and that's where the @ comes from. Consistently, all commands related to building or administration use @ while in-game commands like look, get, inventory etc. do not. It would be simple to have the default commands accept both @ and -not though; just have an alias for the non-@ version. Does Ares list the commands with @ (but accept without too) or are they listed without @ (but accepts one anyway) ?

    The latter, as I recall. Everything is just listed without prefix, but they all will take @ and + (as Faraday described). It just gave me a moment of zen because like -- I just hate prefixes at this point. I hate the weird "some have @ and some have + and some have nothing" thing that's just become so common. (Yes, I know the original reason for it, but it's still just archaic to me at this point.) I think how Ares handled it was, yes, a little different than how things have looked, but cleaner (and also still takes the commands people are used to, so it doesn't get in the way of actual habitual usability).

    There are some touches in Ares like that that really seem to be specifically about "Making things easier/simpler/more streamlined for the user."

    (Also, letting players set a color for quoted text like Ares officially does now would be the bEST.)

    The default Evennia commands are pretty low on coloration, admittedly. They are intentionally bland since they are intended to be customized per-game. So technically you should direct this request to @Tehom if you want it in Arx. :) But that said - since all is in place for allowing players to customize things like that, maybe it would be an idea to support it out of the box in vanilla Evennia too.

    I THINK IT'D BE PRETTY AWESOME. I think a lot of folks would agree, too. It's such a big help in scenes. (I have it set client-side with a regexp highlight on Atlantis at this point.)


  • Coder

    @Griatch said in What is out there? Hard and soft codebases of choice.:

    The default Evennia commands are inspired by MUX and that's where the @ comes from. Consistently, all commands related to building or administration use @ while in-game commands like look, get, inventory etc. do not. It would be simple to have the default commands accept both @ and -not though; just have an alias for the non-@ version. Does Ares list the commands with @ (but accept without too) or are they listed without @ (but accepts one anyway) ?

    Ares lists all commands with no prefix at all in help files and whatnot. Unless you explicitly make a command look for a prefix (@, &, /, +), Ares just ignores it completely.

    This is, incidentally, why the default Ares config renamed the public chat channel to "Chat" instead of "Public", to avoid the obvious mav-prone confusion of p for page and +p for public :)

    Edit to add: Codewise Ares breaks the command up into (prefix)root(page#)(/switch) (args). So all the built-in commands only look at cmd.root but you could make one look at cmd.prefix if you really wanted.


  • Coder

    @faraday said in What is out there? Hard and soft codebases of choice.:

    @Griatch said in What is out there? Hard and soft codebases of choice.:

    The default Evennia commands are inspired by MUX and that's where the @ comes from. Consistently, all commands related to building or administration use @ while in-game commands like look, get, inventory etc. do not. It would be simple to have the default commands accept both @ and -not though; just have an alias for the non-@ version. Does Ares list the commands with @ (but accept without too) or are they listed without @ (but accepts one anyway) ?

    Ares lists all commands with no prefix at all in help files and whatnot. Unless you explicitly make a command look for a prefix (@, &, /, +), Ares just ignores it completely.

    This is, incidentally, why the default Ares config renamed the public chat channel to "Chat" instead of "Public", to avoid the obvious mav-prone confusion of p for page and +p for public :)

    Edit to add: Codewise Ares breaks the command up into (prefix)root(page#)(/switch) (args). So all the built-in commands only look at cmd.root but you could make one look at cmd.prefix if you really wanted.

    How do you handle single-letter shortcuts, like ":" for emoting?
    .
    Griatch


  • Coder

    @Griatch said in What is out there? Hard and soft codebases of choice.:

    How do you handle single-letter shortcuts, like ":" for emoting?

    So yeah, in the vein of "everything is consistent until it isn't", there are a couple special cases for channels, room exits and poses. :) There's an emote catcher at the bottom of the Pose Plugin's get_cmd_handler method to look if the command starts with : or ; or whatnot. But command roots can be single letters, and there's also a shortcut system for aliasing (for instance) 'con' to 'connect'.


  • Coder

    After all of this, I can only say:

    I am a self taught coder for the "Horror" of MUX code. I learned by reading the help files built in, examining each function in detail, and then just by playing around.

    My code is not elegant. My code is a monstrosity and probably could be done a billion times more efficiently. I have no doubt but...

    My code is stable. My code doesn't crash the whole game if it doesn't work (I avoided endless loop code thankfully).

    I can code chargen (I have done multiple systems). I can code XP systems. I can code economy systems. I can code a great many things but there's a lot I cannot code as well (Well, I probably could, but it would be horrific to look at and examine) such as vehicle combat systems, and I am /still/ learning how to code customized grids for battle turn based systems.

    But... as anyone on this board can tell you I am not the smartest person around, but I can still build a game from scratch if I need to using old school platforms.

    Evennia? Nope. I have no clue where to even begin. I don't know the language at all and trying to use it just seems like it'd take me /years/ rather than a few months to build a game.

    I'd be in the same boat with MUCK most likely.

    So from a programmers perspective MUX code might be a horror, but, there's a lot of code out there I can look at, and see how stuff works, and learn from that makes it incredibly easy to just pick up and start screwing around with, as I did, than trying to learn Python just to get started.


Log in to reply
 

Looks like your connection to MU Soapbox was lost, please wait while we try to reconnect.