UDP LAN multiplayer (continued) Pt2

Blitz3D Forums/Blitz3D Userlibs/UDP LAN multiplayer (continued) Pt2

Rick Nasher(Posted 2016) [#1]
(continuation of LAN multiplayer(UDP)..
NOTE: Flanker's UDP Library and media I'm using(audio) can also be found in for mentioned thread.


*** ROADMAP/HISTORY ***
This started off from Flanker's initial example code "ADVANCED 3D EXAMPLE.bb" for usage with his marvelous UDP lib V1.12.

Goal is to learn & create a Blitz3D MultiPlayer example for the community.

I've decided to call it:
B.U.M.P. - Blitz3D's Ultimate Multi Player, as a working title.

The conversion/extension to Hybrid could then be called(once on the road):
H.U.M.P. - Hybrid's Ultimate Multi Player (DX9/11) << nogo due to Ploppy's unfortunate passing away..

Next best other possibilities are:
I.U.M.P. - Irrlicht's Ultimate Multi Player(DX9/OpenGL)

Or(less likely):
X.U.M.P. - Xors3D'a Ultimate Multi Player(DX9)



---------------------------------------------------------------------------------------------------------------------------------------------

ADDED SO FAR:
-chattext colors matched to playercolors.
-different health strengths and spawn times.
-hide entities names when one player cannot see each other(so can play hide&seek)..
-different health item strengths, which are also displayed above the
item and take time to become available again depending on strenght.
-fixes to keybd input and window focus.
-sound fx(quicky, needs more work).

UPDATE 29-04-2016:
-lock/unlock mse + hud.focus to window switch 'f'.
-F1=help.
-F2=change player color on the fly.
-rapidfire toggle command.

UPDATE 12-05-2016:
V1.66 fixed friendly fire bug.(no more shooting yourself in the foot, stommach or whatever :-)
V1.66.2 correctly displaying msg+snd.
V1.69.2:
-Added 2nd (and higher) ramp to fall and die from.
-F3=display current player coords.

V1.69.3:
-fixed bug where chat held onto keys that would turn into player controls after submit.e.g. space=jump.
-Temporary disabled health loss when falling ability.
-Changed death sound, fixed all sounds to play local and on networked players,
added typwrittersounds for chat(only Local) and submit snd on network to attract attention.
only 1 audio bug remaining: producing hit sound while actually collecting an item or when player(client)
gets introduced into game (unclear why).

V1.69.5(14-05-2016):
-fixed fall bug aka (when enabled 'health loss when falling ability' it works, but also kills the player when running down a ramp)

V1.70.0(14-05-2016):
-Fixed bugs: health inacuracies. color at start always displaying ok on players.

V1.72.4(21-05-2016):
-Added push player function. Caution: pushing someone requires energy. :-)

V1.72.5d(29-05-2016):
-Delay working.
-bug: wrong player getting color(mixed up, for not properly netsent)

V1.72.5t(02-06-2016):
-bugfix: Color working ok now.
-Immobility when dead also working.
-Now storing previous color and revives when.. well, revived of course.
-Added another chat cheat '/' command.
-Several bugfixes/optimizations.
-Added teleportation locations.
-Preventing players having same color.
-adjusted title bar.

V1.72.5u(13-06-2016):
-bugfix: wrong location after push / teleport resolved (most of the time).
-added jump pads.
-fixed negative fall value display.
-added close range/far range mode(only can shoot each other close range with pistol, not machinegun<< diff weapons not implemented yet:-)
-fixed jumping health deduction.

V1.72.5z(16-06-2016):
-Added bullets through teleports feature..


TODO UPTO VERSION 2.0 (not nesacerrily in this order, all using procedural gfx, without ext libs/media, except sound):
-ammo boxes.
-change click true defaults.
-default full screen when not locally testing.
-anim stars rotating above head, if dead squased char.
-bullit hit impact response
-test w gf, flanker or others. ;-)
-scorch marks on hit objects.
-fps /tps switch.
-weapon upgrades.
-collectable coins< take/kill all=winner.
-'/' cheatmodes and additional commands.
-flashlight,freelook + day nightcycle.
-add moving platforms demo code.
-game music. playing more exited when near an enemy.
-robo players with simple ai.
-gui with saveable prefs.
-simple animated chars.
-ladder climbing/crouching.
-walking, running and sounds to match.
-superjump powerup.
-shields.
-jumping pads.
-weather conditions.
-inventory/hud.

