This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
4rpl:overview [2021/01/14 17:01] – Karsten75 | 4rpl:overview [2025/02/14 14:57] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
< | < | ||
+ | |||
+ | :!: To edit files you will need an editor. Read how to get started with [[creating and editing 4rpl scripts]]. | ||
====== Scripting ====== | ====== Scripting ====== | ||
Line 6: | Line 8: | ||
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. | ||
+ | |||
+ | <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 + | + | 2 4 + |
- | | + | TraceAllSP |
</ | </ | ||
- | The code above puts 2 numbers on the stack, the `add` (or +) command took the 4 and the 2 (last-in, first out) added them and pushed the result (6) back on the stack. [[4rpl: | + | The code above puts 2 numbers on the stack, the '' |
+ | |||
+ | :!: 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. | ||
<code 4rpl> | <code 4rpl> | ||
- | | + | 12 23 100 AddCreeper |
+ | </ | ||
+ | |||
+ | Run this **once** in the console and then unpause the game and 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, | ||
+ | |||
+ | |||
+ | ===== Comments ===== | ||
+ | Comments in 4RPL can be either a whole line or a partial line. The comment terminates when a line ends. | ||
+ | Comments are indicated by the " | ||
+ | |||
+ | <code 4rpl> | ||
+ | # 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 | ||
</ | </ | ||
- | Run this **once** in the console and then unpause the game and 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, | ||
===== Warp Notation ===== | ===== 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 is called warp notation since it warps, or moves, things around. Parentheses can be added anywhere in 4rpl and will move the command that proceeded the opening parenthesis to the location of the closing parenthesis. This can be useful for making some expressions look more like functions in some other languages | + | Warp notation is an optional notation that allows the use of parentheses to change the order that things are written. The use of parentheses is called warp notation since it warps, or moves, things around. Parentheses can be added anywhere in 4RPL and will move the command that proceeded the opening parenthesis to the location of the closing parenthesis. This can be useful for making some expressions look more like functions in some other languages |
- | ==== Example ==== | ||
<code 4rpl> | <code 4rpl> | ||
- | 12 23 100 AddCreeper | + | 12 23 100 AddCreeper |
- | | + | AddCreeper(12 23 100) # Does the same thing as the line above. |
+ | |||
+ | 1 (2 3 +) 4 # Demonstrate wrapping affects all stack locations. | ||
+ | 2 3 + 1 4 # This line is the same as the one above. | ||
</ | </ | ||
===== Conditionals ===== | ===== Conditionals ===== | ||
- | 'If' | + | **If** statements in 4RPL consist of an **if**, optional **else** and a closing |
<code 4rpl> | <code 4rpl> | ||
Line 50: | Line 75: | ||
</ | </ | ||
- | ===== Loops ===== | ||
- | 4rpl support both " | ||
+ | Note: See [[4rpl:Data Types]] for comparison between dissimilar types and type conversion. | ||
+ | ===== 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 // | ||
- | Old stuff below | ||
- | ---- | ||
- | |||
- | |||
- | ===== Flow Control ===== | ||
- | |||
- | sometimes one wants to do something a number of times, that is called a **loop** and an important part of programming. | ||
- | |||
- | Here is a small sample that puts a diagonal line of creeper on a map. | ||
<code 4rpl> | <code 4rpl> | ||
- | GetMapSize | + | 3 4 + ->result |
- | do(< | + | "3 plus 4 is" |
- | # 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 | + | |
</ | </ | ||
- | fixme after this | + | Note: See [[4rpl:Data Types]] |
- | ---- | + | |
- | 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. | + | |
- | An 4RPL instruction either use arguments (data) that is on a " | ||
- | 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 </ | ||
- | As an illustration, | + | ===== 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 **: | ||
- | <code 4rpl>2 4 5 add</ | + | <code 4rpl> |
+ | 4 2 @Function1 Trace # prints " | ||
+ | @Function2 | ||
- | | + | :function1 |
- | Either of the scripts above will read the two most recent arguments | + | |
- | <code 4rpl>2 9</ | + | |
- | <wrap info round > | + | :function2 |
- | You can find more commands and detailed explanations of them in the [[crpl: | + | " |
- | </wrap> | + | </code> |
- | ==== Comments ==== | + | Read more about functions on the pages for [[4rpl: |
- | 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 to do. | ||
- | Comments in 4RPL can be either | + | ===== Loops ===== |
+ | 4RPL supports both " | ||
+ | For an example of a **do** loop see: [[4rpl: | ||
+ | For an example of a **while** loop see: [[4rpl: | ||
- | Comments are indicated by the " | + | \\ |
+ | ---- | ||
+ | ===== 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 4rpl># This is how we add two of the three numbers | + | If you load map as a regular player and then enter edit mode, the game will stick the scripts into the _UNKNOWN project directory. If there are already matching scripts present at that location, they will not be overwritten (importing a CPACK is the only exception to this). |
- | # that are on the stack | + | |
- | # Below is code # | + | |
- | 2 4 5 add # adds 4 and 5 to get 9</ | + | |
- | <wrap important> | + | The case of on-the-fly opening the editor |
- | 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. | + | If you want to grab the scripts from a map (like an FPS map) and you want to make sure you have the latest scripts, you should either create a project for the map and open it from the project page, or you should clean your _UNKNOWN directory before you open the map on the fly. |
- | ==== Warp Notation ==== | + | Basically, just deleting the _UNKNOWN directory is the easiest way to clean it |
- | An extra and optional <wrap hi> | ||
- | This operator is called the **warp** | + | ---- |
- | <code prpl>3 4 add </ | + | ===== Code translator |
- | + | ||
- | 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 4RPL (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. | + | |
- | + | ||
- | 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> | + | |
- | + | ||
- | That's 4RPL in a nutshell. | + | |
- | + | ||
- | Using **warp notation**, we can make this slightly more readable. | + | |
- | + | ||
- | <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. | + | |
- | + | ||
- | 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 ==== | + | |
- | + | ||
- | Many arithmetic operators | + | |
- | + | ||
- | ^ Operator ^ Symbol ^ | + | |
- | | ADD | + | | + | |
- | | SUB | - | | + | |
- | | MUL | * | | + | |
- | | DIV | / | | + | |
- | | MOD | % | | + | |
- | | AND | && | | + | |
- | | OR | %%||%% | | + | |
- | | NOT | ! | | + | |
- | | POW | %%^%% | | + | |
- | | GT | > | | + | |
- | | GTE | >=| | + | |
- | | LT | < | | + | |
- | | LTE | %%<=%% | | + | |
- | | EQ | == | | + | |
- | | NEQ | != | | + | |
- | + | ||
- | ==== Code translator ==== | + | |
[[https:// | [[https:// | ||
For those struggling to master 4RPL's post-fix format, this may be a useful tool. It can be obtained from [[https:// | For those struggling to master 4RPL's post-fix format, this may be a useful tool. It can be obtained from [[https:// | ||
- | Here are some sample translations, | ||
- | |||
- | <WRAP group> | ||
- | <WRAP half column> | ||
- | **mplLang code** | ||
- | <code c> | ||
- | x = 2 + 2 * 2; | ||
- | </ | ||
- | </ | ||
- | <WRAP half column> | ||
- | **4RPL 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 |