├── lib
└── put-openrct2.d.ts-here.md
├── src
├── startup.ts
└── plugin.ts
├── tsconfig.json
├── package.json
├── LICENSE
├── .gitignore
├── rollup.config.js
└── README.md
/lib/put-openrct2.d.ts-here.md:
--------------------------------------------------------------------------------
1 | Put the `openrct2.d.ts` file in this folder.
2 |
3 | You can take it from a OpenRCT2 installation or download it from here:
4 |
5 | https://raw.githubusercontent.com/OpenRCT2/OpenRCT2/develop/distribution/openrct2.d.ts
6 |
7 | For more information, please read the [README.md](../README.md).
--------------------------------------------------------------------------------
/src/startup.ts:
--------------------------------------------------------------------------------
1 | function onClickMenuItem()
2 | {
3 | // Write code here that should happen when the player clicks the menu item under the map icon.
4 |
5 | console.log("Hello world!");
6 | }
7 |
8 |
9 | export function startup()
10 | {
11 | // Write code here that should happen on startup of the plugin.
12 |
13 |
14 |
15 | // Register a menu item under the map icon:
16 | if (typeof ui !== "undefined")
17 | {
18 | ui.registerMenuItem("My plugin", () => onClickMenuItem());
19 | }
20 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "esModuleInterop": true,
4 | "forceConsistentCasingInFileNames": true,
5 | "module": "ES2020",
6 | "moduleResolution": "node",
7 | "noFallthroughCasesInSwitch": true,
8 | "noImplicitAny": true,
9 | "noImplicitOverride": true,
10 | "noImplicitReturns": true,
11 | "noImplicitThis": true,
12 | "noUnusedLocals": true,
13 | "noUnusedParameters": true,
14 | "outDir": "out",
15 | "strict": true,
16 | "target": "es5",
17 | "lib": [ "es5" ]
18 | },
19 | "include": [
20 | "./lib/**/*.ts",
21 | "./src/**/*.ts",
22 | ],
23 | "noEmit": true
24 | }
25 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "openrct2-typescript-plugin",
3 | "version": "1.0.0",
4 | "type": "module",
5 | "license": "MIT",
6 | "scripts": {
7 | "start": "nodemon --watch ./src --ext js,ts --exec \"npm run build:dev\"",
8 | "build": "rollup --config rollup.config.js --environment BUILD:production",
9 | "build:dev": "rollup --config rollup.config.js"
10 | },
11 | "devDependencies": {
12 | "@rollup/plugin-node-resolve": "^15.0.1",
13 | "@rollup/plugin-terser": "^0.4.0",
14 | "@rollup/plugin-typescript": "^11.0.0",
15 | "nodemon": "^2.0.22",
16 | "rollup": "^3.15.0",
17 | "tslib": "^2.5.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/plugin.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import { startup } from "./startup";
4 |
5 | registerPlugin({
6 | name: "Name of your plugin",
7 | version: "1.0",
8 | authors: [ "Your name" ],
9 | type: "remote",
10 | licence: "MIT",
11 | /**
12 | * This field determines which OpenRCT2 API version to use. It's best to always use the
13 | * latest release version, unless you want to use specific versions from a newer develop
14 | * version. Version 70 equals the v0.4.4 release.
15 | * @see https://github.com/OpenRCT2/OpenRCT2/blob/v0.4.4/src/openrct2/scripting/ScriptEngine.h#L50
16 | */
17 | targetApiVersion: 70,
18 | main: startup,
19 | });
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OpenRCT2 TypeScript API declaration file
2 | lib/openrct2.d.ts
3 |
4 | # Logs
5 | logs
6 | *.log
7 | npm-debug.log*
8 | yarn-debug.log*
9 | yarn-error.log*
10 | lerna-debug.log*
11 |
12 | # Diagnostic reports (https://nodejs.org/api/report.html)
13 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
14 |
15 | # Runtime data
16 | pids
17 | *.pid
18 | *.seed
19 | *.pid.lock
20 |
21 | # Directory for instrumented libs generated by jscoverage/JSCover
22 | lib-cov
23 |
24 | # Coverage directory used by tools like istanbul
25 | coverage
26 | *.lcov
27 |
28 | # nyc test coverage
29 | .nyc_output
30 |
31 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
32 | .grunt
33 |
34 | # Bower dependency directory (https://bower.io/)
35 | bower_components
36 |
37 | # node-waf configuration
38 | .lock-wscript
39 |
40 | # Compiled binary addons (https://nodejs.org/api/addons.html)
41 | build/Release
42 |
43 | # Dependency directories
44 | node_modules/
45 | jspm_packages/
46 |
47 | # TypeScript v1 declaration files
48 | typings/
49 |
50 | # TypeScript cache
51 | *.tsbuildinfo
52 |
53 | # Optional npm cache directory
54 | .npm
55 |
56 | # Optional eslint cache
57 | .eslintcache
58 |
59 | # Microbundle cache
60 | .rpt2_cache/
61 | .rts2_cache_cjs/
62 | .rts2_cache_es/
63 | .rts2_cache_umd/
64 |
65 | # Optional REPL history
66 | .node_repl_history
67 |
68 | # Output of 'npm pack'
69 | *.tgz
70 |
71 | # Yarn Integrity file
72 | .yarn-integrity
73 |
74 | # dotenv environment variables file
75 | .env
76 | .env.test
77 |
78 | # parcel-bundler cache (https://parceljs.org/)
79 | .cache
80 |
81 | # Next.js build output
82 | .next
83 |
84 | # Nuxt.js build / generate output
85 | .nuxt
86 | dist
87 |
88 | # Gatsby files
89 | .cache/
90 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
91 | # https://nextjs.org/blog/next-9-1#public-directory-support
92 | # public
93 |
94 | # vuepress build output
95 | .vuepress/dist
96 |
97 | # Serverless directories
98 | .serverless/
99 |
100 | # FuseBox cache
101 | .fusebox/
102 |
103 | # DynamoDB Local files
104 | .dynamodb/
105 |
106 | # TernJS port file
107 | .tern-port
108 |
109 | # Visual Studio
110 | .vs/
111 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import resolve from "@rollup/plugin-node-resolve";
2 | import terser from "@rollup/plugin-terser";
3 | import typescript from "@rollup/plugin-typescript";
4 | import { exec } from "child_process";
5 | import { homedir } from "os";
6 | import { promisify } from "util";
7 |
8 |
9 | const options =
10 | {
11 | /**
12 | * Change the file name of the output file here.
13 | */
14 | filename: "my-plugin.js",
15 |
16 | /**
17 | * Determines in what build mode the plugin should be build. The default here takes
18 | * from the environment (ex. CLI arguments) with "development" as fallback.
19 | */
20 | build: process.env.BUILD || "development"
21 | };
22 |
23 | /**
24 | * Tip: if you change the path here to your personal user folder,
25 | * you can ignore this change in git with:
26 | * ```
27 | * > git update-index --skip-worktree rollup.config.js
28 | * ```
29 | * To accept changes on this file again, use:
30 | * ```
31 | * > git update-index --no-skip-worktree rollup.config.js
32 | * ```
33 | */
34 | async function getOutput()
35 | {
36 | if (options.build !== "development")
37 | {
38 | return `./dist/${options.filename}`;
39 | }
40 |
41 | const platform = process.platform;
42 | const pluginPath = `OpenRCT2/plugin/${options.filename}`;
43 |
44 | if (platform === "win32") // Windows
45 | {
46 | const { stdout } = await promisify(exec)("powershell -command \"[Environment]::GetFolderPath('MyDocuments')\"");
47 | return `${stdout.trim()}/${pluginPath}`;
48 | }
49 | else if (platform === "darwin") // MacOS
50 | {
51 | return `${homedir()}/Library/Application Support/${pluginPath}`;
52 | }
53 | else // Linux
54 | {
55 | const configFolder = process.env.XDG_CONFIG_HOME || `${homedir()}/.config`;
56 | return `${configFolder}/${pluginPath}`;
57 | }
58 | }
59 |
60 |
61 | /**
62 | * @type {import("rollup").RollupOptions}
63 | */
64 | const config = {
65 | input: "./src/plugin.ts",
66 | output: {
67 | file: await getOutput(),
68 | format: "iife",
69 | compact: true
70 | },
71 | treeshake: "smallest",
72 | plugins: [
73 | resolve(),
74 | typescript(),
75 | terser({
76 | compress: {
77 | passes: 5,
78 | toplevel: true,
79 | unsafe: true
80 | },
81 | format: {
82 | comments: false,
83 | quote_style: 1,
84 | wrap_iife: true,
85 | beautify: (options.build === "development"),
86 | }
87 | })
88 | ]
89 | };
90 | export default config;
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Simple OpenRCT2 plugin template with Typescript
2 |
3 | A simple and minimal template for OpenRCT2 plugins, using Typescript, without any unnecessary extra's.
4 |
5 | Also supports:
6 | - Automatic plugin reload in OpenRCT2 (hot reload);
7 | - Out of the box minification to improve file sizes;
8 | - Support for external NPM packages (like FlexUI).
9 |
10 | ## How to start
11 |
12 | 1. Install latest version of [Node](https://nodejs.org/en/) and make sure to include NPM and enable the "Add to PATH" option during installation.
13 | 2. Use the green "Use this template" button in the top right corner of this page, or download the project to a location of your choice on your PC.
14 | 3. Open a terminal or command prompt.
15 | 4. Use `cd` to change your current directory to the root folder of this project.
16 | 5. Run `npm install` to install the project's dependencies.
17 | 6. Find `openrct2.d.ts` TypeScript API declaration file in OpenRCT2 files. copy it to `./lib/` folder.
18 | - This file can usually be found in the [OpenRCT2 installation directory](#openrct2-installation-directory).
19 | - Alternatively you can download the file from Github [here](https://raw.githubusercontent.com/OpenRCT2/OpenRCT2/develop/distribution/openrct2.d.ts).
20 | - Another option is to make a symbolic link instead of copying the file, which will keep the file up to date whenever you install new versions of OpenRCT2.
21 | 7. In `./src/plugin.ts`, change the name and author of the plugin to your liking.
22 | 8. In `./rollup.config.js`, change the filename of the outputted plugin.
23 |
24 | ---
25 |
26 | ## Commands
27 |
28 | The template comes with several terminal commands to make developing plugins easier.
29 |
30 | `npm run build`
31 |
32 | Creates a release build of your plugin. This version is optimized for sharing with others, using Terser to make the file as small as possible. By default, the plugin will be outputted to `./dist/`.
33 |
34 | `npm run build:dev`
35 |
36 | Creates a develop build of your plugin. This version is not optimized for sharing, but easier to read in case you want to see the outputted Javascript. By default, the plugin will be outputted in the plugin folder of the default [OpenRCT2 user directory](#openrct2-user-directory).
37 |
38 | `npm start` or `npm run start`
39 |
40 | Will start a script that will automatically run `npm run build:dev` every time you make a change to any Typescript or Javascript file inside the `./src/` folder.
41 |
42 | ### Output paths
43 |
44 | These output paths can be changed in `rollup.config.js`. In this file you can also change the outputted filename of the plugin.
45 |
46 | ---
47 |
48 | ## Access game logs
49 |
50 | When your plugin is not loading properly, it may be useful to be able to read the logs of the game to see if there are any errors. Furthermore, if you use the `console.log` function, the resulting logs can be read here as well.
51 |
52 | ### Windows
53 |
54 | 1. Navigate to the folder where [OpenRCT2 is installed](#openrct2-installation-directory).
55 | 2. Launch the `openrct2.com` file located there (the MS-DOS application).
56 | - If file extensions are hidden, make sure to [enable them](https://support.microsoft.com/en-us/windows/common-file-name-extensions-in-windows-da4a4430-8e76-89c5-59f7-1cdbbc75cb01).
57 |
58 | ### MacOS
59 |
60 | 1. Launch a terminal or another command-line prompt.
61 | 2. Using the `cd` command, navigate to the folder where [OpenRCT2 is installed](#openrct2-installation-directory).
62 | 3. Run `open OpenRCT2.app/Contents/MacOS/OpenRCT2` to launch OpenRCT2 with logging enabled.
63 |
64 | ---
65 |
66 | ## Hot reload
67 |
68 | This project supports the [OpenRCT2 hot reload feature](https://github.com/OpenRCT2/OpenRCT2/blob/master/distribution/scripting.md#writing-scripts) for development.
69 |
70 | 1. Navigate to your [OpenRCT2 user directory](#openrct2-user-directory) and open the `config.ini` file.
71 | 2. Enable hot reload by setting `enable_hot_reloading = true` in `config.ini`.
72 | 3. Run `npm start` in the directory of this project to start the hot reload server.
73 | 4. Start the OpenRCT2 and load a save or start a new game.
74 | 5. Each time you save any of the files in `./src/`, the server will compile `./src/registerPlugin.ts` and place compiled plugin file inside your local OpenRCT2 plugin directory.
75 | 6. OpenRCT2 will notice file changes and it will reload the plugin.
76 |
77 | ---
78 |
79 | ## Folders
80 |
81 | ### OpenRCT2 installation directory
82 |
83 | This is the directory where the game is installed.
84 |
85 | - **Windows:** usually `C:/Users//Documents/OpenRCT2/bin/` when using the launcher or `C:/Program Files/OpenRCT2/` when an installer was used.
86 | - **MacOS:** the folder where the `OpenRCT2.app` application file was placed.
87 | - **Linux:** depends on the distro, but likely either `/usr/share/openrct2` when installed through a package manager, or mounted in `/tmp` when using an AppImage.
88 |
89 | ### OpenRCT2 user directory
90 |
91 | This is the directory where the game stores user data, like save games and plugins.
92 |
93 | - **Windows:** usually `Documents/OpenRCT2/` or `C:/Users//Documents/OpenRCT2/`.
94 | - **MacOS:** usually `/Users//Library/Application Support/OpenRCT2/`. Note that `Library` is a hidden folder in your user directory, so by default it will not show up in Finder.
95 | - **Linux:** usually `/home//.config`, `$HOME/.config`, or where the environment variable `$XDG_CONFIG_HOME` points to if it's set.
96 |
97 | You can also open this folder from inside OpenRCT2, by selecting "Open custom content folder" in the dropdown under the red toolbox in the main menu.
98 |
99 | ---
100 |
101 | ## Dependencies
102 |
103 | The following libraries and tools are used in this template:
104 |
105 | - **NodeJS** is the JavaScript engine used to develop and run code when the game is not running.
106 | - **NPM** is a library and package manager for JavasScript and TypeScript and can be used to install new packages and update existing packages in the project.
107 | - **TypeScript** is a expansion language to JavaScript that adds type checking when you are writing the code. It allows you to specify rules for how objects and values look like, so TypeScript can report back if your code follows these rules (instead of crashes or errors in-game).
108 | - **Rollup** bundles all source code, runs it through some plugins like TypeScript, and then outputs a single JavaScript plugin file.
109 | - **Nodemon** is the program that can watch a folder for changes and then trigger a specified action. It is used by `npm start` to watch the `./src/` folder and triggers `npm run build:dev` if any changes occur.
--------------------------------------------------------------------------------