Jump to content
Guest

Something I made up in my head

Recommended Posts

Guest

I want to share this little script that intents to increase FPS on any client using any mod or mission.

You just need to run it in inti.sqf.

if (isNil "BRPVP_fpsBoost") then {
	BRPVP_fpsBoost = true;
	[] spawn {
		_cantDisable = {isPlayer _x};
		if (isServer) then {
			_init = time;
			_entities = [];
			_range = 0;
			_rangeLast = 0;
			_extra = 0;
			_rangeNow = 0;
			_countA = 39;
			_countB = 0;
			waitUntil {
				_time = time;
				if (_time - _init >= 0.25) then {
					_init = _time;
					_countA = _countA + 1;
					_countB = _countB + 1;
					if (_countA == 40) then {
						_entities = entities [["AllVehicles"],[],false,true];
						_delCount = 0;
						{
							if (_x call _cantDisable) then {
								_entities deleteAt (_forEachIndex - _delCount);
								_delCount = _delCount + 1;
							};
						} forEach + _entities;
						_countEntities = count _entities;
						_range = floor (_countEntities/16);
						_extra = _countEntities mod 16;
						_countA = 0;
					};
					_indexInit = (_countB - 1) * _range;
					if (_countB == 16) then {
						_rangeNow = _range + _rangeLast;
						_countB = 0;
					} else {
						_rangeNow = _range;
					};
					{
						_vel = velocity _x;
						_x setPosWorld getPosWorld _x;
						_x setVelocity _vel;
					} forEach (_entities select [_indexInit,_rangeNow]);
				};
				false
			};
		} else {
			_init = time;
			_countA = 4;
			_near = [];
			_childs = [];
			{
				_class = configName inheritsFrom _x;
				if (_class == "AllVehicles") then {
					_childs pushBack _class;
				};
			} forEach ("true" configClasses (configFile >> "CfgVehicles"));
			waitUntil {
				_time = time;
				if (_time - _init > 1) then {
					_init = _time;
					_countA = _countA + 1;
					_near = player nearEntities ["AllVehicles",viewDistance * 1.25];
					{
						if (!simulationEnabled _x) then {
							_x enableSimulation true;
						};
					} forEach _near;
					if (_countA == 5) then {
						_away = [];
						{
							_away append (entities [[_x],[],false,true]);
							sleep 0.001;
						} forEach _childs;
						{
							if (_x call _cantDisable) then {
								if (!simulationEnabled _x) then {
									_x enableSimulation true;
								};
							} else {
								if (simulationEnabled _x) then {
									_x enableSimulation false;
								};
							};
						} forEach (_away - _near);
						_countA = 0;
					};
				};
				false
			};
		};
	};
};

Since the simulation is not completely frozen, there is a lot small chance of game break results.

 

Works on dedicated server or listem server, but it does not increase fps for the listem server client.

 

Thanks!

Share this post


Link to post
Share on other sites

What advantages this has over the vanilla dynamic simulation?

 

Isn't the nearEntities pretty heavy to check every few seconds with such big radius? And wouldn't the object view distance be better than the view distance*x?

 

  • Like 1

Share this post


Link to post
Share on other sites

Bit weird. You already have active units and vehicles inside specific arrays. No need to check for nearEntities at all, especially on such a radius as greenfist stated.

 

Cheers

Share this post


Link to post
Share on other sites
3 hours ago, donnovan said:

I want to share this little script that intents to increase FPS on any client using any mod or mission.

 


