Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Scriptref Intro: Difference between revisions

From Lost City Wiki
Branon (talk | contribs)
No edit summary
Branon (talk | contribs)
Line 1: Line 1:
[[Category:Scriptref]]
[[Category:Scriptref]]


= RuneScript Reference/Scripting Tutorial =
== RuneScript Reference/Scripting Tutorial ==
<blockquote>Disclaimer: this document is being written by a relative noob in an effort to document my findings and iron out any incorrect notions or faulty assumptions. It is not complete and may be (read: probably is) egregiously wrong in certain areas. Continue at your own peril!</blockquote>Table of Contents: [[:Category:Scriptref]]
<blockquote>Disclaimer: this document is being written by a relative noob in an effort to document my findings and iron out any incorrect notions or faulty assumptions. It is not complete and may be (read: probably is) egregiously wrong in certain areas. Continue at your own peril!</blockquote>Table of Contents: [[:Category:Scriptref]]



Revision as of 00:33, 22 August 2025


RuneScript Reference/Scripting Tutorial

Disclaimer: this document is being written by a relative noob in an effort to document my findings and iron out any incorrect notions or faulty assumptions. It is not complete and may be (read: probably is) egregiously wrong in certain areas. Continue at your own peril!

Table of Contents: Category:Scriptref

This document aims to bring new developers up to speed with the basics of writing RuneScript as used by Lost City. Before reading, you are expected to have:

  • Decent reading comprehension, go slowly and read each section multiple times if needed
  • Willingness to ask for help if needed, Lost City is learning community and we are here to help
  • Most importantly - a winning attitude! If you get confused, ask a question and come back to the problem later

While not strictly required, having a working development environment set up on your computer would be a great advantage. You will be best able to follow along with the tutorial if you have:

Knowledge of basic programming fundamentals (variables, functions) will also help but is by no means required.

Intro

RuneScript files are written as plain text with the extension . RuneScript files are placed under `./data/src/scripts` in the server's source tree and are further organized by various criteria (area, quest, skill, etc).

The Lost City game server is capable of hot-reloading RuneScript files as you change them, meaning you can follow along with this tutorial and see your changes appear in-game in real time!

Triggers

RuneScript operates primarily via **triggers**, which describe how and when to execute functions. Triggers consist of two parts: the trigger itself, and a subject.

Triggers will fire when a player interacts with the game world (typically by clicking) and the functions executed by the trigger are responsible for what actions the game engine will take after the player clicks.

