This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
4rpl:overview [2021/01/11 11:12] – Karsten75 | 4rpl:overview [2021/03/28 11:42] – [Variables] Karsten75 | ||
---|---|---|---|
Line 6: | Line 6: | ||
Scripting in CW4 uses a custom language, **4RPL**. It is stack-based, | Scripting in CW4 uses a custom language, **4RPL**. It is stack-based, | ||
- | 4RPL commands either read data from the //stack// or place data on the // | + | 4RPL commands either read data from the //stack// or place data on the // |
- | You can place arguments on the stack by typing them, or executing an instruction that will push arguments on to the stack. For instance, you can type <code 4rpl>2 4 </ | + | You can place arguments on the stack by typing them, or executing an instruction that will push arguments on to the stack. For instance, you can type |
+ | |||
+ | <code 4rpl> | ||
+ | 2 4 | ||
+ | </ | ||
+ | |||
+ | and then these two numbers will be pushed onto the stack when your script executes. | ||
An easy way to familiarize yourself with 4RPL is to use the [[cw4: | An easy way to familiarize yourself with 4RPL is to use the [[cw4: | ||
- | As an illustration, | + | As an illustration, |
<code 4rpl> | <code 4rpl> | ||
- | 2 4 5 add | + | 2 4 + |
- | TraceAllSp | + | TraceAllSP |
</ | </ | ||
- | The code above put 3 numbers on the stack, the `add` command took the 4 and the 5 (last-in, first out) added them and pushed the result (9) back on the stack. [[4rpl: | + | The code above puts 2 numbers on the stack, the '' |
- | {{console_output_1.png}} | + | :!: Note that 4RPL is a // |
Part of 4RPL is the commands that manipulate map objects, such as creeper, terrain and units. Here is a simple script to put some creeper on a specific cell on a map. | Part of 4RPL is the commands that manipulate map objects, such as creeper, terrain and units. Here is a simple script to put some creeper on a specific cell on a map. | ||
Line 29: | Line 35: | ||
</ | </ | ||
- | Run this **once** in the console and then press the pause key to let the game simulation run a few frames. You will see a stack of 100 deep creeper at map coordinate x=12 and z=23((For more information on the game coordinate system and why we use `x` and `z` coordinates, | + | Run this **once** in the console and then unpause |
- | ===== Warp Notation ===== | ||
- | About now is a good time to introduce **warp notation**, a method to improve the readability of 4RPL script. | + | ===== Comments ===== |
- | + | Comments | |
- | An extra and optional <wrap hi> | + | Comments are indicated by the " |
- | + | ||
- | This operator is called | + | |
<code 4rpl> | <code 4rpl> | ||
- | AddCreeper (12 23 100) | + | # This is how we add two of the three numbers |
+ | # that are on the stack | ||
+ | # Below is code # Below is a comment | ||
+ | 2 4 5 add # adds 4 and 5 to get 9 | ||
</ | </ | ||
- | Now one can more clearly see which arguments are intended for the AddCreeper command. | ||
- | ===== Flow Control | + | ===== Warp Notation |
- | + | Warp notation is an optional notation that allows the use of parentheses to change the order that things are written. The use of parentheses | |
- | sometimes one wants to do something a number | + | |
- | Here is a small sample that puts a diagonal line of creeper on a map. | ||
<code 4rpl> | <code 4rpl> | ||
- | GetMapSize ->sizeZ -> | + | 12 23 100 AddCreeper |
- | do(<-sizeX 0) # iterate over every cell in the x-direction | + | AddCreeper(12 23 100) # Does the same thing as the line above. |
- | # starting at zero (first cell) | + | |
- | AddCreeper(I I 50) # if so, plop down some creeper | + | |
- | loop # rinse, repeat until we get to the maximum of I = <-sixeX | + | |
</ | </ | ||
+ | ===== Conditionals ===== | ||
+ | **If** statements in 4RPL consist of an **if**, optional **else** and a closing **endif** instruction. The **if** instruction pops the item from the top of the stack and evaluates it as a boolean (true or false, not 0 or 0). If the item is false, then execution jumps to the **else** or **endif** instruction in the script. | ||
- | fixme after this | + | <code 4rpl> |
- | ---- | + | if ( GetGameUpdateCount 900 >= ) |
- | 4RPL programming is a stack-based language, similar to programming a HP calculator or Forth language programming. If this is not something you have done, read on for a brief introduction to 4RPL and stack-based programming. | + | TraceAllSp(" |
+ | else | ||
+ | | ||
+ | endif | ||
+ | </ | ||
- | An 4RPL instruction either use arguments (data) that is on a " | + | ===== Variables ===== |
+ | The stack is not the only place to store information in 4RPL, it is possible to take items from the stack and store them in // | ||
- | You can place arguments on the stack by typing them, or executing an instruction that will push arguments on to the stack. For instance, you can type <code 4rpl>2 4 </ | + | <code 4rpl> |
+ | 3 4 + -> | ||
+ | "3 plus 4 is" <-result TraceAllSP | ||
+ | </ | ||
- | As an illustration, | ||
- | <code 4rpl>2 4 5 add</ | ||
- | + | Note: See [[4rpl:Data Types]] for comparison between dissimilar types and type conversion. | |
- | Either of the scripts above will read the two most recent arguments on the stack (4 and 5), add them and push the sum on to the stack. After the instruction has completed, there will be two numbers on the stack. The " | + | |
- | <code 4rpl>2 9</ | + | |
- | <wrap info round > | ||
- | You can find more commands and detailed explanations of them in the [[crpl: | ||
- | </ | ||
- | ==== Comments ==== | ||
- | Adding comments makes code easier to understand, and sometimes helps the programmer or other readers to grasp complex pieces of logic. Also, after some time interval, it refreshes one's memory about exactly what a certain piece of code was intended | + | ===== Functions ===== |
+ | 4RPL supports user-defined functions that can be called from anywhere in the script. Functions are declared at the end of a script and are formatted as **: | ||
- | Comments in xRPL can be either a whole line or a partial line. The comment terminates when a line ends. | + | <code 4rpl> |
+ | 4 2 @Function1 Trace # prints " | ||
+ | @Function2 | ||
- | Comments are indicated by the " | + | : |
+ | add # adds together 2 items on the stack | ||
+ | 5 add | ||
- | + | :function2 | |
- | <code 4rpl># This is how we add two of the three numbers | + | " |
- | # that are on the stack | + | |
- | # Below is code # | + | |
- | 2 4 5 add # adds 4 and 5 to get 9</ | + | |
- | + | ||
- | <wrap important> | + | |
- | + | ||
- | Likewise, note that the most recent item pushed on to the stack will also be the first item to be removed. This is referred to as LIFO (**L**ast **I**n, **F**irst **O**ut) processing. | + | |
- | + | ||
- | ==== Warp Notation ==== | + | |
- | + | ||
- | An extra and optional <wrap hi> | + | |
- | + | ||
- | This operator is called the **warp** | + | |
- | + | ||
- | <code prpl>3 4 add </ | + | |
- | + | ||
- | This means to push 3 to the stack, push 4 to the stack, then to call <wrap round box> | + | |
- | + | ||
- | This means two items on the stack before the operation, and one item on the stack afterwards. | + | |
- | This is all xRPL (or RPL, or Forth...) standard stuff and the primary principle of the language. | + | |
- | + | ||
- | Introducing the Warp operator. | + | |
- | + | ||
- | <code prpl>3 4 add</ | + | |
- | can become | + | |
- | <code prpl>add (3 4)</ | + | |
- | + | ||
- | The open parenthesis <wrap round box> | + | |
- | + | ||
- | Here the warp operator is used to make the code slightly more readable. | + | |
- | <code prpl>3 add(4)</ | + | |
- | Here, the <wrap round box> | + | |
- | + | ||
- | Take a second example: | + | |
- | + | ||
- | <code prpl> | + | |
- | # CurrentCoords obtains the (X, y) location and places it on the stack | + | |
- | # GetCreeper uses the (X,Y) coordinates to look at a cell on a map | + | |
- | # and returns the amount of creeper on that cell | + | |
- | # The " | + | |
- | # other words, creeper exists in a significant amount) and if true | + | |
- | # displays a message in the trace output. | + | |
- | + | ||
- | CurrentCoords GetCreeper 1 gt if | + | |
- | " | + | |
- | endif | + | |
</ | </ | ||
- | The comments in the sample above explains what we're trying to achieve with this code snippet. | + | Read more about functions on the pages for [[4rpl: |
- | It uses the current coordinates, | ||
- | Because of the way the stack works, you have to push two coordinates to the stack first (<wrap round box> | + | ===== Loops ===== |
+ | 4RPL supports both "do/loop" and "while/repeat" | ||
+ | For an example | ||
+ | For an example | ||
- | That's xRPL in a nutshell. | + | \\ |
- | Using **warp notation**, we can make this slightly more readable. | + | ---- |
+ | ===== Working with CPACKs ===== | ||
+ | When a CPACK is imported, it does not overwrite any scripts that might be on disk. So if there are scripts on disk those will get jammed back into the CPACK whenever a compile is done (and a compile is done during finalization). | ||
+ | <WRAP width center twothirds> | ||
+ | < | ||
+ | %HOMEPATH%\Documents\My Games\creeperworld4\creeperworld4\editor\map2\cpacks\[CPACKNAME] 92415695-49d6-4e97-852b-64493e76233b\scripts\ | ||
+ | </ | ||
+ | </ | ||
- | <code prpl> | + | What you want to do is make sure there are no 4rpl files on disk at that location, then import |
- | # CurrentCoords obtains the (X, y) location and places it on the stack | + | |
- | # GetCreeper uses the (X,Y) coordinates to look at a cell on a map | + | |
- | # and returns the amount of creeper on that cell | + | |
- | # The " | + | |
- | # other words, creeper exists | + | |
- | # displays a message in the trace output. | + | |
- | if ( GetCreeper(CurrentCoords) | ||
- | Trace (" | ||
- | endif | ||
- | </ | ||
- | Notice that spaces before or after a warp operator <wrap round box> | ||
- | Note also that this syntax is totally optional and can be intermixed with standard RPL notation as seems appropriate. | + | ---- |
- | <code prpl> | + | |
- | 7 ->x | + | |
- | ->x(7) | + | |
- | </ | + | |
- | Both the above statements assign 7 to the variable " | + | |
- | ==== Symbol Aliasing | + | ===== Code translator |
+ | [[https:// | ||
- | Many arithmetic operators | + | For those struggling to master |
- | + | ||
- | ^ Operator ^ Symbol ^ | + | |
- | | ADD | + | | + | |
- | | SUB | - | | + | |
- | | MUL | * | | + | |
- | | DIV | / | | + | |
- | | MOD | % | | + | |
- | | AND | && | | + | |
- | | OR | %%||%% | | + | |
- | | NOT | ! | | + | |
- | | POW | %%^%% | | + | |
- | | GT | > | | + | |
- | | GTE | >=| | + | |
- | | LT | < | | + | |
- | | LTE | %%<=%% | | + | |
- | | EQ | == | | + | |
- | | NEQ | != | | + | |
- | + | ||
- | ==== Code translator ==== | + | |
- | [[https:// | + | |
- | + | ||
- | For those struggling to master | + | |
- | + | ||
- | Here are some sample translations, | + | |
- | + | ||
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | **mplLang code** | + | |
- | <code c> | + | |
- | x = 2 + 2 * 2; | + | |
- | </ | + | |
- | </ | + | |
- | <WRAP half column> | + | |
- | **xRPL translated code** | + | |
- | <code 4rpl> | + | |
- | 2 2 2 mul add ->x | + | |
- | </ | + | |
- | </ | + | |
- | </ | + | |
- | + | ||
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code c> | + | |
- | z = f(x, y); | + | |
- | </ | + | |
- | </ | + | |
- | <WRAP half column> | + | |
- | <code 4rpl> | + | |
- | z = f(x, y); | + | |
- | </ | + | |
- | </ | + | |
- | </ | + | |
- | + | ||
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code c> | + | |
- | [x, y] = CurrentCoords(); | + | |
- | </ | + | |
- | </ | + | |
- | <WRAP half column> | + | |
- | <code 4rpl> | + | |
- | CurrentCoords ->y ->x | + | |
- | </ | + | |
- | </ | + | |
- | </ | + | |
- | + | ||
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code c> | + | |
- | if(a<b && (c+1 == -c)) [a, b, c] = 1, 2.0, 3.14; | + | |
- | </ | + | |
- | </ | + | |
- | <WRAP half column> | + | |
- | <code 4rpl> | + | |
- | <-a <-b lt <-c 1 add <-c neg eq and if | + | |
- | 1 2 3.140000 ->c ->b ->a | + | |
- | endif | + | |
- | </ | + | |
- | </ | + | |
- | </ | + | |
- | + | ||
- | <WRAP group> | + | |
- | <WRAP half column> | + | |
- | <code c> | + | |
- | do (1 .. 42){ | + | |
- | a = refRead(" | + | |
- | refWrite(7*(3.14+i), | + | |
- | } | + | |
- | </ | + | |
- | </ | + | |
- | <WRAP half column> | + | |
- | <code 4rpl> | + | |
- | 42 1 do | + | |
- | " | + | |
- | 7 3.140000 i add mul " | + | |
- | loop | + | |
- | </ | + | |
- | </ | + | |
- | </ | + | |
- | ===== Tutorials and how-to ===== | ||
- | link to Cornucanis' | ||
- | link to rotation tutorial |