This readme is intended for developers wishing to work on the GeckoLib plugin.
Inspect the contents of .nvmrc - this specifies the recommended version of Node.JS to use for plugin development. You can download the corresponding version of Node.JS here.
It's recommended, though not required, to install the correct version of Node.JS using the Node Version Manager script (nvm). Follow the install guide here.
A brief summary of how to use nvm once it's installed is to cd into the src folder of the plugin and then run:
nvm install `cat .nvmrc`
followed by:
nvm use
If you have multiple versions of node installed on your system, it may be convenient to change the default version to the version of node you just installed. Otherwise you may need to run nvm use every time you start a new terminal session. If you are using nvm for other projects with other versions of node, you can also use a shell hook script to automatically run nvm use when changing directories.
You can confirm the active node version by running
node --version
After Node.JS has been installed, run:
npm install
Inside the src folder.
You should run this command any time there has been a change to package.json. You might see a diff on package-lock.json. This is usually OK and indicates an update to transient dependenices, and should be OK to commit. If you see a LOT of changes to this file it might be an indication you are using the wrong version of node/npm.
First, start the development webpack bundler:
npm start
The development bundler will watch the filesystem for changes and automatically re-build the plugin to geckolib.js.
Then, you can load the plugin in Blockbench from File -> Plugins and selecting the Load Plugin from File button. Every time you make a change to the plugin source code, the bundler will automatically rebuild the plugin, but you still need to reload it in Blockbench in order for the changes to take effect. You can do this by selecting Help -> Developer -> Reload Plugins. In some cases if the global state has been messed up, you may need to reload the entire application using Help -> Developer -> Reload Blockbench. It's also recommended to select Open Dev Tools from this menu as it can be very helpful to explore the Blockbench API using the console and inspect error logs and debug breakpoints.
As every time you load the plugin, it's considered by the JS interpreter to be a different source file, any breakpoints set on the previously loaded file will be lost. You can work around this by adding a debugger; statement inside the source code where you want to set a breakpoint, which will force the JS interpreter to break on that line.
If a TypeScript compiler error is encountered, it will be logged to the terminal window, but the JS bundle will still be generated.
To check for errors, you can run:
npm run test
This will run all pretest scripts (eslint and TypeScript type check) as well as unit tests. It's also possible to run pretest separately, or the individual checks by themselves. To see all available npm scripts, run:
npm run
First, inspect package.json to make sure all the properties are correct. If you are making a release of the plugin, you should bump the version property to be one minor version up for a bugfix, minor version for new features, or major version for backwards-incompatible breaking changes.
Then, check the pluginOptions section. min_version should be the lowest version of Blockbench the plugin is known to work with and max_version should be the first version the plugin is expected to not work with that's higher than the versions it was tested on. When the metadata is ready, run:
npm run build
This will first run prebuild/pretest/test scripts, then build the plugin and automatically update the plugins.json manifest with your settings.
Then, update the changelog to add patch notes for the new version. New version entries go at the bottom.
Double-check everything looks right, then commit and make a PR to JannisX11/blockbench-plugins to release the plugin.
Note that it is possible to skip pre-build scripts by running:
npm run build:only
This is dangerous and shouldn't be done to make a full release, it's better to fix any errors from tests, lint, and compiler before publishing changes.
The plugin is now written using a loose version of TypeScript. Blockbench types are supplied by the blockbench-types package. Note that these types are hand-written and may contain errors or be missing certain APIs. So just because you see an error message in your IDE or the bundler output doesn't neccessarily mean your code is wrong, it's possible it could be an issue with the type definitions. TypeScript errors won't prevent the plugin from being built so you can always test your code manually and/or inspect the Blockbench source code to confirm the code is correct. If there's an error in the types, there are a few ways of fixing it:
- Make a PR to
blockbench-types. This is the best, although possibly the slowest method of fixing type errors, and will help all other plugin authors.- These changes can be tested locally first using
npm link. To do so, clone the repo and ensure the same node version is being used as the one for the plugin. Then runnpm linkinsideblockbench-types. Finally, runnpm link blockbench-typesinside the pluginsrcfolder. This will create a symbolic link insidenode_modulesso that the types are resolved from your local copy ofblockbench-types. You need to runnpm link blockbench-typesafter every time you runnpm installbecause an install overwrites the symlink.
- These changes can be tested locally first using
- Massage the types inside the plugin. There are a number of ways you can do this, such as:
- Use type assertions (aka casting). Performing an
ascast directly into the target type is the safest method. If neccessary, casting viaas unknown as <Target Type>will cause the compiler to ignore insufficient overlap between types. It's also possible to attempt to change the type of a function parameter or inferred variable type by adding a type annotation, such as:
or(kf: GeckolibKeyframe) => { } // Otherwise kf would be a Keyframe
let easingBar: HTMLElement = document.createElement('div'); // Otherwise this would be an HTMLDivElement
- Subclassing a blockbench type (for an example of this see usage of the
GeckolibBoneAnimatorin codec.ts). - Performing type narrowing.
- There are other options, such as declaration merging.
- Use type assertions (aka casting). Performing an
- The nuclear option when all else fails: slap a
// @ts-ignorecomment above the problematic line(s). This is a bit dangerous as it shuts off ALL type checking on on that line, but sometimes this is necessary if you need to just force the compiler to ignore a problematic area of the code.
Some places that are good to look for help with TypeScript are the TypeScript Handbook, TypeScript Discord, or you can ping Eliot on the GeckoLib Discord.
ESLint is a tool for checking the code for common errors or problematic coding styles. It can be integrated into IDEs via plugins, and can be run from the terminal like so:
npm run lint
Some lint errors can be fixed automatically by running:
npm run lint:fix
It's best to fix errors by changing the source code when possible. There are some cases in which certain lint rules might get in the way of particular things we might need to do in the plugin. In this case, the rules can be disabled for different scopes. It's best to keep the scope as small as possible, so disabling individual rules per-line is the best way to start, or if it's needed in a larger area, disabling individual rules for a block of code, then lastly a whole file. You can search the code for eslint-disable to find examples. In some cases it may be necessary to disable a rule for the entire codebase, this can be done in the rules block of the .eslintrc.cjs file.