So, it took under 30 minutes for me to follow the tutorial for hello world here. Would have been much faster, but that is a fairly outdated tutorial. Mostly the issue is that twistd has changed a lot. Here’s what I ended up with for the twistd plugin code if anyone is interested:
from zope.interface import implements
from twisted.plugin import IPlugin
from twisted.application.service import IServiceMaker
from twisted.application import internet
from twisted.python.usage import Options
from nevow import appserver
Command-line options for the web server.
optParameters = [
('config-file', 'c', None, 'The file to load configuration from.'), ]
The plugin that starts the website
tapname = "helloworld"
description = "hello website"
options = HelloOptions
def makeService(self, options):
self.site = appserver.NevowSite(helloworld.HelloWorld())
self.webServer = internet.TCPServer(8080, self.site)
thePlugin = HelloWorldPlugin()
With that finished, it’s off to the ‘hello Axiom-world’. But first, some MV3D stuff.
I’ve been doing a lot of refactoring, reformatting, and re-testing of code. I started changing things up so that instead of inheriting from something like odeObject in order to be an object in a 3D environment that has a physical representation, I’m adding Body classes that handle physical and visual representations. This way, those can just get sent to the client as they will have no data in them that the client should not see.
Right now, there is a FastObject3D class that you can inherit from that basically aggregates its position updates and queues them for all objects going to a connection. The queue will drop updates if there are too many, and updates sent to the client are thinned down by a few factors such as distance between the PC and the object that is moving. This was a direct result of the load testing I did a while back with thousands of objects. The load ended up not being the physics engine once I got things straightened out there, but instead, it was in serializing all the updates to send them down the wire. I’m thinking that I’ll move FastObject3D’s logic to the Body classes more or less, and then add some extras to it. One thing I’d like to do to make user experience better is whenever there is a position/rotation update that is significantly different from what the position/rotation is on the client, the client will average that in over a few frames to make it less jerky. I’ve put in some thinking on a related subject of “the client is usually right about where he’s looking,” but I’m still not ready to make a decision on that one yet. The other thing I may add in if I get really fancy is to have the update queue send info to clients/other servers over UDP as just a stream of bytes. That could speed it up even more. Though right now, I don’t really have speed or bandwidth problems, so that would be a premature optimization, imho.
One more thing to mention about the Body classes. They need to handle collisions between objects in adjacent areas that have different coordinate systems. To explain, MV3D has areas, which don’t have a size or a position (except OctreeArea since Octrees require it). You can connect areas with gateways, and one thing you can do with gateways is specify a translation or rotation for any object that passes through the gateway. This is absolutely essential since MV3D uses floats instead of fixed point. Without it, as you got further away from (0,0,0), the accuracy of the physics will get worse because of how floating point numbers work. Anyway, now there is no need to extend things very far from (0,0,0). Just make a gateway at (0,0,10000) that goes to (0,0,0) in its destination. Anyway, this brings about an interesting challenge when an object is on the border between two areas that are in different coordinate systems. The physics engine only understands one coordinate system. Currently, only Bipeds can handle collisions between areas in different coordinate systems. They do it by creating duplicate physics bodies in each area near their position. This works, but is not very efficient and also causes some strange artifacts when passing between areas. It’s not efficient because the “main” body has to update the sub bodies positions every frame. I’ve tried just adding colliders in the other areas, but that doesn’t hold up if the object rotates (because they act like two objects connected by a very long pole). The same thing if I create two bodies and use a joint to keep them in sync. Basically, I’m not sure how best to handle this, and it is fairly important. I need to figure this out before I can move on basically, but at least with Bodies, it’ll be all kept in the same place.
What’s next after I get all of that working? I’ll have to yank out 90% of all the currently created objects’ code and replace it with Bodies. That will be fun. Then, well I think I want to create a new object using Bodies to see if it is sufficiently painless. I’m thinking of making a sword object that is modular and is derived from three models so that I can make a random sword generator (after making multiple blades, hilts, and guards). From there, I’d like to do some more load testing, some refining of the world editing tools, and lots of other things. I really need to get v0.4 out the door though, so I’ll have to draw the line somewhere.
All these changes have been taking a while to make because other than not having much time to work on them, I’m also reformatting modules that use the old formatting style, switching all unit tests to trial, adding unit test coverage where there is none, and refactoring quite a bit. More later.