Collection of gta scripting and map weirdness

Anything to do with GTA1/GTA2 modding (tools, scripts and more).
User avatar
B-$hep
Immortal
Posts: 579
Joined: 24 Apr 2009, 21:43
GH nick: B-Shep
Location: EU

Re: Collection of gta scripting and map weirdness

Post by B-$hep »

This is very SICK.

The script 1:
[mis]counter c1=1
LEVELSTART
if(((c1=3) and
(c1=35)) and
//
(c1=11))
//
do_nowt

endif
LEVELEND[/mis]

And script 2:
[mis]counter c1=1
LEVELSTART
IF ( ( c1=3 )
AND ( (c1=35 )
AND (c1=11 ) ))
//
//
do_nowt

endif
LEVELEND[/mis]

Are actually same.
But because of nr of brackets and how they are used the script content is different.
2 files differ.

I have not tested if they act also differently in GTA2.
Maybe one is BIG BUG and one is correct.

This is driving me nuts.

I have to count brackets also when scripting? WTF really.
Will try this in GTA2 and report the results.

Wasted whole day trying to make NOT command to work in my compiler. Wondered what the thing is, why it shows wrong results.

Now i think i understand why.
My logic was correct but its "good" old miss2 again with its nice "features".

Did anybody knew this already? Or its old known bug?
Always wear safety glasses while programming.
User avatar
elypter
Immortal
Posts: 1119
Joined: 26 Dec 2009, 23:53
GH nick: elypter

Re: Collection of gta scripting and map weirdness

Post by elypter »

i didnt know that. at some point maybe its better not to 100% copy miss2 bugs and implement it in a reasonable way if it doesnt break any existing scripts :)
yur sa'nok ngeyä
User avatar
Sektor
Boss
Boss
Posts: 1431
Joined: 04 Mar 2008, 06:51
GH nick: Sektor
Location: GTAMP.com
Contact:

Re: Collection of gta scripting and map weirdness

Post by Sektor »

I knew brackets were ugly and hard to keep track of.
User avatar
B-$hep
Immortal
Posts: 579
Joined: 24 Apr 2009, 21:43
GH nick: B-Shep
Location: EU

Re: Collection of gta scripting and map weirdness

Post by B-$hep »

Whats the difference between WHILE or WHILE_EXEC.
Only difference i see in scr files is that return values are changed.

But in game, i dont see nothing different.
Can somebody please make or show me good example when the WHILE_EXEC is important?

I tested this:
[mis]counter mainloop=1
COUNTER runonce = 1
CAR_DATA nextcar1
PLAYER_PED p1 = (88.5, 106.5, 255.0) 10 0 //ste.gmp
LEVELSTART
IF(runonce = 1)
SET_AMBIENT_LEVEL ( 0.3 , 1 )
nextcar1 = CREATE_CAR (80.5, 106.5) 2 180 GT24640 END
DISPLAY_BRIEF ( 1020 )
//DISPLAY_MESSAGE (5504)

ENDIF
WHILE_EXEC (mainloop = 1)
IF (IS_CAR_WRECKED ( nextcar1 ))
nextcar1 = CREATE_CAR (80.5, 106.5) 2 180 GT24640 END

ENDIF
SET runonce = 0
endwhile
LEVELEND[/mis]

Changed WHILE_EXEC to WHILE and same thing. Nothing changed.


I need good example when there is really need for WHILE_EXEC.
Always wear safety glasses while programming.
User avatar
Sektor
Boss
Boss
Posts: 1431
Joined: 04 Mar 2008, 06:51
GH nick: Sektor
Location: GTAMP.com
Contact:

Re: Collection of gta scripting and map weirdness

Post by Sektor »

I think the only difference is the speed. WHILE runs one line of script per frame, WHILE_EXEC runs ALL lines per frame.

This WHILE script takes 10 frames to finish (1 frame per WHILE script line, even DO_NOWT will take a frame):
[mis]PLAYER_PED p1 = (49.5, 46.5, 255.0) 25 0

COUNTER true = 1
COUNTER framepointer = 6193416 // this address is a pointer to the total number of elapsed frames
COUNTER frameaddress
COUNTER frame
ONSCREEN_COUNTER time

LEVELSTART

WHILE (true=1)
ADD_ONSCREEN_COUNTER (time,frame)
DO_NOWT
DO_NOWT
DO_NOWT
DO_NOWT
DO_NOWT
CHANGE_GANG_CHAR_RESPECT (framepointer, frameaddress, 104)
CHANGE_GANG_CHAR_RESPECT (frameaddress, frame, 102)
SET true=0
ENDWHILE

