Jump to content

  • Log In with Google      Sign In   
  • Create Account

Calling all IT Pros from Canada and Australia.. we need your help! Support our site by taking a quick sponsored surveyand win a chance at a $50 Amazon gift card. Click here to get started!


fjholmstrom

Member Since 22 Jan 2012
Offline Last Active Jun 02 2014 07:24 AM

#5022473 Network message solution for client/server architecture

Posted by fjholmstrom on 17 January 2013 - 04:27 AM

First, note that I mainly use C# together with XNA and Unity3D, so maybe the rules for games and engines using C++ are different. Anyway, I strongly prefer the first option. While there are quite a few classes that needs to be created, I do not see this as a major drawback. It creates a very clear separation of "data that is put on the wire" and the other code which deals with this data. Everything gets encapsulated into one neat little package. And I suspect that even if you use something which is more akin to your second example (the SWG emulator one), you would still end up with some sort of encapsulation similar to an "Message" or equivalent to be able to do reliable sends, sequencing, etc. 

 

Just as an example, this is a "Message" (my networking lib calls them "Events") which is used to send the click position and target object in a physics based puzzle game:

 

public class ShootBallEvent : NetEvent
{
    public static readonly ushort Id = 0;

    public NetObject Target;
    public Vector3 Position;

    public ShootBallEvent()
        : base(Id, NetEventDelivery.Unreliable, NetEventDirection.ClientToServer)
    {

    }

    public override void Pack(NetConnection conn, NetPacket packet)
    {
        packet.WriteVector3(Position);
        packet.WriteNetObject(Target);
    }

    public override void Unpack(NetConnection conn, NetPacket packet)
    {
        Position = packet.ReadVector3();
        Target = packet.ReadNetObject();
    }

    public override void Process(NetConnection conn)
    {
        if (Target == null)
            return;

        if (!ReferenceEquals(Target.Owner, conn))
            return;

        // ... do stuff to Target and Position
    }
}

 

I find this encapsulation to be very clear and easy to work with.




#5012818 "Shield" shader - How to create "bullet effects" and borders?

Posted by fjholmstrom on 20 December 2012 - 09:35 AM

OMG too long video can you capture that specific effect?

I linked with a time/second mark, but apparently the embedded youtube player didnt pick up on that, no need to be a douche about it.


#4983214 A few questions about GPU based geo clip maps by Arul Asirvatham and Hugues H...

Posted by fjholmstrom on 24 September 2012 - 07:31 AM

Ok, so I did some more googling and also talked to a few friends on IRC, so this is what my conclusion is, if someone could confirm/deny it:

  • The degenerate triangles are created by using the same positions as the outer and inner grids depth, and stitches them together
  • They are drawn as separate draw calls, and their size ends up being zero as the vertices from the different grids are supposed to align, but it helps to smooth out any interpolation errors.
  • If done correctly, this removes errors due to texture interpolation


I drew a simple picture to illustrate, which the grids pulled apart to show the actual degenerate triangles, and I hope this is correct:

Posted Image


#4978393 Dealing with high packet loss or long pauses in transmissions in custom UDP p...

Posted by fjholmstrom on 09 September 2012 - 03:35 PM

I've been working on my own UDP networking library for a while, mostly because I wanna learn and know more about how one works. I've managed to implement the basic NACK/ACK:ing of packets and two types of delivery unreliable-drop-late and reliable-in-order. But I digress, I have a question about a very specific edge case:

When sending a package, which might be the last package to go between the two peers for a little while (say loading a new map at the end of a round or something) - how does one deal with detecting that this package has been dropped? Assuming a message such as "Load Map", which will most likely be sent reliable-in-order and is the last message to originate from the server to a client for a few seconds as after this package is sent the server starts loading the map.

Now, if everything doesn't go as planned there are two things that can happen:

  • The packet gets dropped on the way to the client
  • The packet gets to the client, but the ACK back to the server is dropped

If this happens, the server is now waiting for an ACK that will not come, no matter which packet was dropped. During normal operation this is not a problem as packets are flying back and forth constantly and the ACK/NACK from the client will show that the package was dropped. There are two possible solutions to this the way I see it:

  • Run a timer on the server, if the package has not been ACK/NACK:ed within some limit (roundTripTime * 2 or something), re-send it
  • The client usually works at some fixed send-rate, make sure to always send the latest acks at these intervals even if there are not data to send - if the server detects that the package is not getting through it can re-send it.

I'm not sure if there are more ways to solve this, or if I'm even on the right track - but that's why I'm asking, how is this *usually* solved in popular networking libraries? I know that the Lidgren library for .NET uses the first method, I have been peeking at the OpenTNL library and they *seem* to be using method 2 (as I can only ever see that re-sends being queued when they get NACK:s from the other peer).

The first solution to me, feels a bit dirty - and it also feels like it could make the situation worse if you already have high packet loss and the server keeps spouting data over and over even if the packet might have arrived at the client but the ACKs are getting dropped. The second solution feels a lot cleaner, but maybe there are other ways?


#4909471 Synchronizing actions to interpolated movement

Posted by fjholmstrom on 04 February 2012 - 03:39 AM

I've implemented pretty much the techniques described by valve here: https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking It all works on both the server and client(s). With one little issue, or rather, a concern/question:

When I interpolate the movement of an entity between two points I already know, this causes a blanked 100ms rendering lag on the client (I receive state updates at 20Hz) of remote entities. This is fine, but when a remote entity does some action (say shooting or jumping), which needs to be synchronized to movement - do I not also need to delay these events by the same amount when I receive them from the server, so everything lines up nicely?


PARTNERS