mtr_addon:nte:js:start
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
mtr_addon:nte:js:start [2024/02/06 13:08] – added source weryskok | mtr_addon:nte:js:start [2025/05/10 18:51] (current) – Improve scripting explanation based on JCM wiki lx862 | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== JavaScript Support ====== | ====== JavaScript Support ====== | ||
+ | |||
NTE supports fully customizable control of rendering and other features using JavaScript. This page lists the various functions, objects, and types provided when using JavaScript with NTE. | NTE supports fully customizable control of rendering and other features using JavaScript. This page lists the various functions, objects, and types provided when using JavaScript with NTE. | ||
===== Why Overcomplicate Everything? ===== | ===== Why Overcomplicate Everything? ===== | ||
+ | |||
The main purpose of this feature is to implement dynamic displays on trains with the intent to support many different types and displays found in trains all over the world. | The main purpose of this feature is to implement dynamic displays on trains with the intent to support many different types and displays found in trains all over the world. | ||
By simplifying this process, it would be too hard to accurately reproduce how the system looks and works in real life and a lot of people would complain. This more complicated format is designed to let all sorts of logic and display types be implemented in the game without limiting creators too much. The downside to this is that now, all creators who want to create things will have to learn JavaScript to make use of these features. | By simplifying this process, it would be too hard to accurately reproduce how the system looks and works in real life and a lot of people would complain. This more complicated format is designed to let all sorts of logic and display types be implemented in the game without limiting creators too much. The downside to this is that now, all creators who want to create things will have to learn JavaScript to make use of these features. | ||
- | ===== How To Edit JavaScript | + | ===== What is JavaScript? ===== |
- | A JavaScript | + | |
+ | JavaScript is a programming language | ||
+ | |||
+ | It can describe logic, an example would be: //__If__ there' | ||
This rest of this article assumes that you have a basic understanding of JavaScript and JavaScript types, so it won't delve into the basic syntax and other aspects of it here. You can learn JavaScript from resources on the web, such as [[https:// | This rest of this article assumes that you have a basic understanding of JavaScript and JavaScript types, so it won't delve into the basic syntax and other aspects of it here. You can learn JavaScript from resources on the web, such as [[https:// | ||
- | ===== Type Annotation | + | ===== The Nature of Scripting in NTE ===== |
+ | |||
+ | While JavaScript is commonly associated with webpages or even server applications (via Node.js), NTE's implementation of JavaScript only utilize the language itself. | ||
+ | |||
+ | As such, this means that you only really need to care about the language itself (e.g. Variable & Function Declaration, | ||
+ | |||
+ | Keep that in mind, as IDE (e.g. Visual Studio Code) may assume you are developing for a webpage and provides suggestions that are not applicable to our method of scripting! | ||
+ | |||
+ | ===== Script Flow ===== | ||
+ | |||
+ | ==== Initial Parsing ==== | ||
+ | |||
+ | Instead of each train having it's own script instance, your JS scripts are parsed (Or rather, executed) **once** during the resource pack loading. Your script are expected to have functions with specific name (e.g. **create()**, | ||
+ | |||
+ | These functions will be invoked by NTE with the parameter corresponding to a specific train/ | ||
+ | |||
+ | Consider the following example of scripting applied to a train: | ||
+ | |||
+ | <code javascript> | ||
+ | let displaySpeed = 1; | ||
+ | |||
+ | function create(ctx, state, train) { | ||
+ | | ||
+ | } | ||
+ | |||
+ | function render(ctx, state, train) { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | function dispose(ctx, | ||
+ | } | ||
+ | |||
+ | console.log(displaySpeed); | ||
+ | </ | ||
+ | |||
+ | An example output would be: | ||
+ | |||
+ | <code -> | ||
+ | 1 // The console.log at the bottom of the script, as the entire script is executed once during resource reload | ||
+ | |||
+ | dp: 1.75 // Train A rendering | ||
+ | dp: 2.75 // Train A rendering | ||
+ | |||
+ | // Assume Train B now enters the view | ||
+ | |||
+ | dp: 3.75 // Train A rendering | ||
+ | dp: 1.75 // Train B rendering | ||
+ | |||
+ | dp: 4.75 // Train A rendering | ||
+ | dp: 2.75 // Train B rendering | ||
+ | </ | ||
+ | |||
+ | ==== Execution ==== | ||
+ | |||
+ | An example flow is available below. The following diagram assumes the player is running Minecraft at **13fps** (For simplicity sake), which means 13 frames in 1 second. | ||
+ | |||
+ | {{: | ||
+ | |||
+ | Immediately you may have noticed the following thing: | ||
+ | |||
+ | === Scripts are executed asynchronously / In a different thread === | ||
+ | |||
+ | This means that the script runs in the background and does not prevent the game from continue rendering (Therefore, less fps lag). __Note that this does NOT mean you can freely block script execution or run some **Thread.Sleep**, | ||
+ | |||
+ | === Functions are invoked every frame === | ||
+ | |||
+ | More precisely, the '' | ||
+ | |||
+ | If there' | ||
+ | |||
+ | As such, you should not assume that your function will always be called "x times per second", | ||
+ | |||
+ | This also means that if you increment a variable by a fixed amount for each frame, that increment speed won't be the same if the fps is higher/ | ||
+ | |||
+ | Delta timing is used to solve this by obtaining the time since last frame, which can then be used to balance out the value. | ||
+ | |||
+ | === Except they aren't always invoked every frame! === | ||
+ | |||
+ | While NTE //tries// to call the '' | ||
+ | |||
+ | ===== Do I have to learn Java to write JavaScript? ===== | ||
+ | |||
+ | JavaScript does not have anything, or not much to do with Java at all, even though they share " | ||
+ | |||
+ | ===== But can I use Java classes in JavaScript? ===== | ||
+ | |||
+ | Under normal circumstances, | ||
+ | |||
+ | //However// the JavaScript Engine that NTE uses - **Rhino**, //do// allow using classes from the standard Java library as '' | ||
+ | |||
+ | ===== Documentation Format ===== | ||
As you know, values in JS have different types. When calling a function, you must pass parameters of the appropriate type, and the result it returns will also have a type. In this article, all of the functions have their parameter and return types stated. For example: | As you know, values in JS have different types. When calling a function, you must pass parameters of the appropriate type, and the result it returns will also have a type. In this article, all of the functions have their parameter and return types stated. For example: | ||
- | | + | |
+ | | ||
+ | static Resources.id(idStr: | ||
+ | </ | ||
* '' | * '' | ||
* '' | * '' | ||
* '': | * '': | ||
- | * <code javascript> | + | * <code javascript> |
+ | Matrices.rotateX(radian: | ||
+ | </ | ||
* The lack of '' | * The lack of '' | ||
* '' | * '' | ||
* '': | * '': | ||
* '': | * '': | ||
+ | * | ||
- | ===== Using Built-In Java Classes | + | ===== Errors ===== |
- | The Rhino JS engine allows | + | |
+ | If the script is executed incorrectly, | ||
+ | |||
+ | In addition, NTE pauses the script for 4 seconds and then tries to run it again. | ||
+ | |||
+ | ===== Tips & Notes ===== | ||
+ | |||
+ | ==== Declaring variables | ||
+ | |||
+ | NTE uses JavaScript's **strict mode**, which does not allow variables to be assigned without first declaring them. | ||
+ | |||
+ | This means you can't do '' | ||
- | ===== Declaring variables using let or var ===== | + | Instead, you have use syntax like '' |
- | NTE uses JavaScript' | + | |
[Translator' | [Translator' | ||
- | ===== Don't Block Or Infinitely Loop ===== | + | ==== Don't Block Or Infinitely Loop ==== |
- | NTE calls the function you wrote once per frame and expects your function to finish processing and return a value as soon as possible. Therefore, there is no such thing as "stop execution and wait for a while" | + | |
- | If locks or infinite loops occur in the code, the entire script execution will stall because NTE scripts are executed one at a time [in the same thread]. | + | The function you wrote are called once per frame by NTE, in which your function is expected to finish processing and return a value //as soon/fast as possible//. As such, there' |
+ | |||
+ | What you likely want to do instead is to //do a thing later on//, in which case you will need to time it and then execute the appropriate action on a call made at the right time. | ||
+ | |||
+ | If you are trying to execute a long-running operation (e.g. Fetching data over the internet), you should submit it to another thread/ | ||
+ | |||
+ | If blocks | ||
+ | |||
+ | ==== Interoperability between Java Classes/ | ||
- | ===== Differences In Using Java Classes ===== | ||
For common function types such as strings, Java and JavaScript have different class implementations, | For common function types such as strings, Java and JavaScript have different class implementations, | ||
For example, here's an example of a problem caused by using '' | For example, here's an example of a problem caused by using '' | ||
+ | |||
<code javascript> | <code javascript> | ||
var stationName = train.getThisRoutePlatforms().get(0).station.name; | var stationName = train.getThisRoutePlatforms().get(0).station.name; | ||
Line 47: | Line 167: | ||
print(("" | print(("" | ||
</ | </ | ||
+ | |||
Similarly, there is a '' | Similarly, there is a '' | ||
- | ===== Supported Parts Of The JavaScript Standard ===== | + | ==== Supported Parts Of The JavaScript Standard ==== |
The Rhino engine does not support all of the latest JavaScript features. See [[https:// | The Rhino engine does not support all of the latest JavaScript features. See [[https:// | ||
- | ===== Errors | + | ==== Running Other Scripts |
- | If the script is executed incorrectly, | + | |
- | In addition, NTE pauses the script for 4 seconds and then tries to run it again. | + | |
- | + | static include(relPath: | |
- | ===== Running Other Scripts ===== | + | </ |
- | | + | |
* Loads and runs another JS file relative to the current JS file. | * Loads and runs another JS file relative to the current JS file. | ||
- | * <code javascript> | + | * <code javascript> |
+ | static include(path: | ||
+ | </ | ||
* Loads and runs the JS file by location in the resource pack. For example, '' | * Loads and runs the JS file by location in the resource pack. For example, '' | ||
===== Source ===== | ===== Source ===== | ||
- | * https:// | + | |
+ | * [[https:// | ||
+ | |||
+ | * [[https:// | ||
+ |
mtr_addon/nte/js/start.1707224880.txt.gz · Last modified: 2024/02/06 13:08 by weryskok