{"id":306,"date":"2008-02-29T03:54:25","date_gmt":"2008-02-29T07:54:25","guid":{"rendered":"http:\/\/www.rakkar.org\/blog\/?p=306"},"modified":"2008-02-29T03:54:25","modified_gmt":"2008-02-29T07:54:25","slug":"replica-manager-2-done-video","status":"publish","type":"post","link":"https:\/\/rakkar.org\/blog\/index.php\/2008\/02\/29\/replica-manager-2-done-video\/","title":{"rendered":"Replica Manager 2 Done + Video"},"content":{"rendered":"<p>\t\t\t\tI spent an entire day on Sunday thinking about the architecture on how to write a generic system to create, destroy, serialize, and control scope over networked objects in C++. It&#8217;s a very hard problem to solve because you know nothing about the game objects themselves, or what complexities the end-users might introduce with their specific architecture.<\/p>\n<p>In the end I decided on 3 classes. One class, ReplicaManager2, is the base plugin for the system. All it does is essentially serialization, deserialization, transmission, and bookkeeping. Stuff you wouldn&#8217;t normally care about. I have the user pass a class factory that generates connection instances, one per connection. This controls high-level and non-object specific functionality such as how to create object instances. Lastly, there is the base class Replica2, which game objects should derive from.<\/p>\n<p>The main reason I did it this way, rather than putting everything in the ReplicaManager2 plugin (as I did in its predecessor) was so that the functionality can be easily overridden. This should solve a problem I had with the old system, where I ended up passing a ton of data to the callbacks in order to force it to get it to do what I wanted. By assuming users will override functions, this also gives me the ability to make assumptions and thus much more elaborate functions.<\/p>\n<p>Improvements it has over the old system are:<\/p>\n<p>1. Relay across systems actually works correctly. So you could have a server cluster, with n clients on each server, and everything would just get sent out properly. It automatically deals with cyclical connection graphs up to a depth of 1 away from the source node.<\/p>\n<p>2. Defaults to polling for changes. Each tick, if an object is now constructable, or in scope, and it was not in the last tick (or vice-versa) the object is created or destroyed appropriately. The object is also serialized every n milliseconds, and if it serializes differently under the same context, the newly serialized value is transmitted. This is easier to use than event-based updates (which are also supported) so the user has to write less code.<\/p>\n<p>3. Downloads construct all objects first, then deserializes them, and in the order they were originally created. This is likely what a user would do were they to hand-write the download system, and maximizes the chance that pointers and other dependencies will be valid on deserialization. This also allows you to have objects that cross-reference each other when deserializing, each both have already been created anyway.<\/p>\n<p>4. It&#8217;s easier to modify events and more information is given about what triggered those events. For example, it&#8217;s now trivial to send using different reliability types based on the context of what is being sent, something that was hard to do before.<\/p>\n<p>5. Changes are easier to initiate on the client, especially construction, which before would have taken custom game code.<\/p>\n<p>Here&#8217;s a video that goes over the system. I start out too fast because I was tired of starting over when I made mistakes, but later on it gets better.<br \/>\n<a HREF=\"http:\/\/www.rakkarsoft.com\/raknet\/manual\/ReplicaManager2.html\">http:\/\/www.rakkarsoft.com\/raknet\/manual\/ReplicaManager2.html<\/a>\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I spent an entire day on Sunday thinking about the architecture on how to write a generic system to create, destroy, serialize, and control scope over networked objects in C++. It&#8217;s a very hard problem to solve because you know nothing about the game objects themselves, or what complexities the end-users might introduce with their [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[],"_links":{"self":[{"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/posts\/306"}],"collection":[{"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=306"}],"version-history":[{"count":0,"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/posts\/306\/revisions"}],"wp:attachment":[{"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=306"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=306"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=306"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}