@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 from default_cmds.CharacterCmdSet
compared to, e.g. DefaultObject
or DefaultCharacter
. And where the heck does CmdSet
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 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
into objects.py
vs. creating a new object class. This required some of the functions from tb_basic
. I left the new child typeclasses for weapons and armor in tb_equip
, which also had the wield, unwield, etc commands. Meanwhile the commandset definitions were still in tb_basic
, though I'd split them to create a general set (that I added in default_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 importing Object
, which imported tb_basic
functions, which imported tb_equip
(for CmdWield
etc). ImportError. However even when I reorganized stuff (I split tb_basic
to have the script, commandsets, and functions across 3 modules so objects.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 doing char.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).