LEVELEND[/mis]

This WHILE_EXEC script takes 2 frames to finish (add more lines and it will still take 2 frames total):
[mis]PLAYER_PED p1 = (49.5, 46.5, 255.0) 25 0

COUNTER true = 1
COUNTER framepointer = 6193416
COUNTER frameaddress
COUNTER frame
ONSCREEN_COUNTER time

LEVELSTART

WHILE_EXEC (true=1)
ADD_ONSCREEN_COUNTER (time,frame)
DO_NOWT
DO_NOWT
DO_NOWT
DO_NOWT
DO_NOWT
CHANGE_GANG_CHAR_RESPECT (framepointer, frameaddress, 104)
CHANGE_GANG_CHAR_RESPECT (frameaddress, frame, 102)
SET true=0
ENDWHILE

LEVELEND[/mis]
User avatar
T.M.
Immortal
Posts: 960
Joined: 29 Jan 2010, 15:00
Location: F21B3EED

Re: Collection of gta scripting and map weirdness

Post by T.M. »

B-$hep wrote:This is very SICK.

The script 1:
[mis]counter c1=1
LEVELSTART
if(((c1=3) and
(c1=35)) and
//
(c1=11))
//
do_nowt

endif
LEVELEND[/mis]

And script 2:
[mis]counter c1=1
LEVELSTART
IF ( ( c1=3 )
AND ( (c1=35 )
AND (c1=11 ) ))
//
//
do_nowt

endif
LEVELEND[/mis]

Are actually same.
But because of nr of brackets and how they are used the script content is different.
2 files differ.

Lets take a look and clean up the code:

1. snippet:
[mis]
IF
(
(
(c1 = 3)
AND
(c1 = 35)
)
AND
(c1 = 11)
)
[/mis]

2. snippet:
[mis]
IF
(
(c1 = 3)
AND
(
(c1 = 35)
AND
(c1 = 11)
)
)
[/mis]

There you can clearly see the only difference is the order of the AND commands. And by all means of logic, the order of AND's doesnt matter for the result, so thats why it works. The outcome would be different if there were even just one OR command mixed somewhere, but in this case its all just AND's.

However, i always assumed they would have to be chained in highest to lowest way, such as:
(((a & b) & c) & d), but looks like you can also do the opposite:
(a & (b & (c & d))) as well! Nice find. MISS seems smarter than i thought :D

MISS requires AND/OR commands to be wrapped inside brackets every 2 items, so you cant do (a & b & c), thats why you have to "count" the brackets.
User avatar
B-$hep
Immortal
Posts: 579
Joined: 24 Apr 2009, 21:43
GH nick: B-Shep
Location: EU

Re: Collection of gta scripting and map weirdness

Post by B-$hep »

This is just me or its another BUG of miss2?

Compile this. Note the big comment block between XXXX and YYYY.
And there is DO_NOWT after YYYY (it has index 16).
[mis]counter c1=3
LEVELSTART
WHILE_EXEC(c1=3)
do_nowt
WHILE_EXEC(c1=3)
do_nowt
ENDWHILE


//goto
ENDWHILE


//goto
do_nowt

/* // XXXX

do_nowt
//////////
WHILE_EXEC(c1=3)
do_nowt
WHILE_EXEC(c1=3)
do_nowt
ENDWHILE


//goto
WHILE_EXEC(c1=3)
do_nowt
WHILE_EXEC(c1=3)
do_nowt
ENDWHILE


//goto
ENDWHILE


//goto
ENDWHiLE


//goto
WHILE(c1=3)
do_nowt
WHILE_EXEC(c1=3)
do_nowt
WHILE_EXEC(c1=3)

do_nowt
ENDWHILE //ifJUMP


//goto
ENDWHILE //ifJUMP


//goto
ENDWHILE //ifJUMP


//goto YYYY */
do_nowt

LEVELEND[/mis]


Now compile this:
Its same, just without that big comment block.
[mis]counter c1=3
LEVELSTART
WHILE_EXEC(c1=3)
do_nowt
WHILE_EXEC(c1=3)
do_nowt
ENDWHILE


//goto
ENDWHILE


//goto
do_nowt
do_nowt

LEVELEND[/mis]

Believe me or not, but in my computer the first version with big comment is actually different from the second.


If you try to compare first and second then you should see that the very last DO_NOWT (with index 16) is removed (IGNORED?) and not even written to the file.

But in second version its in .scr file like it should.


