Make Evennia 'more accessible' - ideas?
-
@sparks said in Make Evennia 'more accessible' - ideas?:
@pyrephox said in Make Evennia 'more accessible' - ideas?:
@sparks Remember that it doesn't have to be the BEST resource. Just one that lets the prospective coder (who, remember, maybe doesn't actually enjoy coding, but just wants something functional enough to do what they do enjoy, i.e. design the game) fumble their way through something that works.
I added some links and more verbose comments to the (currently) final source example, which I desperately hope helps.
@Sparks Maybe build off/reference Evennia's Python intro, which does give brief a tour of Python classes in Evennia?
.
Griatch -
So, following up on my weekend project: I decided to take all the individual turnbattle contribs (which are each a self-sufficient system for one aspect of a system), merge them together, and make something using several parts at once. For instance, combining the range abstraction system with the magic system to make an AoE spell. I was able to do it, so, mostly a success!
What I will say struck me as the greatest frustrations along the way were all more about figuring out where something was or how I was supposed to implement it vs. strictly not having any idea how to do it. Sorting out the relationships of the various modules and classes, your game code vs. base evennia, understanding which ancestor you should be inheriting from or overloading (DefaultX vs. X), where you can put your code and have it actually work vs. needing to call it in some other thing, and how to get your functions and commands accessible.
In my case, I ran into a really arcane (to me anyway) problem with the base classes, commandsets, and circular imports. Totally my bad, and while I did figure out how to get around it (basically, that I needed to refer to commandsets explicitly vs. importing), I think it's an example of the many ways a new user could get stumped.
Overall, I was still able to build something really impressive for the time invested, so I think that says a lot for how powerful the codebase and contribs are. In terms of what trips people up, I only have my own experience but I hope its useful representing one kind of potential user.
@thenomain said in Make Evennia 'more accessible' - ideas?:
My goal right now is to get to "code python".
I think this is actually a good summary. The greatest challenge is getting past the libraries, APIs, etc toward actually doing the code you want to write.
-
Okay, here's a question. Instead of trying to write a really verbose tutorial like the half-done one I linked before, would it be easier for folks if there was just a really basic Evennia-in-a-box that provided some nice basic systems, like a bboard system, a mail system, and so on? (If the systems were really well commented in the source code, I mean. Commented on the level of that last code listing in the tutorial.)
Because writing the tutorial is slow and kind of painful as I try to think what I need to explain, while just writing the code would be much faster.
-
@sparks That would also be helpful! It might be helpful in a different way, but it would certainly lower the bar for usability to get started.
-
@pyrephox said in Make Evennia 'more accessible' - ideas?:
@sparks That would also be helpful! It might be helpful in a different way, but it would certainly lower the bar for usability to get started.
Ninja'd.
People can take apart what's there if it's well-done and/or basic enough. The tutorial part could be, "Look here. Now look there. See how these things work? Now do stuff!"
-
@sparks said in Make Evennia 'more accessible' - ideas?:
Okay, here's a question. Instead of trying to write a really verbose tutorial like the half-done one I linked before, would it be easier for folks if there was just a really basic Evennia-in-a-box that provided some nice basic systems, like a bboard system, a mail system, and so on? (If the systems were really well commented in the source code, I mean. Commented on the level of that last code listing in the tutorial.)
Because writing the tutorial is slow and kind of painful as I try to think what I need to explain, while just writing the code would be much faster.
I personally feel that'd be the way to go. I think learning coding as you go via modifying existing features is much less intimidating than trying to implement them yourself, and tutorials would probably feel less daunting if they're more along the lines of 'Add a character's signature to their mail' than 'Create a simple version of a mail command'.
-
@tehom said in Make Evennia 'more accessible' - ideas?:
@sparks said in Make Evennia 'more accessible' - ideas?:
Okay, here's a question. Instead of trying to write a really verbose tutorial like the half-done one I linked before, would it be easier for folks if there was just a really basic Evennia-in-a-box that provided some nice basic systems, like a bboard system, a mail system, and so on? (If the systems were really well commented in the source code, I mean. Commented on the level of that last code listing in the tutorial.)
Because writing the tutorial is slow and kind of painful as I try to think what I need to explain, while just writing the code would be much faster.
I personally feel that'd be the way to go. I think learning coding as you go via modifying existing features is much less intimidating than trying to implement them yourself, and tutorials would probably feel less daunting if they're more along the lines of 'Add a character's signature to their mail' than 'Create a simple version of a mail command'.
Maybe I'll just finish the WHO command tutorial since it's now maybe two-thirds done anyway, and then just make a basic out-of-box game someone could use. I do have what the final WHO command source will be, with copious—perhaps excessive—comments. (I don't know that I could do an entire example game with that many comments, especially since it looks much more legible without.)
Edit: And, the tutorial's done!
-
@Sparks Thanks for the tutorial! It's not easy to write a comprehensive tutorial as you found out - it's hard to tell where to draw the boundary.
I like the elaborating sections about Commands and other systems, it's fun and useful to see them described with other words.
I have some, hopefully constructive, suggestions:
- Try to explain already at the beginning what you want to do to make the
who
command more 'MUSH-like' (That is, change the formatting, allow users to add their own text in thedoing
column etc). - If you want to do line-by-line explanation of a code (beyond normal code-comments), I think it's usually better to explain the lines in text after the code - as you yourself note, long inline code is making the whole thing look very overwhelming when in fact it's just a few lines of actual code. If it's hard to track, I'd suggest to use after-line comments with, say numbers (
# 5
) and refer to them in the text afterwards. - All of these aspects (commands, command sets, locks etc) have more detailed explanations in the Evennia manual. You can't be expected to explain the full depth in this tutorial so it's a a good idea to add links to those for people to conveniently dive deeper if they want.
- I've found
import ...
/from ... import ...
are major stumbling blocks for new Python users. I'd suggest showing them with explicit examples as soon as importing is mentioned. - You probably need to briefly explain how string formatting works when you first introduce it here
self.msg("Accounts: {}".format(account_names))
- 'Python is not 'just' a "functional programming language". It's very much an object-oriented language (supporting functional paradigms). While that distinction may not matter to complete newbies, it may throw newcomers with no Python knowledge but general programming knowledge for a loop.
- When you use the
@set
command for the first time it would be good to explain why that now works and refer to the place above where the Attribute is set up (it's mentioned in the in-code comment but reading the text it feels like the@set
comes out of nowhere).
More code-specific feedback:
- Avoid using Sphinx ReST formatting like
:param prefix:
in your docstring examples. It's not explained and will just just confuse users. - It's not recommended to use
filter
(normap
) in modern Python code. These can always be written using a list comprehension, without any lambdas:# filter form sessions = \ filter(lambda sess: sess.get_account().key.startswith( prefix) if sess.get_account() is not None else False, sessions) # list comprehension form sessions = [sess for sess in sessions if sess.get_account() and sess.get.get_account().key.startswith(prefix)]
Overall though, this looks quite fine - thanks again for writing this. I'm not the target audience though, so hopefully others can chip in with feedback to help you flesh out where things are still confusing to them.
.
Griatch - Try to explain already at the beginning what you want to do to make the
-
@bored said in Make Evennia 'more accessible' - ideas?:
So, following up on my weekend project: I decided to take all the individual turnbattle contribs (which are each a self-sufficient system for one aspect of a system), merge them together, and make something using several parts at once. For instance, combining the range abstraction system with the magic system to make an AoE spell. I was able to do it, so, mostly a success!
What I will say struck me as the greatest frustrations along the way were all more about figuring out where something was or how I was supposed to implement it vs. strictly not having any idea how to do it. Sorting out the relationships of the various modules and classes, your game code vs. base evennia, understanding which ancestor you should be inheriting from or overloading (DefaultX vs. X),
This is useful experience! Let me ask - which tutorials/texts did you read before getting into things? Did you go through the python tutorial part 2 for example? Just checking since that one includes a tour up the dependency tree into the "DefaultX" (DefaultObject, DefaultScript etc) base classes. I hope you found you could work with the X classes (Object, Script etc) directly after the initual confusion.
Do you think something in particular could be done to make it easier to figure out the relationships of classes/modules etc? Or to guide you to the right info about it etc?where you can put your code and have it actually work vs. needing to call it in some other thing, and how to get your functions and commands accessible.
Was something in particular making this harder than it needed to be, you think?
In my case, I ran into a really arcane (to me anyway) problem with the base classes, commandsets, and circular imports. Totally my bad, and while I did figure out how to get around it (basically, that I needed to refer to commandsets explicitly vs. importing), I think it's an example of the many ways a new user could get stumped.
Could you elaborate more on what the issue was there, not sure what you mean by "explicitly vs importing"?
Overall, I was still able to build something really impressive for the time invested, so I think that says a lot for how powerful the codebase and contribs are. In terms of what trips people up, I only have my own experience but I hope its useful representing one kind of potential user.
@thenomain said in Make Evennia 'more accessible' - ideas?:
My goal right now is to get to "code python".
I think this is actually a good summary. The greatest challenge is getting past the libraries, APIs, etc toward actually doing the code you want to write.
Learning a new library is always going to be a learning obstacle. All we can do is to ease the level of entry.
.
Griatch -
So I think one of the major things about Evennia that's overlooked from the perspective of the people who have some experience working on it, is that a lot of the people interested in using it to develop a game are coming into it with absolutely no coding skills at all. They might have ideas for systems--almost certainly things that they've experienced in games before, or would like to iterate on--but beyond that, they're starting from either zero, or a concept of what coding might be.
To clarify: I mean a lot of the people who might be interested in Evennia have no experience thinking in a way necessary to take what's referenced in the guides and apply it to their own ideas. It's more about coding logic than it is syntax, in my opinion. Learning what a class is can be one thing, but figuring out how to design a piece of code that applies it is totally different.
I know that's certainly out of the scope of what's currently available within Evennia's development, and the easy answer is "Go take a class", but I'm also of the opinion that there's a lot of value in learning to code in the context of MU*s, and even though Evennia isn't currently set up to just pick up and get running (despite the potential ease of use and current library of contribs), figuring out a way to convey the basics in terms that's easy to understand to someone starting completely fresh is hella important.
This definitely isn't the fault of anyone who contributes to it. A) It's not reasonable to ask that they also teach absolute beginners how to code, period, and B) At a certain point it's hard to remember what things are actually completely foreign to beginners.
I have a very, very basic understanding of how to program. I mean I understand how booleans work, and I can write a half-functional if statement. I took a logic class at community college, and I'm taking a coding class here starting in November. Part of the process of me actually applying this class is going to be getting some functional systems onto a fresh install, and I figure while I do that I'll try and document the steps I'm taking to get it working.
If anyone's interested in starting from 0/10 and working towards like, 3 or some shit, hit me up, I'm happy to share whatever I figure out.
-
@griatch said in Make Evennia 'more accessible' - ideas?:
This is useful experience! Let me ask - which tutorials/texts did you read before getting into things? Did you go through the python tutorial part 2 for example? Just checking since that one includes a tour up the dependency tree into the "DefaultX" (DefaultObject, DefaultScript etc) base classes. I hope you found you could work with the X classes (Object, Script etc) directly after the initual confusion.
I'd tried using Evennia once some while ago, so it wasn't strictly a first-look. I read the basic 'basic python with Evennia' tutorials back then, because at that point I had no knowledge of either! So I had a recollection of the setup, it just wasn't necessarily intuitive. This time I was generally using the search to try and grab specific wiki entries/manuals on whatever I was trying to do. I didn't go back to that file (its title makes it sound very beginner oriented), but instead found... there's a diagram version of it somewhere?
However, one that's still baffling to me is how commandsets are set up. Breaking the usual pattern, the file in your game directory in this case is
default_cmdsets.py
(vs.characters.py
,objects.py
, etc) and then imports (from evennia)default_cmdsets
to inherit fromdefault_cmds.CharacterCmdSet
compared to, e.g.DefaultObject
orDefaultCharacter
. And where the heck doesCmdSet
fit into that whole mess?The contrib also does this, and it seems strange you're using a base class like that vs. a 'local to your game' version as with the others. It didn't stop me, but it felt like cargo cult programming.
Do you think something in particular could be done to make it easier to figure out the relationships of classes/modules etc? Or to guide you to the right info about it etc?
I think, as you've pointed out, the info exists (its also in the code comments, which are great) so people can find it, although it's not the best organized and there's a lot of repetition and overlap. The tutorials wiki page has... at least five entries named some synonym of 'basic tutorial'? Then many of the other examples seem way too specific to be helpful to someone starting a project (Weather Emits seem like they'd be pretty close to the bottom of a priority list).
Conversely, that I'm not just being critical, I think the Developer Central page is much better laid out, if more technical.
In my case, I ran into a really arcane (to me anyway) problem with the base classes, commandsets, and circular imports. Totally my bad, and while I did figure out how to get around it (basically, that I needed to refer to commandsets explicitly vs. importing), I think it's an example of the many ways a new user could get stumped.
Could you elaborate more on what the issue was there, not sure what you mean by "explicitly vs importing"?
I can but it's convoluted (hence not going into detail before). Hopefully you can follow, it feels like the only thing worse than reading someone else's code is... someone else second hand explaining why their code didn't work! Spam follows:
Since I was working from the turnbattle contrib, I had a bunch of modules for each aspect of the system (
tb_range
,tb_equip
, etc). They had lots of redundancies (each one defines an alternate version of the same new player typeclass). I'd combined those, thinking about how I'd structure it for a game since it was meant to be practice. So for instance I moved the character stuff intocharacters.py
as it was more logical to me than having a child class, making it default, and having it defined somewhere obscure.For the same reason as above, I'd moved the hooks from
tb_range.py
intoobjects.py
vs. creating a new object class. This required some of the functions fromtb_basic
. I left the new child typeclasses for weapons and armor intb_equip
, which also had the wield, unwield, etc commands. Meanwhile the commandset definitions were still intb_basic
, though I'd split them to create a general set (that I added indefault_cmdsets.py
exactly as in any tutorial) that included the commands to initiate combat and an 'in-combat' one that would get added and removed in play. Again, I wanted to practice a real design, and this seems common (it's how Arx does it, I believe).Long story short,
tb_equip
was importingObject
, which importedtb_basic
functions, which importedtb_equip
(forCmdWield
etc). ImportError. However even when I reorganized stuff (I splittb_basic
to have the script, commandsets, and functions across 3 modules soobjects.py
could import the functions and not the commandset), it still happened. Basically, the commandset was importing everything and so anywhere I imported it (to add/remove the set to combatants as they joined/left) it would throw up the error.The solution (and what I meant by 'explicitly') was adding it via its own path:
char.cmdset.add("path.to.CommandSet")
vs. importing and doingchar.cmdset.add(CommandSet)
. Perhaps not the correct professional programmer term! So, very simple solution (and i think this was shown in one of your examples somewhere), it just didn't occur to me for a long time because I didn't see why the way I was doing it wasn't the way I should be.Ultimately it's worth repeating that I still succeeded in getting everything working (uh, except the spawner, which seems buggy as heck), so the clearly the resources and information is there. I think organization could help, as well as what people have suggested in terms of system tutorials or base example worlds. Right now there's a gap between TutorialWorld (that's very... mud and minigame centric) and Ainneve/Arx (which are great examples but maybe too advanced for some to unpack).
-
So I'm someone who had a rudimentary coding knowledge in PennMUSH and MOO who decided to build a game in Ares. I started in late July, and I feel pretty comfortable saying that I MOSTLY know what I'm doing in coding for Ares now. I recognize more errors than I don't (this is a serious accomplishment). I am not a coder by profession or by hobby, and I have a lot of gaps in my knowledge when it comes to things like 'usual programming workflow'.
I haven't looked at Evennia or Python, but here are the things that were helpful and hard when picking up a new codebase with external documentation available, that might also apply to thinking about Evennia docs.
-
Remember that people probably aren't going to read your documentation in order, from start to end. They're going to skip around to what seems relevant to them. This is why reminding people to start virtual environments or whatever is important every time.
-
I knew how to log into a server shell and do basic commands there, but I lacked the language to even google how to do something more than basic. Give your readers that language whenever possible. It's hard to solve your own problems when you have a vocabulary gap.
-
Github was a ridiculous hurdle for me. I didn't (and still only barely) understand the workflow of how to code, see it on a game, push it to git, pull it into another game, not get conflict errors, resolve conflicts, edit text in the shell... I MOSTLY have this worked out, but just yesterday I fought a battle where git thought there was a conflict and I couldn't find it. Git tutorials often assume a different sort of set-up or a work flow that I didn't have, and were less than useful in figuring this stuff out.
-
I did some basic Ruby tutorials, and they were helpful for vocabulary and the basic way things work. What was more useful were the Ares-specific tutorials that taught me where things lived, how Ares calls certain things, how Ares stores things in its database, etc. I'm not actually sure I can code anything in Ruby, because I'm not sure where Ares ends and Ruby begins. And I DON'T CARE.
-
And this is why general language tutorials aren't always that helpful. They are GREAT when I'm trying to figure out how to manipulate an array or something, but not so great in a 'learn Ruby by reading tutorials' sort of way. Much of it doesn't apply directly, or it's really hard to make the connection between what I'm trying to do in my game-specific environment and what they're trying to do out in some other environment.
-
Tutorials teaching you how to do basic, specific things that you want to do in a game are really, really, really helpful. For every language I've learned, I've started with 'store and retrieve data on an object/character/place/whatever'. Helpfully, @faraday's first tutorial teaches me how to do that. It explains what it's doing and shows me how to do it. The next tutorial steps it up by teaching me how to manipulate that data, etc. These first two tutorials were hands down the most useful thing for me when I started trying to code for Ares. This is also what helped me build my vocabulary enough to google smaller problems.
-
Remember that the people who are learning a language to code a game are interested mostly in building a game. This is the other reason that general ruby tutorials were only helpful for me in the super basics. I never did find a tutorial that taught me how to store and manipulate data on an object. Maybe I would have gotten there eventually, but I'm not here to learn to code Ruby. I don't want hours and hours of general Ruby education. I'm here to code a game, and I want education that will help me do that.
-
Document basic stuff in easy to find lists. Maybe you already do this, IDK. But I want quick references for things I'm going to want to do. For example, what are all the ways I emit a message? To a person, to multiple people, to a room, to the game. How can I format text? Those sorts of things.
-
Teach them debugging skills, and link to them OFTEN. I didn't discover the debug/dev mode in Ares until way too late in the game, and it could have saved me a lot of strife. I didn't know how to write info to the debug mode, so I was constantly trying to emit to my character, sometimes in complicated ways. Link to how to debug on every damn code tutorial page I swear.
Some of these may not be as applicable to Evennia/Python, and I know that you folks don't have the 'game in box' goal that Faraday does, but I'm happy to elaborate about anything that might be helpful.
-
-
@sab said in Make Evennia 'more accessible' - ideas?:
So I think one of the major things about Evennia that's overlooked from the perspective of the people who have some experience working on it, is that a lot of the people interested in using it to develop a game are coming into it with absolutely no coding skills at all. They might have ideas for systems--almost certainly things that they've experienced in games before, or would like to iterate on--but beyond that, they're starting from either zero, or a concept of what coding might be.
This is a problem with getting people developing TinyMUX (and Penn and Rhost) too. This has always been a problem. I have always taken the approach to take something that people know what it does and disassemble it in front of them.
In order:
- finger
- who
- where
Each builds on concepts of the previous, and people can start to see the patterns in the logic.
- finger: conditionals "if this then that" (+ formatting)
- who: loops (+ formatting)
- where: both (+ advanced formatting)
There are no tutorials for these in Mush; the benefit there is that you get to mess around with code while playing a game and socializing. People in the Mushlikes learn these things because they either a) want to help build (or "craft"), or b) have a project in mind. Either way, Step 1 in our world has always been find someone to help you out.
If anyone's interested in starting from 0/10 and working towards like, 3 or some shit, hit me up, I'm happy to share whatever I figure out.
I'm going to again hilite the Evennia IRC or Discord channel and ooze praise from my pores like an excited puppy.
Anyone and everyone who is willing to share gets lumped into that praise.
-
@tat said in Make Evennia 'more accessible' - ideas?:
Github was a ridiculous hurdle for me.
I didn't discover the debug/dev mode in Ares until way too late in the gamThese are good examples of the sorts of things that often are not obvious gaps to people writing tutorials (like me! Which is why I appreciate folks like Tat and @Thenomain - even though he decided he liked Evennia better - helping me build better ones).
Source control is like breathing to anyone who's done software outside of MUSHing. Sure you may not know GitHub specifically, but you know enough of the concepts to figure it out pretty easily. Running a local development environment and installing the tools you need. Doing things on the server shell. These are BIG hurdles to people who only know MUSHcode.
-
@griatch said in Make Evennia 'more accessible' - ideas?:
- If you want to do line-by-line explanation of a code (beyond normal code-comments), I think it's usually better to explain the lines in text after the code - as you yourself note, long inline code is making the whole thing look very overwhelming when in fact it's just a few lines of actual code. If it's hard to track, I'd suggest to use after-line comments with, say numbers (
# 5
) and refer to them in the text afterwards.
Hrm. Fair point. Though I admit, I'm starting to think more and more that a sample game with inline comments (albeit less comprehensive) and a tutorial on changing that existing code might be better than a tutorial that starts from scratch and doesn't have a convenient file to follow along with.
- All of these aspects (commands, command sets, locks etc) have more detailed explanations in the Evennia manual. You can't be expected to explain the full depth in this tutorial so it's a a good idea to add links to those for people to conveniently dive deeper if they want.
Yeah, I definitely should scatter a few more links throughout. I just need to find the right ones.
- 'Python is not 'just' a "functional programming language". It's very much an object-oriented language (supporting functional paradigms). While that distinction may not matter to complete newbies, it may throw newcomers with no Python knowledge but general programming knowledge for a loop.
This is true, and I probably should clarify it (and maybe cover a little of the basics of what object-oriented programming languages even are for those who don't have basic programming knowledge).
- When you use the
@set
command for the first time it would be good to explain why that now works and refer to the place above where the Attribute is set up (it's mentioned in the in-code comment but reading the text it feels like the@set
comes out of nowhere).
That one worries me less, because MUSHers are already familiar with @set to set attributes. But it's still a fair point.
- It's not recommended to use
filter
(normap
) in modern Python code. These can always be written using a list comprehension, without any lambdas:
I admit this one was a conscious choice to go against the grain. I chose to use a lambda there because I'd already explained lambdas in the
sorted
example, and I didn't really want to write a section on list comprehension too, since I worried about confusing people with too many concepts in short order.You're probably correct, though, that it makes more sense to just bite the bullet and add the explanation, since it is the better way to do it.
- If you want to do line-by-line explanation of a code (beyond normal code-comments), I think it's usually better to explain the lines in text after the code - as you yourself note, long inline code is making the whole thing look very overwhelming when in fact it's just a few lines of actual code. If it's hard to track, I'd suggest to use after-line comments with, say numbers (
-
@bored Slightly offtopic, but would you be able to share a bit more of what you did there? I was evaluating using the turnbattle contrib with Ainneve, but the disjointed systems made me think twice.
-
@bored said in Make Evennia 'more accessible' - ideas?:
@griatch said in Make Evennia 'more accessible' - ideas?:
This is useful experience! Let me ask - which tutorials/texts did you read before getting into things? Did you go through the python tutorial part 2 for example? Just checking since that one includes a tour up the dependency tree into the "DefaultX" (DefaultObject, DefaultScript etc) base classes. I hope you found you could work with the X classes (Object, Script etc) directly after the initual confusion.
I'd tried using Evennia once some while ago, so it wasn't strictly a first-look. I read the basic 'basic python with Evennia' tutorials back then, because at that point I had no knowledge of either! So I had a recollection of the setup, it just wasn't necessarily intuitive. This time I was generally using the search to try and grab specific wiki entries/manuals on whatever I was trying to do. I didn't go back to that file (its title makes it sound very beginner oriented),
It is beginner oriented, but it also describes the basics of how classes are inherited.
but instead found... there's a diagram version of it somewhere?
There is Evennia in pictures although it's more of an overview than showing deep technical details.
However, one that's still baffling to me is how commandsets are set up. Breaking the usual pattern, the file in your game directory in this case is
default_cmdsets.py
(vs.characters.py
,objects.py
, etc) and then imports (from evennia)default_cmdsets
to inherit fromdefault_cmds.CharacterCmdSet
compared to, e.g.DefaultObject
orDefaultCharacter
. And where the heck doesCmdSet
fit into that whole mess?I hadn't actually considered organizing default command sets into where they are located, not sure that would make much sense. Remember that the default commands of Evennia is just that - defaults intended to be replaced. The
default_cmds
is a way to gather all the default commands under one flat name space rather than the user having to remember where to find each command class when wanting to inherit from it. In the same way thedefault_cmdsets
need not be extendable by Python code in the same way that typeclasses are - so apart from adding/removing commands from them, that module is not likely to grow very much. Hence why all the command sets are gathered in one module.The three default cmdsets (UnloggedinCmdset, AccountCmdset and CharacterCmdset) are just convenient defaults that the default Evennia setup and command use. The
CmdSet
class is needed if you want to create you own cmdset. Take for example the 'dark room' in the tutorial; that temporarily replaces the CharacterCmdset with its own 'dark' Command set where you get 'room is dark' type messages from your normal commands.The contrib also does this, and it seems strange you're using a base class like that vs. a 'local to your game' version as with the others. It didn't stop me, but it felt like cargo cult programming.
Not sure what you mean by a 'local to your game version as with the others'. The typeclass bases do not exist in your game folder - all that are in the game folder are empty child classes inheriting from the actual base classes. The contrib works in the same way except we of course can't make empty classes in the game dir for every possible contrib. Inheriting from a parent class (or copy&pasting code to tweak it) is how library resources like contribs should be used.
I think, as you've pointed out, the info exists (its also in the code comments, which are great) so people can find it, although it's not the best organized and there's a lot of repetition and overlap. The tutorials wiki page has... at least five entries named some synonym of 'basic tutorial'? Then many of the other examples seem way too specific to be helpful to someone starting a project (Weather Emits seem like they'd be pretty close to the bottom of a priority list).
I see your point about the tutorials - they are somewhat ... diverse, mostly from having grown organically over the years as well as being written by different people. Ordering them up and making some sort of red thread through them would be useful I think.
Conversely, that I'm not just being critical, I think the Developer Central page is much better laid out, if more technical.
That's good to hear, but that main list too could use with some more sub-sections to better show useful links into otherwise hidden sections I think.
In my case, I ran into a really arcane (to me anyway) problem with the base classes, commandsets, and circular imports. Totally my bad, and while I did figure out how to get around it (basically, that I needed to refer to commandsets explicitly vs. importing), I think it's an example of the many ways a new user could get stumped.
Could you elaborate more on what the issue was there, not sure what you mean by "explicitly vs importing"?
I can but it's convoluted (hence not going into detail before). Hopefully you can follow, it feels like the only thing worse than reading someone else's code is... someone else second hand explaining why their code didn't work! Spam follows:
Since I was working from the turnbattle contrib, I had a bunch of modules for each aspect of the system (
tb_range
,tb_equip
, etc). They had lots of redundancies (each one defines an alternate version of the same new player typeclass).Yes, Fluttersprite had a very specific view for how that contrib should be laid out, as stand-alone packages rather than one package with sub-packages building from the main one.
I'd combined those, thinking about how I'd structure it for a game since it was meant to be practice. So for instance I moved the character stuff into
characters.py
as it was more logical to me than having a child class, making it default, and having it defined somewhere obscure.For the same reason as above, I'd moved the hooks from
tb_range.py
intoobjects.py
vs. creating a new object class. This required some of the functions fromtb_basic
. I left the new child typeclasses for weapons and armor intb_equip
, which also had the wield, unwield, etc commands. Meanwhile the commandset definitions were still intb_basic
, though I'd split them to create a general set (that I added indefault_cmdsets.py
exactly as in any tutorial) that included the commands to initiate combat and an 'in-combat' one that would get added and removed in play. Again, I wanted to practice a real design, and this seems common (it's how Arx does it, I believe).Long story short,
tb_equip
was importingObject
, which importedtb_basic
functions, which importedtb_equip
(forCmdWield
etc). ImportError. However even when I reorganized stuff (I splittb_basic
to have the script, commandsets, and functions across 3 modules soobjects.py
could import the functions and not the commandset), it still happened. Basically, the commandset was importing everything and so anywhere I imported it (to add/remove the set to combatants as they joined/left) it would throw up the error.You created a circular import situation. This is a tricky one and not always clear how to solve. Generally one must break one link in the circular chain by doing what is called a delayed import. Those
import
statements clash for you because they are all loaded immediately whenever the given module is loaded into memory. However, Python allows you to add imports also in functions. Here is a neat way to do that:import other_library import yet_another_library # let's say that if we imported 'my_library' here, we'd hit a circular import error. # instead we just set it to None for now. my_library = None def doing_stuff(): "This gets called later, so importing is safe now" global my_library if my_library is None: import my_library # now `my_library` is available globally as well as here # and you can use it as normal
The solution (and what I meant by 'explicitly') was adding it via its own path:
char.cmdset.add("path.to.CommandSet")
vs. importing and doingchar.cmdset.add(CommandSet)
.This is also a working solution to the circular import error problem, yes!
Perhaps not the correct professional programmer term! So, very simple solution (and i think this was shown in one of your examples somewhere), it just didn't occur to me for a long time because I didn't see why the way I was doing it wasn't the way I should be.
Yeah, circular imports is a Python issue one can run into. In this case it happened because of moving things around in a way that they depended on each other in a circular fashion. What you did was break one chain in the import circle, which fixed the problem.
Ultimately it's worth repeating that I still succeeded in getting everything working (uh, except the spawner, which seems buggy as heck)
Please make issues if you find bugs with the spawner (but a PR fixing some issues were merged a day ago or so).
, so the clearly the resources and information is there. I think organization could help, as well as what people have suggested in terms of system tutorials or base example worlds. Right now there's a gap between TutorialWorld (that's very... mud and minigame centric) and Ainneve/Arx (which are great examples but maybe too advanced for some to unpack).
There is no denying there is a big leap from the Tutorial world to Arx People using Evennia generally has very different end goals (not to mention backgrounds) and it's thus not always clear what would best fill that gap.
Thanks for the detailed answer, lots of useful insight there I think!
.
Griatch -
@thenomain said in Make Evennia 'more accessible' - ideas?:
@sab said in Make Evennia 'more accessible' - ideas?:
So I think one of the major things about Evennia that's overlooked from the perspective of the people who have some experience working on it, is that a lot of the people interested in using it to develop a game are coming into it with absolutely no coding skills at all. They might have ideas for systems--almost certainly things that they've experienced in games before, or would like to iterate on--but beyond that, they're starting from either zero, or a concept of what coding might be.
This is a problem with getting people developing TinyMUX (and Penn and Rhost) too. This has always been a problem. I have always taken the approach to take something that people know what it does and disassemble it in front of them.
In order:
- finger
- who
- where
Each builds on concepts of the previous, and people can start to see the patterns in the logic.
- finger: conditionals "if this then that" (+ formatting)
- who: loops (+ formatting)
- where: both (+ advanced formatting)
What, exactly, is the functionality expected from these three commands, what input and what minimum feature-set must they have to be recognized in the mush world as something useful to build?
I'm asking seriously, because commands like these vary a lot across the MU* domains. I don't even know what
where
does - show the location of a character you give as argument?
.
Griatch -
Where shows where everyone is. Appearance varies but here's an example:
Usage: +where +==~~~~~====~~~~====~~~~====~~~~=====~~~~=====~~~~====~~~~====~~~~====~~~~~==+ MY MUSH ------------------------------------------------------------------------ Offstage - Offstage Faraday, Griatch Offstage - Welcome Room Guest-1 ------------------------------------------------------------------------ 3 Online 0 IC 2 Record +==~~~~~====~~~~====~~~~====~~~~=====~~~~=====~~~~====~~~~====~~~~====~~~~~==+
Who is basically the same but with character info instead of locations:
Usage: +who +==~~~~~====~~~~====~~~~====~~~~=====~~~~=====~~~~====~~~~====~~~~====~~~~~==+ MY MUSH Name Faction Rank/Position Idle ------------------------------------------------------------------------ NEW Guest-1 1m STF GameWiz Army Private - Teacher 1s ------------------------------------------------------------------------ 2 Online 0 IC 2 Record +==~~~~~====~~~~====~~~~====~~~~=====~~~~=====~~~~====~~~~====~~~~====~~~~~==+
finger is basically a character profile. Exact fields vary wildly but the general idea is something like:
Usage: +finger <character name> +==~~~~~====~~~~====~~~~====~~~~=====~~~~=====~~~~====~~~~====~~~~====~~~~~==+ Stirling ------------------------------------------------------------------------------ Full Name Nyssa Stirling Callsign Whisper Eyes Blue Gender Female Hair Red Faction Navy Department Air Wing ------------------------------------------------------------------------------
-
@sparks said in Make Evennia 'more accessible' - ideas?:
- It's not recommended to use
filter
(normap
) in modern Python code. These can always be written using a list comprehension, without any lambdas:
I admit this one was a conscious choice to go against the grain. I chose to use a lambda there because I'd already explained lambdas in the
sorted
example, and I didn't really want to write a section on list comprehension too, since I worried about confusing people with too many concepts in short order.You're probably correct, though, that it makes more sense to just bite the bullet and add the explanation, since it is the better way to do it.
My personal feeling is that in example code, it'd be better to create small helper functions and avoid lambda entirely. In my experience, lambda in particular is pretty scary to non-coders. It's not very intuitive to a lot of people without a math background to see something that's literally Greek to them and immediately go, "Aha! Like a math function!" Meanwhile, we use regular functions/methods everywhere, so making some nested helper function or a global function that a command refers to is kind of a helpful example of their use. Turning the definition of lambdas into more emphasis of how functions are first-order objects and can be themselves passed to functions like sorted() might be more useful to people too. I know you did explain it in your example, I just think that particular bit might be more intimidating to a total newcomer than it looks.
- It's not recommended to use