Introduction
A lot of times the available network and cpu resources for a gameserver are limited. Demands for these resources change continously when operating a server.
They change not only when the number of players change, also every player may have other connection properties such as an different client sides rate settings.
It may be challenging to manually find optimal settings when the resources are limited. Also in practise rates must be set to accomodate for the maximum peak usage rate of the server.
Or the maximum number of players must be set very conservative .
The conclusion is When server resources are limited static rates are almost never the most optimal
Manual vs Automatic
Therefore it would be handy to have a plugin that once installed will manage the server load automatically.
A real world analogy would beto having a having a car with automatic transmission, where you can change
gears as compared to a car with no transmission or a manual transmission that is only used once a day or
so when a admin notices the speeds are not optimal.
Examples of such resources in the server world are are:
*the server machine's processing power.
*the networkconnection upstream and/or downstream bandwidth
*a monthly data limit.
Who can benefit from such a plugin?
*everyone who wants their player to support more players with lower resouces per player
without ever having lag because of overloading their resources.
Examples are
- people who want to host a server at home for friends, which usually have very limited resources, a lot of times dont set the rates ok and the users that join lag. This plugin will just remove the headache of server rate settings and set it optimally both for the server owner as for the players.
- Another example is a game server provider. Which may give an option to clients to have a more player server with dynamic rates at a lower price, or also themselves making a profit because they can run more software servers on one machine.
- HIGH level wars cannot use it should be played on a non resource limited server, but thats only about 5% of the usage of al SRCDS servers.
- The other 95% of the non HIGH war servers could benefit from such a plugin
Purpose of this topic
This topic is for discussion about such a plugin. I will be making it but i are open for others to contribute. The more contributions there are the better the plugin will be. Cause a lot of people know more than one. Thats why im posting this here.
First, what im posting here is not fixed im open for suggestions or corrections.I have set the following priorities for what the plugin should do:
plugin priorities- Prevent server lag. The most important priority is to make the probability of server lag because of load exceeding the available resources very small.
- Use the server resources as much as possible. If the server is half full use that cpu and network more instead of sticking to lower settings.
- Fairness, by this its meaned that every player should be able to choose there own rates from between a global minimum and maximum ie: no client side variables must ever be changed. Nor should players be treated differently. They all get the same minimum and maximum rate settings.
- Reduce the amount of setting updates to a minimum. players(and the automatic lag compensation) may adapt to a specific rate setting, changing it too much will deteriorate player performance therefore rate changes should be reduced to a certain value(which may be changed by a cvar if really wanted although the default value should suit everyone)
Lets get started:
The plugin will have to do 3 tasks:
1
measure a certain variable possible multiple recording times to get a series for the second step to do some basic statistics
2
decide, if, when and to what value to change the variable.
3
change the variable.
The tasks may look simple in theory but in practise there are many possible (wrong, good and better) ways to do them.
I want to find ways that are close to optimum, and im really open to suggestions and hints/help to find these optimal ways.
I will discuss possible options
1.1 Measurements,
What should the interval be between the measurements?
If overload is about to occur you want to be able to change the settings downward fast. But you need to measure the upcoming overload first.
But what is a measurespeed thats high enough, why not just set it to 0.1 to be sure. What is the performance impact of a measurement every
0.1 second. But why measure so often if you only want to change the variables as little as possible.
For now im sticking to a 1 second default measurement rate, as i have tested it and the resource usage seems to change slow enough to
use this rate. but i want to make the measurement rate a cvar so people can choose how often a certain load variable is measured.
but also i want to provide a good set default value (which atm i think is 1 second)
How many measurements should be made before making a decision?
Decisions made based upon a series of measurements may have a higher probability to be better than a decision based on one measurement.
for example as the usage% of a resource drops and increases using a single measurement may set the load too high.
example cpu usage:
measurements:
40% 45% 65% 50% 55% [45%] > decision?<
maximum = 65%
average = 50%
minimum = 45%
last = 55%
setting the value to the average minimum or last is obviously wrong as there are higher peaks than those values which will cause lag.
therefore i will measure at the set measure interval rate and only remember the maximum value of the current serie of measurements.
when taking a decision the maximum value is used and the maxium is reset. then measuring continues yielding a new maximum for the next decision.
How to measure bandwidth usage?
There is the handy function below in the API.
It gives the current upload and download speed in bytes/s the srcds server is using:
GetServerNetStats(&Float:in, &Float
![Surprised](images/smilies/surprised.gif)
ut);So getting the bandwidth usage is no problem.
How to measure CPU usage?
For CPU usage there is not an function in the api that i know of to get it.
A task someone willing to contribute might do to really help the creation of this plugin is to find a neat way to get this value.
i know the rcon stats console command prints the cpu usage and i know that that value is probably correct for use in this plugin.
But i know no other way of getting it other than dumping it to a file and extracting it with the file read options in the api.
there should be a better and more elegant way. If you know please let us know.
2 Decisions.
Should a setting be changed based on the current measurements? To which value should it be changed and why? And when should the change take place. This is what concerns the decision part of the plugin.
Every resource may have its own decision code. because every resource may need a different decision strategy.
I really dont have a decision strategy yet but im working on it for updaterate and cmdrate:
possible choices are to only check if a setting is to low or high and just add or substract a constant value to it untill its ok. but this needs many updates. and with a small constant value the plugin will be setting a value higher and lower al the time. a too big constant will change the rate too much / too fast causing lag that can be noticed by the players
therefore its important that the decision is really good so the amount of actual changes in settings is minimal and the changes themselves are more optimal.
its also possible to work with a factor of the current rates instead of a constant value. For example everytime the load is too high multiply the setting by 0.9 (or something). But why 0.9 why not another value?
The best would be if there is a function which takes the old setting the current load and the desired load and calculated the setting that is needed to get at the desired load. For the update and commandrate / cpu this is possible i think. Im working on it.
![Twisted Evil](images/smilies/twisted.gif)
But i would appreciate help and suggestions.
custom cvars also play a role in the decisions:
These are the values i invented.9with the suggested default value)
(at = plugin abbreviation names could change im not sure of the name yet)
at_enabled = 1 //enables or disables the plugin
at_maxcpu = 90 // cpu value at which the server must immediatly lower the settings to return to a cpu value below it.
at_maxin = 512000 // maximum incoming network bytes per second value the server may use.
at_maxout = 64000 // maximum outgoing network bytes per second value the server may use.
(this setting will support 32 players without lag(hitting will be more difficult but there will be no yerkyness/hiccups prediction works very well.)
i have done extensive research and found this:
1Knowledge about rate variables:
1.1Updaterate
1.1.1sv_minupdaterate- setting it to 0 will set not minimum updaterate the client can choose and have no effect on sv_maxupdaterate
- setting it to 1 or higher will limit the client to use at least this updaterate.
- Setting sv_minupdaterate higher than sv_maxupdaterate will cause strange behaviour as sv_maxupdaterate will not reflect the set sv_maxupdaterate value.
1.1.2sv_maxupdaterate
The following settings were set with a non-restrictive sv_minupdaterate:
·setting 0 gives the maximum server updaterate(only limited by the server tickrate)
·setting 1 gives hiccups every second as the client exceeds the default maximum prediction time, stops the objects on the screen from moving, and waits for the next server update.
·Setting 2 will not give hiccups, but cannot be set when sv_maxupdaterate was previously set to 0 If it was set to another value it will change to 2: First set it to another value then to 2.
·2-9 when shooting a barrel the barrel moving is delayed because the next update takes some time to arrive. Physics are thus a bit off. In Player-player interaction this fact is hidden by using prediction. Its gives no disturbing hiccups in player- player contact.
·Setting it to 10 or higher also gives acceptable physics for objects like barrels
1.2Commandrate
Command rate can be dynamically changed to all values without apparent hiccups and regardless of the current updaterate values. Changing sv_maxcmdrate is straightforward
1.2.1sv_mincmdrate- setting 0 will totally disable enforcement of sv_mincmdrate and sv_maxcmdrate
the client is able to choose any value.
- Setting 1 or higher enables enforcement of sv_mincmdrate and sv_maxcmdrate
The client _cl_cmdrate value will be clamped between sv_mincmdrate and sv_maxcmdrate
1.2.2sv_maxcmdrate- setting it to 0 causes the clients display to literally freeze regardless of sv_mincmdrate setting. The client will also time out after the time out period and drop from the server.
Because the server thinks the client has crashed as the client sends no commands. Also
The clients HL2.exe may crash with this setting. Also accessing the server by rcon is sometimes impossible. (as it will accept no incoming commands)
- setting it to 1 will not give the problems mentioned with the 0 setting. But it will cause severe hiccups in which the player command is revoked and the players is teleported back to a previous point. The player is almost unable to move.`
- setting it to 2 – 9 gives hiccups in reducing severity s rate increases, the predicted physics do not match with the physics using default rate settings. Every second there is a hiccup. These effects get smaller as the sv_maxcmdrate increases.
- Setting it to 10 or higher is acceptable
A minimum setting of 5 for updaterate and 10 for commandrate is acceptable for player-player contacts and shows no yerkyness.
3 Change
Changing variables seems straightforward. But it isnt :p
For example its not possible to change the actual updaterate from any value below 66 to 100. The svmaxupdaterate will change but the actual meassured values at net_graph 2 wont change!
This is only an example. But it is much worse:
the actual maxupdaterate will change from any value between 1 and 14 to any value between 1 and 14 directly
the actual maxupdaterate will NOT change from 14 to 15 or 15 to 14
BUT it will change from 14 to 16 or 16 to 14.
the actual maxupdaterate will change from any value between 16 and 22 to any value between 16 and 22 directly
as long as the difference between the old and the new value is at least 2...
this is a part of the equation :
rate minimum decrease to change | actual value
2 1
16 2
23 3
36 6
40 7
50 10
67 17
80 23
87 27
90 28
100 34
i plotted this in a graph and concluded there is a certain formula that valve must have used.
i came at minimum difference = (current value/16)² but it doesnt exactly match the pattern i found. Im afraid it has to do with integer division or something. Im really not able to deduce the formula valve has used for this if i would have it i could set the values to the next possible value.
i have allready tried for example when going from sv_maxupdaterate 100 to sv_maxupdaterate 90 to first issue a maxupdaterate 10 (or so) . if done immediatly it has no effect and the actual value stays 100.
if done with a delay of at least 0.5 second or 50 server ticks? then
it will change from 100 to 10 then to 90 and it stays at 90 but this method really cause a displacement of all players and a severe hiccup so its not the way to go.
If i would have the formula i would only need to set the sv_maxupdaterate to 65 then to 100 which would be a bit better. But without the formula i cannot do this. Cause there are a lot of possible rate changes so for example when i want to change rate from 49 to 53 will this work? the formula would tell the minimum difference needed. But without it i have to guess or try al values by hand and put them in a table or something. Which is not efficient.
So if someone can deduce the formula used by valve for setting the sv_maxupdaterate it would be really great help.
OF course if someone knows a way to circumvent this quadratic limitation on changing sv_maxupdaterate it would be better. or an alternative way to change it. I just want to be able to change maxupdaterate to 75 when its 90 or from 50 to 45 etc without it dont changing.
summary
This plugin once installed will prevent lag, use resources more optimally depending on the load and make it a lote easier to manage the resources.
There are still some important design decisions to be made as well as some practical problems.
Every contribution will be taken in consideration when making the plugin.
- questions
- suggestions
- functions or other code
- equations
- suggested cvar list
- tips
regarding the plugin related cvars and resource management can all be posted in this topic
After the most important decisions are made i will post the an alpha version of the plugin in this post. then it will be a joint effort to adapt the code untill it is truly usable.