10 Aug, 2011, Griatch wrote in the 21st comment:
Votes: 0
@Nich

Evennia is a MUD-creation engine, intended for the flexible creation of custom mud designs. That said, it's of course impossible to be equally useful or practical for all possible design ideas. :) I don't suggest Evennia is uniquely suitable for your particular ideas by all means (that's your call), but it sounds like there are some misconceptions and that you might be worrying about the wrong things.

Firstly, the database schema never changes at runtime in Evennia. You won't be adding or deleting new tables to the database no matter what you do. Don't confuse "Object", which happens to be the name of the root Typeclass (a normal Python class with some custom get/setattr methods), with the "ObjectDB" which is a Django database model decorated by said typeclass. Object can change to be whatever you like (like it is already everything from Rooms to Characters by default). ObjectDB cannot, it's really a very dumb thing that don't care much if its decorating typeclass is a chair or a general. The Typeclass system is described in quite some details in the docs, so I won't go into the details more here.

Now, in code (i.e. not on the fly), creating a venus flytrap typeclass could be done with one typeclass "Predator" (or similar) being combined with another typeclass "Flower" through normal Python multiclassing. Default Evennia won't let you activaly re-code that typeclass from the command line, but you can morph an already existing object into it just fine: Out-of-the box Evennia lets you transform one "object" into another using the @typeclass command (you can of course change and call it whatever you like, that's the point of the system).
In principle this is simple – all it does is tell the database model that it is now decorated by a new typeclass. That's basically all that happens to the database – the only complexity is if you had persistent attributes stored on the old object that differ greatly between typeclasses (the "max health" attribute of a "dragon" object is probably different from the "bunny" object it was just changed into). The default @typeclass command in Evennia offers reset options for that, for more advanced transitions you'd have to build your custom system anyway. All the while the database model is mostly oblivious of the drama. You could by all means store all such database in non-persistent storage too, without touching the database if you are really convinced database writes are too much to bear.

Players in-depth editing/redefining objects on the fly is a quite different matter though. Evennia works with full Python modules parsed at runtime to create its typeclasses, this is what makes it so flexible. You can in principle edit the modules and have the change be applied while the server runs (@reload), but that's no help if you want users to modify things. For that you'd need to add some some sort of slot mechanism, or try your hand with defining a safe code subset for them to use. As mentioned by others, it is a non-trivial problem and you'd need some serious planning to make that safe.

Quote
If I would make any change to Evennia as a base, though, it would be to add a layer between the DB and Typeclass so that someone wanting to dodge the serializer can subclass that level, rather then turning the serializer off. i.e. Typeclass should extend Object, not vice versa.

Are you sure you don't confuse Object with ObjectDB above? Just to make sure: Object is a typeclass, and is a child of Typeclass simply because of naming convention (Object felt like a better default for people to inherit from), they are otherwise the same thing. ObjectDB is just one of three typeclassed database models, the one that handles entities having an in-world existence (the others are ScriptDB and PlayerDB). Having Typeclass inherit from ObjectDB … doesn't make much sense to me. I could well be misunderstanding what you are saying here though.

It's always interesting with feedback and discussions. And making an on-the-fly creation system for players to use is a worthy design challenge indeed. I'm just not sure Evennia's database abstraction system is really what you should worry about. :)
.
Griatch
11 Aug, 2011, Nich wrote in the 22nd comment:
Votes: 0
Griatch said:
misconceptions


Wow, no kidding.

Griatch said:
Firstly, the database schema never changes at runtime in Evennia. You won't be adding or deleting new tables to the database no matter what you do. Don't confuse "Object", which happens to be the name of the root Typeclass (a normal Python class with some custom get/setattr methods), with the "ObjectDB" which is a Django database model decorated by said typeclass. Object can change to be whatever you like (like it is already everything from Rooms to Characters by default). ObjectDB cannot, it's really a very dumb thing that don't care much if its decorating typeclass is a chair or a general. The Typeclass system is described in quite some details in the docs, so I won't go into the details more here.


