strats: custom types stay editable after importing object types (custom code kept last), references between custom types by name, edit can change where fields come from, opcode aliases with clearer names, script view gotos 400 -> 31 (labeled break/continue, condition chains, jumps to return), script language 2: event handlers, switch, short-circuit && ||, constant folding, schema parameter names, plain numbers in cells
This commit is contained in:
1 parent
d6f84be125
commit
386a06006d
21 files changed
+1771
-252
No files matched your search
+23
-13
@@ -36,7 +36,9 @@ one, and how many objects of it are placed.
|
||||
meaning, the script uses its name (`snapToFloor`).
|
||||
* `g12` is a global variable shared by all scripts.
|
||||
* Numbers are in game units: `1.0` = one cell (or "true"), angles are written like `5.625deg`.
|
||||
Speeds and turn rates are **per frame** (the game runs at 30 frames per second).
|
||||
Speeds and turn rates are **per frame** (the game runs at 30 frames per second). Small raw
|
||||
numbers have an `r`: `204r` is 204/4096 of a cell (about 0.05).
|
||||
* `break name` / `continue name` leave or repeat the outer loop labelled `name:`.
|
||||
* `yield` ends the object's turn for this frame; a `loop { … yield }` runs once per frame.
|
||||
* `onEvent` installs a handler, for example "when the player touches me" (event type 4).
|
||||
* `spawn<…>(…)` creates another object, `address model:5` names a 3D model of the level.
|
||||
@@ -55,7 +57,7 @@ can be edited show a tooltip; edited lines turn **orange**.
|
||||
* It applies to **every object of that type** in the level, also to objects other scripts spawn.
|
||||
* It is saved in the project and written into the level when you build or play.
|
||||
|
||||
Example: in the Coin's script, `self.y = self.floorHeight + 204` puts snapping coins just above
|
||||
Example: in the Coin's script, `self.y = self.floorHeight + 204r` puts snapping coins just above
|
||||
the floor. Changing `204` to `1.5` makes them float one and a half cells high:
|
||||
|
||||

