# 🛠️ Simplified Mojang API

> [!WARNING]
> ⚠️ **WORK IN PROGRESS!** ⚠️
> This repository is constantly evolving and undergoing active updates, so some features or simplified methods may be missing or not yet implemented. Please keep this in mind when using it!

A simple tool that makes it easier to use the Mojang scripting API for Minecraft Bedrock, by providing pre-built and simplified classes.

## What is this?

It's an informal or professional repository designed to simplify the logic of the native `@minecraft/server` module by integrating various pre-built classes and methods to save time and reduce code, as well as tools I've customized myself for use in any add-on.

## Install:

Just run this in your terminal:

```bash
# In case of errors, use --legacy-peer-deps
npm install simplified-mojang-api@latest
```

or

```bash
pnpm install simplified-mojang-api@latest
```

> (Make sure you also have the base @minecraft/server stuff installed!)

## Build Setup:

If you are new to TypeScript and Minecraft Add-on development, don't panic! Minecraft only reads `.js` files, so we need to "compile" or "bundle" our `.ts` files into a single JavaScript file. We use `esbuild` for this because it's incredibly fast.

Here is the step-by-step guide to setting up your compiler:

### 1. Install the Bundler

First, you need to install `esbuild` as a development dependency in your project. Run this in your terminal:

```bash
npm install --save-dev esbuild
```

### 2. Prepare your Folder Structure

Make sure your behavior pack looks something like this:

```text
📦 behaviors/YOUR_ADDON/
 ┣ 📂 scripts/      (This will be auto-generated by the compiler)
 ┣ 📂 src/
 ┃ ┗ 📜 main.ts     (You write your TypeScript code here)
 ┗ 📜 manifest.json
```

### 3. Update your `package.json`

Open your `package.json` file and replace or add the `"scripts"` section with these commands. You will need to replace `YOUR_ADDON` with the actual folder name of your behavior pack:

```json
  "scripts": {
    "copy:api-assets": "node -e \"const fs = require('fs'); const src = 'node_modules/simplified-mojang-api/structures'; if (fs.existsSync(src)) fs.cpSync(src, 'behaviors/YOUR_ADDON/structures', { recursive: true, force: false });\"",
    "compile": "npm run copy:api-assets && esbuild behaviors/YOUR_ADDON/src/main.ts --bundle --format=esm --outfile=behaviors/YOUR_ADDON/scripts/main.js --target=es2020 --external:@minecraft/server --external:@minecraft/server-ui --external:@minecraft/server-gametest --external:@minecraft/server-graphics --external:@minecraft/server-net --external:@minecraft/debug-utilities --external:@minecraft/gameplay-utilities --sourcemap",
    "watch": "npm run compile -- --watch"
  }
```

### 4. Run

Now you are ready to compile! Open your terminal and use one of these commands:

- **To compile once:** (Do this before publishing your add-on)

```bash
npm run compile
```

- **To auto-compile (Recommended):** (Run this while you are coding. It will stay open and automatically re-compile every time you save a file!)

```bash
npm run watch
```

## Available Modules

The API is split up into several handy modules to fit whatever your development workflow needs. Here is what's currently available out of the box:

> [!NOTE]
> The wrapped `@minecraft/...` modules might not have _every_ single vanilla event fully mapped out just yet. I'll be adding the rest and keeping things updated to make your dev experience as smooth as possible.

```ts
import {
    afterEventsSimplified,
    beforeEventsSimplified,
    customEventsManager,
    debugToolsSimplified,
    fakePlysSimplified,
    worldToolsSimplified,
} from "simplified-mojang-api";
```

Each module comes packed with different methods for your daily coding routine. Here's a quick rundown of what they do:

- **`afterEventsSimplified`**: Wraps the main `world.afterEvents` methods. These fire off right _after_ an action has already happened. Perfect for reading data or triggering logic after the fact.
- **`beforeEventsSimplified`**: Wraps the main `world.beforeEvents` methods. These trigger _right before_ the actual event takes place in the game. Super handy if you need to cancel an event entirely or tweak things before they go through.
- **`customEventsManager`**: Packed with custom-built tools designed to streamline your workflow, cut down on boilerplate code, and give you robust tools to handle pretty much any scenario.
- **`debugToolsSimplified`**: Custom and simplified wrappers for the `debug-utilities` module to make visual debugging a lot easier for developers.
- **`fakePlysSimplified`**: Clever wrappers for the `server-gametest` module to make spawning and managing simulated entities/players a breeze. Mostly focused on helping you test multiplayer features solo with fake players.
- **`worldToolsSimplified`**: Your go-to toolbox for `server.world` and `server.system`. It brings cleaner shortcuts and universal tools for everyday tasks, making your coding loop way faster and straightforward.

## API Examples:

### Fast Offhand Items

> Make items jump to the offhand with a single click.

```ts
import { customEventsManager } from "simplified-mojang-api";

// Any item with these words in its ID becomes a fast-equip item
customEventsManager.fastItemsSystem(["totem", "shield", "arrow"]);
```

### Visual Debugging (Hitboxes)

> Easily show visual hitboxes for all nearby entities using the debug module. Great for testing custom mob sizes or attack ranges!

```ts
import { debugToolsSimplified } from "simplified-mojang-api";

// Shows hitboxes to the specific player within a 50 block radius
debugToolsSimplified.showHitboxes(player, 50);

// Turn them off when you're done testing
// debugToolsSimplified.stopHitboxes();
```

### Fake Player Spawner

> Instantly spawn a simulated player into the world using the gametest API. Perfect for testing multiplayer mechanics solo.

```ts
import * as mc from "@minecraft/server";
import { fakePlysSimplified } from "simplified-mojang-api";

// Spawns a fake player named "Dummy" in Survival mode
fakePlysSimplified.createFakePly("Dummy", mc.GameMode.Survival);
```

### Real-Time Timer

> Creates a timer that's saved directly on the player and runs in real-time, no need to mess with scoreboard ticks! Set an initial value and you're good to go—super easy and fast to use.

```ts
import { customEventsManager } from "simplified-mojang-api";

const paramsTimer: CustomTimerParam = {
    sourcePly: player, // The player who gets the timer
    timerId: "ha:timer_unique", // Unique ID for the timer, just in case you run more than one
    initialMns: 2, // Starting minutes for the timer, or the minutes to display
    forceRestart: true, // (Optional) Need to update the time? E.g., new minutes or seconds? Set this to true to restart the timer.

    // (Optional) Events triggered every time a second goes by.
    onSecondPass: (ply, timer) => {
        console.log(`A second has passed! The timer now is ${timer}`);
    },
};

// Starts the timer for the player. HEADS UP: this is an under-the-hood timer so it's invisible by default. To show it on a UI, use events like onSecondPass.
customEventsManager.startTimerLocal(paramsTimer);
```

## Contributing

Found a bug or want to wrap a new Mojang method? PRs are welcome!

> Author: HaJuegos
> License: MIT
