Custom Script Reader

A script reader interprets the raw string of a scriptable keyframe when that keyframe plays. Each script is prefixed with a reader id (e.g. meg:... or mm:...); the prefix selects which reader handles the rest of the string. Model Engine ships a default meg reader and, when MythicMobs is present, an mm reader. You can register your own reader to add custom script behavior.

Creating a reader class

A reader implements the ScriptReader functional interface, which has a single read method. The IAnimationProperty gives you access to the playing animation and its model, and script is the part of the keyframe string after your reader's prefix.

public class CustomScriptReader implements ScriptReader {

	@Override
	public void read(IAnimationProperty property, String script) {
		// property -> the animation currently playing this keyframe
		// script   -> everything after your reader prefix (the "reader:" part is stripped)

		ActiveModel model = property.getModel();
		Object original = model.getModeledEntity().getBase().getOriginal();

		// Interpret `script` and do your custom logic here.
		// e.g. only act when the base is a Bukkit entity:
		if (original instanceof Entity entity) {
			// ...
		}
	}

}

How the prefix works

When a script keyframe fires, the keyframe string is split on the first : into a reader id and the remaining script text. The id is looked up in the registry and that reader's read is called with the leftover text. A string with no : falls back to the meg reader, so walk is equivalent to meg:walk.

What you get from IAnimationProperty

property.getModel() returns the ActiveModel running the animation. From there you can reach the base via model.getModeledEntity().getBase().getOriginal() (the wrapped target, e.g. a Bukkit Entity) and the model data via model.getBlueprint(). The rest of IAnimationProperty exposes the animation's timing and state if you need it.

Registering the reader

Readers live in the ScriptReaderRegistry, reached through ModelEngineAPI.getAPI().getScriptReaderRegistry(). There is no static convenience accessor for this registry, so go through getAPI(). Register your reader under the id you want players to use as the prefix.

// On plugin start-up
ModelEngineAPI.getAPI().getScriptReaderRegistry().register("custom", new CustomScriptReader());

Once registered, a scriptable keyframe with the script custom:do something will be handled by your reader, with do something passed as the script argument.

Updated Aug 19, 2026