|
1 | | ---- |
2 | | -hide_title: true |
3 | | ---- |
| 1 | +# Execution Context |
4 | 2 |
|
5 | | -```mdx-code-block |
6 | | -import NotLocalized from "@site/src/components/NotLocalized" |
| 3 | +Defines the space where all your code resides. Variables and constant values, functions, and converted classes are stored here, and future code interactions with the space are performed here. |
7 | 4 |
|
8 | | -<NotLocalized /> |
| 5 | +Each function and object can create its own, so-called "local" space. It is not available from the outside, but values from it can be obtained through the hierarchy below. I think if most of what is written remains unclear, it is time to fix this problem. |
| 6 | + |
| 7 | +## API — Global Context |
| 8 | + |
| 9 | +If in browsers, and other browser-like engines, the main object is the page whose content we modify, then in the case of Inner Core, we interact directly with the game. And for this we need spaces, methods, and classes, which are in the global context. |
| 10 | + |
| 11 | +Inner Core defines several global contexts, each with its own specific goals. For many years, the main one has been Core Engine, since the entire functionality of the launcher is located around it. This context extends the capabilities of another, Adapted Script. It provides purely native methods provided by the game itself, or auxiliary ones for the operation of Core Engine itself. There are also Preloader, used exclusively by the preloader, and Preferences Window API, which was used for the functioning of the workbench, and once for in-game mod settings. Their use is quite specific, so we will not consider them in detail. |
| 12 | + |
| 13 | +```md |
| 14 | +- AdaptedScript |
| 15 | + - CoreEngine |
| 16 | +- PrefsWinAPI |
| 17 | +- Preloader |
| 18 | +``` |
| 19 | + |
| 20 | +These contexts are used in every script and are described in the `api` properties of your *build.config*. |
| 21 | + |
| 22 | +In the case of Core Engine, it is possible to change the global context, as done, for example, in Ender IO: |
| 23 | + |
| 24 | +```js title="dev/Base/Items/powder.js" |
| 25 | +// highlight-malformed-start |
| 26 | +Item.createDyeItem = function(id, name, type) { |
| 27 | + IDRegistry.genItemID(id); |
| 28 | + Item.createItem(id, name, { |
| 29 | + name: "item_material_organic_" + type + "_dye" |
| 30 | + }, { stack: 64 }); |
| 31 | +}; |
| 32 | +// highlight-malformed-end |
| 33 | + |
| 34 | +Item.createDyeItem("greenDye", "Organic Green Dye", "green"); |
| 35 | +Item.createDyeItem("blackDye", "Organic Black Dye", "black"); |
| 36 | +Item.createDyeItem("brownDye", "Organic Brown Dye", "brown"); |
| 37 | +``` |
| 38 | + |
| 39 | +However, think about the consequences, this will change the context in all mods. That is, the `Item.createDyeItem` method can be called from any mod if Ender IO is installed. But in this case, there is also a danger of replacing existing methods or those added with updates. If you need to export something, consider [ModAPI.registerAPI](TODO), it was created specifically for these purposes. |
| 40 | + |
| 41 | +### Global Values |
| 42 | + |
| 43 | +Each context defines its own namespace, access to which can be used to obtain values or perform actions. However, in addition to values in the context, the engine provides built-in values exclusive to each mod individually. These values are the same regardless of which script this space touches. This includes technical values, mod information, and in-game constants. |
| 44 | + |
| 45 | +```js |
| 46 | +const MINECRAFT_VERSION = getMCPEVersion(); |
| 47 | +if (MINECRAFT_VERSION.main == 16) { |
| 48 | + alert("Minecraft " + MINECRAFT_VERSION.str + " is currently relevant!"); |
| 49 | + // outputs: Minecraft 1.16.201 is currently relevant! |
| 50 | +} else if (MINECRAFT_VERSION.main == 11) { |
| 51 | + alert("Legacy version " + MINECRAFT_VERSION.array.join("-") + " is not relevant for " + __name__); |
| 52 | + // outputs: Legacy version 1-11-4 is not relevant for <mod name> |
| 53 | +} |
| 54 | +``` |
| 55 | + |
| 56 | +The `getMCPEVersion` and `alert` methods here are part of the global API context, while `__name__` is a global value available from any part of the mod. You do not need to think about what properties are available here, they are listed in the API summary and toolchain declarations. |
| 57 | + |
| 58 | +## Script Body |
| 59 | + |
| 60 | +The last and most important step in the formation of your space is the code itself. JavaScript uses Rhino 1.7.7 (partially supporting ES6, however, most of the functionality remained in the ES5 implementation) as the main engine that executes all scripts. The language is interpreted, which means it is processed in real time, or with minimal processing before launch. All code is executed sequentially, and by script body we mean all the code that is contained in the files included in the build. |
| 61 | + |
| 62 | +The script is usually executed once, and any spaces it defines (this can be variables or constants, as well as objects or functions) are activated as a result of events. The content, the logic of your mod is defined in the body, other content is integrated, and everything else that the engine is capable of in principle. |
| 63 | + |
| 64 | +## Restartable Contexts |
| 65 | + |
| 66 | +Considering the life cycle earlier, we superficially introduced __custom__ scripts. Unlike other scripts, this is the only type that can be run any number of times, and in addition, accepts and returns values. Probably, you could have associations with functions if acquaintance with the language once went successfully. But unlike functions, these are still spaces; they work in a new context and store values. |
| 67 | + |
| 68 | +Consider this with an example from Solar Flux Reborn: |
| 69 | + |
| 70 | +```js title="dev/tests.js" |
| 71 | +alert( |
| 72 | + runCustomSource("custom.js", { |
| 73 | + THUNDER_MULTIPLIER: 0.4, |
| 74 | + RAIN_MULTIPLIER: 0.6, |
| 75 | + WEATHER: World.getWeather() |
| 76 | + }) |
| 77 | +); |
9 | 78 | ``` |
| 79 | + |
| 80 | +Values passed to the space will be overwritten or created if they do not exist yet. Any constants created in the body of restartable scripts must be set only once. Their repeated modification will cause an error, in which case a simple option would be to place them between `try-catch`. |
| 81 | + |
| 82 | +```js title="custom.js" |
| 83 | +let raining = WEATHER.rain / 10; |
| 84 | +raining = raining > 0.2 ? (raining - 0.2) / 0.8 : 0; |
| 85 | +raining = Math.sin(raining * Math.PI / 2); |
| 86 | +raining = 1 - raining * (1 - RAIN_MULTIPLIER); |
| 87 | + |
| 88 | +let thundering = WEATHER.thunder / 10; |
| 89 | +thundering = thundering > 0.75 ? (thundering - 0.75) / 0.25 : 0; |
| 90 | +thundering = Math.sin(thundering * Math.PI / 2); |
| 91 | +thundering = 1 - thundering * (1 - THUNDER_MULTIPLIER); |
| 92 | + |
| 93 | +// Values must still be returned by a function, since |
| 94 | +// the script body is not capable of returning anything |
| 95 | +(function() { |
| 96 | + return raining * thundering; |
| 97 | +})(); |
| 98 | +``` |
| 99 | + |
| 100 | +Depending on weather conditions, the efficiency of solar panels changes, values from the current space are involved. Thus, `runCustomSource("custom.js")` will not change the values and will return the previous result. The context does not change, so the values remain the same. |
| 101 | + |
| 102 | +Modding tools use this type to execute code during the game. Since their space is easily configured and saved between different executions independently of the rest of the mod context, subdividing the main code here was a good idea. A more concrete way to use these scripts simply does not exist. Suggest your ideas where such functionality could be useful. |
0 commit comments