[] spawn {
	_init = time;
	_countD = 1;
	_countC = 2;
	_countA = 6;
	_countB = 16;
	_onView = [];
	_arround = [];
	_away = [];
	waitUntil {
		_time = time;
		if (_time - _init > 0.5) then {
			_init = _time;
			_countA = _countA + 1;
			_countB = _countB + 1;
			_countC = _countC + 1;
			_countD = _countD + 1;
			if (_countD == 2) then {
				_onView = player nearEntities [["CaManBase","LandVehicle","Air"],viewDistance];
				{if (!simulationEnabled _x) then {_x enableSimulation true;};} forEach _onView;
				_countD = 0;
			};
			if (_countC == 3) then {
				_arround = player nearEntities [["CaManBase","LandVehicle","Air"],viewDistance*1.5];
				_array = _arround - _onView;
				{_x enableSimulation true;} forEach _array;sleep 0.001;{_x enableSimulation false;} forEach _array;
				_countC = 0;
			};
			if (_countA == 7) then {
				_away = player nearEntities [["CaManBase","LandVehicle","Air"],viewDistance*2];
				_array = _away - _arround;
				{_x enableSimulation true;} forEach _array;sleep 0.001;{_x enableSimulation false;} forEach _array;
				_countA = 0;
			};
			if (_countB == 17) then {
				_farAway = BRPVP_centroMapa nearEntities [["CaManBase","LandVehicle","Air"],50000];
				_array = _farAway - _away;
				{_x enableSimulation true;} forEach _array;sleep 0.001;{_x enableSimulation false;} forEach _array;
				_countB = 0;
			};
		};
		false
	};
};

What it does is lower the simulation rate of far away objects. The more the far, the lower the simulation rate is.

In my tests it does very well,

My idea in publishing it here is to get help to improve it.

 

You just need to run it client side.

 

Since the simulation is not completely frozen, there is a lot small chance of game break results.

 

Thanks!

 

 

Where do you place this code within the game 

Share this post


Link to post
Share on other sites
Guest

I updated the code.

 

I have not tested dynamic simulation in my mission already. But this code at least don't cause problem to my complex mission.

 

i set my i7 4790K to run at 1600 Mhz and the only problem i had was with that line:

_farAway = entities [[],[],false,true];

It causes a small lag. The other lines don't cause any lag.

 

Michael poole, you can put it in your init.sqf, but be sure to use the updated code. If you get any lag tell me.

 

OBS: For my mission this is not needed but if in your mission the client tends to host things you can't disable simulation on those client hosted things because this can cause probblems to the other player (still need to test).

 

On some missions new entities can be spawned, this is why i need to check for all entities from time to time.

 

Would be nice an script command that updates a object that have simulation off, like updateSimulationState _object, but i'm not sure if this is possible, its some thing i believe to be desirable. This is what i do with the lines:

{_x enableSimulation true;} forEach _array;sleep 0.001;{_x enableSimulation false;} forEach _array;

 

Share this post


Link to post
Share on other sites
29 minutes ago, donnovan said:

 

 

 

Would be nice an script command that updates a object that have simulation off, like updateSimulationState _object, but i'm not sure if this is possible, its some thing i believe to be desirable. This is what i do with the lines:


{_x enableSimulation true;} forEach _array;sleep 0.001;{_x enableSimulation false;} forEach _array;

 

 

That activates the object for a split second - why? It doesn't have any time to actually do anything, right?

Besides, I think enabling the simulation on AI units triggers some sort of 'initialization' process which creates a small lag. At least I've noticed some brief fps drop when enabling a lot of units at once.

So doing this just for a thousandth of a second seems a bit pointless.

  • Like 1

Share this post


Link to post
Share on other sites
Guest

At my tests the 0.001 sleep is enough to make the object update at least its position.

I'm trying to simulate other systems setting my computer Mhz to 1000, 1600, 2400, 4600 etc..


This does nothing:

{_x enableSimulation true;} forEach _array;{_x enableSimulation false;} forEach _array;

But the sleep fix the problem.

 

May be i can set the position where the object is local (mostly server where simulation is on) with _object setPosWorld getPosWorld _object and see if the position get updated on all clients (where simulation can be off). so this is a way to update object position where its simulation is off.

 

I also believe there are some kind of initialization, but not obstant there is a considerable FPS gain. Also i have not noticed the lag problem. The only lag noticed, even with CPU at 1000 Mhz is with the command entities, but this command just need to be run when some new entitie is created on the map. with 2500 Mhz it cause no lag anymore. It can be run each 60 seconds... it can be run in parts, one for LandVehicle, one for Air, one for CaManBase and then join the arrays.

 

Ah, the test server have more or less 360 vehicles, 110  AI units and 50 agents.

 

Share this post


Link to post
Share on other sites