|
||||
@@ -70,7 +72,8 @@ empty template) opens the type editor:
|
||||
1. **Name** – the name of the new type (letters, digits, `_`).
|
||||
2. **Entry label** – where the script starts (for clones: the renamed strat).
|
||||
3. **Type fields / parameters from** – which existing type's settings (parameters, waypoints,
|
||||
flags) new objects of this type start with.
|
||||
flags) new objects of this type start with. In a script you can use that type's parameter
|
||||
names (for a Coin: `snapToFloor` for parameter 0).
|
||||
4. Edit the source. **Check** assembles it and verifies the result; errors name the line.
|
||||
5. **Create type**. The type appears in **Assets → Objects** and can be placed like any other.
|
||||
|
||||
@@ -83,7 +86,9 @@ Select an object of a custom type (or pick the type in the Script panel's *Type*
|
||||
|
||||
* **Edit type…** (Script panel or the Inspector's *Script* section) opens the type editor with
|
||||
its script. Change it, **Check**, then **Apply**. Objects of the type that are already placed
|
||||
keep their place and run the new script. **Ctrl+Z** undoes the change.
|
||||
keep their place and run the new script. **Ctrl+Z** undoes the change. *Type fields /
|
||||
parameters from* can be changed here too: new objects start with the other type's settings,
|
||||
placed ones keep theirs.
|
||||
* **Delete type…** removes the type. If objects in the level use it, the editor tells you how many
|
||||
and deletes them together with the type (also undoable).
|
||||
|
||||
@@ -113,12 +118,19 @@ strat Pulser {
|
||||
```
|
||||
|
||||
* Statements: `x = value`, `x += value`, `if (…) { } else { }`, `while (…) { }`, `loop { }`,
|
||||
`do { } while (…)`, `break`, `continue`, `yield`, `end`, `call name` (for `sub name { … }`).
|
||||
`do { } while (…)`, `switch (…) { case 1: … break default: … }`, `break`, `continue`, `yield`,
|
||||
`end`, `call name` (for `sub name { … }`).
|
||||
* `on touched { … }` runs its block when the player touches the object (the object needs
|
||||
`collisionOn<0x20000>()` and `collRadius(…)`, like a coin); `on event(type, param) { … }` for
|
||||
other events. The block ends like a sub (`remove` deletes the object).
|
||||
* `a && b` and `a || b` in conditions stop as soon as the answer is known.
|
||||
* Any instruction can be called by name with its values in brackets: `turnLeft(4deg)`,
|
||||
`scale(size)`; values that are part of the instruction go in `<>`: `collisionOn<0x8000>()`.
|
||||
* Places: `v0`… (or a name given with `alias`), globals `g12`, properties `self.y`, `player.x`…
|
||||
* Numbers mean the same as in the assembly: write `10.0` for ten (a plain `10` is ten 1/4096
|
||||
steps), angles as `90deg`.
|
||||
* Numbers: `10` and `10.0` both mean ten cells, angles are written `90deg`. For a raw value (as
|
||||
the Script view shows them) add `r`: `215r` = 215/4096; hex like `0x8000` is raw too. Values
|
||||
inside `<…>` are raw. Scripts written before this rule start with `use rawNumbers` when you open
|
||||
them, so they keep working.
|
||||
* **Check** compiles and verifies; errors name the line. Switching *Language* back to *Assembly*
|
||||
shows the generated instructions. The full reference is in `notes/strat-language.md`.
|
||||
|
||||
@@ -138,11 +150,11 @@ in one test level below: on the left the waypoint way, on the right the script w
|
||||
|
||||
1. Import Bucky (**Assets → All worlds**, search "Bucky", drag it into the level).
|
||||
2. Select it and open the **Script** panel. The script shows `wpFirst()`, `wpNext()` and
|
||||
`wpTurnToY(v1)` / `moveForwardQ(215)`: Bucky **runs along its waypoint chain**, turning
|
||||
`wpTurnToY(v1)` / `moveForwardQ(215r)`: Bucky **runs along its waypoint chain**, turning
|
||||
with the rate in parameter 1 and moving 215/4096 cells per frame.
|
||||
3. At every node it reads `self.wpParam` (the node's field **+26**): the low part chooses run
|
||||
(`0`) or jump (`1.0`, `2.0`), the high part `128.0` means "run on", `64.0` "wait until the
|
||||
player comes close". At the end: `if (!(!v0 && (self.wpEndFlags & 2))) goto …` – with
|
||||
player comes close". At the end: `} while (!(!v0 && (self.wpEndFlags & 2r)))` – with
|
||||
**parameter 0** set the chain repeats instead of ending.
|
||||
|
||||
### Way 1: a circular waypoint chain (no script change)
|
||||
@@ -182,15 +194,13 @@ circle:
|
||||
|
||||
## Limits
|
||||
|
||||
* Custom types can't be edited or deleted right after importing object types from another level
|
||||
in the same session – save and reopen the project first.
|
||||
* Big structural changes are up to you: the editor checks that the code is well-formed and that
|
||||
every model/animation/code reference points somewhere valid, not that the object behaves well.
|
||||
* Names of rarely used instructions are educated guesses (the opcode list shows a confidence for
|
||||
each).
|
||||
* Small constants stored as short numbers only accept −8.0 … 7.99 (see *Changing numbers*).
|
||||
* The Script view shows `while`, `do … while`, `switch`, `break` and `continue` where it can and
|
||||
`goto` where the original jumps don't form nested blocks (a few hundred places in the whole
|
||||
game); the Assembly view is always exact.
|
||||
`goto` where the original jumps don't form nested blocks (31 places in the whole game, all in
|
||||
the llama's script); the Assembly view is always exact.
|
||||
* In the clone dialog, renaming the type doesn't yet rename the entry label or the name inside
|
||||
the script text – edit those by hand if you want them to match.
|
||||
Reference in new issue
Block a user