Jump to content

Recommended Posts

Heh, i just forgot for a minute how setVariable works. Obviously i meant to use the mission namespace. I edited the code, which by the way i haven't tested at all and am obviously not recommending anyone use.

Share this post


Link to post
Share on other sites

I don't think just because you put something in an array, that means that it's atomic. If that were the case, we could just use:

[_arg call _fnc]

Share this post


Link to post
Share on other sites

 

I don't think just because you put something in an array, that means that it's atomic. If that were the case, we could just use:

[_arg call _fnc]

 

You're right, this is not atomic. However an array initializer containing only atomic statements is atomic. For example:

//long running command pretty much guaranteed to go over 3ms
#define COMMAND (selectBestPlaces [position player, 500, "meadow + 2*hills", 1, 5])

[] spawn
{
	systemChat "async";
	
	systemChat str diag_frameNo;
	COMMAND;
	COMMAND;
	COMMAND;
	COMMAND;
	systemChat str diag_frameNo;
	
	systemChat "sync";
	
	[
		systemChat str diag_frameNo,
		COMMAND,
		COMMAND,
		COMMAND,
		COMMAND,
		systemChat str diag_frameNo
	]
};

Share this post


Link to post
Share on other sites

Well apparently isNil <code> is atomic. Case closed. We can all go home now.

fxy_fnc_sync =
{
	private "_result";
	_result = [];
	isNil { _result set [0, _this select 1 call (_this select 0)] };
	_result select 0
};

Test case:

#define DELAY (selectBestPlaces [position player, 200, "meadow + 2*hills", 1, 5])

0 spawn
{
	_func =
	{
		private "_frame";
		_frame = diag_frameNo;
		DELAY;
		DELAY;
		DELAY;
		DELAY;
		diag_frameNo - _frame
	};
	
	_control =
	{
		_this select 1 call (_this select 0)
	};
	
	systemChat format ["control: %1 frames", [_func, 0] call _control];
	systemChat format ["sync:    %1 frames", [_func, 0] call fxy_fnc_sync];
};

Output:

control: 4 frames
sync:    0 frames
  • Like 1

Share this post


Link to post
Share on other sites

Yeah, but you're not using the command how it was meant to be used. You might crash your game ;-)

  • Like 1

Share this post


Link to post
Share on other sites

I know you're being sarcastic, but seriously though this is by far the best solution i've seen so far.

  • Like 2

Share this post


Link to post
Share on other sites

Yeah, but you're not using the command how it was meant to be used. You might crash your game ;-)

While this might be amusing to you, I am actually not amused at all. You distribute CBA to thousands of users who TRUST you. At the very least you have moral obligation to provide reliable product. I told you, the way you approached it is unsafe because I have tried it before and managed to crash the game. Instead of taking a note of it, you decide to ridicule me with your sarcasm. Fine, but know this, I will be 1st to not recommend CBA, only now I have a good story to tell as well. ;)

Share this post


Link to post
Share on other sites

I told you, the way you approached it is unsafe because I have tried it before and managed to crash the game.

And how exactly did you manage to do that? Because I don't see it.

  • Like 1

Share this post


Link to post
Share on other sites

 

Well apparently isNil <code> is atomic. Case closed. We can all go home now.

 

Can I just ask, what do you mean by "isNil is atomic"?

Share this post


Link to post
Share on other sites

Can I just ask, what do you mean by "isNil is atomic"?

The CODE-block after the isNil command is always executed in unscheduled environment.

Share this post


Link to post
Share on other sites

@killzone_kid Could you provide us with sample code that reliably crashes the game? Until you do i don't think there's any reason to believe that this use of the command is at fault. Unfortunately the forum rules prevent me from going into detail on why i think it's perfectly safe.

  • Like 1

Share this post


Link to post
Share on other sites

why would he do that, that's something for our QA and programmers to see ...

  • Like 1

Share this post


Link to post
Share on other sites

why would he do that, that's something for our QA and programmers to see ...

 

No, not really when CBA are the one's that maintain their code base and KK just basically reported a major bug but then didn't explain how to reproduce it.

Share this post


Link to post
Share on other sites

I agree with cyruz. Might as well just report it on bug tracker and hold your tongue if you're not going to add anything constructive to the discussion. If you do bring up something like this, at least back it up with some evidence.

Share this post


Link to post
Share on other sites

Dwarden's point is you should post proof directly to BIS privately rather than post a game destroying bug publicly.  Certainly all involved have already sent their proof to Dwarden so that BIS can fix the error, right?   :blush:

Share this post


Link to post
Share on other sites

Guys, let's not get hostile here. It is probably some deliberate limitation like having a small stack allocation for the interpreter state. The "exploit" would then be either producing deep enough recursion through "call" or a complex enough expression to overload the expression parser or something along those lines. You would be surprised what code accumulates over a decade and a half.

Would be nice to know what exactly it is though, as any mission maker can already "crash" a game just by infinite loop in unscheduled env, so unless you believe it is security related, a disclosure wouldn't hurt, so we have an idea of what counts as "simple enough" expression to be used for isNil / diag_codePerformance / etc.

Thanks.

  • Like 1

Share this post


Link to post
Share on other sites

@kylania I think you missed the point of this conversation entirely. There is no bug.

Share this post


Link to post
Share on other sites

@commy2 I don't think that's necessarily the case. I just tried and this code does crash the game:

dbg_fnc = { isNil dbg_fnc }; isNil dbg_fnc;

