Jump to content
seba1976

Sleep not working after JIP

Recommended Posts

Hi, I'm having what to me seems a completely unexpected behaviour. I've reached the end of the rope here. It is above my knowledge by any measure. Here's the issue:

 

This is my init.sqf

 

if (!isDedicated) then {waitUntil {!isNull player}};

//wait for the simulation to start
waitUntil {time>0};

//Finish world initialization before mission is launched.
finishMissionInit;

[] call compile preprocessFileLineNumbers "sac_functions.sqf";

SAC_PLAYER_SIDE = west;
SAC_ENEMY_SIDE = east;

[] call compile preprocessFileLineNumbers "SAC_GEAR\main.sqf";

if (!isNull player) then {

	[] call compile preprocessFileLineNumbers "SAC_TEL\main.sqf";
	
};

And this is SAC_TEL\main.sqf

if (isNull player) exitWith {};

SAC_TEL_teleport = {

	private _done = false;

	//params ["_sameSide", "_onlyPlayers"];
	private _unit = [true, true] call SAC_fnc_selectUnit;

	if (SAC_user_input == "") exitWith {};

	if (isNull _unit) exitWith {hint "Unit not found."};

	if (!alive _unit) exitWith {hint "The unit is dead."};

	if (isNull objectParent _unit) then {
	
		player setPos (getPos _unit);
		
		_done = true;
	
	} else {
	
		if (!isNull objectParent player) then {
		
			moveOut player;
			waitUntil {isNull objectParent player};
			
		};
		
		_done = [vehicle _unit, ["Cargo", "personTurret", "commonTurret", "Commander", "Gunner", "Driver"]] call SAC_fnc_movePlayerToVehicle;
		
	
	};

	if (_done) then {
	
		//SAC_TEL_allow = false;
	
	} else {
	
		hint "The unit has no place left in his vehicle.";
	
	};

};

SAC_TEL_manager = {

	sleep 120;

	SAC_TEL_allow = false;

};

SAC_TEL_allow = true;

[] spawn SAC_TEL_manager;

["Reconnect Teleport","sac_teleport_key", "Teleport", {if (SAC_TEL_allow) then {[] spawn SAC_TEL_teleport}}, "", [20, [false, true, false]]] call CBA_fnc_addKeybind;

 

Intended behaviour is a player has 120 seconds to press Ctr+T to use the teleport function to rejoin with his team after connecting to the server. And the first time he connects, it works as intended. The problem starts if the player hits 'Abort' button, gets returned to the lobby, and hits 'OK' once there, to return to the mission. I've debugged this for the past hours, and the problem is, the engine does not pause execution when it founds the sleep line, inside SAC_TEL_manager function. Not only I don't understand why that happens, I can't think of any workaround for this issue. Any help?

 

 

Share this post


Link to post
Share on other sites

Your code seems okay to me but I'm on my phone and can test. However since you are using cba you should maybe take advantage of  thathttps://cbateam.github.io/CBA_A3/docs/files/common/fnc_waitAndExecute-sqf.html that allows you to add delay in unscheduled environment.  Might even fix your issue.

Share this post


Link to post
Share on other sites

Thanks for the quick answer. Ideally, CBA should not be a requirement. The only reason I included that part in this code is for the players to be able to change the key binding more easily. Besides, AFAIK, the sleep instruction is not supposed to be in unscheduled environment at that point. Notice the 'spawn'.

Share this post


Link to post
Share on other sites

I cannot see where variable SAC_user_input is set, but if it is not reset the second time when you enter as a JIP the behavior will be as you described.

Share this post


Link to post
Share on other sites
4 hours ago, seba1976 said:

I've debugged this for the past hours, and the problem is, the engine does not pause execution when it founds the sleep line, inside SAC_TEL_manager function.

how did you debug this?

You added a diag_log with diag_tickTime before and after the sleep in your function? and both logged successfully?

 

The code looks correct so I'm searching for the human error now.

Maybe somewhere some code does a publicVariable on that variable?

Share this post


Link to post
Share on other sites

I guess the best thing I can do is to provide a code you can test, so let me narrow it down to the bear minimum.

 

init.sqf

if (!isDedicated) then {waitUntil {!isNull player}};

//wait for the simulation to start
waitUntil {time>0};

//Finish world initialization before mission is launched.
finishMissionInit;

if (!isNull player) then {

	[] call compile preprocessFileLineNumbers "SAC_TEL\main.sqf";
	
};

main.sqf

if (isNull player) exitWith {};

SAC_TEL_teleport = {

	hint "Hey! I'm working!"; systemChat "Hey! I'm working!";

};

SAC_TEL_manager = {

  	hint "Waiting 120 seconds..."; systemChat "Waiting 120 seconds...";
	sleep 120;
  	hint "I'm disabling the teleport."; systemChat "I'm disabling the teleport.";

	SAC_TEL_allow = false;

};

SAC_TEL_allow = true;

[] spawn SAC_TEL_manager;

["Reconnect Teleport","sac_teleport_key", "Teleport", {if (SAC_TEL_allow) then {[] spawn SAC_TEL_teleport}}, "", [20, [false, true, false]]] call CBA_fnc_addKeybind;

When you JIP that, you'll see instantly the "I'm disabling the teleport" hint, and the systemChat lines "Waiting 120 seconds..." and "I'm disabling the teleport." one after the other, without the wait. If you want I can replace the CBA key system call with a native keyboard hook. BTW thanks for all the answers.

 

 

 

 

 

 

Share this post


Link to post
Share on other sites
8 hours ago, killzone_kid said:

Why did you use finishMissionInit?

