I think the issue is that the value of intro_done will not be synchronised for JIP players until after you are checking if the value exists. Thus, just using isNil will fail for JIP players since they won't have the value. By making sure that everyone waits until they have been given an actual value, you can avoid this problem. I think this should work:
if (isServer) then
{
[] spawn
{
// The server tells all initial players to run the intro.
intro_done = false;
publicVariable "intro_done";
// Wait for all initial players to read the public value, before updating it.
sleep 2;
// The server tells all JIP players to not play an intro.
intro_done = true;
publicVariable "intro_done";
};
};
// On all clients (including host), check what the server is telling us to do and play the intro
// if appropriate. (Note: you might want to run the intro on every machine instead, if there
// are server-side effects as well as just client-side camera effects).
if (not (isServer and (isNull player))) then
{
// Perhaps blank the screen here, while waiting to see if intro should be shown.
// On the client, wait until a value (true or false) has been synced.
waitUntil { not (isNil "intro_done") };
if (not intro_done) then { [] exec "scripts\intro.sqs"; };
};
You won't need to alter intro_done in the intro.sqs if using this method.
EDIT: Missed a bracket...