Script commands index and hints

Started by FIQ, June 24, 2012, 10:16:04 PM

Previous topic - Next topic

FIQ

Hi. Even if PJBottomz is awesome and has already made a tutorial in the form of a VVVVVV level, I felt that it would probably be nice to have a list of the commands and the usage of them, and examples, and hints/tricks, and hard limits.

Link to PJBottomz level for those that want a nice pedagogic way of looking how to script: http://distractionware.com/forum/index.php?topic=450.0

This might or might not look over-complicated. If you feel like it is, please see the above link instead, to get started on scripting. This is just thought as a list of the commands, plus technical details, and some usage hints at the bottom.

And here it goes...

Quick info
Things in [] are optional and not required for the basic usage of a command. When | is used, it means either one thing or another ("A|B" means that it can be A or B).
I will not cover exploits.

Command Index
Commands in the current stable version - 2.0
* - Usage was updated in the 2.1 beta, see below for new usage. Note that 2.0 usage will always work in 2.1, but not the opposite!

say(N)*
Opens a gray text dialog of N lines. Text below the command will be part of the text dialog.
Variables:
N - a number between 1 and 5
Example:
say(3)
This is a test
using the say
command!

reply(N)*
Opens a cyan text dialog, positioned relatively to Viridian of N lines. Text below will be part of the text dialog.
Usage:
N - a number between 1 and 5
Example:
reply(2)
Hello!
This is a dialog

