Better Scripts

Thamus_Knoward

Shadowbinder
Once you've installed the macro mod, as described here, you are able to not only able to run a lot of World Edit commands in simple sequence, but also using iterative using loops and adaptive to special conditions.

In this thread, I'll try to outline and collect some of the quirks of this awesome power while also touching on things that I consider good conduct.

Resources:
FAWE Wiki
Macro/Keybind Mod Readme
Tham's Script Collection And Macro Config

Good Conduct:
  • Use log statements at the very beginning of your script to introduce what your script does and what preconditions need to be met for it to run:

    Code:
    $${LOG(Before you start using this script)}$$$${LOG(make sure that you have selected ONLY the y layer of the water surface)}$$
    $${LOG(This script provides three general profiles:)}$$
    $${LOG(U-shaped, U: each step becomes one block wider)}$$
    $${LOG(U-shaped inverted, UI: the first step is as wide as the provided maximum depth, each subsequent step becomes one block shorter)}$$
    $${LOG(V-shaped, V: equal step size all the way down, you will be prompted for the step size)}$$
    $${LOG(Custom, C: you will be prompted at each step for the desired step size)}$$

  • Keep using log statements throughout to indicate the different stages of your script. This is both helpful for you and others for debugging but also to see if execution runs without interruptions.

    Code:
    ELSEIF(%&type% == "UI") LOG(Initiating inverted U-shaped profile)
    #width = #maxdepthminus2

  • Also, consider using a log statement at the end of the script. This is a nice indicator that all commands in your script have been triggered. Although it is important to point out that due to the asynchronicity of FAWE the commands may NOT have completed yet.

    Code:
    $${WAIT(1)}$$|//replace 0 31:1,31:2
    $${WAIT(2)}$$|
    $${LOG(Script Complete)}$$|

  • Avoid using /gmask if possible. In scripts, this is quite an expensive operation! If you use it without accounting for the time it takes to mask/unmask the scripts commands may run out of sync and mess up a large area big time! Instead, use smarter /replace or /rep statements:

    Code:
    //replace <[air]&[white] #biome[river]
    as a substitute for
    Code:
    //gmask <[air]
    //rep white #biome[river]

  • ALWAYS, seriously, always use placeholders when you work with scripts. I prefer to use wool because I can simply use color words like 'red' and 'black' etc. However, that's obviously a little more difficult when working with selections that already contain wool blocks i.e. scripts that are supposed to run on an area after some construction has been done. In this case I'd suggest mapping the wool blocks to concrete bocks first and then mapping them back once the script is completed. Wool is nice for the above reason, concrete is nice because it most definitely isn't used in regular builds and coloured glass is nice because you can see through it (good for scripts that work with caves or rivers). Try to take great care never to mask/ replace 'natural' blocks i.e. blocks that could be used, instead map to a placeholder and at the end of the script map it back to regular blocks.

    Code:
    //replace [blue] #simplex[6][30%blue,70%pink]$${WAIT(1)}$$
    //replace [[blue]&~[pink][1][8]] pink,blue
    $${WAIT(1)}$$
    //replace [[wool]&<[pink]] brown
    $${WAIT(1)}$$
    
    $${LOG(Transform Wool)}$$
    //replace blue 90%air,3%2006:6,7%2205:2,3%2061:6,7%2061:8
    $${WAIT(1)}$$
    //replace pink air
    $${WAIT(1)}$$
    //replace [[air]&>[brown]] 2066:12
    $${WAIT(1)}$$
    //replace white #simplex[7][70%black,15%2034:0]
    $${WAIT(1)}$$
    //replace brown 2034:1
    $${WAIT(1)}$$

  • Try to make modular scripts. Here's an example of how you could do it. Imagine you want to create a field script. Some fields require rows of crops, some are just densely packed. Instead of bundling the logic to determine the packing with each crop, separate it out into a script of it's own. Now users can create a bunch of shapes to their liking and override the 'packing' placeholders with the crops of their choice.


    I'll edit this thread over the coming week to include more guidelines and give y'all a brief rundown on the more arcane things to do with the Macro/Keybind Mod like variables, loops, and controlflow; and the maths functionality from FAWE. Gotta run!
 
Last edited:

Emoticone11

The Dark Lord Sauron
Staff member
Thanks Tham, this’ll be super helpful!

