strat scripts: all 434 vm opcodes named from groove.exe handlers (argonaut names via croc 2 lineage), own assembly syntax with byte-exact round trip over all 1461 code units, script view and script panel in the editor, editing values with undo, custom object types from script or clone, manual chapter with the bucky circle tutorial
This commit is contained in:
1 parent
b36a366240
commit
2386443fac
32 files changed
+5983
-5
No files matched your search
@@ -57,6 +57,7 @@ a saved `.llamalevel` file.
|
||||
| **Problems** | bottom | yes |
|
||||
| **Environment** | left | yes |
|
||||
| **Visibility** | right | yes |
|
||||
| **Script** | bottom | yes |
|
||||
<!-- /generated:panels -->
|
||||
|
||||
### Outliner
|
||||
|
||||
@@ -106,6 +106,7 @@ built-in tools and every plugin):
|
||||
| **C** | Show collision | View |
|
||||
| **Ctrl+Shift+T** | Texture manager | View → Panels |
|
||||
| **Shift+V** | Vertex colours only | View |
|
||||
| **Ctrl+Shift+K** | Script | View → Panels |
|
||||
| **Ctrl+B** | Build | Level |
|
||||
| **F5** | Play | Level |
|
||||
| **Shift+F5** | Play from camera position | Level |
|
||||
@@ -209,6 +210,7 @@ Every menu command with its shortcut and a short description.
|
||||
| Light objects (LGHT preview) (on/off) | | |
|
||||
| Vertex colours only (on/off) | **Shift+V** | Show the baked/painted vertex colours without textures |
|
||||
| Panels → Texture manager | **Ctrl+Shift+T** | Pages, textures, usage and animations |
|
||||
| Panels → Script | **Ctrl+Shift+K** | Strat script of the selected object type |
|
||||
|
||||
### Level menu
|
||||
|
||||
@@ -226,6 +228,7 @@ Every menu command with its shortcut and a short description.
|
||||
| Visibility regions | | |
|
||||
| Import objects of a world… | **Ctrl+Shift+I** | Copy object types (enemies, pickups, platforms …) of another world into this level |
|
||||
| Rebuild object catalogue | | Scan all levels of the CD again (thumbnails, sizes) |
|
||||
| New object type from script… | | Create a custom object type from strat source text |
|
||||
|
||||
### Geometry menu
|
||||
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
# Strat scripts: reading and changing object behaviour
|
||||
|
||||
Every object in the game – a coin, a squirrel, a moving platform, a camera – is driven by a small
|
||||
program, its **strat** (Argonaut's "strategy" scripts). The level editor shows these programs in
|
||||
the **Script** panel, lets you change their numbers (speeds, heights, timers, damage) and lets you
|
||||
create **your own object types** by copying a script and editing it.
|
||||
|
||||

|
||||
|
||||
## The Script panel
|
||||
|
||||
Open it with **View → Panels → Script** (**Ctrl+Shift+K**), the **Open script** button in the
|
||||
Inspector's *Script* section, or click its tab in the bottom dock.
|
||||
|
||||
| Part | What it does |
|
||||
|---|---|
|
||||
| **Type** | the code unit to show. A unit is one compiled script file and can hold several strats (Bucky + ThrowAcorn). Custom types are marked *[custom]* |
|
||||
| **Script / Assembly** | *Script* is a readable view with expressions, `if`/`else` and `loop`; *Assembly* is the exact instruction list (the language you write new types in) |
|
||||
| **Follow selection** | shows the script of the object you select in the viewport or the Outliner |
|
||||
| **Find**, **Next** | search the text (Enter = next match) |
|
||||
| **Uses** | lists every line that uses the selected line's variable, property or label |
|
||||
| **Edit value…** | changes the numbers of the selected line (also: double-click) |
|
||||
| **Clone as new type…** | copies this type into a new, editable object type |
|
||||
|
||||
The side panel explains the selected line: what the instruction does, how many values it takes
|
||||
from the stack, its Argonaut name where known, and what properties like `floorHeight` mean. With
|
||||
nothing selected it lists the unit's parameters, which other scripts **spawn or reference** this
|
||||
one, and how many objects of it are placed.
|
||||
|
||||
### Reading a script
|
||||
|
||||
* `self.x`, `self.rotY`, `self.floorHeight` are properties of the object itself; `player.…`,
|
||||
`parent.…` (the object that spawned it) and `camera.…` those of others.
|
||||
* `v0`, `v1`, … are the object's variables. The first ones are the **parameters** you set in the
|
||||
Inspector (*Object parameters*): parameter 0 = `v0`. Where the editor knows a parameter's
|
||||
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).
|
||||
* `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.
|
||||
|
||||
## Changing numbers
|
||||
|
||||
Double-click a line with a number (or select it and press **Edit value…**). Lines whose numbers
|
||||
can be edited show a tooltip; edited lines turn **orange**.
|
||||
|
||||

|
||||
|
||||
* Type the new value as `1.5` (fixed point), `90deg` (angle), `42` or `0x2a`. The dialog shows
|
||||
the value in all three readings and refuses impossible ones (a `pushShort` holds only
|
||||
−8.0 … 7.99).
|
||||
* The change can be undone (**Ctrl+Z**) like every other edit.
|
||||
* 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
|
||||
the floor. Changing `204` to `1.5` makes them float one and a half cells high:
|
||||
|
||||

|
||||
|
||||
## Your own object types
|
||||
|
||||
**Clone as new type…** in the Script panel (or **Level → New object type from script…** for an
|
||||
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.
|
||||
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.
|
||||
|
||||
The new script is added to the level's code; the original type is not changed. Custom types are
|
||||
stored in the project (as text) and rebuilt every time it is opened.
|
||||
|
||||
Language reference: every instruction is one line, labels end with `:`, comments start with `;`.
|
||||
`push 4deg` / `turnLeft` pushes a number and lets an instruction use it; `jmpYield label` waits
|
||||
for the next frame and jumps. The full syntax and the list of all 434 instructions are in the
|
||||
LlamaMod notes (`notes/strat-language.md`, `notes/strat-opcodes.md`).
|
||||
|
||||
## Tutorial: make the squirrel run in a circle
|
||||
|
||||
Bucky, the nut-throwing squirrel of *Jungle at Night*, can run in a circle in two ways. Both are
|
||||
in one test level below: on the left the waypoint way, on the right the script way.
|
||||
|
||||

|
||||
|
||||
### Find out how Bucky moves
|
||||
|
||||
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
|
||||
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
|
||||
**parameter 0** set the chain repeats instead of ending.
|
||||
|
||||
### Way 1: a circular waypoint chain (no script change)
|
||||
|
||||
1. With Bucky selected, delete its imported path (**Delete path** in the Inspector) and draw a
|
||||
new one with the waypoint tool (**N**): 12 nodes on a circle (radius 1.5–3 cells).
|
||||
2. Select all nodes of the chain and set **Field +26** to `524288` (= 128.0, "run on without
|
||||
waiting").
|
||||
3. Set Bucky's **Parameter 0** to `1.0` (repeat the chain). Parameter 1 is the turn rate
|
||||
(`64.0` = 5.6° per frame; larger turns faster).
|
||||
4. Play. After the last node Bucky continues with the first one – forever.
|
||||
|
||||
### Way 2: a scripted circle (custom type)
|
||||
|
||||
1. Select Bucky, **Clone as new type…**, name it `BuckyCircle`.
|
||||
2. In the source, find the label `L_05b0:` (the start of the main loop) and insert before it:
|
||||
|
||||
```
|
||||
push 3.0
|
||||
popVar v9 ; animation state: running
|
||||
push 3.0
|
||||
popVar v22
|
||||
circle:
|
||||
push 4deg ; turn 4° per frame
|
||||
turnLeft
|
||||
pushShort 215 ; forward speed per frame
|
||||
moveForwardQ
|
||||
forceCollision
|
||||
pushProp floorHeight ; stay on the ground
|
||||
popProp y
|
||||
call L_0180 ; Bucky's animation routine
|
||||
jmpYield circle ; next frame
|
||||
```
|
||||
|
||||
3. **Check**, **Create type**, place a BuckyCircle from **Assets → Objects** and play. The
|
||||
circle's size is speed ÷ turn rate: 215/4096 cells × 90 frames per turn ≈ 4.7 cells around.
|
||||
|
||||
## Limits
|
||||
|
||||
* Custom types cannot be deleted or edited in place yet – clone the custom type again with the
|
||||
changes and replace the placed objects.
|
||||
* 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 `goto` where the original jumps don't form nested blocks; 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.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 188 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 103 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 228 KiB |
@@ -46,6 +46,7 @@ open the chapter about the panel, tool or dialog under the mouse pointer.
|
||||
* [Environment: zones, fog, music and light](12-environment.md)
|
||||
* [Visibility regions](13-visibility.md)
|
||||
* [Level settings](14-level-settings.md)
|
||||
* [Strat scripts: reading and changing object behaviour](22-strats.md)
|
||||
|
||||
## Testing and sharing
|
||||
|
||||
|
||||
Reference in new issue
Block a user