I remember this kind of thing. Somewhere 2010-2011 or something, just when i started to mess with new compiler. Did some random scripts and comparisons. between miss2 files.
To see what changes make .scr contents to change etc..

Somehow this thing feels familiar.


I did comparison of scripts also in WinMerge. Only difference is the big comment block.


Very very strange thing is going on here.

But clearly it seems bug. Because maybe i need that DO_NOWT in there.
But compiler just removes or doesnt write it to the file.


I compared the .scr files of miss2 and my compiler and it was like WTF.
Same script and differences.


EDIT: Maybe big comment blocks between script make miss2 go crazy?
Havent tried yet.


EDIT2:
This will instacrash miss2.
[mis]counter c1=3
LEVELSTART
WHILE_EXEC(c1=3)
do_nowt

ENDWHILE //ifJUMP

/* //crash with this big comment block. and no crash without comment block
WHILE_EXEC(c1=3)
do_nowt
do_nowt
WHILE_EXEC(c1=3)
do_nowt
do_nowt
ENDWHILE //ifJUMP


//goto*/
LEVELEND[/mis]


Remove all the comments (big comment block) and no more crash.
Always wear safety glasses while programming.
User avatar
elypter
Immortal
Posts: 1119
Joined: 26 Dec 2009, 23:53
GH nick: elypter

Re: Collection of gta scripting and map weirdness

Post by elypter »

did you check if only do_nowts are being removed or any commands? maybe its an internal cleanup routine that cleans up one do_nowt too much.

do 2 do_nowt in a row produce 2 scr commands or are they combined into one?
yur sa'nok ngeyä
User avatar
B-$hep
Immortal
Posts: 579
Joined: 24 Apr 2009, 21:43
GH nick: B-Shep
Location: EU

Re: Collection of gta scripting and map weirdness

Post by B-$hep »

I dont know.
I will try after work when i get home.


There is not even singlest word about any optimizations done in scripting doc.
And i dont believe there is.

It doesnt make sense that some big comment is somehow related to while_exec.
Should try to remove all text in comment and just leave /* */ like they are. In same place and range.

Maybe its coded in. Maybe they hacked some bugfix like this.


But this is all "maybe"

Same with upper last script.
Almost same and same style and crashes compiler.


More testing should be done.

EDIT

I think i figured it out.
Compile this and you will loose everything after /*//*/ in .scr file.
[mis]counter c1=3
LEVELSTART
WHILE_EXEC(c1=3)
do_nowt
WHILE_EXEC(c1=3)
do_nowt
ENDWHILE


//goto
ENDWHILE


//goto
do_nowt

/*//*/
do_nowt
LEVELEND[/mis]

Compile this:
[mis]counter c1=3
LEVELSTART
car_data car1
car_data car2
car_data car3
/*//*/
do_nowt
LEVELEND[/mis]

And you will get invalid .scr file where commands after /*//*/ are not written to the file.
DO_NOWT, LEVELEND are missing.

So long story short: AVOID /*//*/ and/or /*//xxxx*/ style comments.
Always wear safety glasses while programming.
User avatar
T.M.
Immortal
Posts: 960
Joined: 29 Jan 2010, 15:00
Location: F21B3EED

Re: Collection of gta scripting and map weirdness

Post by T.M. »

I think you should not have two WHILE_EXEC loops at the first place (not to mention making them nested like that), since it doesnt make sense anyways, not to mention the compiler/gta2 might not even support it.

GTA2 script compiler is really crappy, i can only suggest you to avoid putting two different types of comments at same line.
User avatar
B-$hep
Immortal
Posts: 579
Joined: 24 Apr 2009, 21:43
GH nick: B-Shep
Location: EU

Re: Collection of gta scripting and map weirdness

Post by B-$hep »

Im just testing new compiler with these tests.
Im not trying to make missions.

I posted here so scripters can avoid some troubles.
Thats what this thread is all about. Isnt it?


From your words i read that only me shouldnt do that.
Rest here can.


No need to tell me what i already know and will not do.

No offence. Maybe i just misunderstood you.
Always wear safety glasses while programming.
User avatar
T.M.
Immortal
Posts: 960
Joined: 29 Jan 2010, 15:00
Location: F21B3EED

Re: Collection of gta scripting and map weirdness

Post by T.M. »

Oh, i thought this was related to your own compiler project, sorry maybe mixed the threads in my mind.
User avatar
B-$hep
Immortal
Posts: 579
Joined: 24 Apr 2009, 21:43
GH nick: B-Shep
Location: EU

Re: Collection of gta scripting and map weirdness

Post by B-$hep »

