The cup is finally over with sK1p winning in the final with 2-0 vs AndySYS.
Final Standings:
| 1st | sK1p | |
| 2nd | AndySYS | |
| 3rd/4th | n i s m o | |
| 3rd/4th | Cue-X0 |
Links:
http://www.own3d.tv/stream/61177/
The cup is finally over with sK1p winning in the final with 2-0 vs AndySYS.
Final Standings:
| 1st | sK1p | |
| 2nd | AndySYS | |
| 3rd/4th | n i s m o | |
| 3rd/4th | Cue-X0 |
Links:
http://www.own3d.tv/stream/61177/
PK++ 1.31.1.64
=============
ADD: Console now bound to F1 (may make key configurable later)
CHANGE: Console now completes on settings as well as commands
ADD: DeferLoadingPlayers and DeferLoadingRest for faster load times
FIX: Teleporters and Jumppads now work based on client, rather than server
CHANGE: Converted PK++ over to easier-to-maintain format
Have fun 🙂
Demos were the original reason I started looking at PK, but in fixing demos a lot of other things need to be in place first. But before I explain that let me give an overview of demos as they are now.
Firstly when existing demos are played, they are simply rendering the few entities that you can see and nothing else. There is no game running, the player objects aren
This is slightly annoying, since I had planned to at least write a converter into any new/improved format. The fact a lot of the information I want is not there stored, or cannot be determined from the gameplay, is frustrating.
However, in order to create a new demo format – one where, say, you can run it at any speed, switch POVS, go spec, make movies from it. Effectively what I need is to write the netcode to file, and replay it. Obviously I would not want to store it at rendering fps, or even at netcode fps. To play it back, everything needs to be smooth, being played from any framerate. Of course this is where interpolation comes into play, and why it is so very important. With smooth interpolation I can replay demos and fill in the missing information.
The only thin I have yet to do is to tie up some loose ends of an initial snapshot of the level (item respawn times, etc), although in truth, this can just be captured from the netcode.
INTERPOLATION
=============
Firstly PCF did not write interpolation properly, on mouse, on animations, or anything. What they typically did was:
rotation = m_lastRotation + rotationDelta*0.33
where rotationDelta = m_lastRotation – m_nextRotation
Whereas what they should have is:
rotation = m_lastRotation + rotationDeltaRate*deltatime
where rotationDeltaRate = (m_lastRotation – m_nextRotation) / deltatimeperiod
They have made this mistake lots. Fixing interpolation in the bits we can see is straightforward. As I discussed with PeTjA, we can apply this interpolation to ALL items on the map, so that everything moves smoothly.
Typically linear interpolation is used for unpredictable items, and Catmull-Rom (cubic) splines for predictable movement (e.g. any mass subjected to constant or continuous accelerations.)
TIMING
======
Yikes! This is an important one. Ever since I improved item spawn times for PK++, I have always been suspicious of how accurate PK
The first problem is that PK works out time by adding deltas. This is CRAZY, since floating point (even double) will exhibit rounding errors quite quickly through any addition.
To test this, I set up the delta addition in comparison to os.time and os.clock. They were WAY off. Particularly because my machine is slow and does not always achieve the 45 FPS of the server. When the machine is slow it ASSUMES that the delta is 1.0/FPS regardless of whether it achieves that or not.
It gets worse though…
—
The MEASURED delta used varies by a huge amount, but dependent on it trying to hit a certain FPS. This is because they have imposed a minimum loop period of 30FPS or 0.0167secs. What this means is that loops can only occur in multiples of 30FPS, but such that over a second or so, they will meet the total FPS.
Say for example the desired FPS is 45. For PK this will run like this:
30,60,30,60,30,60,30,60,30,60,30,60,30,60 etc.
Of course the average delta for 45FPS is correct.
In other words the loops are not evenly spaced in time. What is terrible for netcode and interpolation and ANYTHING else.
This explains why 30 and 60 FPS seem to be smoothest. Iterations seem to only occur in 0-30, 30 or 62.5 FPS steps.
—
It is possible to stall the frames so they become evenly spaced (by setting FPS very very high and limiting within the LUA). But the issue is not that a frame goes too quickly, but too slowly, to average.
The maximum speed at which Havok can run is also set, at 62.5 FPS (or rather, this is the minimum time step it can accept).
—
Finally we can address these issues by setting the frame rate to zero (so max speed), then controlling the actual tickrate through the LUA. A suitable tickrate is 62.5 FPS providing one tick per physics iteration. This has already been tested for CPU usage and is very low.
Given this, the number of updates a client can recieve (q3
= number of players * update rate (serverframerate on client) * 30
So 32 players at 10fps is around 9KBps which is reasonable.
Additional work needs to be completed before reducing the update data further. This should be possible without access to the source code.
NETCODE
========
Interpolation now works, although there is a small glitch I need to resolve which might be a rendering issue. Other than that play is smooth at 1 network frame per second, but much more reasonable at about 10-20. PCF
Extrapolation was added too, although we will need to play with this. It may be possible to auto-compensate for lag, both on the server and client. Extrapolation of course makes things slightly less smooth, but this can be controlled.
I have yet to play with item/weapon prediction.
I have to look at whether I can reduce the amount of data per player.
I also added all the netcode commands to console.
COOP
=====
Killua-chan provided an excellent map, although I believe PeTjA has some minor alterations.
It is possible to add a lot of the monsters already, but their code requires a listen server. Once I have perfected how to deal with multiple players using one monster, I will duplicate to all (probably via the AI Brain code).
My thoughts for COOP are basically either SP COOP or MP COOP, MP COOP perhaps more like ffa with monsters. I also thought about a COOP Arena gamemode.. where as a group of players you have to make it through progressively more difficult levels. Imagine DM_Boss with Thor to start, you have to kill him without you all dying, then level 2 is the same map, but with Thor and Panzer_Demon, and so on…
CODE
=====
Now is a good time to work on structuring the code better – so this is what I am doing, mainly the game and player code. I wish to use polymorphism rather than conditionals for custom gamemode responses (if you know what I mean). This will make thing a lot easier to make new custom gamemodes without screwing up existing code – an important method
PHYSICS
=======
At a glance it might be possible to try some new movement code, but we can try this later.
PKGUID
======
I am still yet to confirm whether I can obtain the CDKEY to MD5/RSA. Without it, making something unqiue generated from the game might be difficult.
DEMOS
======
Netcode improvements make writing this easier.