Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client-side coefficient calculation #9

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Conversation

rekterakathom
Copy link
Owner

Calculate coefficients on clients because dedicated servers are unreliable

Calculate coefficients on clients because dedicated servers are unreliable
Copy link

@thegamecracks thegamecracks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to work as expected when loading the mod on both client and server:

_unit = player; 
_playerTex = getObjectTextures _unit param [0, ""]; 
_groundTex = surfaceTexture getPosASL _unit; 
_playerTexAvg = (getTextureInfo _playerTex) # 2; 
_groundTexAvg = (getTextureInfo _groundTex) # 2; 
_averages = [];  
for "_i" from 0 to 2 do {  
    private _playerTex = _playerTexAvg # _i;  
    private _groundTex = _groundTexAvg # _i; 
    _averages pushBack (abs (_groundTex - _playerTex) / ([_playerTex, _groundTex] select (_playerTex <= _groundTex)));  
}; 
_result = 1.1 + sin (deg (pi * selectMax _averages) - 89.95) / 2; 
_localityText = ['Client','Server'] select isServer; 
systemChat format [ 
    'Locality: %1, camouflageCoef: %2, average: %3, playerTexInfo: %4, groundTexInfo: %5', 
    _localityText,_result,_averages,getTextureInfo _playerTex,getTextureInfo _groundTex 
];
systemChat format ['Actual camouflageCoef: %1', player getUnitTrait 'camouflageCoef'];

Camouflage coefficient of 0.767 on sand
Camouflage coefficient changed to 0.979 on dirt

To remove the client mod dependency, could the client cache and loop be installed with JIP remote execution?

@rekterakathom
Copy link
Owner Author

Technically it still works even without the client having the mod, it's just that every client without the mod won't be contributing any texture information.

For remote execution, the function would need to exist on the client or we would need to send the entire function over the network, which really isn't ideal.

I'll think about this for a while, it would be a drastic change for all server admins who currently expect this mod to work serverside to suddenly add a clientside requirement, but that would be the easiest solution by far...

Send the function to the clients, removing dependency
Ensure that clients have CBA
Cut down on the accuracy to remove amount of data in JIP queue
@rekterakathom
Copy link
Owner Author

Now it's back to being totally serverside. I'll investigate any possible solutions to reducing the network load before release though

@thegamecracks
Copy link

thegamecracks commented Jul 23, 2023

fwiw I know Advanced Urban Rappelling broadcasts its 28 functions over JIP, but I haven't noticed any issues running it:

AUR_Advanced_Urban_Rappelling_Install = {
    if(!isNil "AUR_RAPPELLING_INIT") exitWith {};
    ... // global function definitions
};
publicVariable "AUR_Advanced_Urban_Rappelling_Install";
[] call AUR_Advanced_Urban_Rappelling_Install;
remoteExecCall ["AUR_Advanced_Urban_Rappelling_Install", -2,true];

There's also the extra bandwidth cost of sending texture data to every client despite the computations being server-side; perhaps that can be implemented as a callback for when texture data isn't available?

/* fn_updateCamo.sqf */
// Client may remote execute this function to give us texture data
// BREAKING CHANGE: DYNCAS_fnc_updateCamo required in CfgRemoteExec
params ["_unit", ["_playerTexAvg", []], ["_groundTexAvg", []]];

_playerTex = (getObjectTextures _unit) param [0, ""];
_groundTex = surfaceTexture getPosASL _unit;

// Use cached texture if available;
// if not available then add client textures to cache, if defined
_playerTexAvg = GVAR(texInfoCache) getOrDefault [_playerTex, _playerTexAvg, _playerTexAvg isNotEqualTo []];
_groundTexAvg = GVAR(texInfoCache) getOrDefault [_groundTex, _groundTexAvg, _groundTexAvg isNotEqualTo []];

// No texture from client/cache? Ask client for textures
// Possibly timestamp player/ground textures to rate-limit calls?
if (_playerTexAvg isEqualTo [] || {_groundTexAvg isEqualTo []}) exitWith {
	[[_playerTex, _groundTex], FUNC(clientSendTextures)] remoteExec ["call", _unit];
};

// Otherwise we're good to calculate camouflageCoef...
/* fn_clientSendTextures.sqf */
params ["_playerTex", "_groundTex"];

_playerTexAvg = (getTextureInfo _playerTex) # 2;
_playerTexAvg deleteAt 3;
_groundTexAvg = (getTextureInfo _groundTex) # 2;
_groundTexAvg deleteAt 3;

[player, _playerTexAvg, _groundTexAvg] remoteExec [QFUNC(updateCamo), 2];

@rekterakathom
Copy link
Owner Author

Currently the texture information is shared to all to avoid clients sending duplicate data to server. Maybe a callback system would indeed be smarter, that way the only JIP bloat would be the function itself.

Use callback instead of constant loop for getting data to prevent JIP bloat
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants