Handling default attributes
From WorldForgeWiki
Up until now the default values for attributes defined in server class rules have simply been added to the entity instances at creation time, then overridden as the server runs. Starting with cyphesis 0.5.17 the default values are now stored in one place in an object associated with the class, and only attributes which have been overridden are stored on the instances. This opens up the possibility of modifying the protocol conventions so that the default attributes are not sent to the client in response to a Look operation, and instead the client session library Eris is responsible for maintaining the defaults from the class definitions, and presenting the results of combining the defaults with the instance attributes in the correct way to the client API.
Discussions
Extend the TypeInfo class to handle all sent info
Currently the TypeInfo class only contains information on the type hierarchy. However, all type info is sent from the server, including default attributes. The TypeInfo class should therefore be extended to also provide methods for inspecting this data. This will make it easier for authoring tools, since they can use this data when creating new entities. Another possible advantage could be that entities on the server that use default values, for example the default bbox, doesn't send this to the client unless it has been changed, depending on the client using the bbox set in the type info. This would save some bandwidth.
I think the most valuable aspect of this is in the use of default values for attributes defined in the class, and removing the need to send values for these attributes on the instances unless they have been overriden. As cyphesis uses the same model for attributes internally when handling this AI, a switch to a model where Sight operations only include data about instance attributes would safe massively on memory usage and processor load of the server. /al
I've created another blueprint, dependent on this, for the a little more complex task of making sure that only attributes that are changed are transferred. The main reason why I want to separate them is that I think that the latter task is quite large, and my main concern currently is getting entity persistence to work. With this blueprint implemented it's very, very easy to quickly create or alter the world from Ember, but without proper entity persistence all the work one would put into crafting a world would be lost whenever the server either is restarted or crashed. /erik
Only send/store attributes that have been changed from their defaults
With better support in TypeInfo for accessing the default attributes we can alter the way entity attributes are transmitted to the client (and also stored locally on the server) to only send/store those attributes that have changed from their default values. For most entities this would result in major decrease of traffic and storage needed. Any such effort would require a coordinated update on both the server and client (or rather eris) side.
The server work for this change is effectively done. All that is left is to flip a couple of switches to stop sending the defaults. Now that defaults are being stored in a sane way on the client side, we are well on the way to it being implemented on the client side, though inheritance is far from sorted yet. /al
Would this change be optional, or would the changes needed in cyphesis require that all clients connecting used the new Eris release? If the latter, how would this be negotiated between the client and server? I know Atlas has a protocol resolution step in it's handshake; could that be used for marking whether the client could handle this? /erik
It will break to some extent all clients with earlier versions, but I really don't see this as a problem at the current point in our development. Atlas has a codec negotiation step, but currently nothing is done with protocol versions. In a sense this is not even really a change in protocol at the layer that Atlas-C++ implements, but is rather a change in a higher layer. Older clients are still going to see the types, locations and velocities of everything, though bounding boxes for most things will disappear. /al
Regarding the Eris part, a simple solution would be to alter the Eris::Entity::init method to copy all attributes from its types. The alternative approach would be to instead alter the Eris::Entity attribute accessing methods to perform lookup into the TypeInfo whenever an attribute is requested. The former is perhaps more straight forward and easier to implement, while the latter would save on some memory (though I don't think that the memory usage is too great since only a limited number of entities are ever shown to the client at any time) but would require some refactoring of the attribute accessing code (for example getAttributes()). /erik
The latter seems the right way, but the former would be simple. Inheritance is going to be vital though, and is going to require TypeInfo to store the attribute defaults specific to that class separately, then compile and override the inheritted attributes which will change and propagate down the tree whenever a TypeInfo node is updated. /al