State labels in the middle of statements

Discussions about Coding and Scripting
User avatar
Shrimp
Adept
Posts: 299
Joined: Wed Oct 10, 2018 11:15 am
Location: Australia

State labels in the middle of statements

Post by Shrimp »

I'm looking at the exported ScriptedPawn source and I see that it seems to have state labels in the middle of the if/else statements.

Is this some sort of corruption of the scripts stored within the package files (perhaps due to size?), or is this a genuinely supported syntax?

I can't really make out how it's valid though, since it seems to intersect the if/else statements in arbitrary places and leaves them "unclosed" under some conditions under some labels.

Below is a small example of where it first appears within ScriptedPawn's Patrolling state.

Is this a known issue? It seems to be present even in older sources.

Code: Select all

Begin:
    sleep(0.1);

Patrol: //FIXME -add stasis mode? - also set random start point in roam area
    WaitForLanding();
    FindNextPatrol();
    Disable('AnimEnd');
    if (PatrolPoint(OrderObject) != None)
    {
        ////log("Move to next patrol point");
        if ( !bQuiet && (FRand() < 0.4) )
            PlayRoamingSound();
        TweenToWalking(0.3);
        FinishAnim();
        PlayWalking();
        numHuntPaths = 0;

MoveToPatrol:
        if (actorReachable(OrderObject))
            MoveToward(OrderObject, WalkingSpeed);
        else
        {
            PickDestination();
            if (OrderObject != None)
            {
SpecialNavig:
                if (SpecialPause > 0.0)
                {
                    Acceleration = vect(0,0,0);
                    TweenToPatrolStop(0.3);
                    Sleep(SpecialPause);
                    SpecialPause = 0.0;
                    TweenToWalking(0.1);
                    FinishAnim();
                    PlayWalking();
                }
                numHuntPaths++;
                MoveToward(MoveTarget, WalkingSpeed);
                if ( numHuntPaths < 30 )
                    Goto('MoveToPatrol');
                else
                    Goto('GiveUp');
            }
            else
                Goto('GiveUp');
        }

ReachedPatrol:      
        ////log("Got to patrol point "$OrderTag);	
        OrderTag = Patrolpoint(OrderObject).Nextpatrol;
        ////log("Next patrol point "$OrderTag);	
        if ( Patrolpoint(OrderObject).pausetime > 0.0 )
        {
            ////log("Pause patrol");
            Acceleration = vect(0,0,0);
            TweenToFighter(0.2);
ShrimpWorks
Unreal Archive - preserving over 25 years of user-created content for the Unreal series!
Buggie
Godlike
Posts: 3117
Joined: Sat Mar 21, 2020 5:32 am

Re: State labels in the middle of statements

Post by Buggie »

Not see any problem here. "if" is nothing more from one or two block of code, with some "goto", one from which is conditional.
In uscript block (and "if" as well), not create new scope, so nothing worry about.

in fact simple "if" is can be written as:

Code: Select all

if (a) {
	do_stuff();
}

Code: Select all

if (!a) goto end_if;
do_stuff();
:end_if
With else it is more complicated, but still same:

Code: Select all

if (a) {
	do_stuff_a();
} else {
	do_stuff_b();
}

Code: Select all

if (!a) goto else_if;
do_stuff_a();
goto end_if;
:else_if
do_stuff_b();
:end_if
User avatar
Shrimp
Adept
Posts: 299
Joined: Wed Oct 10, 2018 11:15 am
Location: Australia

Re: State labels in the middle of statements

Post by Shrimp »

The problem is not how if statements work, it's the interleaving of the state labels per my example.

The code in ScriptedPawn ends up looking like:

Code: Select all

Stuff:
  if (whatever) 
    doSomething();
  else
  {
    if (nonsense)
    {
RandomLabel:
      wtf()
    }
AnotherLabel:
    randomStuff();
  }  
ShrimpWorks
Unreal Archive - preserving over 25 years of user-created content for the Unreal series!
User avatar
sektor2111
Godlike
Posts: 6433
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: State labels in the middle of statements

Post by sektor2111 »

As far as I recall, ScriptedPawn states are working somehow normally. Yes, they do "Accessed Nones" because are missing sanity checks concerning "Enemy" and "Target" and or mixing these without to check them if are valid, but calling them. These are main factors which I wrapped in NsScriptedPawn without altering those labels... Okay, I redefined some attitude bytes which were preventing games with monsters to lock down server in random cases.
If you ask me more details, my monster games are working with different "stock" files because original stock is not really ensuring a stable game-server toward ScriptedPawn. Those are codes written in a big rush - unfinished, labels are not a big issue but sanity checks and assigning valid "bytes" were mandatory.
User avatar
Shrimp
Adept
Posts: 299
Joined: Wed Oct 10, 2018 11:15 am
Location: Australia

Re: State labels in the middle of statements

Post by Shrimp »

OK, I just did a small test in the same style, and this appears to compile without errors. I have no idea what it would do at runtime though:

Code: Select all

class HaxPawn extends ScriptedPawn;

state Patroling
{
        function helloWorld() {
                log("hi");
        }

Begin:
        log("begin");

Stuff:
        log("stuff");
        if (true) {
                log("stuff.true");
        } else {
BreakMe:
                log("broken?");
        }

        if (true) {
WTF:
                log("wtf?!?!");
        } else {
How:
                log("makes not sense");
        }
}
From a logical point of view, I'm not sure how the engine intends to make sense of this.

For example, if we do GotoState('Patroling', 'WTF'); would it print "wtf?!?!"? Again from a logical point of view, there's now a dangling closing brace and an else there.

Anyway, it's enough for me to know that it compiles, and it's probably not an export bug, but the code does actually seem to be structured like that. Maybe it is just a side-effect of hacky development - but I'm curious why the compiler accepts it.
ShrimpWorks
Unreal Archive - preserving over 25 years of user-created content for the Unreal series!
User avatar
sektor2111
Godlike
Posts: 6433
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: State labels in the middle of statements

Post by sektor2111 »

Perhaps after bad "WTF" it should go to a another suitable state - such as "Waiting" if this order/state it's no longer logic in environment.
The compiler story - my notes ?
Compiler is accepting all codes having the right syntax. But there is a problem if codes are going into endless loops - because there is no problem in compiling such a lousy code.
Buggie
Godlike
Posts: 3117
Joined: Sat Mar 21, 2020 5:32 am

Re: State labels in the middle of statements

Post by Buggie »

Shrimp wrote: Sun Jun 12, 2022 6:07 am The problem is not how if statements work, it's the interleaving of the state labels per my example.

The code in ScriptedPawn ends up looking like:
And? I not see anything wrong in that. You can jump to any place inside state code.

Code start execute from specified point that's all.

Automatically merged

Shrimp wrote: Sun Jun 12, 2022 6:31 am From a logical point of view, I'm not sure how the engine intends to make sense of this.
Jump to specified point and execute code started from it.
Shrimp wrote: Sun Jun 12, 2022 6:31 am For example, if we do GotoState('Patroling', 'WTF'); would it print "wtf?!?!"? Again from a logical point of view, there's now a dangling closing brace and an else there.
Yes, it is print it.
Shrimp wrote: Sun Jun 12, 2022 6:31 am Anyway, it's enough for me to know that it compiles, and it's probably not an export bug, but the code does actually seem to be structured like that. Maybe it is just a side-effect of hacky development - but I'm curious why the compiler accepts it.
It is goto-way. It is rare for modern langs, since modern langs (usually) use blocks which create new scope inside. So you: or not able jump inside block at all, or able only if there not defined new vars.
Since uscript create scope only for function, and global scope, there no such limitation, and awful coder can make spaghetti-code with tons of goto.

Automatically merged

Also exist fancy trick:

Code: Select all

if (false) {
:runIt
	PreCode();
}
MainCode();
You can run such code in two ways.
With goto and without.
With goto this call additional code before main.
So this avoid duplicate code in some cases.

Automatically merged

Also wanna note, labels inside state it is not something important or tracked. It is just labels. When you make GoToState with label, actor goes to state and start execution from specified label, not from "Begin" label.
But not think about this labels as about substate. It is not substate. It just point in code, where you can redirect execution flow.