The District of Joban JCM:Building a Scripted PIDS Preset

JCM:Building a Scripted PIDS Preset

From The District of Joban
Revision as of 14:15, 3 November 2024 by LX86 (talk | contribs) (More work)

This is a step-by-step tutorial on building a Scripted PIDS Preset using JavaScript.

By the end of the tutorial, you would have built a Fictional LRT (Light Rail) version of the MTR Railway Vision PIDS, which can adapt to Custom PIDS Messages and handling long string.

Top: Default RV PIDS Preset, Bottom: Custom JS-based PIDS Preset

Getting started

To get started, [download](link here) the tutorial resource pack here and apply it to Minecraft. This resource pack specifically set-up for this tutorial, and therefore the JS scripts inside are (mostly) empty. However we can still take a look at how a Scripted PIDS Preset is set-up.

joban_custom_resources.json

The file will look like this:

{
  "pids_images": [
    {
      "id": "pids_tut",
      "name": "DIY JS Preset",
      "scripts": ["jsblock:scripts/pids_tut.js"]
    }
  ]
}

This is mostly the same from a JSON PIDS Preset, except the scripts which is a JSON array that points to the actual JS script to load for this preset. Multiple JS files can be loaded for the same preset, however to keep things simple, we are simply going to use 1 single JS file, scripts/pids_tut.js.

scripts/pids_tut.js

By opening up pids_tut.js in the scripts folder in a text editor (Notepad etc.), we can see the following script:

function create(ctx, state, pids) {
  // Your custom logic here...
}

function render(ctx, state, pids) {
  // Your custom logic here...
}

function dispose(ctx, state, pids) {
  // Your custom logic here...
}

Our custom logic can be placed between each curly brackets on each of the function. As seen, there are a total of 3 functions: create, render, dispose.

The create function is called when our PIDS enters the player's view. So this means that when a player switches the PIDS preset to our preset, or if a player is approaching a station with our PIDS in sight, everything within the curly bracket of the create function will be run.

The render function is called every frame (So 60fps = 60 times per second)*. Notice the asterisk? Because running scripts simply takes time, even if a short amount of time. JCM will try to, whenever possible, call your function every frame. However if there are too many scripts or your script is slow, then it may not be called every frame.

The dispose function is called when a PIDS Preset is switched away from, or the PIDS is no longer in sight for the player. This can be used to do clean-up work in complex PIDS that stores texture etc.


In this tutorial, the most useful one is going to be the render function, since this is where we can obtain up-to-date information and dynamically render our PIDS. But let's not get ahead of ourselves, and instead start from something very simple: A hello world scripts.

Hello, World!

First, let's insert print("Hello World ^^"); to the brackets within the create function

And now, let's insert print("Goodbye World ^^;"); within the brackets of the dispose function.

Now F3+T and look at your game console!

You should the following message:

[JCM] [Scripting] Hello World ^^

[JCM] [Scripting] Hello World ^^

As PIDS in JCM (as well as MTR) are constructed in a way where each "side" is drawn separately, a normally placed PIDS will would call the function 2 times. This is normal behavior, you didn't do anything wrong!

Now, you can try going very far away from the PIDS, to the point where you can visually no longer sees them. (More technically, when the PIDS chunk is no longer loaded). You will notice the following 2 also pops up:

[JCM] [Scripting] Goodbye World ^^;

[JCM] [Scripting] Goodbye World ^^;

There you have it, a simply Hello World script for the Scripted PIDS Preset.

(In case you got lost, run /tp 0 -60 0).

So this concludes the Scripted PIDS tutorial, I hope that...

No where are you going!

ok I am sorry :<

Now let's actually draw the "Hello World" text onto the PIDS, because printing to console isn't considered exciting for most players apparently!

We can insert the following code to the render method to draw a text with "Hello World":

Text.create().text("Hello World").draw(ctx);

If this looks confusing, we can also split it line by line in the code:

Text.create()
.text("Hello World")
.draw(ctx);

This creates a text, setting the text content to "Hello World", and then drawing it to the ctx (Which is a provided parameter in the render function, more on that later).

A statement is only considered finish by ending with a semicolon (;), so our code will still work after breaking down to different lines. For readability purposes, opening new line is generally preferred.

So now your render function code should look something like this:

function render(ctx, state, pids) {
    Text.create()
    .text("Hello World")
    .draw(ctx);
}

Now let's save the file, reload with F3+T and see what happens!

[TODO v0, actually code]

v1: Light Rail, Light Rail Everywhere!

[TODO v1]

v2: Something is missing

[TODO v2 plat number]

v3: It's still missing

[TODO v3 header bar]

v4: Go ham!

[TODO v4 overflow adjustment]

v5: It's coming together