But then again so does this:

dbg_fnc = { call dbg_fnc }; call dbg_fnc;

@kylania @Freghar There is no reason to keep something like this from public knowledge. It can't be exploited. If you want to crash your own game you can just kill the process. And even if it could, i say make it public and if it does get exploited that's just more pressure on the developer to fix it.

  • Like 1

Share this post


Link to post
Share on other sites

@commy2 I don't think that's necessarily the case. I just tried and this code does crash the game:

dbg_fnc = { isNil dbg_fnc }; isNil dbg_fnc;
That's beside the point - of course it crashes the game, it eats all the memory with boilerplate for recursion. If it is well optimized (so-called tail recursion), it just hangs indefinitely.

What remains to be disclosed is what exactly is the issue regarding complex expressions and if there is indeed a limitation, provide guidelines on how severe (roughly) it is, so we can deterministically know what the command can handle.

Alternatively, what KK saw previously was "just" a one-time bug and there's no limitation.

Maybe it's all just a conspiracy and FUD to prevent newbie mission makers copy-pasting unknown code because you can REALLY slow the game down if you're not careful about what you run unscheduled.

We just don't know until somebody comes up with a reproducer or something. :)

Probably won't be recursion related though, the following works just fine:

0 = [] spawn {
    _code = {
        if (_this >= 10000) exitWith { systemchat str _this };
        (_this+1) call _code;
    };
    isNil { 0 call _code };
};
Arithmetic expressions also work fine:

_expr = "";
_genexpr = {
    private _expr = "";
    for "_i" from 0 to 10000 do {
        _expr = _expr + str ceil random 100000 +
            (switch (floor random 4) do {
                case 0: { "+" };
                case 1: { "-" };
                case 2: { "/" };
                case 3: { "*" };
            });
    };
    _expr + "1";
};
_expr = "(" + (call _genexpr) + ") / (" + (call _genexpr) + ")";
_expr = compile _expr;
systemchat str isNil _expr;

Share this post


Link to post
Share on other sites

Maybe it's all just a conspiracy and FUD to prevent newbie mission makers copy-pasting unknown code because you can REALLY slow the game down if you're not careful about what you run unscheduled.

 

It is not just that. Piling everything in unscheduled (I have no doubt that this what would happen if such command was added) would kill FPS very quickly and since every modder would want HIS scripts to have priority, this would hit performance for someone who uses many different mods.

Anyway, back to workaround, isNil + call seems like the best solution so far. 

 

[] spawn {systemchat str [1, canSuspend]; isNil {call {systemchat str [2, canSuspend]}}; systemchat str [3, canSuspend]};

 

[1, true]

[2, false]

[3, true]

 

I doubt there will be dedicated command, but this workaround is pretty neat.

Share this post


Link to post
Share on other sites

It is not just that. Piling everything in unscheduled (I have no doubt that this what would happen if such command was added) would kill FPS very quickly and since every modder would want HIS scripts to have priority, this would hit performance for someone who uses many different mods.

 

You can also kill someone with a hammer or use it to build something, that doesn't mean it shouldn't have been invented since you can also hit a nail with a wrench. With that kind of logic, (on)EachFrame is absolutely dangerous and should be removed. Hell, why not remove scripting altogether, after all, even spawn and execVM have their performance impacts when abused. How about callExtension? And so on.

 

Anyone who understands the difference between scheduled and unscheduled already knows the tradeoffs and probably is conscious about performance anyway. And there are millions of other ways to nuke performance anyway even without such commands.

 

As you say yourself, isNil and various other commands that have been used to get the desired results aren't intended for this, but people who need to scratch this itch will use them. It'd be much saner to have an intended way of doing this, especially when reading such code and in case the current set of commands that are "exploited" for this change their behavior.

 

Let's not repeat the same crap and all the solutions that happened over the years when people needed to execute code per frame before tools like onEachFrame were added.

  • Like 1

Share this post


Link to post
Share on other sites

....

 

All you are saying is correct except when someone has low FPS or crash, who do they blame, the modder for doing something stupid or BI? Also I have zero influence on decisions like this, so you are preaching to the wrong choir.

Share this post


Link to post
Share on other sites

All you are saying is correct except when someone has low FPS or crash, who do they blame, the modder for doing something stupid or BI? Also I have zero influence on decisions like this, so you are preaching to the wrong choir.

 

I'm not preaching to you, I'm just arguing for considering this in a rational manner. And I get what you are saying. Maybe someone at BI currently reading this thinks the same as you do and I'm providing my opinion why such thinking is not rational.

 

Not implementing a good thing for the fear of blame when used badly by modders is disappointing. Especially considering there are already tons of ways to tank the FPS and crash the game anyway. Hence my comments about per frame execution. Might as well limit models to 5k polys, textures to 512x512, sections to 1, remove the ability to proxy in things, force all SQF to be executed in scheduled, remove callExtension or simply just lock "the platform" down and prevent modding altogether. Nobody will be able to harm FPS besides BI then.

  • Like 2

Share this post


Link to post
Share on other sites

 Might as well limit models to 5k polys, textures to 512x512, sections to 1, remove the ability to proxy in things, force all SQF to be executed in scheduled, remove callExtension or simply just lock "the platform" down and prevent modding altogether. Nobody will be able to harm FPS besides BI then.

 

Don't forget to remove Multiplayer because of hacks.

  • Like 2

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

×