Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

[Released] Bolt, The new generation of networking solution for unity!

Discussion in 'Assets and Asset Store' started by fholm, May 30, 2014.

  1. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    I have not taken a look at that specific asset, it depends a bit on if the resoluting output of it is deterministic or not, and how much it affects gameplay.
     
  2. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Those of you that have purchased through the asset store and want to download the latest version of Bolt can go to this link: http://www.boltengine.com/AssetStore.aspx and punch in your asset store invoice number, and it will download whatever version of bolt is the latest, this means you don't have to wait for the asset store to push the update through its pipeline.
     
    Last edited: Jun 18, 2014
    yung likes this.
  3. Ghosthowl

    Ghosthowl

    Joined:
    Feb 2, 2014
    Posts:
    228
    So I spent a good chunk of today trying to debug my animation and generic events systems. After a lot of head scratching I was able to fix my generic event system but not the animation. I fixed the generic event system by marking my events as persistent to survive level loads. Okay, that works, now for my animation event system. This I could not get to the bottom of but after fiddling around with the stand alone version of my current project, I realized I don't know, nor understand what the start up and shutdown processes are for loading scenes and instantiating objects. I am convinced that this is the cause of things breaking as my both my uLink and offline builds work without issue.

    So the final straw for me was this error I ran into. I am trying to switch scenes when a users connects and disconnects. Connecting works perfectly fine, disconnecting however does not. Here is what I am trying to do. Upon a user issuing a disconnect command, he needs to load a scene that contains all the menus. In my build settings I have the following 3 things.

    • 0 - Menu Scene (this is what I want to load)
    • 1 - Bolt Network Map (this is the main Bolt map, that the user is active in and is currently loaded)
    • 2 - Bolt Clear Scene

    So I would think to go to the menu scene, I would kill off the user's entities, disconnect them and then load the scene right? So I do this:

    Code (csharp):
    1.  
    2.   public void Disconnect()
    3.   {
    4.   //Disconnect us from the network
    5.   BoltNetwork.Shutdown();
    6.   System.Threading.Thread.Sleep(100);
    7.   //Load the menu scene
    8.   Application.LoadLevel(0);  
    9.   }
    10.  
    Server Code:

    Code (csharp):
    1.  
    2.   public override void ClientDisconnected(BoltConnection arg)
    3.   {
    4.   BoltEntity entity = arg.userToken as BoltEntity;
    5.  
    6.   if (entity)
    7.   {
    8.   BoltNetwork.Destroy(entity);
    9.   }
    10.   BoltConsole.Write("Destroyed Client " + arg.id);  
    11.   }
    12.  
    This however fails completely, it simply initiates the connection sequence again and the previous entity remains in the world and a new one is spawned for the user, so now user 1 has 2 entities. If I change the last line to: LoadLevel(1) the entity is properly destroyed and my menu scene loads. But this does not make any sense to me. When I then stop the client after doing this I receive 2 errors:

    InvalidOperationException: Node is not in this list
    BoltDoubleList`1[BoltCallbacksBase].VerifyInList (.BoltCallbacksBase node) (at c:/Users/Fredrik/Documents/bolt/src/bolt/bolt/collections/BoltDoubleList.cs:125)
    BoltDoubleList`1[BoltCallbacksBase].Remove (.BoltCallbacksBase node) (at c:/Users/Fredrik/Documents/bolt/src/bolt/bolt/collections/BoltDoubleList.cs:62)
    BoltCallbacksBase.OnDisable () (at c:/Users/Fredrik/Documents/bolt/src/bolt/bolt/BoltCallbacks.cs:20)

    m_InstanceID == 0


    The last one being ambiguous. Obviously I am doing something wrong and not understanding this process. I think my event system problem is linked to it too. I think the player is being instantiated somehow and maybe deleted and re-instantiated or instantiated in the clear scene or something to that degree? because when adding listeners (the player object does this when it is instantiated) they always end up null. I am using the latest version (0.2.1.0)

    6 am here and going to bed now. T_T Here's hoping you could give me / us a quick explanation so I can better debug the issue. Thank you as always~
     
  4. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Hey!

    So I puished another update, 0.2.1.1, contains a few bugfixes I had forgot to merge in and some other things, but in lieu of ghosthowls post I took a look at how Shutdown was working, and while not a direct bug there were some... quirks, with how it worked and it would behave differently depending on *when* in bolts update cycle it was called. I resolved all of those issues and also added a new sample which sets up a server and clients, with two different maps - and will handle all cases correctly (server disconnects, client disconnecting, etc.), you'll find it in bolt/samples/shutdownstartup, you'll find the release notes here http://www.boltengine.com/Releases.aspx#Beta_0_2_1_1 and down below:

    Beta 0.2.1.1

    Fixed: Mecanim parameters will not be set if the Animator component is disabled.
    Fixed: Resolved exception thrown when a destroyed entity got a lost or delivered packet notifiication.
    Fixed: Fixed an issue with the BoltConfig constructor which would cause unity to throw errors when access a configuration asset in Awake().
    Fixed: Bolt will now correctly disconnect all connections when shutting down.
    Fixed: Fixed several subtle quirks causing Shutdown to act differently depending on when it was called.

    Changed: ShutdownDone has been removed from BoltCallbacks since it would never get called as all objects would be destroyed before the callback would fire, BoltNetwork now exposes a .NET event called "ShutdownComplete" which you can subscribe to. Note that after each invocation of the event it will clear it's callbacks so you have to re-register them every time.

    Sample: There's a new sample in the bolts/samples/shutdownstartup folder which demonstrates a clean shutdown-startup cycle for both the client and server. To run it set up your build settings to that the scenes are in this order:

    0: StartupShutdown_Menu.scene
    1: StartupShutdown_MapGreen.scene
    2: StartupShutdown_MapRed.scene
    3: BoltClearScene.scene

    Run Bolt/Compile and then build the project like you normally would (not using the map launcher), and start as many instances as you want and connect them together.

    Getting the new version

    If you bought through the asset store and don't want to wait for the approval process, head to http://www.boltengine.com/AssetStore.aspx and punch in your invoice ID and you will be get to download the new version.

    If you bought through www.boltengine.com, check your mail.
     
  5. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Try to restart unity/mono develop, very rarely this happens, or you could be out of disk space?
     
  6. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Hi fholm,

    Loving the asset so far. Currently working through the tutorial, (there are a couple of little things out of date but I'm sure you are already aware). I'm wondering if you have a good .gitIgnore set of rules for Bolt?

    I figure if it often hinges on compilation, is there a directory or a few directories I can leave off version control, and when I work on it on my laptop I can simply grab the latest version and run the Bolt compile function?

    UPDATE: Ignore below, as always, a restart fixed everything.

    Additionally, following the tutorial with the current Asset Store version, I got up to the:

    Code (CSharp):
    1. using UnityEngine;
    2. public class PlayerSerializer : BoltEntitySerializer<IPlayerState> {
    3.   public override void Attached (IPlayerState state) {
    4.  
    5.   }
    6. }
    section, and in MonoDevelop, the 'IPlayerState' goes red in the Attached function and tells me that it doesn't exist in the current context. Having just updated to the latest version, it suggests I autocomplete with ICarPlayerState or ITeleportPlayer state, which I believe means my PlayerState isn't compiling. I've tried adding and deleting a group, then recompiling it, as well as recompiling Bolt. I also moved it into just a 'Prefabs' directory, thinking maybe that would be the issue, but I can't seem to get it to compile so I can use it. Any help would be excellent!
     
    Last edited: Jun 19, 2014
  7. jasonMcintosh

    jasonMcintosh

    Joined:
    Jul 4, 2012
    Posts:
    74
    Alpha and beta testing would probably lead to a more robust final release, so I would vote for that.

    But prioritize with the big picture in mind. Demand seems high for this feature, but, honestly, there is a lot of fundamental work remaining. QA and documentation are as important as code! One month or three months for this feature, the world won't end.

    And remember to sleep and spend time with your loved ones. Nothing is worth more than that. :) (Yes, I can speak from cold, hard experience.)
     
  8. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Hello again!

    Also while it's obviously not really specific to you, I like to extend all of my scripts from PimpedMonoBehaviour, which is an asset I bought off the asset store to add tooltips and groups to the inspector. In cases where I need to extend from say BoltEntityBehaviour, is there a way (save for editing the BoltEntityBehaviour itself) that I can incorporate the PimpedMonoBehaviour functionality as well as extend from BoltEntityBehaviour?
     
  9. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Good point, I will make sure to do this.

    A core staple of Unity is that you should restart the editor after upgrading any assemblies. Since especially the editor assembly might be "locked" in memory and wont refresh from disk. I will make sure to put a notice of this somewhere in the release .zip from now on.

    I agree with you on alpha/beta tests, and I will go that route. I did a quick test last night with two servers, and you basically end up with a function call like this on the current server:

    Transfer(BoltConnection targetConnection, UdpEndPoint toServer, params BoltEntity[] controlledEntities);

    I just did a basic test with a cube, but it does work.

    I think about ~3 months is reasonable for this feature, yes. I want the final 1.0 out in august first, and then I can start looking at making this feature solid.

    Yeah family is important, my son turns 2 today so going to spend the whole evening with the wife and kid :)

    I will look into this, right now it's not possible. But I've been thinking about having a "script" mode which would compile into script files in /Assets/Plugins/Bolt instead of a dll into /Assets/Bolt/Assemblies. This would let you have the core behavior inherit from a custom class of your choosing, as long as that custom class also was in the Plugins folder.
     
  10. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Thanks for the quick reply! I think my error took over the original point of my post though, hehe. Do you have a list of folders in Bolt that I can get my version control to ignore? So that I don't have to commit compiled files etc., and can instead compile them whenever I pull a new copy from Github?

    And as a second point, in the tutorial it appears that the Mechanim syncing functionality has to have a Bolt Entity on the object with the Animator, is this right? Currently my 'Player' object is the parent, with the 'BoltEntity' on it, and my model is a child with the Animator attached. Is there a way to point the BoltEntitty to the Mechanim child? Or do I have to have my whole player confined to one object?
     
  11. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    The main files and folders for bolt you need are:

    files:

    bolt/assemblies/bolt.dll
    bolt/assemblies/bolt.dll.meta
    bolt/assemblies/editor/bolt.editor.dll
    bolt/assemblies/editor/bolt.editor.dll.meta

    folders (everything in these):

    bolt/assemblies/udpkit/
    bolt/resources/
    bolt/scripts

    I generally also commit the bolt.user.dll file, but you can regenerate it with Bolt/Compile when you want. It is incredibly important that you commit the .meta files also, or unity will break the references between the scripts in the assemblies and the components attached to your objects.

    I usually just commit everything in bolt/assemblies, bolt/resources and bolt/scripts.

    That should be fine, bolt uses GetComponentInChildren<Animator>() to find the animator component.
     
  12. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Ah excellent, thanks very much for the list! (And the insanely awesome asset.) I spent just today on it, and already have multiplayer in my game, with authoritative movement. Incredible. I'm going to have a look at the lag compensation tomorrow, and going by the tutorial it's just as easy as the rest of the engine!

    Also, I own a few of your other assets, and I wanted to mention that the branding work you've done on this is really really nice, haha. Your work is always top notch, but the design stuff takes it up another level.
     
  13. Ghosthowl

    Ghosthowl

    Joined:
    Feb 2, 2014
    Posts:
    228
    Wow fholm, you never cease to amaze me. I woke up to find a new version of Bolt and long and behold, my issues are fixed. Without using the Map Launcher, my stand alone build now works and goes to the scene appropriately. There is one small thing though, the server calls an error on my ClientDisconnected callback (as seen in the code above):

    entity is not attached
    UnityEngine.Debug:LogError(Object)
    BoltLog:<.cctor>b__3(String) (at c:/Users/Fredrik/Documents/bolt/src/bolt/bolt/BoltLog.cs:45)
    BoltLog:Error(String) (at c:/Users/Fredrik/Documents/bolt/src/bolt/bolt/BoltLog.cs:156)
    BoltEntity:Detach() (at c:/Users/Fredrik/Documents/bolt/src/bolt/bolt/entity/BoltEntity.cs:644)
    BoltCore:Destroy(BoltEntity) (at c:/Users/Fredrik/Documents/bolt/src/bolt/bolt/BoltCore.cs:209)


    Checked the docs and tut and I am not sure how to detach an entity properly. I only see callbacks for when detaching occurs.

    Also I was able to fix my event systems by restructuring the player's a bit to better fit Bolt and it's way of handling things.. Very cool to see you considering these huge new features and addons. Definitely want to beta that, would be more than happy to :D.

    But enough from me - Happy birthday to your son! Enjoy the rest of the day with him and your wife. You damned well deserve it!
     
  14. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    I'm glad Bolt is working out for you! :)

    Yeah I did pay an artist to do the branding for me this time :)

    Hehe ;) I'm glad it works for you.

    This indicates that you are destroying the same entity twice, basically it saying that the entity you called destroy on is not attached to the networking (which either means it's been detached already, or you are trying to destroy one that wasn't attached to begin with).

    Next up is the master server, which should be out next week some time. After that NAT punching will be added to the server, and then we're starting to see the end of all the major features: only playmaker integration and wp8 support left.

    This I will! :)
     
  15. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    296
    First off, this looks amazing. I just saw this after working a bit with both PUN and uLink - so I haven't really gotten past the basics yet, but the more I read/see the more I'm interested! At first I was thinking - oh look, another asset store networking "solution" (sorry, I've seen a few of those), but seeing who was behind it, I've definitely noticed your name and avatar pic several times as I've been reading up on Photon. You seem to know your stuff!

    I will keep reading and likely buy.
    __

    I'm probably one of an increasing demographic on these forums - a self-taught, decently competent game programmer, but very much a n00b at network programming.

    In the last week I've learned some with PUN, and wrote a little chat lobby, which was fun - but navigating through some of the p2p stuff seems a bit flimsy (I guess just not having an authoritative server seems untenable for the games I'm trying to make). Additionally, sending over (what I thought) was basic data has been problematic.

    For instance, I have a concept in my game where a user can create a team with a custom name and invite one other person. When the team list changes, somehow (someone creates/deletes, leaves/joins) I want everyone to be able to see that.

    Of course, when a new person joins the game, I also want them to receive the full list of teams (with all the team names and user names in that team) - from the master client.

    (Pic) http://forum.exitgames.com/download/file.php?id=231&sid=635e8973c2763e1464884f179eb097ac

    I would store the team info like this:

    [System.Serializable]
    public class Team{
    public string TeamName;
    public string[] TeamMembers;
    }
    public Team[] AllTeams;

    This quickly turned into something more complicated than I thought because there doesn't seem like an easy way to send the data in AllTeams via RPC without writing some custom serialization, even though each just contains a string and a string array.

    uLink seems to be better at this as http://developer.muchdifferent.com/unitypark/uLink/Serialization states that it can easily serialize: "Any user defined class where all members have types described in this enumerated list. This works recursively in a hierarchy of classes as long as all members are ultimately defined in this list."

    Now, maybe (probably) this is just user error on my part, and it's possible to do the above in both, but your system looks slick, and fun to learn with - if it can handle the above usecase elegantly, then it's a no brainer purchase for me.


    Like I said, I'm going to keep reading your website/tutorials before I bug with any more specific questions :)

    Cheers
    Jesse
     
  16. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    JesseAlexander, uLink can indeed serialize user defined classes pretty easily. I don't know if Bolt can, but I can't imagine it would be terribly difficult to implement... and it should be implemented. I was amazed and happy I didn't have to build 10 different arrays of arrays of whatever and send them over the network, only to rebuild the custom class on the other end using uLink.

    I find that there are a lot of uLink features I'd probably (and by probably, I mean definitely) want with Bolt; however, I realize the product is very new and a lot of other core features need to be implemented first.

    However, the wishlist is (in no order, and excuse my terminology):
    • Network Object Migration between Bolt servers
    • Data serialization for Networked Objects between Bolt servers (so that object above can move its data with it) - customizable, or maybe more like we have to code it, as all data is not necessary
    • Communication between Bolt servers (Peer2Peer RPCs in uLink)
    • Serializable custom types (JesseAlexander's post)
    • Approval/Deny methods prior to creating/validating a connection (was stated this was there, just not exposed)
    • When a Network object is migrated, inform the client of this and allow sending data to direct client which scene to load, etc.
    Probably other stuff, but I admit, I purchased Bolt; however, I have yet to use it. Too entrenched with uLink and need some other features before I can switch, though I do have these strange plans to try to get both running at once - Bolt for the player movement / uLink for everything else.

    It looks to just keep getting better for Bolt, so keep it up!
     
  17. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    I'm glad you are interested i Bolt, and yes we're trying hard to just not be "another networking solution" and offer something that actually is new and different (and better? ;p)

    Yes, there is a lot of handy work in sending arbitrary data over the wire in most other networking solutions.

    I can't access this picture (I don't have a Photon forum account).

    Yeah, this is a huge issue with a lot of libraries: Transferring large amounts of arbitrary data.

    The uLink solution is pretty decent, and while Bolt does not have anything like that currently - I got something... very nice, in store.

    We have chosen to base our custom object serializer on google Protocol Buffers, and the protobuf-net implementation. The way it will work is this:

    You define your protocol buffer object in a designated file, something like this:

    Code (CSharp):
    1.     [ProtoContract]
    2.     class Person {
    3.         [ProtoMember(1)]
    4.         public int Id {get;set;}
    5.         [ProtoMember(2)]
    6.         public string Name {get;set:}
    7.         [ProtoMember(3)]
    8.         public Address Address {get;set;}
    9.     }
    10.     [ProtoContract]
    11.     class Address {
    12.         [ProtoMember(1)]
    13.         public string Line1 {get;set;}
    14.         [ProtoMember(2)]
    15.         public string Line2 {get;set;}
    16.     }
    Bolt will detect this file and compile it into a protobuf-net assembly for you, and it will also generate a serialization assembly on the side using the protobuf-net tool-chain, which removes the need for any type of runtime reflection or other annoyances, which gives great performance and ensures iOS compatibility.

    There will be a new object type on events and states called "Object" (generic enough for you? ;p), where you can just set an instance of your protobuf object, and Bolt takes care of the rest. Now, the object on here will be limited to a configurable (128 bytes by default) size limit. Since this is sent with the gameplay data you can not expect to send huge amounts of data here.

    But, there will be a new method available on the BoltConnection with the following signature "TransferObject(object obj, int packetSize, int packetsPerSecond)" which lets you send an object to the other end of the connection - streamed at a configurable kb/s rate (using packetSize + packetsPerSecond). This mode of transfer is 100% reliable and ordered and have no limit on size or any other arbitrary restriction.

    This lets you send *any* type of data with Bolt, wanna transfer images? height maps? meshes? you name it.

    These two are coming, I would say within 3 months.
    This will also be available in the server-transfer update.

    The ProtocolBuffer support will be available in 0.2.2.0 (next feature update), expect it in a week.

    Oh, good you reminded me of this I completely forgot. This will be in the next update coming in a few days 0.2.1.2.

    The way this will work is that because we are using UdpKit, we can "switch" the connection to the server behind the back of the client, so all objects and references will stay the same. And because Bolt uses a per-connection identifiers for objects you can keep all of your existing objects on the client. Yes there will be a callback for this when it begins and when it ends.
     
    Yukichu likes this.
  18. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    296
    Awesome, those future plans sound excellent!

    Just picked this up and went through the tutorial. Apologies if you covered this somewhere but what is the best method to do an fps cam on the client while still syncing relevant third person mecanim animations to remote clients?

    If you had an example of this even better, if not I'll try to get something working once I understand the system a bit more.

    Ultimately I hope to use UFPS and Bolt together. Ufps is getting multiplayer compatibility soon and i believe an analagous third person mecanim animator controller. I'm going to do my best to try to integrate these two systems and share with the community.
     
  19. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Hi again!

    I'm wondering if you could add an explanation of compression to the tutorial or documentation? Should I be using it where possible?

    For example I store a normalized float in PlayerCommand, which obviously will only ever be between 0 and 1. That is set to Byte [0,1]. As well as a eulerAngle, so I've got that set to Byte[0, 360]. Should I be trying to set appropriate compression wherever I can? Or am I misunderstanding?

    e.g. I have two Vector3 inputs and two Vector3 states are well, currently uncompressed because I'm not really sure what the options would do to Vector3s.
     
  20. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Yes, it's mostly based on input from current users, as I deliberately held off on implementing custom object serialization and transfer of large amounts of data until I could get feedback from people!

    I think the best solution would be to have two sub-objects on your main gameobject prefab, and enable/disable them depending on if you want to be in first or third person. This should work out of the box with Bolt, as if you are the controlling player (1st person view) you don't need to send any animation syncing over the wire (it only goes from server to remote clients).

    I actually own UFPS, and I've been looking at doing integration for it in Bolt - the current version of UFPS is... very focused on local play, so it makes it a bit tricky currently.

    Pretty much, yes. But there are exceptions.

    The only exception where you should not use compression is the commands, as the commands need to be a perfect representation of the data used locally by your own client when they go over the wire, otherwise your client will get corrected by the server as the input will differ slightly on the server.

    Turning on compression on vectors individually compresses the selected axes. If you have XYZ axes of a Vector3 and turn on Byte [0, 1] the total data used for the vector goes from 12 bytes to 3 bytes.
     
  21. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    296
    So it looks like Cal is doing a re-write of UFPS to be more multiplayer friendly, and in addition adding support for PUN: http://visionpunk.vanillaforums.com/discussion/74/latest-info-about-upcoming-releases/p6

    So it won't be compatible with Bolt out of the box for sure, but maybe the overhaul and the separation of scripts can make it manageable to integrate. Obviously I'd be overjoyed if you did some kind of integration support directly, but barring that I'm going to get more familiar with Bolt and hope to try to integrate myself when the new UFPS drops.
     
  22. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,551
    Addressing base fundamentals and polishing that would be much preferred to integrating support for other asset store products that are moving targets.
     
    jasonMcintosh likes this.
  23. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Oh definitively, I agree. I was basically saying "I have looked into it, and it's not happening now because it's not possible" - maybe I wasn't clear ;p
     
  24. sballew7

    sballew7

    Joined:
    Sep 3, 2013
    Posts:
    76
    Does anyone know if there's a way to check if the current instance is a server or a client? I see it in the source on BoltCore, but that is not exposed externally.

    For example, I would like to add a ping display on clients, but I do not want to be restricted to putting it in the "ClientCallbacks" object on the BoltConfig. I would find it easier to have my own GameObject with my own script attached that just checks if it is a client.

    If it's not exposed via Bolt, I can likely just use the callbacks to determine it for myself. For example, ConnectedToServer would indicate I am a client.

    Thanks!
     
  25. jasonMcintosh

    jasonMcintosh

    Joined:
    Jul 4, 2012
    Posts:
    74
    I've spent a little bit of time with Bolt now, and I like it a lot.

    Something that would improve it, though, is a cleaner separation of client and server classes. One thing that uLink does very well is make it obvious where logic runs and, in the process, it also eliminates special case checking (ie, "if this is a proxy" or "if this is the server", etc). The special case code gets messy very quickly and is error prone. For a complex game, this could become a nightmare.

    I don't think you would have to do a lot of work to improve that part of the code, since it's already implicitly separated. It just needs to be enforced explicitly with classes/components. We could do that on our own but then we still have to remember which calls correspond to which parts of the code flow, and that means we're still vulnerable to subtle bugs.

    I'd also like to see the various callbacks separated in a similar way, because their naming does not make it clear which ones are client or server exclusive (I have to look it up in the docs every time). In fact, the naming is kind of confusing all around for events.

    I'm on the fence about having callbacks implemented in a class rather than being exposed as plain old C# events, but my gut feeling is that this is limiting their utility (ie, nobody else can listen for those events unless we dispatch yet another event in the callback class) in exchange for some convenience.

    Great work so far!
     
    Ghosthowl likes this.
  26. jasonMcintosh

    jasonMcintosh

    Joined:
    Jul 4, 2012
    Posts:
    74
    Oh, and one little nit pick: persistence is misspelled. ;) This would be important if anyone is searching the API, they might miss it.
     
  27. sballew7

    sballew7

    Joined:
    Sep 3, 2013
    Posts:
    76
    I seem to have got it working by checking whether BoltNetwork.server is null or not.
     
    Last edited: Jun 22, 2014
  28. jaybennett

    jaybennett

    Joined:
    Jul 10, 2012
    Posts:
    165
    Hi Fholm,

    If you need any help testing the host migration feature (zone migration, server migration, whatever you might call it) I can help you with that (alpha, beta, you name it).

    I'm also hoping to prod you a bit about the pathfinding tutorial that you mentioned might happen soon. I know you have a ton of things on your plate as-is, but even a few tips on how you might implement it generally with Bolt would be appreciated :D I guess I'm stuck on whether to try and synchronize the paths or the individual frame movement vectors, or both?

    Also, I think ProtoBufs is a good choice for custom object serialization! At work we have some projects using it, and there is also Thrift which is similar. Since you already have some workflows with custom compiling it fits nicely to generate from IDL!
     
  29. jasonMcintosh

    jasonMcintosh

    Joined:
    Jul 4, 2012
    Posts:
    74
    For player pathfinding (ie, click to move), I would just find the path on the client, and then automate moving to each node as normal client-side input. Since you want your server to be as light on CPU as possible, this method would require no extra server work.

    For enemies, which the player can't control, the server would need to find their paths and then walk them to their destinations. Clients would receive enemy entity positions as usual.
     
  30. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    BoltNetwork.isServer and BoltNetwork.isClient should be what you want.

    Could you provide an example on exactly how uLink achieves this? I have used uLink, but it was a long time ago. And also how you would like this to look/work in Bolt.

    Would you like them split in global/server-only/client-only callbacks, or just have a prefix, something like "OnServer_ClientConnected", "OnClient_ConnectedToServer" ?

    Do you mean the events as in event assets, or the callbacks?

    I could see this an issue, yeah - the reason I chose to not use .NET events is because of how un-intuitive they are with Unity and that it often leads to crashes.

    Ah, will fix :)

    When it's time for testing, I will put up a form on boltengine.com where you can sign up to take part in the alpha/beta/rc-cycle.

    Oh, yeah I have not had time to merge this into the main branch yet, it's about 75% done or so. I'll try to get it done ASAP, I know a lot of people wanna see this.

    About this, I have a rough working prototype of this at the moment, but there's one issue/quirk I would like feedback on:

    Since Bolt needs to compile the protobuff into an assembly, but there's two ways you can define the protobuf objects in: C# code, or .proto files. Which one would you prefer?

    The benefits of C# is that it's well... C#, but since I need to do some magic trickery with the protobuf objects I would need to "hide" them from your normal unity code like this:

    Code (CSharp):
    1. #if BOLT_PROTO_OBJECTS
    2. using ProtoBuf;
    3. using UdpKit;
    4. using UnityEngine;
    5.  
    6. [ProtoContract]
    7. public class Person {
    8.   [ProtoMember(1)]
    9.   public int Id { get; set; }
    10.   [ProtoMember(2)]
    11.   public string Name { get; set; }
    12.   [ProtoMember(3)]
    13.   public Address Address { get; set; }
    14.   [ProtoMember(4)]
    15.   public Vector3 Vector3 { get; set; }
    16. }
    17.  
    18. [ProtoContract]
    19. public class Address {
    20.   [ProtoMember(1)]
    21.   public string Line1 { get; set; }
    22.   [ProtoMember(2)]
    23.   public string Line2 { get; set; }
    24. }
    25. #endif
    So that you can't "get" to the through your normal code, and only get access to the objects through he assembly that bolt compiles. So, this becomes quite a quirk, the other solution is to use .proto definitions, which look like this:

    Code (CSharp):
    1. message SearchResponse {
    2.   repeated Result result = 1;
    3. }
    4.  
    5. message Result {
    6.   required string url = 1;
    7.   optional string title = 2;
    8.   repeated string snippets = 3;
    9. }
    Which isn't really a lot like C#, but it gets around the whole quirk with doing it in C# but not exposing it to your own C# code.

    Which way would you prefer?
     
  31. jaybennett

    jaybennett

    Joined:
    Jul 10, 2012
    Posts:
    165
    I'm familiar with the proto files, but most others wont be. With C# definitions, people can jump into it more easily and so I think that is the way to go.
     
  32. sballew7

    sballew7

    Joined:
    Sep 3, 2013
    Posts:
    76
    I too am familiar with proto files, but I would have to say I think proto files would be better than C# here for the following reasons:

    1. Proto files have good documentation.
    2. Proto files are much more clean and concise.
    3. It is language-agnostic (which is good in the Unity world)
    4. People will get tripped up by the quirk fholm mentioned.
     
  33. jasonMcintosh

    jasonMcintosh

    Joined:
    Jul 4, 2012
    Posts:
    74
    I think I agree here, because of #2 and #4. We use Thrift at work, and I'm not a huge fan, but proto files look pretty good.
     
  34. jasonMcintosh

    jasonMcintosh

    Joined:
    Jul 4, 2012
    Posts:
    74
    uLink has three different prefabs which spawn, depending on its capabilities on the host. They call these "roles," which are server, owner, and proxy. There's good documentation about their design, which might be useful to you (see the section called The object roles: Server, Owner and Proxy).

    The goal would be to keep code related to each entity's role (to use uLink's word) in a separate component: logic for owners, logic for a controller, and logic for a proxy. Then you know the code running in that component is only for a specific purpose, and you eliminate the case checks and modularize the architecture more.

    I don't know how much this diverges from the internals of Bolt, though, so maybe it's not as simple as it seems on the surface. I'll let you know if something really obvious presents itself as I continue to work with the system. :)

    I think splitting them into separate callback objects would be the ideal approach, since it entirely eliminates the possibility that you will implement the wrong handler for a similar type of event.

    My confusion is around the naming of the callback methods. For example, there is Attach() which is sealed, but also Attach(state) which is what we should override. Another example is Connected() and ClientConnected(), which you eventually memorize, but it's not obvious at a glance what those do. :)

    Overall, none of these issues are awful. Bolt is easy to work with, and it works well. As it grows in complexity, though, I think it would benefit from streamlining some things like this.
     
    Ghosthowl likes this.
  35. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    296
    So probably a very basic question, but it's early...

    What's the preferred way for the client to be informed when he is given control of an entity? For example, in the tutorial under ServerCallbacks.cs the server instantiates a player when a client loads the map and then hands the control of the player over to the client.

    In this case I want to disable the 3rd person model for the controlling client - and doing this via the method FirstPerson() on the PlayerController.cs - figured the best way of doing that is checking if the client has control or not.

    Can't seem to do it in Awake/Start because the client hasn't been given control immediately

    I send a message right after I give control: The problem is the following message gets sent only to the server's entity.

    Code (CSharp):
    1.         // give control of this entity to the client we spawned it for
    2.         entity.GiveControl(arg);
    3.  
    4.         //Tell the contoller's client that it should be in first person mode - not working, this message only gets sent to the server gameobject
    5.         entity.SendMessage ("FirstPerson");
    So is there like an OnGainedControl() method I can use in the player controller script?
     
  36. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    296
    This seems to work though - making a seperate bool that gets updated by .boltIsControlling - but seems kind of messy

    Code (CSharp):
    1.     void Update () {
    2.         if (boltEntity.boltIsControlling) {
    3.             if (!controlledByMe) {
    4.                 FirstPerson();
    5.                 controlledByMe = true;
    6.             }
    7.  
     
  37. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Right now it's looking like I am going to go with .proto files, as it is language agnostic, and you can use them in other languages also, etc.

    Okey, yeah I remember this now. Been a while, Bolt does have the same thing technically with its SimulateOwner, SimulateController, SimulateProxy - but it's not separated on a per-prefab level.

    It's not that far off from how bolt works internally, but specifically switching the prefabs around might be a bit tricky since the "is in controll" state doesn't take until after the object is created.

    I will look into how I can do this the best way, I am leaning towards a naming convention of
    OnBoth_XXX, OnClient_XXX, OnServer_XXX simply because of how the compiler works in Bolt where it injects methods - having more and more classes convolutes this a fair bit.

    I agree that this needs to be made a lot clearer, and documented better.

    There is a callback on the BoltCallbacks object called ControlOfEntityGained which you can subscribe to, which will be invoked with the entity you got control of - this works on both the client and server.
     
    Jesse_Pixelsmith likes this.
  38. Ghosthowl

    Ghosthowl

    Joined:
    Feb 2, 2014
    Posts:
    228
    Okay Mr Fholm,

    So I spent literally ALL weekend recoding our entire game to fit the Bolt paradigm and I have got to say, it is one of the best moves I have made this year. It was a daunting task that was surprisingly easy once I got the hang of how Bolt was and handled things. So I will split this up into three parts, the pros of the move, the cons and the areas of confusion.

    Pros:
    • Simplicity and Heavy duty lifting. It is simply heavenly. I got rid of about 5000 lines of code and more than 15+ classes because I simply did not need them anymore, Bolt handles it all for you and might I add does a better job of it. These include our Mecanim syncing classes, bandwidth and data compression algorithms for sending RPCs, authoritative movement code (based off uLink's strict platformer mind you) and more. I'm still using a modified rewinding system based off Fholm's rewinder until the bolt rewinding allows for some more options :)
    • The design of the engine allows for very very good coding fundamentals. (can't speak on MVC and all those) I was able to modularize and clean up huge bundles of mess and spaghetti of RPCs bouncing around and trying to check things syncing up properly.
    • Event system is a HUGE breath of fresh air. It is awesome and completely does away with two things: the need to have an event system of your own for anything traveling over the network and the dreaded blank RPCs that plagued us when we used uLink. (basically under a lot of cases, the RPCModes were limited and did not work as intended, so those who should not be receiving certain RPCs were, this was solved by separation of roles and placing blank RPC receivers to offset the issue - thanks @Yukichu~)I think in total I've only used 15-20 events and some are duplicates because of the issue I had below. With uLink I had at least 50+ RPCs.
    • Authoritative movement just works. And not only does it work, it respects boundaries WELL. I could not get this to work in uLink. If the server had a collider that wasn't on the client getting a smoothed out way of colliding with that invisible object or preventing the player from moving past just wouldn't work. ALWAYS there would be a discrepancy, either small or large depending on how much of an margin of error you were accounting for. Not in Bolt. Everything is synced PERFECTLY without any need to code or add modifications. There is no de-sync or ghosting anymore, something that I was dealing with regularly when trying moderate to worst case scenarios.
    • Moving platforms and teleporting built in with no issues!
    • Synchronized map loading and the map loading procedures and callbacks make things so much nicer to work with and gets rid of a lot of guesswork and headaches if you need this to be on point in your game.

    Cons:
    • Event system can be a bit cumbersome when it comes to defining properties and unloading them. This affected me a lot because we have an inventory system that uses extensive networking code to check the client. Most of my events I had to do in this category were about 5-8 properties big. Because of a lack of understanding or knowing, there seems to be no way to change events and their recievers after compiling, so an event that is exactly the same that needs to be sent to just the controller on one occasion or all proxies on another would require 2 events instead of one. This can be done with one RPC in uLink.
    • Juggling separation can be a bit frustrating - and it needs to be done for everything - players, entities and client and server environments. Say we have owner controller and proxy, but we only have one prefab for them. We need to have child objects or some sort of system to turn on and off components that don't belong to the other role. This can get confusing and convoluted quick, so it is wise to think it through and come up with a method of handling this. I made 2 objects for the player that contain all the components for that respective role. One called 'Controllable' and one called 'Owned'. If owner, 'Owned' will be activated, if controller, 'Controllable' will be activated, and if proxy, none of them will be activated. This however led to some interesting issues I will mention in tips below.
    • Jumping and falling have issues with fixed frame rate simulation with authoritative movement (Fholm is aware of it and is fixing it soon)

    Areas of Confusion:

    Okay so bare with me here. A lot of questions I have are simply ones that would be easily answered with documentation and or video tutorials, but I know those are coming. So in the meantime I hope you can answer these:

    1. How do get a constant 100% foolproof way of matching entities to connections? Our Player Database and Inventory system heavily depends on this and I don't know or understand what does what. In uLink it was simple - info.owner.id was a simple number system that started from 1 and moved up and viewID.id - a 4 digit number that could be allocated and or changed (such as 1999). Currently I am using BoltEntity's boltPrefabId to line up to BoltConnection boltId. I tried using boltId on BoltEntity but I don't understand how it is counting, when I only have one user online it reports 2, I assume it is counting off based upon enties spawned (one for server, one for controller). I am using GetComponent<BoltEntity>() to get these on objects that aren't cached to do a quick lookup to see who they are in the world. I tried using boltSource or boltRemoteController (? can't remember these off the top of my head) but they are always null and are read only values, so I am not sure how to get those to initialize.
    2. When overriding a OnEvent, how do we get the timestamp of when the event was originally raised from the sender?
    3. I can't for the life of me get my Standalone build to work like my editor build. I am always getting errors about something. I solved the last issue I had by removing the clean up method I had in the disconnect sequence. But now I have 2 new errors. Upon Startup: Node is not in this list > BoltDoubleList`1[BoltCallbacksBase].VerifyInList(.BoltCallbacksBase node) at c:/Users/Fredrik/Documents/bolt/src/bolt/bolt/collections/BoltDoubleList.cs:127

    There are more features that I haven't gotten into yet, and a lot that I have no idea about.

    Suggestions:

    1. Add a timestamp for the beginning of BoltLog that can be toggled on or off
    2. Add some way of being able to edit the senders and receivers of events in script / at run-time to allow for flexibility
    3. Allow the instantiation of objects to have their positions and rotations set with the Instantiate command
    4. Mixing and matching global events with entity events in the same class? o_O
    5. I agree with @jasonMcintosh on pretty much all of his points. Better separation of knowing what is what and what goes where would definitely help. I found myself having to keep the section of the tutorial that states what all the callbacks are open the entire time, constantly checking to see if something is ran on the client or server and exactly what it was doing. There is one thing I do not want though, I do not want the look or feel of uLink or too much that creeping it. I love how different and innovative and fresh this is and the workflow in my opinion is far superior. I would not have been able to do the migration is just 3 days with uLink, that is for sure.
    6. Documentation, documentation, documentation! I know this is coming already so this isn't really a suggestion. There are a TON of options and configurations in Bolt I discovered that I have no clue in what they do. But this is beta.
    7. Clearer understanding of EXACTLY step by step the process in how Bolt Starts up and shuts down in both the editor and the standalone builds. I still cannot understand this and there is no clear explanation.It is very hard to code my own implementation when I do not know what is happening behind the scenes :(
    Tips:

    • When making a moving platform of your own, you may run into a distortion issue. This does not happen in the demo but if you have an FPS game like we do, it can be an issue. You can solve this by making your object like this:
    1. Empty GameObject (With Bolt Origin attached - MUST BE SCALED THE SAME AS YOUR PLAYER)
    2. --> Child 1 (Your model / mesh with a box collider attached - Scale this to whatever you want)
    3. --> Child 2 (Empty gameobject with collider marked as a trigger + your moving platform bolt script - Scale this to match your child 1)
    • I had an issue like jason mentioned with separation of server and client, here is how I did it - Make 2 classes that are called from your server and client objects respectively (BoltCallBacks). I called them 'ServerEnvironment' and 'ClientEnvironment'. They are both called on MapLoadDone. Have these either construct your server and client environments at runtime by making objects and then adding components to them, or making prefabs of these objects and having them spawned in. You could also have all the objects in the scene and use this class to turn on and off different gameobjects and components depending on your needs. I think something like this, or a better way of doing this should be implemented at some point. If you do not do things this way here is the problem I ran into. When I left items in the scene, after the Bolt startup procedure and the switching of scenes, all my references / things that needed to be done in Start and Awake would have failed because their dependencies either did not exist yet or were missing.
    • I had another issue with moving platforms. When you move on to a moving platform using the setOrigin script, your parent is changed to that object. As I wrote above since I have child objects on my player, this quickly got very interesting. What was happening was, I was using transform.root to control and do things. This automatically switched to the platform upon me going on to it. To solve this issue I made a public property that many of the components affected by this inherit called PlayerRoot which does 'transform.parent.parent' instead. I also made a static helper method to traverse up the hierarchy of an object to find the specified root by tag. These two methods solved the issue for me.
    That is all I can think of now. I know there was more but arg!!! It is 7 am in the morning already and I haven't slept! Forgive any typos or things not making sense, my brain isn't up to snuff at this hour.
     
  39. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    296
    Thanks the ControlOfEntityGained worked!

    Also I seem to be getting this frequently when compiling:

    error CS0016: Could not write to file `bolt.user', cause: Sharing violation on path C:\Users\JesseG75\Documents\3dSurvival\Assets\bolt\assemblies\bolt.user.dll

    It seems inconsistent and not sure what is causing it
     
    Last edited: Jun 23, 2014
  40. jaybennett

    jaybennett

    Joined:
    Jul 10, 2012
    Posts:
    165
    Proto files is good too :)

    Follow up question, if I have an already existing set of plain old C# objects that define my data model, am I better off overriding Pack() and Read() myself? Is there a way to bind the existing objects to a bolt state custom type?
     
  41. Ghosthowl

    Ghosthowl

    Joined:
    Feb 2, 2014
    Posts:
    228
    Jesse, this is caused by trying to compile Bolt when Unity hasn't finished compiling yet. Just make sure to check the bottom right for the spinning white wheel and wait for that to finish before hitting compile. Fholm is aware of this and is going to make it like the start button not be clickable until compilation has finished.
     
  42. Jesse_Pixelsmith

    Jesse_Pixelsmith

    Joined:
    Nov 22, 2009
    Posts:
    296
    Ah totally makes sense, cheers!
     
  43. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Hello!

    I am getting an error when trying to run my project on a version with Unity free. On mine and a friend's pro copies, we can pull from Github, compile Bolt and play the game and it works fine. (Not using the Map Launcher, just using a menu I've setup.)

    However on another computer with a free version, I get an error saying:

    "WeaponManager.OnEvent<IPlayerShoot, BoltConnection> is marked as an override but no suitable method found to override"

    Which in the past has taught me I either need to restart Unity, or recompile Bolt. Even after restarting Unity, waiting until it's loaded everything, and compiling Bolt, Bolt says that it has compiled successfully. Also the error isn't there until I actually compile Bolt. Opening the project and waiting has no errors. Is there something I've missed that I should be doing differently in Unity free? I checked the tutorial, and the Unity free part seems to only talk about the Map Launcher.

    Thanks in advance!
     
  44. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Double post, I suck =(
     
  45. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Hey!

    So, apparently email notifications from the forum has been down, and I missed all of these posts - I'll try to catch up now, first of - Ghosthowl, thanks for a great post! Here's my reply:

    This has been my goal the whole time with Bolt, to take these concepts which are conceptually easy but in practice hard to implement and make them available to everyone using Bolt.

    I did put a lot of work into the flow of logic in the engine, there are still quirks and issues - but it's (in my opinion) a lot better then the other solutions out there. Yes it is a bit more rigid and you can't just do "whatever the heck you want", but in 99% of the cases, that's the proper thing to do. And if you want to change the core flow of Bolt, you have the full source code.

    I am so happy to hear this, because I felt like the event system was one of the big gambles in Bolt, I know from empirical experience that it is better then using RPCs, and is a lot more flexible and powerful. But everyone is used to RPCs, so I was scared that it would make people shun away from using Bolt, as it's an unfamiliar concept.

    The authoritative movement is getting a big boost in both usability and smoothness soon, as I'm going to re-enable the interpolation of corrections (currently it just snaps) from the server, and a few other "nice to haves". So hopefully it should be getting even better.

    I have a solution for both of these issues, first of creating and sending events and manually inputting all the parameters, I intend to have the BoltFactory instance automatically get extended with methods that look like this "NewMyEventType( ... )" which has a list of all the events parameters, and also let you toggle parameters as "optional" so you don't have to set all of them every time.

    About sending one event with different recipients, I'm planning to provide an overload BoltNetwork.Raise and BoltEntity.Raise which take a bit mask of receivers.

    Yeah, like I'm sure you have seen others have raised this issue also - I'm looking for input and I am open to try several implementations to find one which suits most peoples needs - so any idea you might have, throw it my way. I will throw a few ideas in here later today or tomorrow and see what you guys think. I am not super fond of having several different prefabs as it's too easy to "trip up", we'll see where it lands

    Edit: Forum screwed up the rest of my reply below this point, I will post another post with the reply for the remaining posts.
     
  46. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    It depends a bit on where you want to match them, if it's only on the server then just connect them together using the BoltConnections userToken property.

    the boltId on BoltEntity is local only, and not distributed over the network. Bolt also uses unique identifiers for network traffic for all entities to the entity with "network id 2" is not going to be the same for two different clients.

    If you give me more info on exactly how and where you want to pair a connection and an object, I can either provide a solution for you - or implement the behaviour you need in case it' missing.

    This already exists, but is not exposed publicly. I will make sure to do so.

    Can you provide me the whole error for this?

    Will do.

    Will do.

    Will do.

    ... Maybe, if the goal is to get reliable events on entities then I am planning to allow them between the owner and controller of an object.

    I agree on this also, with both of you. A lot of things need to be communicated better, and there needs to be a better separation of logic.

    What exactly is giving you issues? Is there something which is not explained in the startupshutdown sample? Or is it something that's not working as intended (you suspect) ?
     
    red2blue likes this.
  47. Ghosthowl

    Ghosthowl

    Joined:
    Feb 2, 2014
    Posts:
    228
    This is why I love Bolt, constant updates, a creator who listens to user feedback and responds not only in the forums, but by doing also. Something so many developers fail at on both fronts monumentally.

    WOW, this is excellent and solves that problem completely

    I don't like having 3 prefabs. It solves the separation issue but I feel it is a cop out. There were many cases in which I was forced into the separation when I didn't need to or want to be. It really only is a big issue with the player, usually with NPCs, enemies etc it is only needed for server and proxy. Even with that it isn't that big of difference, unless you have a complex puppet master. It's something I will have to think about but would love to hear everyone's ideas on this. I am sure we can come up with a simple way to solve it.

    Hmmm.. assigning some sort of property on instantiation would do for just on the server only, but in my case I am trying to match up entities across the network. some form of number or identification that matches up on server and client no matter what would be great. If i have an entity that the server spawns for everyone, if he is spawned with the id 77, then every client should have a way to get this id of 77 (hopefully from his entity component). I saw somewhere there was some thing that let you send an entity over the network? That seems like it could help solve the problem. I only ask here because it would save me a lot of time and effort in keeping the existing system in tact :p

    InvalidOperationException: Node is not in this list
    at BoltDoubleList`1[BoltCallbacksBase].VerifyInList (.BoltCallbacksBase node) [0x00019] in c:\Users\Fredrik\Documents\bolt\src\bolt\bolt\collections\BoltDoubleList.cs:125

    at BoltDoubleList`1[BoltCallbacksBase].Remove (.BoltCallbacksBase node) [0x00001] in c:\Users\Fredrik\Documents\bolt\src\bolt\bolt\collections\BoltDoubleList.cs:62

    at BoltCallbacksBase.OnDisable () [0x0000d] in c:\Users\Fredrik\Documents\bolt\src\bolt\bolt\BoltCallbacks.cs:20


    Happens right after 'udpkit | info | physical socket started' is printed in Boltlog. Only happens in standalone.

    This is exactly what I need, reliable entity events.

    Just my understanding of things. The demo example explained to me exactly how to handle a startup and a shutdown, which worked on a simple level, but as I have now added in my player database to handle adding and removal of players, things are getting tripped up for me. Here is a quick example: http://developer.muchdifferent.com/unitypark/uLink/ConnectingClientAndServer - see the section - 'Detailed connection sequence' & 'Detailed disconnection sequence' ... could you do one of these for Bolt? It seems to be handling a lot of things I normally do, which is refreshing but knowing what that was will save me a lot of headaches :)

    Excellent excellent, things are progressing at a good pace and once a lot of these things are updated and added Bolt will be solid. I am super excited to be apart of something new and great and to be able to have access to it :) I have to do it everytime, but thank you for taking out the time and effort to respond back to us here and helping us out with our issues (can you tell I have been deprived of this on many occassions? :p)
     
  48. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    I dont like the prefab thing either, first I have these two suggestions for making scripts which only executes on a specific entities in specific modes:

    Code (CSharp):
    1. // option a: inherit from a specific object
    2. public class PlayerProxyStuff : BoltProxyBehaviour<PlayerSerializer, ITeleportPlayerState> { }
    3. public class PlayerOwnerStuff : BoltOwnerBehaviour<PlayerSerializer, ITeleportPlayerState> { }
    4. public class PlayerControllerStuff : BoltControllerBehaviour<PlayerSerializer, ITeleportPlayerState> { }
    5.  
    6. // option b: add new method on BoltEntityBehaviour which lets you set what entities this script should be active
    7. public class PlayerProxyStuff : BoltEntityBehaviour<PlayerSerializer, ITeleportPlayerState> {
    8.   void Awake () {
    9.     OnlyExecuteOn(BoltEntityMode.Proxy);
    10.   }
    11. }
    12.  
    13. public class PlayerOwnerStuff : BoltEntityBehaviour<PlayerSerializer, ITeleportPlayerState> {
    14.   void Awake () {
    15.     OnlyExecuteOn(BoltEntityMode.Owner);
    16.   }
    17. }
    18.  
    19. public class PlayerOwnerOrControllerStuff : BoltEntityBehaviour<PlayerSerializer, ITeleportPlayerState> {
    20.   void Awake () {
    21.     OnlyExecuteOn(BoltEntityMode.Owner | BoltEntityMode.Controller);
    22.   }
    23. }
    And then also a behaviour which would let you drop it on a gameobject, and set which entity modes it should be active for:

    Code (CSharp):
    1.  
    2. public class BoltEntityModePrefab : MonoBehaviour {
    3.   [SerializeField]
    4.   BoltEntityMode activeOn;
    5. }

    Hm, okey I see where you're going with this. This is technically possible today, but the functions are not public (you can write an entity into a packet stream) could do some type of functionality which lets you easily identify entities across the network - I will have to ponder this a bit.


    Does this happen on the first start, or only if you try to restart bolt with Shutdown and then Start again? Another reasoning for this happening could be if you have a callbacks object which you dont set as DontDestroyOnLoad and you load scenes, etc.


    Okey, I will see what I can do here.


    Will do, I plan to do more in-depth tutorials/documentation for Bolt which focus on specific areas.
     
    jasonMcintosh and Ghosthowl like this.
  49. jaybennett

    jaybennett

    Joined:
    Jul 10, 2012
    Posts:
    165
    I really like Option B!!
     
  50. Ghosthowl

    Ghosthowl

    Joined:
    Feb 2, 2014
    Posts:
    228
    Interesting, again I am up late lol, so my brain is not working well but I like option B the most. They both seem like very good solutions the question is which would be more robust. But those are very interesting ways of thinking. I will have to give them another look over after I have thought about it some more.

    Bingo solved my issue, I didn't have DontDestroyOnLoad(gameObject); on my two client and server components that inherit from BoltCallbacks in my menu screen.

    Okay, using BoltNetwork.connections for now to line up whose who and it seems to be working serverside just fine, client side is a whole other issue.

    Two more questions:

    I am getting: 'could not send all unreliable events, 1 events remain in queue'. Upon entry to the server, the client gets a bunch of updates about many things in the world. It seems like a harmless warning and the events (whoops, almost called them RPCs for a second!) are being sent (queued up), just not at the specified frame they were supposed to?

    Is there a way to send initial data on connection request, like a version number or a Playername, etc?