@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-module
After 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 init
will not overwrite the existingmanifest.json
file andsrc
folder, and will, by default, generate a javascript file (index.js
) insidesrc
that is used as the entry file in themanifest.json
.
# To initialize the current working directory
npx yl-module init
The 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