Tokamak possible in Multi-User Online?
Blitz3D Forums/Blitz3D Userlibs/Tokamak possible in Multi-User Online?
Has anyone every attempted to use Tokamak in a multi-player online environment?
I understand that Tok's simulation results are extremely sensitive to the frame rate, so if a computer is just a tad slower or faster you get slightly different results. Making it very hard to get the same results on multiple computers.
A possible solution could be to have the fastest computer 'current in the network' do the physics simulation for the others...
Any thoughts on this?
cheer,
Danny.
Yes, I use Tokamak for a multiplayer game. I think a lot about this issue of physics which should be identical on several computers.
Finally I have found a solution and I am very happy with that.
In a few words:
every computers run the physics at exactly the same rate (say, 30 cycle per second). So they will do exactly the same, since the deltatime of the physics will be the same (here, 1/30 s). In practice, I use render tweening to do that for the physics.
Thanks vincent,
Interesting to hear you got it working.
Render Tweening still scares me because on my (crappy) system it creates a choppy frame rate, and I've heard other people having the same problem as well.
Do you do any checking to see wich computer is the slowest and then limit the others to match. Or do you just 'force' a 30fps as a minimal safety sort of thing?!
cheers,
Danny
RepeatUntil, do you have a barebone example of this?
For me, physics slowly get out of sync.
Perhaps if you do as RepeatUntil suggest but with the addition of some kind of synchronization once in a while.
Let the server send out the exact positions & velocities of all rigid bodies once every Nth second and let every client adjust it's bodies.
Yes, you have to resynchronize bodies from time to time, especially when there is a lot of interactions...
I will post a barebone example as soon as I have some time (I have no access to Blitz right now).
this is probably the most stupid idea of all time... but what would happen if only one computer handles the physics data... then the others just take the locations and angles to update their objects... they can use pushes and things like that... they get sent to the main pc that handles the physics, the impulses get applied and so on....
yeah... I can see the flaws as well... but I figured it might work... sorry If I'm slowing people down
You could adapt on that idea a little, and make it so all computers can control physics objects. But, only 1 computer (the host) can control who gets to control what.
So the server computer could dish of control of say a box, to user 1. This will then run the physics simulation for box and send the data along with its update packets. Which inturn is then delivered from server to all othere clients. That way you would have smoother interaction.
A bit late for my answer, but here we go.
Here is a barebone example of a technics to have physics synchronized on every computers using a physics engine (eg Tokamak).
The idea is to run the physics engine 50 times per second on every computers (using tween method) which results in the same calculations on every computers (since the physics step would be the same everywhere)
For this to work, you need to give the same initial conditions (time, position, velocity) for every object when something happens to them (thrown by a player for ex.)
Hope this helps,
;
; A barebone example of a technics to have physics synchronized on every computers
; using a physics engine (eg Tokamak).
; The idea is to run the physics engine 50 times per second on every computers (using
; tween method) which results in the same calculations on every computers (since the
; physics step would be the same everywhere)
; For this to work, you need to give the same initial conditions (time, position, velocity)
; for every object when something happens to them (thrown by a player for ex.)
;
;
; Author: RepeatUntil
;
Const PHYS_FPS = 50 ; The FPS for the physics (only the physics, the rest of the game
; running at the quickest possible rate)
Global physicsStep# = 0.8/PHYS_FPS ; The step for physics (parameter given to Tokamak)
;
; Some game initialisations here...
;
; The function Ms() is the time synchronized on all computers, ie it's the same time (to the
; best approximation) on all computers
; Ueful to guarantee that the physics happens at the same time on every computers
Local oldTime% = Ms()
; This loop permits to start when Ms() is a multiple of 1 sec (every computer do physics at the same time)
; There should be no heavy computation between this and the "For k=1 to ticks"
Repeat
Until (Ms() Mod 1000) < 10 ; < 10 is better than = 0 if the computer is slow
period=1000/PHYS_FPS
time=Ms()-period
;
; Main loop of game
;
While Not abortGame
; Compute deltaTime
newTime = Ms()
deltaTime = newTime - oldTime
oldTime = newTime
; Handle inputs from the player
HandleInputs()
; Do tweening for the physics (and physics only as we want the same FPS for every player)
Repeat
elapsed=Ms()-time
Until elapsed
;how many 'frames' have elapsed
ticks=elapsed/period
;fractional remainder
tween#=Float(elapsed Mod period)/Float(period)
For k=1 To ticks
time=time+period
If k=ticks Then CaptureWorld
; Apply physics
TOKSIM_Advance(physicsStep#)
; Check for collision and render world
UpdateWorld
Next ; k ticks loop
RenderWorld tween
;
; Some useful routines here...
;
;
; Some network routines here...
;
Flip
; End of the main loop
Wend
Cheers for the example RepeatUntil, I'll go check it out now..
D
Why not have:
Timer#=MilliSecs()
GameSpeed#=0
Frames=30
While Not KeyDown(1) ; Main loop of game
GameSpeed#=((MilliSecs()-Timer#)/Float(Frames))
Timer#=MilliSecs()
UpdateGame#(GameSpeed#);Players, etc
TOKSIM_Advance(GameSpeed#)
RenderWorld()
Flip
Wend
End
So you can faster computers can have high FPS.
No, that doesn't work. Maybe I didn't explain it well enough: the parameter GameSpeed# (as you call it) given to TOKSIM_Advance() *must* be the SAME for every players on the network AND TOKSIM_Advance *must* be called the SAME number of time per second.
In your case, GameSpeed# will vary at each iteration, and will be never the same on two computers (= different physics!).
The solution that I propose obeys these 2 rules:
- parameter given to TOKSIM_Advance() is
physicsStep# = 0.8/PHYS_FPS
(with PHYS_FPS = 50 for example)
(so the computation is *strictly the same* on every computers)
- TOKSIM_Advance() is called the same number of time per second on every computers thanks to the render tweening. In my example (see above), it's called 50 times/sec (= PHYS_FPS) (only the physics, the rest of the game running at the best available speed)
Hope it helps and explain a bit better the posted example (I have edited this example to make it more clear)...
Faster computers will run TOKSIM_Advance more because they are faster but GameSpeed# will be less, Slower computers will run TOKSIM_Advance less but GameSpeed# will be more.
Eg:
Fast computers may run:
TOKSIM_Advance 0.25
TOKSIM_Advance 0.25
TOKSIM_Advance 0.25
TOKSIM_Advance 0.25
(=1)
and slower computers may run:
TOKSIM_Advance 0.5
TOKSIM_Advance 0.5
(=1)
In the same amount of time
In the code I have posted, only the physics is running at a fix FPS, the rest of the code (graphics eg) is running at the maximum available speed. And who cares about a fix FPS for the physics?
Also, I am not sure that:
TOKSIM_Advance 0.25
TOKSIM_Advance 0.25
is equivalent to
TOKSIM_Advance 0.5
This have to be check, but I bet it's not equivalent, and that a slight difference could happen from this...