why not just call this something like "caching system" instead of client side fps boost? Because we all know that's a fallacy. 

  • Like 1

Share this post


Link to post
Share on other sites
Guest

Because it is not a caching system.

 

What i'm doing is giving a hand to the minErrorToSendNear config parameter, and making it a lot more agressive after the view distance.

 

I ask,

 

This is equivalent?

_array = player nearEntities ["AllVehicles",viewDistance];
_array = player nearEntities viewDistance;

AllVahicles contain units, land vehicles, air vehicles, ships, bunnys.

Share this post


Link to post
Share on other sites
Guest

This is a try to remove the lag created by the entities function. A full entities execution is broken in many entities execution:

 

[] spawn {
	_init = time;
	_countA = 4;
	_countB = 10;
	_countC = 20;
	_countD = 40;
	_onView = [];
	_arround = [];
	_away = [];
	_derived = [];
	{
		_class = configName inheritsFrom _x;
		if (_class == "AllVehicles") then {
			_derived pushBack _class;
		};
	} forEach (configFile >> "CfgVehicles");
	waitUntil {
		_time = time;
		if (_time - _init > 0.2) then {
			_init = _time;
			_countA = _countA + 1;
			_countB = _countB + 1;
			_countC = _countC + 1;
			_countD = _countD + 1;
			if (_countA >= 5) then {
				_onView = player nearEntities ["AllVehicles",viewDistance * 1.2];
				{if (!simulationEnabled _x) then {_x enableSimulation true;};} forEach _onView;
				_countA = 0;
			} else {
				if (_countB >= 11) then {
					_arround = player nearEntities ["AllVehicles",viewDistance * 1.7];
					_array = _arround - _onView;
					{_x enableSimulation true;} forEach _array;sleep 0.001;{_x enableSimulation false;} forEach _array;
					_countB = 0;
				} else {
					if (_countC >= 21) then {
						_away = player nearEntities ["AllVehicles",viewDistance * 2.2];
						_array = _away - _arround;
						{_x enableSimulation true;} forEach _array;sleep 0.001;{_x enableSimulation false;} forEach _array;
						_countC = 0;
					} else {
						if (_countD >= 41) then {
							_farAway = [];
							{
								_farAway = _farAway append (entities [[_x],[],false,true]);
							} forEach _derived;
							_array = _farAway - _away;
							{_x enableSimulation true;} forEach _array;sleep 0.001;{_x enableSimulation false;} forEach _array;
							_countD = 0;
						};
					};
				};
			};
		};
		false
	};
};

 

Share this post


Link to post
Share on other sites
16 minutes ago, donnovan said:

This is a try to remove the lag created by the entities function. A full entities execution is broken in many entities execution:


[] spawn {
	_init = time;
	_countA = 4;
	_countB = 10;
	_countC = 20;
	_countD = 40;
	_onView = [];
	_arround = [];
	_away = [];
	_derived = [];
	{
		if (configName inheritsFrom _x == "AllVehicles") then {
			_derived pushBack _class;
		};
	} forEach (configFile >> "CfgVehicles");
	waitUntil {
		_time = time;
		if (_time - _init > 0.2) then {
			_init = _time;
			_countA = _countA + 1;
			_countB = _countB + 1;
			_countC = _countC + 1;
			_countD = _countD + 1;
			if (_countA >= 5) then {
				_onView = player nearEntities ["AllVehicles",viewDistance * 1.2];
				{if (!simulationEnabled _x) then {_x enableSimulation true;};} forEach _onView;
				_countA = 0;
			} else {
				if (_countB >= 11) then {
					_arround = player nearEntities ["AllVehicles",viewDistance * 1.7];
					_array = _arround - _onView;
					{_x enableSimulation true;} forEach _array;sleep 0.001;{_x enableSimulation false;} forEach _array;
					_countB = 0;
				} else {
					if (_countC >= 21) then {
						_away = player nearEntities ["AllVehicles",viewDistance * 2.2];
						_array = _away - _arround;
						{_x enableSimulation true;} forEach _array;sleep 0.001;{_x enableSimulation false;} forEach _array;
						_countC = 0;
					} else {
						if (_countD >= 41) then {
							_farAway = [];
							{
								_farAway = _farAway append (entities [[_x],[],false,true]);
							} forEach _derived;
							_array = _farAway - _away;
							{_x enableSimulation true;} forEach _array;sleep 0.001;{_x enableSimulation false;} forEach _array;
							_countD = 0;
						};
					};
				};
			};
		};
		false
	};
};

 