No probs. I will show the compiler soon.
Just must figure out the logic behind NOT command.

Seems pretty tricky.
Always wear safety glasses while programming.
User avatar
B-$hep
Immortal
Posts: 579
Joined: 24 Apr 2009, 21:43
GH nick: B-Shep
Location: EU

Re: Collection of gta scripting and map weirdness

Post by B-$hep »

I now implemented DO..WHILE_TRUE() command.
And noticed strange thing again.
Looked into DMA .doc file to read about counters a bit.
I needed some stuff for displaying variable and variables, to see how DO..WHILE_TRUE() works and see its "internals".
So i put this together:

[mis]counter c1=0
counter c2=5
ONSCREEN_COUNTER ctr
PLAYER_PED p1 = (88.5, 106.5, 255.0) 10 0 //Coords are for ste.gmp
LEVELSTART
ADD_ONSCREEN_COUNTER (ctr, c1)
do if(c2=3)
++c1

endif
while_true(c1<30)
//i


//g
DO_NOWT
LEVELEND[/mis]

If you read carefully: if(c2=3) then increment counter c1. Otherwise get out of there.
But as you see, c2 is actually initialized to 5.
The condition is false and c1 shouldnt be touched at all.
But counter still displays in game that loop is running. Even if c2 = 5 and not 3.

I looked into .scr file and noticed that GOTO command for the DO..WHILE_TRUE jumps directly into ENDIF. Which makes no sense. GOTO should jump to the "DO" index.
Because ENDIF will check if condition is true and if not then it will not allow to continue.

But atm it seems that GOTO just took over the control.

My compiler fortunately points to correct place, assuming that this is really bug in miss2 and i didnt do something wrong in example script above.

Ok..
I manually changed index of GOTO in .scr file and the loop was not running anymore like it should be actually. I then changed variable c2 value to 3 in .scr and executed game. Counter was running.
Because c2 = 3 and condition is true. So loop can increment c1.

If its not a BUG in miss2, then i dont know what it is. You tell me then.. Or im sleepy?
Always wear safety glasses while programming.
User avatar
T.M.
Immortal
Posts: 960
Joined: 29 Jan 2010, 15:00
Location: F21B3EED

Re: Collection of gta scripting and map weirdness

Post by T.M. »

Maybe the MIS compiler noticed it is an infinite loop and jumped out of it to avoid game freezing? Can you reproduce this with other looping structures? (i dont remember if there are equivalents for loops).

Is it possible to make a loop by using "recursion" in function calls? (as far as i understand, MIS scripts doesnt support recursion, but rather just uses GOTO)
[mis]
function somefunc:
if(c2 = 3)
++c1
endif
if(c1 < 30)
somefunc:
endif
return
[/mis]
Something like that. Its been long time since i looked at MIS scripts so there may be some errors.
User avatar
B-$hep
Immortal
Posts: 579
Joined: 24 Apr 2009, 21:43
GH nick: B-Shep
Location: EU

Re: Collection of gta scripting and map weirdness

Post by B-$hep »

This compiles but c1 stays 0 on screen.

[mis]counter c1=0
counter c2=3
ONSCREEN_COUNTER ctr
PLAYER_PED p1 = (88.5, 106.5, 255.0) 10 0 //ste.gmp
forward somefunc:
LEVELSTART
ADD_ONSCREEN_COUNTER (ctr, c1)
gosub somefunc:
LEVELEND
somefunc:
if(c2 = 3)
++c1

endif
if(c1 < 30)
somefunc:

endif
return[/mis]

I think it needs GOTO. But miss2 doesnt know probably that its a recursion.
Recursion i guess can be detected in compiler with something like:

Code: Select all

if we are in subfunction named somefunc for example
if function there called is with same name as current subfunction.
Then we probably have recursion.


I guess this can be invented. Just work out something on paper (like i almost always first do) and try to generate something.

Also if this "bug" also is in other style loops, i dont know..
Have to try..

Tried this in C++ and really this freezes, if c2 is not 5 for example and when doing check if(c2==5).
If we do "(c2==3)", loop runs from 1 to 30.

Code: Select all

	 int c1 =0;
	 int c2=3;
	 
	 do
	   if(c2==5)
	   {
	    			++c1;
	    			cout << c1 << endl;
		} // endif
   while(c1<30);
So it seems to detect that its infinite loop. But im cant tell for sure.
There are not many loops available. Only WHILE..ENDWHILE.


