This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
4rpl:overview [2021/01/09 23:46] – [Symbol Aliasing] Fixed <= showing up as an arrow instead of text bluebolt | 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 ====== | ||
- | 4RPL programming | + | Scripting in CW4 uses a custom language, **4RPL**. It is stack-based, |
- | An 4RPL instruction | + | 4RPL commands |
- | 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 |
- | As an illustration, | + | < |
+ | 2 4 | ||
+ | </ | ||
- | <code 4rpl>2 4 5 add</ | + | 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: | |
- | 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 > | + | As an illustration, |
- | You can find more commands and detailed explanations | + | |
- | </ | + | |
- | ==== Comments ==== | + | <code 4rpl> |
+ | 2 4 + | ||
+ | TraceAllSP | ||
+ | </ | ||
- | Adding comments makes code easier to understand, and sometimes helps the programmer | + | The code above puts 2 numbers on the stack, the '' |
- | Comments in xRPL can be either a whole line or a partial line. The comment terminates when a line ends. | + | :!: Note that 4RPL is a // |
- | Comments are indicated by the " | + | 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> | ||
+ | 12 23 100 AddCreeper | ||
+ | </ | ||
- | <code 4rpl># This is how we add two of the three numbers | + | 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 | # that are on the stack | ||
- | # Below is code # | + | # Below is code # Below is a comment |
- | 2 4 5 add # adds 4 and 5 to get 9</ | + | 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 ===== |
+ | Warp notation is an optional notation | ||
- | ==== Warp Notation ==== | + | <code 4rpl> |
+ | 12 23 100 AddCreeper | ||
+ | AddCreeper(12 23 100) # Does the same thing as the line above. | ||
- | An extra and optional <wrap hi> | + | 1 (2 3 +) 4 # Demonstrate wrapping affects all stack locations. |
+ | 2 3 + 1 4 # This line is the same as the one above. | ||
+ | </ | ||
- | This operator is called the **warp** | ||
- | <code prpl>3 4 add </ | + | ===== 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. | ||
- | This means to push 3 to the stack, push 4 to the stack, then to call <wrap round box>add</ | + | <code 4rpl> |
+ | if ( GetGameUpdateCount 900 >= ) | ||
+ | | ||
+ | else | ||
+ | | ||
+ | endif | ||
+ | </code> | ||
- | 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</ | + | Note: See [[4rpl:Data Types]] for comparison between dissimilar types and type conversion. |
- | 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: | + | ===== 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 // | ||
- | < | + | < |
- | # CurrentCoords obtains the (X, y) location and places it on the stack | + | 3 4 + ->result |
- | # GetCreeper uses the (X,Y) coordinates to look at a cell on a map | + | "3 plus 4 is" |
- | # and returns the amount of creeper on that cell | + | |
- | # The "IF" | + | |
- | # 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> | + | Note: See [[4rpl:Data Types]] for comparison between |
- | That's xRPL in a nutshell. | ||
- | Using **warp notation**, we can make this slightly more readable. | ||
- | <code prpl> | + | ===== Functions ===== |
- | # CurrentCoords obtains | + | 4RPL supports user-defined functions that can be called from anywhere in the script. Functions are declared |
- | # GetCreeper uses the (X,Y) coordinates to look at a cell on a map | + | |
- | # and returns | + | |
- | # The " | + | |
- | # other words, creeper exists in a significant amount) | + | |
- | # displays | + | |
- | if ( GetCreeper(CurrentCoords) | + | <code 4rpl> |
- | | + | 4 2 @Function1 |
- | endif | + | @Function2 |
- | </ | + | |
- | 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> | + | add # adds together 2 items on the stack |
- | 7 ->x | + | 5 add # adds an extra 5 to that |
- | ->x(7) | + | |
+ | :function2 | ||
+ | " | ||
</ | </ | ||
- | Both the above statements assign 7 to the variable " | ||
- | ==== Symbol Aliasing ==== | + | Read more about functions on the pages for [[4rpl: |
- | Many arithmetic operators | ||
- | ^ Operator ^ Symbol ^ | + | ===== Loops ===== |
- | | ADD | + | | + | 4RPL supports both " |
- | | SUB | - | | + | For an example of a **do** loop see: [[4rpl:commands:do]] \\ |
- | | MUL | * | | + | For an example of a **while** loop see: [[4rpl: |
- | | DIV | / | | + | |
- | | MOD | % | | + | |
- | | AND | && | | + | |
- | | OR | %%||%% | | + | |
- | | NOT | ! | | + | |
- | | POW | %%^%% | | + | |
- | | GT | > | | + | |
- | | GTE | >=| | + | |
- | | LT | < | | + | |
- | | LTE | %%<=%% | | + | |
- | | EQ | == | | + | |
- | | NEQ | != | | + | |
- | + | ||
- | ==== Code translator | + | |
- | [[https:// | + | |
- | For those struggling to master xRPL's post-fix format, this may be a useful tool. It can be obtained from [[https:// | + | \\ |
- | Here are some sample translations, taken directly from the GitHub repository: | + | ---- |
- | + | ===== 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 half column> | + | < |
- | **mplLang code** | + | < |
- | < | + | %HOMEPATH%\Documents\My Games\creeperworld4\creeperworld4\editor\map2\cpacks\[CPACKNAME] 92415695-49d6-4e97-852b-64493e76233b\scripts\ |
- | x = 2 + 2 * 2; | + | </ |
- | </ | + | |
- | </ | + | |
- | <WRAP half column> | + | |
- | **xRPL translated code** | + | |
- | <code 4rpl> | + | |
- | 2 2 2 mul add ->x | + | |
- | </code> | + | |
- | </WRAP> | + | |
</ | </ | ||
- | <WRAP group> | + | 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). If you export, it will take the scripts on disk. Basically, in the normal case there is a project directory on disk. When you open a project, that directory is where scripts are location on disk. When you compile, those are the ones compiled. They get placed into the exported or finalized CPACK. |
- | <WRAP half column> | + | |
- | <code c> | + | |
- | z = f(x, y); | + | |
- | </ | + | |
- | </ | + | |
- | <WRAP half column> | + | |
- | <code 4rpl> | + | |
- | z = f(x, y); | + | |
- | </ | + | |
- | </ | + | |
- | </ | + | |
- | <WRAP group> | + | The case of on-the-fly opening the editor in a map you are playing is no different -with one exception: The game doesn' |
- | <WRAP half column> | + | |
- | <code c> | + | |
- | [x, y] = CurrentCoords(); | + | |
- | </ | + | |
- | </ | + | |
- | <WRAP half column> | + | |
- | <code 4rpl> | + | |
- | CurrentCoords | + | |
- | </ | + | |
- | </ | + | |
- | </ | + | |
- | <WRAP group> | + | 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 |
- | <WRAP half column> | + | |
- | <code c> | + | |
- | if(a<b && | + | |
- | </ | + | |
- | </ | + | |
- | <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> | + | Basically, just deleting the _UNKNOWN directory is the easiest way to clean it |
- | <WRAP half column> | + | |
- | <code c> | + | |
- | do (1 .. 42){ | + | ---- |
- | a = refRead(" | + | |
- | refWrite(7*(3.14+i), | + | ===== Code translator ===== |
- | } | + | [[https:// |
- | </code> | + | |
- | </ | + | For those struggling to master 4RPL's post-fix format, this may be a useful tool. It can be obtained from [[https://github.com/Arin112/ |
- | <WRAP half column> | + | |
- | <code 4rpl> | + | |
- | 42 1 do | + | |
- | " | + | |
- | 7 3.140000 i add mul " | + | |
- | loop | + | |
- | </code> | + | |
- | </WRAP> | + | |
- | </WRAP> | + | |
- | ===== Tutorials and how-to ===== | ||
- | link to Cornucanis' | ||
- | link to rotation tutorial |