This thing doesn't make any sense.

Might as well rename the thread into "Something I made up in my head".

 

Cheers

  • Like 1

Share this post


Link to post
Share on other sites
Guest

Or you just have a very low IQ.

 

Your IQ may not be enough but you allways can test it. See i'm not asking you to test.

 

Also you can ask why something is that way, but i'm also not aksing you to ask. lol.

Share this post


Link to post
Share on other sites
35 minutes ago, donnovan said:

Or you just have a very low IQ.

 

Your IQ may not be enough but you allways can test it. See i'm not asking you to test.

 

Also you can ask why something is that way, but i'm also not aksing you to ask. lol.

With an forEach and if then statement like in the top of your script that's filled to the brim with undefined variables and syntax errors, I'd be careful who to insult.

And no, I'd rather not want to know why you'd write it that way.

This thing is throwing .rpt errors before I even execute it.

:yay:

 

Cheers

  • Like 3

Share this post


Link to post
Share on other sites
Guest

Yes, i changed the code and still not tested it, you is bypassing a not tested code and because of basic error that can be easily fixed after one run.

And i don't believe i need to choose better who to insult, i don't insult anyone, and also don't believe you can choose your IQ on born, right?

Share this post


Link to post
Share on other sites
10 minutes ago, Grumpy Old Man said:

 I'd be careful who to insult.
:yay:

 

Cheers

 

All your comments have been rude and destructive, in addition you now include threats.
If you have a better way to do this please show them to others but right now you are giving the impression that you are trying to provoke a useless fight.

Share this post


Link to post
Share on other sites

I know very little about MP scripting, so forgive me if this is a stupid question, but I hope someone with a higher IQ could help me understand this.

Why do you need to update the position of a disabled unit across network while its position can not even change? Why not just keep it disabled and let dynamic simulation or manual enableSimulation wake it up when needed?

  • Like 1

Share this post


Link to post
Share on other sites
Guest

I'm not that inteligent, just a little, sorry for my bad words.

 

Because check if the position changed for all entities is more expensive than just enabling and disabling simulation even if it not changed.

 

Also, if simulation is disable, i can't check for position change because it will not change, so the position change should be made on the server and send to clients.

 

The far away entities have its simulation enabled only each 8 seconds, this and full disable is more or less the same thing.

Share this post


Link to post
Share on other sites
37 minutes ago, djotacon said:

 

All your comments have been rude and destructive, in addition you now include threats.
If you have a better way to do this please show them to others but right now you are giving the impression that you are trying to provoke a useless fight.

 

Quoting me out of context won't make his code right.

I'm sorry that dancing banana offended you.

 

Spoiler

:yay:

 

15 minutes ago, Greenfist said:

I know very little about MP scripting, so forgive me if this is a stupid question, but I hope someone with a higher IQ could help me understand this.

Why do you need to update the position of a disabled unit across network while its position can not even change? Why not just keep it disabled and let dynamic simulation or manual enableSimulation wake it up when needed?

 

I'm at a loss too.

That "waitUntil" loop makes no sense, he's returning false at the end of it, might as well use "while something do" loop.

The first "forEach" should show scripterrors but who would know without testing, right?

 

This game already has a problem with badly scripted MP missions.

Folks posting untested, error ridden "Client side fps boost" scripts won't help either.

 

5 minutes ago, donnovan said:

Because check if the position changed for all entities is more expensive than just enabling and disabling simulation even if it not changed.

 

But what does it achieve?

As greenfist said, it doesn't make any sense, maybe you could elaborate further what you're trying to achieve.

 

 

Cheers

  • Like 2

Share this post


Link to post
Share on other sites
1 hour ago, donnovan said:

Or you just have a very low IQ.

 

Your IQ may not be enough but you allways can test it. See i'm not asking you to test.

 

