---
# NOTE: This file is MDX/Markdown and is intended for static site generators too.
id: minecraft:golden_sword
title: BestiaryJS Scripting API
---

Overview

BestiaryJS is a small, dependency-free Java helper shipped with Araxer's Bestiary that exposes read-only player progression data to KubeJS scripts. You can load and call it from kubejs/server_scripts without installing any extra addons.

- Class: com.araxer.araxers_bestiary.integration.kubejs.BestiaryJS
- Load in KubeJS: const BestiaryJS = Java.loadClass('com.araxer.araxers_bestiary.integration.kubejs.BestiaryJS');
- Minecraft: 1.20.1
- KubeJS: v6 (Forge)
- No KubeJS addon dependency is required.

Rank code mapping

- No Rank (empty string "") → 0
- E → 1
- D → 2
- C → 3
- B → 4
- A → 5
- S → 6
- X → 7

Notes about inputs and defaults

- player parameter: All methods accept either a ServerPlayer (from events) or a string identifying the player (exact name or UUID). For convenience in scripts, pass event.player.username or event.player.uuid.
- entityId: A string resource location like minecraft:zombie or modid:my_mob.
- If inputs are invalid or the player/entity can’t be resolved, methods return safe defaults:
  - rankCode → 0
  - meets → false
  - rank/rankName → "" (No Rank)
  - isObserved/isDiscovered → false
- Threshold validation: meets(...) requires a letter in E, D, C, B, A, S, X. The empty rank "" never meets any threshold.
- Internals: BestiaryJS queries a Forge capability (IBestiaryProgress) attached to players; if not available, it falls back to the global progression store. There is no data duplication.

API reference

Each method has two overloads: one that takes a ServerPlayer and one that takes a player identifier (name or UUID as String). Signatures are shown in KubeJS-friendly terms below.

1) rankCode(player, entityId) → int
- Overloads:
  - rankCode(ServerPlayer player, String entityId)
  - rankCode(String playerNameOrUuid, String entityId)
- Returns the numeric rank code 0..7 using the mapping above.
- Defaults to 0 for unknown player/entity or if the rank is empty.

2) rank(player, entityId) → string
- Overloads:
  - rank(ServerPlayer player, String entityId)
  - rank(String playerNameOrUuid, String entityId)
- Returns the letter rank: "" | E | D | C | B | A | S | X.
- "" means No Rank (undiscovered).

3) rankName(player, entityId) → string
- Overloads:
  - rankName(ServerPlayer player, String entityId)
  - rankName(String playerNameOrUuid, String entityId)
- Alias of rank(...). Provided for compatibility with some examples.

4) meets(player, entityId, threshold) → boolean
- Overloads:
  - meets(ServerPlayer player, String entityId, String threshold)
  - meets(String playerNameOrUuid, String entityId, String threshold)
- Returns true if the player’s rank for the entity meets or exceeds threshold.
- threshold must be one of: E, D, C, B, A, S, X. "" never meets.

5) isObserved(player, entityId) → boolean
- Overloads:
  - isObserved(ServerPlayer player, String entityId)
  - isObserved(String playerNameOrUuid, String entityId)
- Returns true if the entity is marked as observed (e.g., spyglass) for that player.

6) isDiscovered(player, entityId) → boolean
- Overloads:
  - isDiscovered(ServerPlayer player, String entityId)
  - isDiscovered(String playerNameOrUuid, String entityId)
- Returns true if the entity is marked as newly discovered for that player. Note: this flag can clear after viewing even if the player still has a non-empty rank.

KubeJS usage examples (v6, MC 1.20.1)

Load and use in server scripts

```js
// kubejs/server_scripts/bestiary_examples.js
const BestiaryJS = Java.loadClass('com.araxer.araxers_bestiary.integration.kubejs.BestiaryJS');

PlayerEvents.loggedIn(event => {
  const p = event.player;
  // Numeric rank code for zombie
  const code = BestiaryJS.rankCode(p.username, 'minecraft:zombie'); // 0..7
  p.tell('Your zombie rank code: ' + code);

  // Check for S on blaze
  if (BestiaryJS.meets(p.username, 'minecraft:blaze', 'S')) {
    p.tell('You have S on blaze!');
  }

  // Letter rank and flags
  const r = BestiaryJS.rank(p.username, 'minecraft:warden'); // '', E..X
  const seen = BestiaryJS.isObserved(p.username, 'minecraft:warden');
  const disc = BestiaryJS.isDiscovered(p.username, 'minecraft:warden');
  p.tell(`Warden rank: ${r}, observed: ${seen}, discovered: ${disc}`);
});
```

React to rank changes (no ForgeEvents global required)

Use the KubeJS-friendly helper on the event class to subscribe directly to the Forge bus.

```js
const RankEvent = Java.loadClass('com.araxer.araxers_bestiary.api.BestiaryRankChangedEvent');

RankEvent.rankChanged(event => {
  // Helper getters: getEntityId(), getPlayerName(), getPlayerUUID(), getOldRankCode(), getNewRankCode()
  if (event.getEntityId() === 'minecraft:zombie' && event.getNewRank() === 'S') {
    event.getPlayer().tell('You reached S on zombie!');
  }
});
```

Tips and behavior details

- Player identifier: When using the String overloads, BestiaryJS tries UUID first, then exact name. If the player is offline, methods will return safe defaults.
- Performance: Methods are lightweight. For bulk checks across many entities per tick, consider caching or event-driven updates.
- Validation: meets(...) silently returns false for invalid thresholds; check your input when debugging.
- Interop: These helpers mirror the underlying capability API (IBestiaryProgress). Java mods can use that capability directly without KubeJS.

Related docs

- Quests and KubeJS Integration: integration:quests-and-kubejs
- FTB Quests Integration (No Advancements): integration:ftb-quests
- Rank utilities (Java): src/main/java/com/araxer/araxers_bestiary/data/RankUtils.java