Just one addition, it’s super important to have the “$${WAIT(1)}$$” lines in-between every WE command, as you can see in Tham’s examples, and also giving it an appropriate amount of time (in this case it’s 1 second, but some commands like gradient mask are more expensive, and so would require a higher number). Otherwise, commands could finish asynchronously (not in the intended sequence) which would completely screw up execution. Make sure to test scripts on larger selections before releasing them to the public.
 

CashBanks

A Knight at the Opera
Staff member
Tham I’m super curious about how you went with the Norridge forest scripts. It sounds like they got the job done, was it super painful? Do you think the scripts have enough versatility to be customized and used in other areas?

The dream has been to have a script where you can select an area, plug in the region/Schem details and it will figure out the rest, do you reckon this is a step in that direction?
 

Thamus_Knoward

Shadowbinder
Do you think the scripts have enough versatility to be customized and used in other areas?

Yeah totally! In fact, the scripts I used at Norridge are customized variants of my Rousemont scripts. To explain the process a little I have broken down the forest generation into three modules: Tree placement, Debris placement, and Forest floor placement. The last includes both shrubs, grasses, and the ground mix, which I guess could be split up into separate modules to customize it further.


It sounds like they got the job done, was it super painful?

It did, and it did so reasonably conveniently however here are a few painful things:
- Spam protection kicked me several times mid-script despite having at least a 1-second waiting time between each command. The tree placement script is quite long and being booted half-way through sucks.
- The larger the selection the longer it takes to run the scripts and the higher the risk of being kicked or something fucking up. I was eager to get it done on one day trying to run the scripts on large areas at once. However, this notably decreased server performance as indicated by many complaints about lag in chat and the run-time of a single script was upwards of 15 minutes. So I generally recommend pacing yourself, doing only small chunks at a time.
- Converting our schematics to the right format. My scripts only work with schematics that have the origin of selection in the north-western-bottom corner!!! I've made a script that automates the creation of schems this way. Once you have found the 'physical' schematics in-game, this needs to be run prior to any forest gen work.
- The single most annoying thing is having to find schematics. Marge wanted to use ThamBirchS trees, which funnily enough I had not created myself. I checked the birch section at treetest but couldn't find them. After asking around for a couple of hours, the creator of the set joined and could finally clear this up for me. The schematics were kept floating above their current project.

- Another pet peeve of mine: Tree inconsistency is rampant even in our treetest schems. I've seen what is supposedly one type of tree going from oak to jungle to spruce as it increases in size from S to M to L. For some trees, there are alt-sets that use wholly different combinations of materials. I think that is super confusing.

The dream has been to have a script where you can select an area, plug in the region/Schem details and it will figure out the rest, do you reckon this is a step in that direction?
Absolutely.
Some things I think need to be addressed before that can become a reality:
- We should be able to shift the origin of selection of schematics to their center on creation. I've opened a FAWE ticked for this a while ago but they only addressed it in their current version. Not in our legacy 1.12 build. Maybe our coders could help us with that. Centering the schematics would shorten the scripts significantly! Currently, the placement of each tree requires to place an offset placeholder first and then replacing that with the tree to bypass the fact that the origin of selection isn't in the center of the schematic.
- I have stopped experimenting with it, but I think it is possible to use my schem generation script to also define standardised schem sets that could immediately be used. This would marry the two ("feuding") paradigms of schematic use that currently coexist on the server. HOWEVER, first Iwan and I discovered a bug in the schematic brush that needs to be addressed, and second somebody would have to play a little with running the schem brush commands through the macro and keybind mod.
- And then you'd obviously need to define a few region standard modules for tree placement, debris, undergrowth, and ground mixes.
 

Thamus_Knoward

Shadowbinder
Do your scripts work on steeper regions?
I think so, the only issue is that due to the placement of offset placeholders and their subsequent removal we get some holes in the terrain. I have a script to fill the holes afterwards though.

How steep is steep? You could check the forests at Rousemont and Whitegrove to get an idea! I’m happy to run in on steeper surfaces for testing.
 

CashBanks

A Knight at the Opera
Staff member
I think the Schems having their respective trees in the right part of the Schem is key, since steep hills are less forgiving and it becomes very easy for trees to spawn floating in the air.

Maybe we should make a bunch of new schems using your Schem script (rather than running the risk of messing with existing ones) just for the purposes of this Forest Script.
 

Thamus_Knoward

Shadowbinder
I've updated the OP to include my Macro folder containing my macro/keybind mod config and all the scripts I've collected and made so far:



I should add that using these is at your own risk. I'll be working on better documentation of my scripts in accordance with this guide little by little as I find the time.
 
Last edited:
  • Like
Reactions: Iwan and Luk