@yl-module/yl-m-test v0.5.1
Yl-Module
A minecraft gametest scripting module that aims to make gametest scripting much more customized, and currently has a few features.
Yl-Module Features
- Command Management System
- Database System
- Customized Events
And much more there is to come in the near future.
Command Management System
Yl-Module manages custom commands in clusters, giving the module the opportunity to be much more efficient in handling data. Command instances are the units of data in the system, which are separated and stored in different managers. Managers, or CommandManager instances to be precise, manage commands and handle their execution. Command managers must have unique names and prefixes to be easily distinguishable from each other.
Creating Custom Commands
For custom commands to be created, a CommandManager must be instantiated first in order for the commands to be stored and managed somewhere.
Command Manager
constructor(name: string, prefix: string): CommandManager
Command
constructor(options: CommandOptions): Command
import { CommandManager, Command } from "yl-module";
// Instantiation of CommandManager
const testManager = new CommandManager("Test", "-");
// Registration of a command
testManager.register(
new Command({
name: "ping",
description: "Replies with pong!",
callback: (interaction) => {
// Reply to the interaction
interaction.reply("Pong!");
},
})
);Command Execution
The command system is quite unique and requires a little more effort to execute. The command ping from above can be executed in the format {prefix}{command}, where {prefix} is the prefix of the manager where the command is stored, and {command} being the name or an alias of the command.
In cases where a command has subcommands and options, the format for specifying which subcommand is executed is {subcommand}, and the format for specifying options is {option}: {value}. The {option} is the name of the option and {value} is the value passed. Note that the colon is required to avoid ambiguity between options and subcommands.
This may be confusing, but consider the following example to illustrate the format:
Say a command tag is created:
import { CommandManager, Command, CommandTypes } from "yl-module";
// Instantiate the CommandManager
const commands = new CommandManager("GeneralCommands", "-");
// Register the command
commands.register(
new Command({
name: "tag",
description: "Manages the tag of players",
options: [
{
name: "player",
aliases: ["p"],
description: "The player to have their tags managed",
type: CommandTypes.Player,
required: true,
subcommands: [
{
name: "add",
description: "Adds tags to the player",
options: [
{
name: "tag",
aliases: ["t"],
description: "The tag to be added",
type: CommandTypes.String, // This is not required as "type" is set to String by default,
required: true,
},
],
},
{
name: "remove",
description: "Removes tags from the player",
options: [
{
name: "tag",
aliases: ["t"],
description: "The tag to be added",
type: CommandTypes.String,
required: true,
},
],
},
{
name: "list",
description: "Shows the tags of the player",
},
],
},
],
callback: (interaction) => {
// Retrieve the subcommand and options entered by the player
const subcommand = interaction.options.getSubcommand(2);
const player = interaction.options.getPlayerOption("player");
const tag = interaction.options.getStringOption("tag");
// Check what subcommand the player entered
switch (subcommand) {
case "add":
const added = player.addTag(tag);
if (added) interaction.reply(`Added the tag "${tag}" to ${player.name}`);
break;
case "remove":
const removed = player.removeTag(tag);
if (removed) interaction.reply(`Removed the tag "${tag}" from ${player.name}`);
break;
case "list":
const tags = player.getTags();
interaction.reply(tags.length ? `${player.name}'s Tags:\n${tags.map((tag) => `- ${tag}`).join("\n")}` : "No tags found");
break;
}
},
})
);In the command example above, the command can be executed this way:
{prefix}{command} {option}: {value} {subcommand} {option}: {value}
For example: -tag player: Ylon add tag: "test-tag" -tag p: Ylon list-tag p: "Player Name" remove t: "Test Tag"
Database System
Yl-Module includes a database system which utilizes world dynamic properties in order to store data within the world. There is a limit of 10,000 dynamic properties that can be defined which limits the data that can be stored. With this database system, 10 string dynamic properties are defined for the database in order to increase the character limit of a property, which is 4,294,967,295 by 10 times.
To create a database, the Database class must be instantiated.
Database
constructor(tableName: string, model: Model | ModelOptions): Database
example-database.js
import { Database, DataTypes, events, type } from "yl-module";
// Create a database
const Stats = new Database("Stats", {
name: DataTypes.String,
deaths: {
primary: true, // Sets a primary value
type: DataTypes.Number,
},
});
// Listen on the death event of entities
events.on("EntityDie", (data) => {
// Check if the entity that died is a player
if (type.isPlayer(data.deadEntity)) {
// Fetch the data of the player, if not found, create one
const { data: stat } = Stats.findOrCreate({ name: data.deadEntity.name });
// Increment the "deaths" property of the stat
// NOTE: 1 is the default increment amount of the method
stat.increment("deaths");
}
});In this example, a Database is created with a table name and a model. The tableName is the identifier of the database that is generally used for retrieving the value of dynamic properties, which is the main reason databases must not have similar names. Although that is the case, table names are case-sensitive; therefore, it allows users to create databases with table names that have the same characters but different cases. The model is the structure of the data that is either written, erased, modified, or retrieved. The model of the database is the ideal shape of the data, hence why the data passed is reshaped and other properties that are not within the model are excluded. A model can be a Model instance or a ModelOptions object.
Customized Events
Events within Yl-Module are customized, and Minecraft events within this module are encapsulated for a much more customized experience. The built-in events ofYl-Module can be listened to and unlistened from with the events object, which is an instance of the EventEmitter class. Creation of custom events is also possible with either the EventEmitter class or the Emitter class. The EventEmitter contains the built-in events, such as BeforeChat, EntityDie, PlayerJoin, etc., which are Yl-Module wrapped Minecraft events, as well as custom events that are not originally within the @minecraft/server module, such as Message and more.
Listening to built-in events can be done like this:
import { events } from "yl-module";
// Listen to the Message event
events.on("Message", (data) => {
data.sender.sendMessage(`You said: "${data.message}"`);
});Unlistening is also possible by fetching the reference of the callback function passed and calling events.off:
import { events } from "yl-module";
// Store the reference of the function passed
// events.on returns the listener function
const tick = events.on("Tick", (data) => {
console.log(`currentTick: ${data.currentTick}`);
events.off("Tick", tick);
});Installation
Yl-Module is installed with Node Package Manager (npm) by typing npm i yl-module in the terminal, which means Node.js must be installed for the npm CLI to be accessible.
# To install Yl-Module
npm i yl-moduleAfter installing Yl-Module, you can initialize the current working directory as the script pack to be used by running npx yl-module init, doing so will initialize the directory as a pack by adding the manifest.json and the src folder. The command also adds the scripts field inside the package.json for production.
NOTE: Executing
npx yl-module initwill not overwrite the existingmanifest.jsonfile andsrcfolder, and will, by default, generate a javascript file (index.js) insidesrcthat is used as the entry file in themanifest.json.
# To initialize the current working directory
npx yl-module initThe build script can then be ran once done editing the contents of the src folder. Running the script will compile all of the javascript files inside the source folder to the scripts folder, as well as the built Yl-Module which will be inside yl_modules/yl-module.
# To compile the source folder and build the module
npm run build