Also you can ask why something is that way, but i'm also not aksing you to ask. lol.

These sort of flame-baiting posts are not needed on this forum, please think before you post.

 

@all Also lets try to be civil, i hate to hand any further forum infractions.

  • Like 2

Share this post


Link to post
Share on other sites
Guest

Ah,

 

Topic changed to "Something I made up in my head".

 

I probabily fixed the error in the first  forEach loop.

the _class variable was not declared.

 

There was a working code, but i removed it to put the new one.

Share this post


Link to post
Share on other sites
Guest

I'm using _object setPosWorld getPosWorld _object to updated the not simulated units, but this is not perfect...

 

If anyone know a better way to update a not simulated unit position, can be any function that simulate it by one frame and the function can't do anything that create a problem.

 

Example: _x setVelocity velocity _x;

But sadly this don't update the object over the internet.

 

Using now:

_vel = velocity _x;
_x setPosWorld getPosWorld _x;
//Here the update over internet happens
_x setVelocity _vel;

 

But still not perfect.

 

I'm sure you understand me.

 

Just sharing the final result:

https://www.dropbox.com/s/aqi25gnahs2oiof/brpvp_fps_boost.fsm?dl=0

Share this post


Link to post
Share on other sites
Guest

The idea is really simple, but the result now is tailored for my mission BRPVP so i can't share, and the version i put above have bugs (i have not noticed the bug early because there was significative gain in fps instead).

 

The idea:

1 - You disable simulation and hide everything that its not local to your machine and is not in the desired radius; This rad can be viewDistance for example.

2 - On the local objects of your machine you record its actual position, can be in 2D, using _object setVariable ["xxx_local_pos",_pos2D,true]. You can use different update rates for LandVehicles, Air, Ship and CaManBase, and you also can check if the object moved before record a new position.

3 - For the same objects in 1, you check if they entered the radius (viewDistance for example) by measuring the distance from player to the object var xxx_local_pos. If the distance is smaller than the radius, you enable its simulation and unhide, if not, you disable simulation and hide.

 

Extra:

You can have exclude arrays, for example:

XXX_excludeAir = [object1,object2,...]

XXX_excludeLandVehicles = [object1,object2,...]

XXX_excludeCaManBase = [object1,object2,...]

XXX_excludeShip = [object1,object2,...]

 

And for example, you can put units of the player group in XXX_excludeCaManBase to exclude then from the process so they get full updated all the time.

 

Also, if your mission have code to hide and unhide objects, you will need to make sure the performance code will not interfer with it.

 

You can record positions with different rates: each 4 seconds for CaManBase, each 1 second for Air, etc, to avoid the most the player to see poping objects.

 

If a machine hosts AI, it will need to keep CaManBase entities fully simulated, or the local AI will have the chance to meet frozen units. If only the server hosts AI, only it will not be able to disable CaManBase entities.

 

Possible AI on the player group don't count on the above statement because they will, may be, be allways near the player. If you want to make sure those AI don't meet any frozeen unit add to the radius distance the greater distance from the player to each of the group unit. For example, if the radius is viewDistance and the player group have 3 other mates and the player distances for those mate are 35 meters, 57 meters and 207 meters, change the radius to viewDistance + 207. With that you don't need to fully simulate all CaManBase entities just because of AI on player group.

 

Players will normally have tons of objects to disable and hide so performance will be like to play in an mostly empty map.

 

Instead of using viewDistance as radius you can use viewDistance*1.25, for example. This is another way to avoid fast objects to pop up deep in the view area. They will have simulation set to on early, before entering in the view area.

 

Objects generated sounds continues to happens even if the objects are disabled and hide.

 

So thats it. This is what i wanted to share. Its something somewhat generic as an idea, huge gain in fps, need some, not much, tailorement for your mission, but it worth. Important is to understand the simple idea.

Share this post


Link to post
Share on other sites

problem with dynamic simulation system is the global wakeup ... why client A (10km away) needs to simulate object woken up by client B (300m away)?

 

Needs a local-effect wakeup mode to be truly useful for MP.

 

also i have had a number of server crashes when using Dyn Sim, cant figure out exactly what is causing the crashes though.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×