I'm an old coder, it's been there since a long time in all my inits, and the documentation I could find says nothing for it or against it. I guess if it's not broken don't fix it would be the answer. Of course I'm curious and if you know something else about it please tell me. I used to read your blog posts a long time ago, and I've 'borrowed' your code pieces more than once.

Share this post


Link to post
Share on other sites

Ok, I have news. This looked interesting, so I gave it a real try, with two licences, a hosted server and a JIP.

 

First I can confirm that it really is the sleep command that does not do its job. I actually narrowed it down to these three lines in the init file:

 

init.sqf:

  hint "Waiting 120 seconds..."; systemChat "Waiting 120 seconds...";
  sleep 120;
  hint "I'm disabling the teleport."; systemChat "I'm disabling the teleport.";

 

And sleep still does not work for the JIP!

 

An what is more is that the mission gets really wierd after that. After leaving game for the lobby, only one slot is visible (I had two from the begining). And if I then leave the server it is impossible to get in again.

 

There was a small update today. Maybe sleep for JIPs got broken...?

 

EDIT: I forgot - actually uiSleep seemed to work for the delay part. But the problems I described with the mission slots remained.

  • Like 1

Share this post


Link to post
Share on other sites

Thank you @engima! I'll give it a try using uiSleep. I have absolutetly no problems with the slots, so that might be unrelated to this topic I guess. Anyway, if sleep is not working for JIP, a lot of things I usually do, I will not be able to port to dedicated servers, which is a real bumer for me. We need more people testing this, to see if this is indeed a bug, or we just don't know enough.

 

 

Share this post


Link to post
Share on other sites

I did a little more testing.

 

First with a simple init.sqf file like this:

 

init.sqf:

waitUntil { !isNull player };
 
hint "First";
sleep 10;
hint "Second";
sleep 3;
hint "Third";
sleep 3;
hint "Fourth";

 

The first sleep (sleep 10) was simply ignored (for the JIP). The rest of the sleep commands worked as expected.

 

I did the same thing, but put the hints and sleeps in another file, and started it with execVM. But the result was the same. First sleep was ignored.

 

I did the first thing, but put the code in initPlayerLocal.sqf instead (which would be a bit of a better practice). The same result.

 

Then I put an action on a coffee table in game and started the hint-sleep sequence on an action (putting an addAction in the init.sqf). This worked as expected for both hosted server's player and JIP.

 

Then I tried to replace the sleep with a waitUntil like this:

 

init.sqf:

waitUntil { !isNull player };

private _jipEnteredTime = serverTime;

hint "First";
waitUntil { serverTime > _jipEnteredTime + 10 };
hint "Second";
sleep 3;
hint "Third";
sleep 3;
hint "Fourth";

 

This worked as expected, so for some reason only the first sleep command was a problem.

 

Conclusion:

First sleep command for a JIP seems to be ignored if hit during the initialization phase. My guess would be that there is something scheculish thing that has not yet been initialized properly, so to be able to trust the sleep command one should not use it until a few seconds into the mission. Use of sleep in init files should really work, but actually I have never regarded it as best practice. A suggestion to a solution or workaround (if not Boehmia fixes this) would be to only use init files for initializations, and not running code. Init could contain a waitUntil a few seconds so that everything stabilizes and initializes, and the the running code can be started (like execVM "start.sqf").

Share this post


Link to post
Share on other sites
12 hours ago, engima said:

After leaving game for the lobby, only one slot is visible

if you don't have respawn or AI enabled, and the one player dies, then his slot will disappear.

 

12 hours ago, engima said:

actually uiSleep seemed to work for the delay part

That was my idea too, some acceleration running which makes the sleep skip. But I can't think of why anyone would do that.
And that shouldn't happen in a empty mission, maybe JIP join by default does some time acceleration for some reason.

 

27 minutes ago, engima said:

The first sleep (sleep 10) was simply ignored (for the JIP). The rest of the sleep commands worked as expected.

That actually confirms that. Its probably just a short (1-2 frame) time acceleration which makes the first sleep skip, then the scheduler makes the script wait till next frame where the acceleration has ended.

Could try logging https://community.bistudio.com/wiki/accTime

Also I'd recommend using

diag_log [diag_tickTime, diag_frameNo, accTime, "your message here"];

to log, that way you have the exact timing and all messages, unlike hint which just hides the previous message.

Share this post


Link to post
Share on other sites

Ok. Sounds probable. Let’s hope it is an easy fix.

Share this post


Link to post
Share on other sites

I have it working using uiSleep, of course, but it doesn't make sense. Thank you for finding it! Much appreciated. Let's not forget though, I'm not using sleep in init.sqf, I'm calling the initialization script, which in turn spawn SAC_TEL_manager, to handle the sleep. In other words, I'm not at any time trying to suspend init.sqf, but creating a new thread (with spawn) and then suspending it.

 

I find it interesting the accTime hypotesis, because that could potencially explain this behaviour. A good test for that would be to put a sleep with a really big number, and see if it still gets ignored. The fact that is seems to be the first sleep no matter what though, goes against it.

 

 

Share this post


Link to post
Share on other sites

Sleep works for me just fine on jip. Make sure you waitUntil {time > 1} not time > 0, it is possible that the mission is still in preloading state this early and sleep is ignored. 

EDIT:
Even better, it seems relying on detection of mission display is the way to go:

 

// init.sqf
if (!hasInterface) exitWith {};
waitUntil {!isNull findDisplay 46};
.....

 

  • Like 1

Share this post


Link to post
Share on other sites

Sorry for the delay, notification got lost somehow. I'll check and report back very soon. Thanks!

 

Share this post


Link to post
Share on other sites

@killzone_kid Indeed, it works. I'll start waiting for (!isNull findDisplay 46) in all my missions from now on, to avoid similar "surprises". Thanks a lot.

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

×