TODO FOR VERSION 3.0 (more advanced, incorporating media and ext libs):
-move to stayne's level.
-3d animated chars.
-AlienBreed 3d characters?
-Special effects, doors, etc.
-Vehicals/terrian.
-PhysX.
-Shadows.

IDEA'S:
-electrocution pads..
-colorpicker.


KNOWN BUGS:
-player dislocated after spawned(again?), mostly happens after pushing when player is dead..
-health not showing properly 0 but negative value after fatal fall.
-when too many players pushing each other system getting 'carried away'.
-when pushing another player into teleport or when the other player is dead then will return at old spot instead of new location.

Latest version of code here:
http://www.mediafire.com/download/n147k5ovuhvyrng/BUMP_V1.72.5z.bb


RustyKristi(Posted 2016) [#2]
hey Rick. This is an awesome update! I have a question, do you still have copies of your previous versions?

It would be nice to have a history of the changes that you have made since Flanker's build.

EDIT: It looks like the links are still there, awesome! thanks :D


Rick Nasher(Posted 2016) [#3]
yeah in previous archives, not all of them but it's easy to compare with the original from Flanker using https://www.diffchecker.com/
It highlights all changes.


RustyKristi(Posted 2016) [#4]
thanks!


Rick Nasher(Posted 2016) [#5]
You're welcome. It's nappy time for me, so nighty night. ;-)


Rick Nasher(Posted 2016) [#6]
Just added player color flash on hit by bullet. Works pretty good. Now adding flattened player after fatal fall ;-)
No code update yet, perhaps later today.
Next: adding Moving Platforms Demo into this..(hope it won't be too much of a hassle)


Rick Nasher(Posted 2016) [#7]
Things are getting progressively more unreliable: wrong positions, colors & life values after a pushed player died, which in part is explainable by my crappy coding(should have left server do all collision checking/updating).

So I went back to basics and found that even then whenever there's been a collision prior to re-spawn (it being a player or bullit) then the locations, life and colors are not properly updated and sometimes it just randomly happens. It apparently is unfixable by hiding, moving and showing the entities as well as by resetting them.

So my best guess is that this can happen due to UDP being an unreliable protocol. Now positions can be interpolated, but other stuff nogo, so is too sloppy for usage in a real game as intended.

Also it gets worse the more messaging is going on so.. Guess I'll have to throw the towel in the ring and pull the plug on this(which is a pity, for had plenty ideas if would have worked)..
:-(


RemiD(Posted 2016) [#8]

So my best guess is that this can happen due to UDP being an unreliable protocol.


Or due to a bad approach or to bad coding.


RemiD(Posted 2016) [#9]
And to be more constructive, here is a hint of a better, more reliable approach (than sending positions) :

... i don't find the post, basically the idea is to have one separate server and several separate clients. Each client sends his player orientation and his input (actionstate), then the server manages the collisions detection and repositionning, then it sends back the new orientation, new position, new state of all players/projectiles, to all clients.
It is compatible with UDP, since if there is a missing packet for a client, the server does not wait for the new packet of a client, instead it uses the orientation and input/state of the previous packet.

This is most likely the approach they used for old games like unreal tournament or quake 3...


Rick Nasher(Posted 2016) [#10]
Hmm, well, bad coding is very well possible from my side for I'm not the world's greatest(and messy too lol). But from what I remember/afaik Quake3 used it like that and also the technique of peer2peer/host swapping is also available in other packages such as Unity, so would be great if Blitz3d has it.
It has the advantage(if working correctly) that one doesn't require hosting a server and will go on if the server is down. So independent of just about anything. Again: if everything is working correctly.
Drawback is of course that it might overcomplicate things..


RemiD(Posted 2016) [#11]
from the tests that i have done, UDP works well, some packets may take more time to travel and some may reach the destination in the wrong order (and some may never reach the destination)
In any case this should not provoke any error on your server or on the datas sent to the clients.
The worse that should happen (if it is coded with the right approach and without major bug) is that a client is expeled if no packet from him has been received after xs.

I don't see how you expect to have no problem with collisions detection and repositionning if you position an entity at a position instead of turning/moving it... It is like teleporting it.


Rick Nasher(Posted 2016) [#12]
@RemiD - True. You have a point there. Admitting, half the time I didn't know what I was doing and what the right approach regarding this networking stuff would be, therefore I've run into all sorts of unforeseen, unimagined things, so is a bit of a learning curve.

For instance how do you make sure that an entity color change occurs when hit on all players screen and health are update 100% accurate all of the time? If it loses a packet or something then it fails to do so. The only solution would be a constant pol I guess or do error checking, requesting resend(like TCP) but I don't think that would be a good idea or feasible with my limited skillset.

BTW: if you have any ideas on how to fix the player pushing player problem for instance (as this is using PositionEntity) feel free to adjust, that is if you have the time, energy and interest for that of course. ;-)



Anyway, latest and greatest below for anyone interested, bit more bugfixed and cleaned(a little ;-)
Doesn't fit a code box(need to split), so download link for source, media(.wav files) and compiled version here BUMP V1.74.bb (3.62MB)

Changes/Fixes/Additions:
-added player squashed when fell to death.
-when get reintroduced to game players face to center of scene.
-added brief change of player color when hit feature.
-added squashed player when fallen and out of health.
-fixed teleport stuck in between 2 ports issue and adjusted ramp.(in future version put collision entity inside liquid mirror or something)
-changed detail on player sphere and spawn hill objects(more smooth)
-added two more chat commands
-fixed re-spawn fall costing life bug.
-reordered some code.
-fixed/updated color changes upon impact.

Pushing feature requires an overhaul/rethink for causing undesired fx, especially when more than 2 players pressent.


RemiD(Posted 2016) [#13]
There is an old post by "Banshee" about a good approach to manage a multi clients + one server game, but i don't find it. Maybe try to find it...


For instance how do you make sure that an entity color change occurs when hit on all players screen and health are update 100% accurate all of the time? If it loses a packet or something then it fails to do so.


It should be accurate only on the server, (where the important logic should be). The world will be slightly different on each client depending on if they have received a recent packet or not, but it does not matter because it is the server which decides if a new orientation new state is valid according to a previous state (with a tolerance)

With the approach that i suggest to use, those with a faster connection (lower ping) will be able to play more accurately than the others, because they can send more updates and receive more updates than those with a slowest connection (higher ping).
That's how i remember it was with unreal tournament or quake 3 or rune, sometimes, with my slow 56k it was difficult and confusing to play (because my state on the server was sometimes not updated fast enough, because probably not received)...


Rick Nasher(Posted 2016) [#14]
I thought about that ping approach too: when switching hosts the one with best (lowest)ping should become host /server.
Btw you can try running 2 instances of the game on your local machine (1 server, 1 client). Did you try this? That appears to work reasonably well?


RemiD(Posted 2016) [#15]
No i have not tried anything, i am just sharing some concepts that may help you. I may try to code a multi players udp system in october just to see if i encounter the same problem than you, but it will depend on my mood and motivation at this time, so don't wait for it :P


Anyway, at least you have tried ! Some kudos for this !


Rick Nasher(Posted 2016) [#16]
-A pity you haven't tried. If you're afraid of executables, like I am, it comes with full source so no need to run that(only included for the lazy people) :-) and the library itself is also a .bb file.

-October is still in a galaxy far far away, so lot's of things can happen, so indeed I won't hold my breath or wait up for it. ;-)

-Thanks, but I can't take full credits for Flanker's work: the UDP library, his example code and stuff other people dragged in. I merely came up with idea's and build upon it. Ok code grew form 24KB to 105KB, but that might just be poor coding. LOL


RemiD(Posted 2016) [#17]
One thing that you could try, is to code a functional multi players system with one server + several clients by writing/reading binary files on the same computer, each binary file being like a packet.
You could simulate the loss of some packets or some packets reaching the destination in the wrong order. (an old packet reaching the destination after a new packet)
I thought to do that before continuing my experiments with UDP, because maybe your problem is not UDP but rather your multi players system (how it handles the loss of some packets and the wrong order of some packets and no packet at all after xs)...


Rick Nasher(Posted 2016) [#18]
Tinkering around. Still not giving up.. :-)


eng_harvey(Posted 2016) [#19]
@Rick Nasher

How is everything going with the UDP LAN multiplayer?

:)


Flanker(Posted 2016) [#20]
The initial goal of this library was to be able to switch server on the fly if the initial server disconnects. If you go with UDP you must keep track of packets order and lost packets, but this library doesn't do it.

It would be simpler to manage without the server switch functionnality.


eng_harvey(Posted 2016) [#21]
@Flanker - I really like this library and the work you did on it! I am using ordered packets in my project! I really like the idea of server switching; the way I am going to tackle it is by having more than one server operational at a time that synchronizes data between them - I mainly want this to avoid DDOS attacks. I agree that this library would be simpler to manage without the switching. The concepts you used and coded are workable concepts in other areas of game networking.

I am just interested to see how Rick is doing with it all as I still find this project interesting.

:)


Flanker512(Posted 2016) [#22]
@eng_harvey
Thanks, I was hoping better results but it would need a complete rewrite at this point to integrate UDP checks. I hope my network code is not too crappy lol, after several months I don't even have the will to dig back into it ! I'm looking forward for infinitude, it seems you know what you are talking about so maybe we will finally have a good network library for B3D.


Rick Nasher(Posted 2016) [#23]
@eng_harvey
Hi, sorry haven't actually done much coding at all during summer holiday. Had to (and still do) take it easy sometimes due to a burnout I've suffered from since last year. :-( Taking it easy at the moment, first time I check here in weeks(and what do I find?? :-)

Was a bit demotivated too as I felt things were a bit hopeless, without the ordered packages feature and lacking the knowledge to incorporate this myself.
Still in love with the library and the host switching feature though. I demonstrated this to my friends and they were very, very impressed with it's flexibility as we were able to play a multiplayer game without hardly any effort and in no time at all.

Pity Flanker is not too eager to put his teeth into it and perfect it to give the world the best multiplayer library Blitz3d deserves.. [hint-hint] ;-)


RemiD(Posted 2016) [#24]

I felt things were a bit hopeless, without the ordered packages feature and lacking the knowledge to incorporate this myself


ordered packets, or rather considering a newly received packet or not, is simply adding an id in each packet and if the now received packed has an id inferior to the last considered packet, discard it (because it is a too ancient packet), else if the now received packed has an id superior to the last considered packet, consider it (because it is a recent enough packet).

And of course the server can also keep a stack of received packets and each loop decide which ones it will consider and which ones it will discard.

That's how i understand it...


eng_harvey(Posted 2016) [#25]
@RemiD - you understand it perfectly - that is exactly what it is. Even TCP uses it as a part of its reliability mechanism.

The server must keep track of each clients packets separately and the order in which its receives them discarding older more useless packets; and for those that are discarded another mechanism is embedded to make up for loss of resolution that would otherwise be taken care of by "perfect packets" - generally called interpolation.


RemiD(Posted 2016) [#26]
@eng_harvey>>so in order to be able to identify the emitter of the packet and the packet number, you add 2 ids in each packet ? one id for the emitter and one id for the packet number ?

In my past tests, the id of the packet was a string corresponding to hour-minute-second-millisecond for example 12-21-20-100 and the id of the emitter was a byte...


eng_harvey(Posted 2016) [#27]
@RemiD - Would you mind elaborating on what you mean by emitter?


Flanker(Posted 2016) [#28]
@RemiD
you don't need the emitter ID, at least in blitz3d, because you can check a message IP and port (UDPMsgIP & UDPMsgPort). The ID of the packet must be an incremental count, if you use millisecs you may send 2 packets with the same ID.

About discarding packets, yes you can discard older packets but not all. Some packets must be taken into account (for example a new player joins, a player dies...). It's not hard to check for them if they come in disorder, but what if they are lost ? I guess these packets need an acknoledgment.


eng_harvey(Posted 2016) [#29]
Acknowledgments are a good idea. I am using the IP and I also setup a Map List (like a hash table) for players. I only acknowledge every third packet at the moment - this is to help speed things up - by the sounds of it you could use this emitter to search the hash table.

Regarding the time stamp I think using a cycling counter is more efficient - give the packets an order between 0 -> 255 and when the last number is reached the counter returns to zero. That way the counter is always expecting a number bigger than zero and when the number goes over 254 then the counter is reset to zero. So 255 is 11111111 in binary and is a good use of packet size.

I hope I am making some sense here!

You could indeed identify a player by using 16 bits and this gives you 65536 ids to work with per server instance starting at zero and finishing at 65535 that way you are only using 3 bytes for user information and packet id combined!

Also by keeping packets a uniform size it makes it easier to encrypt them.


RemiD(Posted 2016) [#30]
Or use an integer instead of a string : 122120100


RemiD(Posted 2016) [#31]
@Flanker>>If you don't add an emitter id in the packet, how do you know which client sent the packet ?


eng_harvey(Posted 2016) [#32]
I think using bits instead of strings or integers is much faster - you would still have to convert from the integer to bits.

Your ids could then be easily hashed and the packet size is minimized.

So player 3 would be 0000-0000-0000-0011(16bit) and her/his packet number could be 234 or 1110-1010(8bit) equaling 3 bytes or 24 bits.

I like using strings and integers for testing the packets but would switch to bits for a production server.

I am assuming in Blitz3D you could use banks by peeking and poking at bytes to process this information(split the 3 bytes up by offset)!


Bobysait(Posted 2016) [#33]
@RemiD:

@Flanker>>If you don't add an emitter id in the packet, how do you know which client sent the packet ?


The standard blitz3d UDP commands can retrive the IP of the packet sent.
So, all you need is to maintain a list (or a hash map - which should be faster for this knid of stuff) with ip/player pairs.
Or ... you just loop the players and check if IP match with the UDP packet's IP.


@All : Interesting stuff here.
I won't help 'cause of lots of work, and from what I see, you don't really need anyone else to finish this community project, but I keep a look on this topic.

Some things you could (or not) consider :
- Don't create meshes for each objects, recycle ! (even for a simple sphere) -> your bullets has no control for fire rate, so this can lead to an excessive memory management (and memory pointers will grow up very fast until you reach the 2 Go ram limit [blitz3d's exes are 32 bit applications, they can't use more than 2 with or without a 64bit computer/OS]. So be carefull with that, it may crash after a long period whithout let you know the reason)
Solution : Preload all models, hide them, then use CopyEntity (really really really faster)

- For the bullet part, blitz collisions is too slow and bullets are supposed to be fast (and while you're already averaging the player's positions, it's not very accurate, so, yuo can use this fact to improve the performance)
solution : anticipate the impact when the player shoots.
-> use EntityPickMode instead of EntityType (also set the pickmode for the players and levels so that a linepick can pick everything relevant)
At the very moment the player shoots, a simple linepick from the bullet emitter along the emitter Z axis will tell you if you'll pick something.
You can also use the distance divided by the bullet velocity to compute the real collision time.

- I'm sure of that, but I think I saw you used collisions for the power ups
(I might be wrong, I 've not been very concentrated while reading to the code)
Use a simple Distance test to check if a player is within a range from the item. (it will drastically speed up the collision process with less entity pairs to check)

(Then, the big part : interpolation between frames is generally the biggest part for a multiplayer game and the one that can lead to the worst behaviors)
- you're using the previous frame to interpolate with an old position, so your code will always show a wrong position (until the player is in standye)
solution : For modern stuff, they frequently anticipate the next position (not the previous ... or why not, to create a catmul rom interpolation).
By knowing the current position and the player's velocity, you can easily know where a player will be at the next frame (and actually after few frames, as players' inputs doesn't change that much)
So, anticipating the next position can give a better average position for other players (just keep in mind there will be times the position is wrong because the player suddently jumped or reverse the direction etc ... and that's the part that you'll have to deal with -> what to do when the anticipated position leads to a wrong position. Commonly, bad engines just replace the player to a new position -> it makes the player teleports, but ... in some way, it works, and players are used to that and arguably accept it as a cost to pay).

Finally, some tricks regarding security/collisions :
- A small trick to prevent some cheating : the server should generate a random key for each player, and they should always use it on top of each message.
- The server should always compute the collisions, moves etc ...
-> if you want clients to do it to, they'll have to update from times to times to be synchronized with the server. And, to be true, blitz collision system is maybe a bit too heavy for a server. most of the collisions can be averaged in 2D before being really computed in 3D
(but it would mean to replace all collisions with a new collision library which is not the easiest thing on earth ... but maybe it could be a goal for a v3 or v4 or v...1000 ?)
Instead, you can use an hybrid system using blitz collisions only for the client-player Versus the level (no other collisions)
The rest can be acheived with sphere/sphere tests

- a project like this could maybe be more accessible on a github-like platform ? (just a suggestion)
Else, every one is waiting for the update from the last one who said he was working on it. (generally, it leads to the end of the project when the last guy just doesn't respond anymore)


eng_harvey(Posted 2016) [#34]
I am also wondering whether to start another thread so as not to pollute Ricks thread with too much information. There are three projects involved - the UDP LAN Multiplayer, The Infinitude Project and a C++ version of Infinitude I am working on called G2 Network.

I think I will download a copy of the UDP Lib and have a look at ordered packets - processing them via banks etc.

Adapting hermite interpolation via a polynomial function or maybe a newton polynomial should yield a derivative for a predicted position for players. I was thinking of something very simple for bullets - like some sort of set and forget function - the client could be used to help detect the collision along with the server.

I don't know; there is so many potential ways to build up game networks and game physics is getting better all the time.

I do think it is better to start with a solid basic framework and build it up to incorporate more complex issues as time goes by; it could yield many different applications for many different gameplay types.

With networking in Blitz3D I do think working within its bounds is the best idea so you can adapt the mathematics that is the best fit for it and I think with a little more work that this library could be acceptable for a number of game types. I am pretty certain the examples based upon it can be worked to provide a satisfying experience for each player.

It is late and I have been up for many hours - GitHub could be an awesome idea for all the projects.

:)

@Bobysait - Lots of interesting things to think about there - thanks!


RemiD(Posted 2016) [#35]

The standard blitz3d UDP commands can retrive the IP of the packet sent.


Oh ! I see, thanks for the info.


Guy Fawkes(Posted 2016) [#36]
How are you doing on this project, Rick Nasher?

~GF


RustyKristi(Posted 2016) [#37]
Hey Rick Nasher, I just tested the latest version you posted and for some reason you lose 1-3 health when you just do a normal jump from the ground?


Guy Fawkes(Posted 2016) [#38]
@RustiKristi : Yea, I know about that bug. It's not really a bug more than it is a calculation error. Try hiring the value of the variable that tells it "hey, lookk. You can only jump THIS high without damaging yourself" :)

Hope that helps! :)

~GF


RustyKristi(Posted 2016) [#39]
thanks, will check that out. maybe this will be corrected on next update


eng_harvey(Posted 2016) [#40]
@Rick Nasher - I hope you are doing well - stay positive - I will be back in December to see how you are doing - don't worry about things - we have much time left to achieve results!

I know exactly what you mean by demotivation - I sometimes play a bit of Sim City 4(deluxe edition) or Need for Speed(Most Wanted)to take my mind off things. Even a bit of YouTube or just chilling with friends!

Maybe playing your favorite game and relaxing is the way to go!

The best thing is you have friends to chill out with!

Take it easy and see you soon!

:)


Rick Nasher(Posted 2016) [#41]
Hi guys,
Thanks for all the input, ideas, kind words.

Burn-out symptoms come, go and back again. Doc told me it takes time, perhaps a lot of time, which is very annoying. Not really allowed to do anything that addresses thinking or performance, only dumb entertainment, but that's A)not very feasible at work and B}just so incredibly boring, bweehk! (can't take it really..) So I'm sort of sinning just being here already. lol


Anyway the 'bug' of loosing life while just jumping is actually intentional; I eventually want the player to loose a little energy/health just doing nothing and increasingly more when walking, running, swimming, jumping, falling, getting hit, pushing etc just as in real life, which has to be leveled by eating, drinking and health powerups/medicine. I feel this could add to the gameplay(if done well).

Meanwhile collecting coins/money to extend on wealth in order to not just pick up free weapons, food etc, but also have the option to buy better versions from merchants/shops/other players(you get the idea)and some capture the opponents flag thingies.

Some might like that, some don't. Always free to adjust to own likings of course. But for now I have to take it easy.