![image](https://github.com/user-attachments/assets/245b221f-c517-4c96-8d97-72208a704c23)

![image](https://github.com/user-attachments/assets/a2a11527-3c8d-448d-9326-987e4ab95a81)

Nearly everything a player does in-game will fire some sort of trigger. Likewise almost all RuneScript is written to execute in response to a fired trigger.

Triggers can be placed in any RuneScript file and the order of triggers does not matter, however it still pays to stay organized!

Types of Triggers

There are several dozen different triggers but they can be divided up into three main types:

* **Specific** triggers fire when the player interacts with a single subject, and use the syntax `[trigger,subject]`  

* **Category** triggers fire when the player interacts with any subjects in a particular category. Categories are prefixed with an underscore so the syntax looks like `[trigger,_category]`

* The **global** trigger acts as a fallback and fires if no other triggers exist for that subject ("*Nothing interesting happens*"). The global trigger actually uses a category so the syntax is `[trigger,_]`

Triggers: `op` versus `ap`

Most triggers you will encounter in everyday use are prefixed with either `op` or `ap`:

* `op`: **Operable** within one tile, requires line of walk, restricted to cardinal directions  

* `ap`: **Approachable** within 10 tiles, requires line of sight

In a nutshell `op` triggers are used for interactions within melee distance (one tile away) and `ap` triggers are used for interactions at range (between two and ten tiles away).

Trigger Naming Convention

Breaking down a bit further, triggers can be categorized by subject type. Different triggers are intended to fire upon interaction with different types of subjects:

* Player subjects: `opplayer1-5`/`applayer1-5`

* NPC subjects: `opnpc1-5`/`apnpc1-5`

* Loc subjects: `oploc1-5`/`aploc1-5`

  * "Loc" (or *location*) is the Jagex term which refers to any interactable (clickable) scenery found in the game.

* Objects on the ground: `opobj`/`apobj`

  * "Object" refers to items, either on the ground or held in the inventory

* Objects held in the inventory: `opheld1-5`/`opheldu` (held objects cannot be `ap`proached)

There are more triggers but this gives you an idea of how the naming convention works.

Examples of Common Triggers

Here are some real-world examples of common triggers you will encounter:

* `[opnpc1,border_guard_lumby]`

  * This is the trigger that fires when a player clicks on a Lumbridge border guard within melee distance. It is a **specific** trigger because its subject is not prefixed by an underscore.

  * The trigger being used here is `opnpc1` which is shorthand for performing `op`eration `1` on an `npc`.

    * Operation 1 for the border guard is `Talk-to`.

* `[oploc1,_door_closed]`

  * This trigger fires when the player clicks any door in the `door_closed` category within melee distance. This is a **category** trigger because its subject is prefixed with `_`.

  * This is a **loc** trigger because a door is clickable/interactable scenery and is therefore referred to as a loc.

    * The trigger used is `oploc1`, and operation 1 on closed doors of this category is `Open`.

* `[applayeru,rotten_tomato]`

  * This trigger fires when the player uses a rotten tomato on another player from `ap`roachable distance (at a range of between 2 and 10 tiles).

  * This is a **specific** trigger because it will only fire when the used item is a rotten tomato.

    * It is also a `player` trigger so it will not fire if e.g. a player uses the rotten tomato on an NPC (that would be `apnpcu`).

Now you understand how to set triggers in RuneScript. The syntax is fairly simple: your desired trigger and its subject, separated by a comma, and enclosed in brackets.

Procedures, Commands, and Labels

There are a few more trigger types to go over. These are slightly more complex but will ultimately make your life easier as they allow a scriptwriter to stay organized and avoid code reuse.

Procedures, commands, and labels are simply triggers that have been given names and may be called from within other triggers. Often, parameters will be used to dictate the precise function of a given procedure/command/label.

The intent is for a scriptwriter to utilize procedures/commands/labels _inside_ the scripts and triggers that they are writing.

Procedures

Procedures are prefixed with `~` when calling. For example:

```ts

[opnpc1,border_guard_lumby]

~chatnpc("<p,angry>I'm in a bad mood, get out of here!");

```

The `~chatnpc` procedure causes an NPC dialog to appear in the player's chatbox. We have called this procedure as part of an `opnpc1` trigger, so `~chatnpc` will run when operation 1 (`Talk-to`) is triggered on the `border_guard_lumby` NPC.

The result looks like:

![image](https://github.com/user-attachments/assets/c288db66-8ae9-4c7d-a660-47183dfecc91)

The important thing to know about procedures is that they **continue execution** of your script after they finish running.

`~chatplayer` in particular will block execution until "Click here to continue" is clicked. Execution of your script will then continue from where it left off. This allows a scriptwriter to trigger additional actions during/after NPC dialogue, for example.

Commands

Commands are provided directly by the game engine and tend to be simpler than procedures.

No special prefix is required when calling commands. For example:

```ts

[opnpc1,border_guard_lumby]

mes("The guard, evidently in a bad mood, shouts at you to leave.");

```

The `mes` command prints a message to the player's chatbox.

![image](https://github.com/user-attachments/assets/bae32d71-189f-4e96-b0be-e276d5dd05f4)

Labels

Labels are similar to procedures with one important difference: they halt execution of the calling trigger after they finish running.

By calling a label, your trigger relinquishes control of the player. Execution of your script will not continue where it left off. Instead, execution begins at the label, and ends when the label ends, without returning to your trigger.

Labels are mostly useful for chaining well-organized blocks of code together, using a trigger only as the initial entry point.

You will often see a trigger call a label, which calls a second label, ... and so on.

Packaging

More in-depth on the server's directory structure. Now that the reader might possibly be capable of writing some RuneScript triggers, have them create a new .rs2 file in an appropriate location and add a test interaction.

Configurations

Zoom out from RuneScript and touch on configs, explain how they might add/change configurations for NPCs and locs, how to move a npc/loc/obj/seq from the `all.*` files into more appropriate locations