Tried this:
[mis]counter c1=0
counter c2=3
ONSCREEN_COUNTER ctr
PLAYER_PED p1 = (88.5, 106.5, 255.0) 10 0 //ste.gmp
LEVELSTART
ADD_ONSCREEN_COUNTER (ctr, c1)
while(c1<30)
if(c2=5)
++c1

endif
endwhile



LEVELEND[/mis]

Works fine if c2=3. Counts from 0 to 30.
If c2=5, displays 0 in game.
But how long game can run like this i dont know (if its inifinite loop).

In scr file the logic seems to be like this, not seems but thats what scr file stores:

IF the "c2 is not 5" then ENDIF jumps to GOTO.
GOTO itself jumps to the "while(c1<30)".
The "while(c1<30)" jumps to "if(c2=5)" if condition (c1<30) is true (and actually it is atm).
If its false, it jumps to LEVELEND.

Im lazy to make deep investigation for this now but for me seems that its a infinite loop.
I tested in C++ and it is.


How the heck compiler could detect infinite loop?
Is there something invented? Any ideas, examples or something?

So compiler could throw error in that case..

Or its simple like this idea that i just thinked about, error or limitation like:
"Its not allowed to increment or decrement WHILE loop counter variable within IF..ENDIF that is inside the WHILE loop".

I know the error msg is long. But take it as limitation of compiler. Can we live with it?
Does it help solving infinite loop?

Who has time to run GTA2 long enough to see if it crashes after some time running such script?
Atm i dont have. Maybe one day..
What do you think about this limitation?
So far i havent seen any scripts that even use DO..WHILE_TRUE command.

EDIT:

Or even "simpler", check and compare values at compile time. And if the c2 is inited to 3 and in expression IF..ENDIF the c2 is compared to something else then throw warning: "Possible infinite loop detected"

Maybe its better idea. Of course compiler cant predict all the cases and problems.
It doesnt have human brain.
Always wear safety glasses while programming.
User avatar
T.M.
Immortal
Posts: 960
Joined: 29 Jan 2010, 15:00
Location: F21B3EED

Re: Collection of gta scripting and map weirdness

Post by T.M. »

B-$hep wrote: Or its simple like this idea that i just thinked about, error or limitation like:
"Its not allowed to increment or decrement WHILE loop counter variable within IF..ENDIF that is inside the WHILE loop".

I know the error msg is long. But take it as limitation of compiler. Can we live with it?
Does it help solving infinite loop?
Maybe try to increment different variable and copy it to the other variable? If MIS scripts even support such thing... :D

Something like...
[mis]
while(c1 < 30)
if(c2 = 5)
++c3
endif
SET c1 = c3
endwhile
[/mis]
B-$hep wrote:Who has time to run GTA2 long enough to see if it crashes after some time running such script?
I think GTA2 will crash no matter what script you use if its run long enough :D
User avatar
B-$hep
Immortal
Posts: 579
Joined: 24 Apr 2009, 21:43
GH nick: B-Shep
Location: EU

Re: Collection of gta scripting and map weirdness

Post by B-$hep »

Near all commands are added to compiler now.

I did simple Delphi app which helps to actually add something like 20 commands at once (basically it generates C++ source for parser), i just pass some params etc (3 of them actually) and it does the rest.

Then just rebuild the compiler.
Its possible because often script command is different but underlying structure is same.
Just the name and type of command changes. Very boring to type all by hand so i let the computer to do the boring work.

It doesnt support mission scripts atm because i want to add the last commands first and if all is added i will mess with mission scripts.

Later these new compiler related posts should be moved to new thread from here.
Always wear safety glasses while programming.
User avatar
B-$hep
Immortal
Posts: 579
Joined: 24 Apr 2009, 21:43
GH nick: B-Shep
Location: EU

Re: Collection of gta scripting and map weirdness

Post by B-$hep »

Is it just me or this really makes miss2 crash because of the "CHECK_MULTIPLIER_GREATER" ??

[mis]player_ped p1 = ( 44.5 , 102.0 , 2.0 ) 25 0
LEVELSTART
CHECK_MULTIPLIER_GREATER ( p1 , 7 )
LEVELEND[/mis]
Always wear safety glasses while programming.
User avatar
Sektor
Boss
Boss
Posts: 1431
Joined: 04 Mar 2008, 06:51
GH nick: Sektor
Location: GTAMP.com
Contact:

Re: Collection of gta scripting and map weirdness

Post by Sektor »

Yes that crashes the official compiler but I think T.M. found that it works in game if you write it to the SCR file: http://gtamp.com/forum/viewtopic.php?p=5166#p5166 (2011, time flies).

It certainly counts as scripting weirdness.
Post Reply