That's good, and makes sense, but obviously rules out persisting classes created at run time. I was right, but for the wrong reasons.


Griatch said:
You could by all means store all such database in non-persistent storage too, without touching the database if you are really convinced database writes are too much to bear.

User objects really *do* need to survive between crashes/downtime, though, and I'd prefer not to keep everything created in memory at the same time besides. There will be a *lot* of this happening, I'm not planning on having it be a niche feature (for all the trouble I'm having… :lol:)

Griatch said:
Players in-depth editing/redefining objects on the fly is a quite different matter though. Evennia works with full Python modules parsed at runtime to create its typeclasses, this is what makes it so flexible. You can in principle edit the modules and have the change be applied while the server runs (@reload), but that's no help if you want users to modify things. For that you'd need to add some some sort of slot mechanism, or try your hand with defining a safe code subset for them to use. As mentioned by others, it is a non-trivial problem and you'd need some serious planning to make that safe.

A slot mechanism is what I'm aiming towards right now. Developing a safe scripting language seems difficult, and unfriendly besides.

Griatch said:
Are you sure you don't confuse Object with ObjectDB above? Just to make sure: Object is a typeclass, and is a child of Typeclass simply because of naming convention (Object felt like a better default for people to inherit from), they are otherwise the same thing. ObjectDB is just one of three typeclassed database models, the one that handles entities having an in-world existence (the others are ScriptDB and PlayerDB). Having Typeclass inherit from ObjectDB … doesn't make much sense to me. I could well be misunderstanding what you are saying here though.


Ah, since Typeclass always holds a TypedObject, I confused the two.

Rather then try to carry on under false assumptions, then, I'll just ask a question. If someone wanted to supply their own Object models from DB (suppose, just for an example, they already have a server with a particular DB model, but they'd like to port the code to Evennia), what would be the most minimal way of making that change? Is that possible at all?

Griatch said:
It's always interesting with feedback and discussions. And making an on-the-fly creation system for players to use is a worthy design challenge indeed. I'm just not sure Evennia's database abstraction system is really what you should worry about. :)


Yes, you're probably right. And anyways, the component (slot) system isn't running into major headaches yet, since each part can be treated as an object both in the DB and python models.
11 Aug, 2011, Griatch wrote in the 23rd comment:
Votes: 0
Quote
[…]That's good, and makes sense, but obviously rules out persisting classes created at run time. I was right, but for the wrong reasons.

You can use metaclasses on a Typeclass too if you want (it is a mostly normal Python class, as said), but sure, before instantiation there will not yet have formed a connection to the database. If you don't need to modify the class itself however, you could easily adapt it at instantiation with the at_object_creation hook (say, for a slot mechanism).

Quote
User objects really *do* need to survive between crashes/downtime, though, and I'd prefer not to keep everything created in memory at the same time besides. There will be a *lot* of this happening, I'm not planning on having it be a niche feature (for all the trouble I'm having… :lol:)

One less worry then. :)

Quote
Ah, since Typeclass always holds a TypedObject, I confused the two.

Vice-versa, the TypedObject also holds a reference to its Typeclass. The two are connected to each other.

Quote
Rather then try to carry on under false assumptions, then, I'll just ask a question. If someone wanted to supply their own Object models from DB (suppose, just for an example, they already have a server with a particular DB model, but they'd like to port the code to Evennia), what would be the most minimal way of making that change? Is that possible at all?

You'd need to write a converter (probably as a separate program) so as to convert the fields of the foreign database to the corresponding Evennia entities. If Evennia happens to have a matching database field you just copy it over directly. If it doesn't, you put it in an Evennia Attribute instead. You also need to write a custom typeclass to make sure the foreign object actually behaves the same way in Evennia as it did in the original. One of our contributors has a work-in-progress Evennia converter for SMAUG object databases, just to take one example.

One suggestion is to lurk in Evennia's IRC channel #evennia on FreeNode as well as hang out on the mailing list, it's a good way to get tips and hints. :)
.
Griatch
20.0/23