delay(N)
Delays further actions by N ingame ticks. To get an idea of how long a tick is - 30 ticks is *almost* 1 second (it's very slightly longer).
Usage:
N - a number 1 or more.
Example: delay(15)

destroy(warptokens|gravitylines)
Destroys every warp token, or every gravity line, on the screen.
Usage: none
Example: destroy(warptokens)

music(N)
Changes the music ingame to track N.
Usage:
N - a number between 0 and 11, which means the following:
0 - Silence (no music)
1 - Pushing onwards
2 - Positive force
3 - Potential for anything
4 - Passion for exploring
5 - Presenting VVVVVV
6 - Predestined fate
7 - Popular potpurri
8 - Pipe dream
9 - Pressure cooker
10 - Paced energy
11 - Piercing the sky
Example: music(4)

flash
Makes the screen white, shake, and play the flash sound effect.
Usage: none
Example: flash

happy*
Makes Viridian happy.
Usage: none
Example: happy

sad*
Makes Viridian sad.
Usage: none
Example: sad

flag(N,off|on)
Turns an ingame flag on or off.
Usage:
N - a number between 0 and 99 except for 67, see bottom of the thread
Example: flag(63,on)

ifflag(N,S)
If flag N is turned on, runs a script named S in case you have a script with that name.
Usage:
N - a number between 0 and 99 except for 67, see bottom of the thread
S - a script name
Example: ifflag(49,destroywarps)

iftrinkets(N,S)
If you have N (or more) trinkets, run the script S.
Usage:
N - a number between 0 and 20
S - a script name
Example: iftrinkets(20,foundalltrinkets)

iftrinketsless(N,S)
If you have less than N trinkets, run the script S.
This command doesn't work correctly at the moment. Don't use it!
Usage:
N - a number between 0 and 20
S - a script name
Example: iftrinketsless(20,findmoretrinkets)

Commands in the 2.1 beta
Changed commands
say(N[,C])
The optional usage here is to change the dialog color to something else than gray via C. Also, N can now be more than 5. The dialog will be positioned adjacant to any possible crewmate the room, or center otherwise.
Usage:
N - a number between 1 and 11
C - 1/viridian/cyan/player, 2/violet/pink/purple, 3/vitellary/yellow, 4/vermillion/red, 5/verdigris/green, 6/victoria/blue
Example:
say(2,violet)
This is a
purple dialog!

happy(C)
Makes a crewmate happy.
Usage:
C - a crewmate's name or all/everyone/everybody
Example:
happy(violet)

sad(C)
Makes a crewmate sad.
Usage:
C - a crewmate's name or all/everyone/everybody
Example:
sad(vitellary)

New commands
map(on|off)
Turns the ingame map on or off (in which NO SIGNAL is showed). In 2.1, the default is on, but in 2.0, maps is never used.
Usage: none
Example: map(off)

squeak(on|off|C)
Turns the squeaking sounds when you use dialogs on or off, or make a crewmate sound.
Usage:
on - Turns the squeaking on when using dialogs (default behaviour).
off - Turns all the squeaking sounds off. This does NOT affect the effect of a forced squeak done with squeak(crewmate).
C - A crewmate, "terminal", "cry" or "player".


---------------


Hints
* When loading scripts, ensure that you have an additional end at the bottom, preferably with nothing in it. This is in addition to the already empty line. Due to a bug, the last line in a loaded script is read wrongly and thus depending on what you're trying to do, might not work as expected.
* Normally, you shouldn't over-use delay(). Many that are confident with scripting tend to do this. This hinders gameplay, which is the most important thing. delay() is nice sometimes, but don't have it too often, it will be a bit frustrating then.
* Many people want to make scripts execute only one time, in which case flags are really useful. To do this, you can use iftrinkets(0,script) as a "loadscripter". This works because you always have 0 (or more) trinkets. Then, you can have a script that checks if a flag is on, and then do nothing. Otherwise, run the "real" script. Like this:

QuoteName: scripta
ifflag(2,stop)
iftrinkets(0,scriptb)

Name: scriptb
say(1)
This will execute one time only!
flag(2,on)

Name: stop - empty script file.
The reason for why you need to seperate scripta and scriptb is that if VVVVVV encounters dialogs in a script, it will turn on cutscenebars (the black borders at the bottom and the top), no matter whether it will actually run or not. So if you don't seperate it like this, you'll end up with nice black borders every time you run the script after the first time (instead of nothing happening at all). You don't have to seperate them if you don't have dialogs, however. Hopefully this will get fixed, but it's like this currently.

* When you load other scripts via ifflag(), or iftrinkets/iftrinketsless, bear in mind that your script MUST be all lowercase. If this is not the case, the script will not be loaded.
* Never use colons (:) in scripts, i.e. in dialogs. If you do, you will corrupt all of your scripts when you save the level. This is because of how VVVVVV store the scripts internally when saving to a .vvvvvv file.
* You MUST have a newline at the end of a script file. Otherwise, the bottom line will be erased. If this happens to be a part of a dialog - too bad, because VVVVVV will crash when it encounters the end before it has placed all the lines as it want!
* Don't have say(6+) or reply(6+) in 2.0, or 11+ in 2.1. If you have a say/reply command that is 6+ in 2.0, VVVVVV will do strange things and you may or may not end up with a crash. Don't try to exploit with this if you find any actual use out of this, as it's not really compatible with newer versions of VVVVVV. Having a say/reply of 11+ in the 2.1 beta will just make VVVVVV crash.
* If you do a very long dialog, and when testing the script encounter a completely empty dialog - you'll have to end the script and begin a new script (you can use iftrinkets(0,script) as a "loadscripter" as described above) before that part, because you've just encountered the higher limit of a script's length before VVVVVV crash when attempting to run it.
* Flag 67 is used in the main game for deciding on whether you should be able to teleport to the ship via the pause menu or not. This flag does this in custom levels too, and if you do it, your main game save will be destroyed. Don't use this flag!

Limits
* Amount of script lines max before VVVVVV crashes if you try to run it: 198
* Amount of script lines before you can't even insert more w/o running: 500
* Amount of scripts: 500
* Amount of entities (excluding spikes): 3000
* Amount of entities (spikes included) in a single room: 500

Exceeding these limits will make VVVVVV segfault immediately. The same if you load such a level.

blue626

I think that this is a good idea, it should help anyone that has 2.1.beta.
However, you should have created this thread in the VVVVVV board (I think this board is for levels only).
Also, you made some mistakes:
In iftrinkets and iftrinketsless, I think that N can only be 0-20 (not sure if 0 works).
Also, I've heard that iftrinketsless doesn't work (at least in 2.0.).
According to theSome scripting commands thread, in flag, N can only be 1-99 (that isn't much important).
Also, you said to not have a say/reply(6+) in v.2.0. when you shouldn't have 5+ (you said that, in say/reply, N is 1-5).
Like I said before, I'm not sure if iftrinkets(0,S) works, but if it works, you won't need a loadscript flag when dividing long dialogs, for example. You can also use for executing scripts only once:

scripta:
ifflag(1,stop)
iftrinkets(0,scriptb)

scriptb:
(dialog)
flag(1,on)

stop:
(empty or different dialog)

Pyrite

Also, happy(crewmate/color) works, as well as sad(crewmate/color

blue626

Iftrinkets(0,S) works! Executing scripts only once like I did above doesn't need flag 1 and the init script (referring to the scripts FIQ wrote to execute scripts only once).

FIQ

#4
Quote from: blue626 on June 25, 2012, 03:10:17 PM
Iftrinkets(0,S) works! Executing scripts only once like I did above doesn't need flag 1 and the init script (referring to the scripts FIQ wrote to execute scripts only once).
Good idea. I tried iftrinketsless(21,blabla) once, but sometimes it just didn't work.

Will replace the above by your suggestion.

Quote from: blue626 on June 25, 2012, 11:28:13 AM
I think that this is a good idea, it should help anyone that has 2.1.beta.
However, you should have created this thread in the VVVVVV board (I think this board is for levels only).
Also, you made some mistakes:
In iftrinkets and iftrinketsless, I think that N can only be 0-20 (not sure if 0 works).
Also, I've heard that iftrinketsless doesn't work (at least in 2.0.).
According to theSome scripting commands thread, in flag, N can only be 1-99 (that isn't much important).
Also, you said to not have a say/reply(6+) in v.2.0. when you shouldn't have 5+ (you said that, in say/reply, N is 1-5).
Like I said before, I'm not sure if iftrinkets(0,S) works, but if it works, you won't need a loadscript flag when dividing long dialogs, for example. You can also use for executing scripts only once:

scripta:
ifflag(1,stop)
iftrinkets(0,scriptb)

scriptb:
(dialog)
flag(1,on)

stop:
(empty or different dialog)
Thanks for the feedback!

I belive it is supposed to be here. Might be wrong though, and someone with the right power can move it if this is the case.
iftrinkets() typo was paste fail. :P
Flags is only 1-99? I thought it went to 100? Have to test this one...

Vallu

Thank you very much for this! This helped me a lot to learn scripting. I'm making my first awesome level, I can't release it here though becauce I'm making it in Finnish.. :P

Bearboy

is there any easy way to explain iftrinkets and iftrinketsless? I'm having a bit of trouble with it, for example, if you need 4 trinkets to destroy a warp line, and you use a terminal to use the script, would I have to make different script boxes?

Then again, I might figure it out on my own, eventually.

But I doubt it  :verdigris:

Hilbert

script1:
iftrinkets(4,gravline)
say(2)
You need to get 4 trinkets to destroy
the gravity line.
_______________________________
gravline:
destroy(gravitylines)
say(1)
Gravity line destroyed.
____________________

This way if you have 4 trinkets it will destroy the line,
but if you don't, it will tell you you need to get four.

did that help? :viridian:

Bearboy

Quote from: RoskillaHULK!! on June 26, 2012, 09:03:31 PM
script1:
iftrinkets(4,gravline)
say(2)
You need to get 4 trinkets to destroy
the gravity line.
_______________________________
gravline:
destroy(gravitylines)
say(1)
Gravity line destroyed.
____________________

This way if you have 4 trinkets it will destroy the line,
but if you don't, it will tell you you need to get four.

did that help? :viridian:

Would I write all of this into one terminal, including the colons? If this is correct, you're amazing.
And I can't believe you know this stuff given your age, lol  :viridian:

FIQ

Quote from: Bearboy on June 26, 2012, 09:21:14 PM
Quote from: RoskillaHULK!! on June 26, 2012, 09:03:31 PM
script1:
iftrinkets(4,gravline)
say(2)
You need to get 4 trinkets to destroy
the gravity line.
_______________________________
gravline:
destroy(gravitylines)
say(1)
Gravity line destroyed.
____________________

This way if you have 4 trinkets it will destroy the line,
but if you don't, it will tell you you need to get four.

did that help? :viridian:

Would I write all of this into one terminal, including the colons? If this is correct, you're amazing.
And I can't believe you know this stuff given your age, lol  :viridian:
Nope, they're two different scripts!
I.e. you create a script with the name "script1" with the content RoskillaHULK told, and a script named "gravline" with that content.

And you use "script1" as your main script (i.e. the script that the terminal targetted)

Also, NO COLONS. Ever (see the "tips" section in the main post for why).

Bearboy

Iftrinkets works! I'm using it in a level now. Thanks you two

Vallu

I'm having a problem (again)...  There is a room where is  :verdigris: in the other side and gravitylines in the other side. How do I make this happen: After rescuing  :verdigris: and walking to middle of the room a script will happen (:verdigris: says something with the "say" command and gravitylines disappear). I placed a script like this to where  :verdigris: is: "flag(1,on)". And I placed a script like this to middle of the room: "ifflag(1,verdigrisdestroylines)" and I did put the vergidrisdestroylines script randomly to the room where it can't be touched. If I did this wrong, how do I do it? (I hope you understand my bad english... :victoria:)

FIQ

Quote from: Vallu on June 28, 2012, 11:25:20 PM
I'm having a problem (again)...  There is a room where is  :verdigris: in the other side and gravitylines in the other side. How do I make this happen: After rescuing  :verdigris: and walking to middle of the room a script will happen (:verdigris: says something with the "say" command and gravitylines disappear). I placed a script like this to where  :verdigris: is: "flag(1,on)". And I placed a script like this to middle of the room: "ifflag(1,verdigrisdestroylines)" and I did put the vergidrisdestroylines script randomly to the room where it can't be touched. If I did this wrong, how do I do it? (I hope you understand my bad english... :victoria:)
First at all, you can remove the "vergidrisdestroylines" scriptbox - the script will not be deleted.
Secondly, will Viridian touch the middle before Verdigris is rescued? Because that will trigger the script (which will do nothing), and then leave it activated like that. Try to go back one room and then do it. If this works, you know what the problem is.

Hilbert

#13
BTW, if you have more than one destroy(gravitylines) script, you could use it twice.

Say :vermillion: is under a line and in another room  :victoria: is under a line, make a script called gravline and put destroy(gravitylines) and use it when you rescue both of them  :viridian:

blue626

#14
If someone, using 2.1 beta, plays a level made in 2.0, does that person see the map? If the answer is yes, I must ask this: does the command map(on/off) create any glitches in 2.0?

EDIT: In the "some scripting commands" thread (see my 1st post above) someone mentioned a way to make scripts execute only once:

Quote from: TheoX on August 07, 2011, 11:48:56 PM
Quote from: Arkatox on August 07, 2011, 08:09:29 PM
What is the command to destroy a script box after it's used?
There isn't one.  You have to use what I call "trigger scripts", or secondary scripts, that use ifflags to make sure a script doesn't run twice.  It's kind of a pain, and one of the reasons my level is taking so long to make.  Example of what I do:

Example script: "talking1trigger"
ifflag(1,talking1)
end()


Example script: "talking1"
say(2)
this script will
only run once!
flag(1,off)
end()


This assumes the flag used was turned "on" previously.

This method uses 2 scripts and 1 flag per terminal/script box and an "init" script. The method I suggested uses 2 scripts and 1 flag per terminal/script box and a "stop" script. The method on this quote is as good as the other one. Note: I think that the "end" commands aren't necessary.