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


  • Coder

    @faraday and @Thenomain on opposite sides of an issue. It should be a podcast!

    Anyhow, I wholeheartedly agree with my compatriot, but I will say that to learn any "real" programming language involves learning some insanely important concepts. Even if you frankencode (definition: taking bits of code from other sources and mashing them together hoping they will work), you have to understand what goes where, a few brief OOP concepts, how stuff gets called, and how to find the help files so you can translate def switch_set(self, target, files, rhs, isadmin): into English. I mean, sure, you have to do the same with iter(), but 'help iter' and boom, done.

    Does Evennia have a 'help switch_set'? If not, it desperately needs one!


    Incidentally, the code comes from https://github.com/evennia/evennia/wiki/Soft-Code, which I have some ethical problems with, mainly how it compares some pretty horribly written softcode in a horribly unformatted manner to elegant and also formatted code. (Yes, I know it's @Volund's code, and I know he is a damn good psychocoder.)

    Let us compare the "scare code":

    &INC`SET u(ifo)=@include u(ifo)/INC`TARGET;@include  \
    u(ifo)/INC`FILENAME;@assert strlen(%q<filename>)=@nspemit \
    %#=announce(INFO)%BERROR: Info file name empty.;@switch/inline \
    gt(strlen(setr(attr,u(u(ifo)/FUN`FINDFILE,%q<target>,%q<filename>))),0)=1,{@assert \
    or(isadmin(%#),strmatch(%q<target>,%#))=@nspemit \
    %#=announce(INFO)%BERROR: You may not change another's Info \
    files.;@switch/inline or(getstat(%q<target>/%q<attr>`FLAGS,Hidden),\
    getstat(%q<target>/%q<attr> `FLAGS,Approved))=1,{@assert \
    isadmin(%#)=@nspemit %#=announce(INFO)%BERROR: That Info File may not \
    be changed by you.}}, ...
    

    To something a little more reasonable:

    &INC`SET u(ifo)=
    	@include u(ifo)/INC`TARGET;
    	@include u(ifo)/INC`FILENAME; 
    	@assert strlen( %q<filename> )=@nspemit %#=u( .error, Info file name empty. ); 
    	@eval setq( attr, u( u( ifo )/FUN`FINDFILE, %q<target>, %q<filename> )); 
    	@if t( strlen( %q<attr> ), 0 )=
    		1, { 
    			@assert or( isadmin( %# ), strmatch( %q<target>, %# ))=
    				@nspemit %#=u( .error, You may not change another's Info files. ); 
    			@switch/inline or( 
    				getstat( %q<target>/%q<attr>`FLAGS, Hidden ), 
    				getstat( %q<target>/%q<attr> `FLAGS, Approved )
    			)=
    				1, { 
    					@assert isadmin(%#)=
    						@nspemit %#=u( .error, That Info File may not be changed by you. ) 
    				}
    		}, 
    		...
    

    There is no reason to softcode unformatted. @Glitch coded an amazing tool called Muxify in order to allow as many people as possible to code formatted. This is so easy to do.


    edit:

    Incidentally, here's how I would have done it:

    &INC`SET u(ifo)=
    	@include u(ifo)/INC`TARGET;
    	@include u(ifo)/INC`FILENAME; 
    	@assert strlen( %q<filename> )=@nspemit %#=u( .error, Info file name empty. ); 
    	@eval setq( attr, u( u( ifo )/FUN`FINDFILE, %q<target>, %q<filename> )); 
    	@assert cand( strlen( %q<attr> ), cor( isadmin( %# ), strmatch( %q<target>, %# )))=
    		@nspemit %#=u( .error, You may not change another's Info files. );
    	@assert cor( 
    			not( u( .orflags, %q<target>, %q<attr>, Hidden Approved )), 
    			isadmin( %# )
    		)=
    		@nspemit %#=u( .error, That Info File may not be changed by you. ); 
    	...
    

    Legibility isn't impossible in softcode. In fact, it's not even that hard to do. You just have to start with: I need to be able to tell my future self what the hell I'm doing, and the experience of yelling at your past self for not knowing the things that you know today.


  • Coder

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

    @faraday and @Thenomain on opposite sides of an issue. It should be a podcast!

    Maybe so since it seems to happen every other Tuesday :)

    how to find the help files so you can translate def switch_set(self, target, files, rhs, isadmin): into English. I mean, sure, you have to do the same with iter(), but 'help iter' and boom, done.

    Does Evennia have a 'help switch_set'? If not, it desperately needs one!

    Uhh... perhaps I'm missing something critical about your point, but with a mainstream (I won't say "real" because say what you will about MUSHCode but it is a "real" language) programming language there are literally gazillions of "how to do a switch in Ruby" type tutorials. You can learn the critical basics in the interactive tryruby.org 15 minute tutorial. Have a wacky question? There are millions of answers on stackoverflow. Given the popularity of Python I have to assume that similar resources exist.

    The critical piece I think is needed for transitioning from MUSHCode to a different framework is a bridge document. "Here's how to do iter(a b c,...) in Ares. Here's how to do set(#123: x) in Ares." That's what I'm working on right now.


  • Coder

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

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

    @faraday and @Thenomain on opposite sides of an issue. It should be a podcast!

    Maybe so since it seems to happen every other Tuesday :)

    Call me.

    how to find the help files so you can translate def switch_set(self, target, files, rhs, isadmin): into English. I mean, sure, you have to do the same with iter(), but 'help iter' and boom, done.

    Does Evennia have a 'help switch_set'? If not, it desperately needs one!

    Uhh... perhaps I'm missing something critical about your point, but with a mainstream (I won't say "real" because say what you will about MUSHCode but it is a "real" language) programming language

    there are literally gazillions of "how to do a switch in Ruby" type tutorials.

    Step 1: Recognize a built-in function from a defined function.

    • In Mushlikes: Is it a u()? No: Is it in 'help'? No: @function/list.
    • In Mainstream Languages: ...?

    I assume the answer to 1b is to hope the people who put the framework together have made it easy to find out.

    Also, before I get complaints about it, I know that what I quoted is the definition of 'switch_set', but what about 'msg()'? How does a beginning coder know where to find the help file on this function, when beset upon by it while frankencoding?

    As you say, though:

    The critical piece I think is needed for transitioning from MUSHCode to a different framework is a bridge document.

    Considering the tone of my comments, I wholeheartedly agree.

    The lack of this document is probably why WTFE's "professionals only" statement came in; sure a pro will know where to find what 'msg()' is, starting with context which is so bloody critical in OOP, but even though Mushers bathe in list-based and OOP-based coding it's going to take some Beginner's Guide education to smooth the transition.

    But, I mean, you know that.


  • Coder

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

    Step 1: Recognize a built-in function from a defined function.

    • In Mushlikes: Is it a u()? No: Is it in 'help'? No: @function/list.
    • In Mainstream Languages: ...?

    Agree with you in general principle. (Gasp!)

    To answer your specific question for Ares/Ruby, the object-oriented bit helps a great deal. When you see FS3Skills.ability_rating(char, "Athletics") or "abc".ljust(22) it is hopefully reasonably obvious that ability_rating is a FS3 function and ljust is a Ruby string function. I do "google ruby whatever" a lot :)

    And of course, using a mainstream language opens up a host of editors from Sublime Text to TextMate to VSCode to RubyMine that will provide you with anything from full-on intellisense support to an easy global search for "now where the heck is emit defined? Search for def emit"

    Docs are critical, but tools and conventions help too.


  • Coder


  • Coder

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

    @faraday and @Thenomain on opposite sides of an issue. It should be a podcast!

    Anyhow, I wholeheartedly agree with my compatriot, but I will say that to learn any "real" programming language involves learning some insanely important concepts. Even if you frankencode (definition: taking bits of code from other sources and mashing them together hoping they will work), you have to understand what goes where, a few brief OOP concepts, how stuff gets called, and how to find the help files so you can translate def switch_set(self, target, files, rhs, isadmin): into English. I mean, sure, you have to do the same with iter(), but 'help iter' and boom, done.

    Does Evennia have a 'help switch_set'? If not, it desperately needs one!

    It does not, because that code is Volund's custom example created for his own needs. In all of Evennia's core code you will find the full documentation of the function directly under the function- or class definition.


    Incidentally, the code comes from https://github.com/evennia/evennia/wiki/Soft-Code, which I have some ethical problems with, mainly how it compares some pretty horribly written softcode in a horribly unformatted manner to elegant and also formatted code. (Yes, I know it's @Volund's code, and I know he is a damn good psychocoder.)

    The main thing would be that both codes are written by the same guy, the mushcode one after years of experience, the second one after only a short while of learning Python/Evennia. And the Python one is not "formatted" in some unethically incomparable way: Python must look this readable to be valid Python. You could in principle make Python code look as compact and (to me) unintelligible as the mushcode above, but you'd have to work very hard at it and know a lot more Python than Volund did at the time.

    Out of curiosity; the nicer-formatted form of mushcode you show, can you edit it like this in-game or do you need an external editor that you copy & paste from?
    .
    Griatch


  • Coder

    Sorry for the double-post but I'm on my phone and it's a little hard to track all the text.

    Step 1: Recognize a built-in function from a defined function.

    • In Mushlikes: Is it a u()? No: Is it in 'help'? No: @function/list.
    • In Mainstream Languages: ...?

    I assume the answer to 1b is to hope the people who put the framework together have made it easy to find out.

    In python: help (module.funcname)
    In evennia (nicer if ipython is installed-colors and tab-completion):

    $ evennia shell
    # Python shell starts
    > import evennia
    > evennia.<TAB>
    evennia.Object evennia.Command ... #contents of the most common Evennia components to use
    > evennia.Object?
    # documentation for Object class
    > evennia.Object??
    # source code for Object class
    > evennia.Object.msg?
    # documentation for msg method
    

    And as I think was already agreed upon, if you use a coding IDE you will get this info popping up in a separate pane while you are typing. It will even make code completion suggestions if you like (I don't, I use VIM with few frills but that's just me).

    Also, before I get complaints about it, I know that what I quoted is the definition of 'switch_set', but what about 'msg()'? How does a beginning coder know where to find the help file on this function

    This particular one would, as said, be up to Volund to document. Normally a search through the code base would find the function. All functions, classes and methods-on-classes are heavily documented in Evennia; some 45% of all lines are in fact documentation (according to Ohloh).

    The lack of this document is probably why WTFE's "professionals only" statement came in; sure a pro will know where to find what 'msg()' is, starting with context which is so bloody critical in OOP, but even though Mushers bathe in list-based and OOP-based coding it's going to take some Beginner's Guide education to smooth the transition.

    But, I mean, you know that.

    The Evennia beginning tutorials cover the use of msg() and there are whole wiki sections dedicated to it. But sure, if one is going in blind and are not familiar with OOP concepts nor Evennia's overall layout it may well be tough to get anywhere.
    I can only say that I see plenty of very much "non-pro" hobbyist people not having any issues with finding this info. I'm willing to concede that this may be a selection effect though and that we just don't hear from those that fall off.

    Edit: We have a standing request for people from different codebases to write "Evennia for <mu codease>" type documents. So far my own article here on musoap box may come closest to a mush one; no musher have stepped up to do a more detailed one yet (I don't feel competent enough to write it myself since I'm not a musher)
    .
    Griatch


  • Coder

    @Griatch This is why I find Python such a bag of WTF?!

    I can find pretty much everything I need in order to code within MUX help files and function lists etc. Sure I have to build some custom functions but the tools are /there/. When I first started to learn to code it was pretty much little stuff, how to code dice rollers, then how to store the results of it so it can be shown to others, then how to verify, then how to code a personalized verify attribute that only the person who set it could see to make sure nobody was spoofing you, etc.

    It seems to me that in Python there's not even a box of tools, you're being given some raw ore and said, now go forge your hammer and nails, then use those to start laying the framework.

    That's a huge barrier of entry by contrast.


  • Coder

    @Lithium

    Python knows nothing about mushes, it's just a language. That is what Evennia is for - it supplies the resources relevant for use in a mu environment. If resources are missing we can add them or have them as optional contribs.

    It's quite clear that Python has many, many more help resources than mushcode has as a language, simply because so many more people use Python in the world than mushcode. But there is no denying that by comparison very few use Python for the specific use of creating a Mu - as far as Python goes, Evennia is one of the few runners in that race. Here mushcode has decades of lead; it's after all the only thing mushcode is used for, anywhere (as far as I know?).

    Now, I personally agree with @faraday that someone who mastered something like mushcode should be well in place for learning something like Python or Ruby. The workflow may be the more jarring aspect (as has been discussed at length here). So if you know mushcode already and it fulfills all your needs for the games you want to create, I agree you may very well be best off sticking to it. The toolboxes offered by Evennia (or Ares) and the workflow they work best with is not necessarily the right fit for everyone.
    .
    Griatch


  • Coder

    Christmas Eve, not much time, still requesting: Evennia have its own help files for people who do not know how to or understand how to pour through code, let alone understand what directory structures mean what. I still facerub when I have to find which library a function or object or template structure lives in, because it is not fun at all for anyone ever period, even people who've been coding Mush softcode for years/decades and "where is it?" is a painfully frequent question.

    I can't ask that Evennia devs do anything for the common Python code, but for the Evennia structures they can sure as heck do something as simple as a searchable wiki. Have you seen how well-organized the Oracle SQL and PL/SQL docs and even some of the other interface docs are? PyDoc, maybe?

    Thinking out loud, there.


  • Pitcrew

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

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

    I suspect that you'd be just as comfortable had you started with MUCK. Forth and Lisp-like thinking are basically similar, only with Forth you wear your hat and shoes backwards. :D


  • Coder

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

    Christmas Eve, not much time, still requesting: Evennia have its own help files for people who do not know how to or understand how to pour through code, let alone understand what directory structures mean what. I still facerub when I have to find which library a function or object or template structure lives in, because it is not fun at all for anyone ever period, even people who've been coding Mush softcode for years/decades and "where is it?" is a painfully frequent question.

    I can't ask that Evennia devs do anything for the common Python code, but for the Evennia structures they can sure as heck do something as simple as a searchable wiki. Have you seen how well-organized the Oracle SQL and PL/SQL docs and even some of the other interface docs are? PyDoc, maybe?

    The wiki is searchable by wiki page-name, by a google-seach (from the "search" link on the right hand side). It can also be read and printed as PDF on readthedocs and finally directly downloaded.
    ... But that said, I agree that the API doc section of our wiki is, while complete, not necessarily aimed at someone just diving in: it lists also systems that a normal user would most likely not be concerned about ever, or at least not until at an advanced level of understanding or when contributing to Evennia itself. So a good idea would be to make a stricter selection as to what is presented there and hide away the details except for those with a particular interest.

    Thinking out loud, there.

    Appreciated and point taken. Merry Christmas!
    .
    Griatch


  • Coder

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

    ... But that said, I agree that the API doc section of our wiki is, while complete, not necessarily aimed at someone just diving in: it lists also systems that a normal user would most likely not be concerned about ever, or at least not until at an advanced level of understanding or when contributing to Evennia itself.

    API docs and tutorials have a completely different purpose and ideal design. One is not a good substitute for another. Merry Christmas / Happy Holidays!

    Edit to add: That was always MUSHCode's problem IMHO. There was plenty of "this function does X, that function does y" type documentation, but it took the community ages before they produced useful docs of how to string those functions together into something useful. Which is why I find the comparison to MUSHcode as a pillar of good documentationto be a bit baffling.


  • Coder

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

    Merry Christmas!

    Merry Christmas! My gift from Soapbox is you, @faraday and others having a long and interesting discussion. We may not be changing minds, but we are exploring them, which is fantastic!

    Merry days to all.


  • Coder

    @Thenomain and others

    Just a quick update that based on the feedback here I added a reference to the shorter "flat" API of Evennia to our API index. This is a set of shortcuts available directly from the evennia top-level import and contains most basic building blocks needed to do stuff. Showing this at the top of the API doc might be easier for a newcomer to digest than the full API (which remains further down the page). Check it out here.

    Note however that API docs are always terse, focused and technical without wasting much space explaining the greater picture. New users remain recommended to get a feel for Evennia development by browsing the Developer Central and do the Tutorials.
    .
    Griatch


  • Coder

    @Griatch Please don't make a setup that creates python environments. venv has a way for it to be done, but it creates nightmares and only leads to suffering.

    Signed,
    An Experienced Python Dev


  • Coder

    @Alzie

    If you have root you could of course always install everything system-wide if you wanted ... but apart from remembering to turn it on, why would you, as an experienced Python dev, say virtual environments only create suffering? Could you elaborate? What would you suggest instead?

    In my view, virtualenv(py2+3) and venv(py3.3+) are simple and lightweight and very useful. I personally often create one for new Python projects to isolate them and to know exactly which dependencies they have. Users can be instructed to install to a virtualenv without worrying about what preexisting parts of their system they may affect. Having things in a virtualenv also allows to install and upgrade without requiring root with has helped me many a time on remote logins. It's also excellent for testing release packages and to help users with issues since you can quickly make sure you have a Python dev environment that matches theirs. As a dev, it's also extremely useful for python2 and python3 testing in parallel.

    (For those reading and not knowing what we are talking about, virtualenvs are just quick little ways to install python packages of arbitrary versions without modifying system-wide default package versions. All gets installed to a folder anywhere you want (so you just delete that to get rid of the whole environment). Not to be confused with a virtual machine or anything complex like that, it's basically just temporary rerouthing of paths and system variables that takes no extra resources.)
    .
    Griatch


  • Coder

    @Griatch Not 'virtual environments are bad.' To be clear, I was saying that creating them automatically for the user was bad. As someone had suggested that you could make an installer that would create the virtual environment. Programmatically creating virtual environments never works out for anyone.


  • Coder

    @Alzie

    Ah, I see. Not sure I necessarily agree with that as a general statement, but I can certainly imagine it could be confusing for the user if they don't know what is being done during the automated setup and are later expected to operate what was installed.
    .
    Griatch


  • Coder

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

    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.

    A bit of a necro of this thread, but it struck me that that the dynamic changing of commands based on a condition is a lot easier in Evennia than I suggested above. The question was essentially "at the moment of entering bob, if this condition is True, get back this version of the bob command, otherwise get the other condition". The way to go is to use locks. Here we decide which bob command to use depending on if the caller has the Attribute "foo" or not:

    from evennia import Command, CmdSet
    
    class CmdBob1(Command):
        key = "bob"
        locks = "cmd: not attr(foo)"
        def func(self):
            # stuff this first bob command does
    
    class CmdBob2(Command):
        key = "bob"
        locks = "cmd: attr(foo)"
        def func(self):
            # stuff this second bob command does
    

    Explanation: Above we create two Evennia Commands, both keyed as "bob" but doing (supposedly) different things. Each also has a lock string. Locks is a mini-language in Evennia, where you call small python functions that always return True/False and combine their returns into the result of the lock. In this case the lock string is cmd:attr(foo) and cmd:not attr(foo) respectively. The cmd bit is the lock type. For a Command, if the cmd type lock is not passed, the entire Command is unavailable to the player at this time. The lock is using the attr(name) lock function. This is a predefined lock function that checks if the caller has an Attribute with the given name ("foo") at all. So in this case, if the "foo" Attribute is set, CmdBob1 will fail the lock and CmdBob2 will pass it and vice versa. You could of course define your own custom lock funcs like is_it_full_moon etc. It's a normal Python function you just tell Evennia to treat as a lock function.

    ... We now just need to add these two commands into their own cmdsets and add them both to whatever object should be able to use or supply the "bob" command(s). When you then enter "bob" on the input line you will get the result of either CmdBob1 or CmdBob2 depending on if you have the "foo" attribute set on yourself or not.

    I added it as a Q&A hint to the Evennia tips and tricks section.


Log in to reply
 

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