Documentation Index
Fetch the complete documentation index at: https://mintlify.com/developer51709/Noxie/llms.txt
Use this file to discover all available pages before exploring further.
Vibe creatures are the heart of Noxie’s collect-and-hunt loop. There are 36 of them in total, each carrying a distinct personality expressed through its mood, vibe type, and flavor description. When a user runs /hunt, the bot rolls a rarity tier and then picks a random creature from that tier’s pool. Every result is rendered inside a Discord Components V2 container — creature artwork at the top, stats in the middle, and a mood banner at the bottom — so each pull feels like opening a card pack.
Rarity System
Six rarity tiers govern how likely each creature is to appear. The weights are intentionally steep at the top end: mythic creatures account for just 1 in 100 rolls on average.
| Rarity | Symbol | Drop Weight | Examples |
|---|
| Common | ◽ | 45% | Gloomfox, Sparkitty, Mossling, Blobette |
| Uncommon | 🟩 | 28% | Driftling, Neonmoth, Plaguerat, Echogolem |
| Rare | 🔷 | 15% | Tidewyrm, Lunarfawn, Emberstag, Hazebird |
| Epic | 🟣 | 8% | Prismhawk, Nullbear, Ashphoenix, Bloomwitch |
| Legendary | ⭐ | 3% | Cosmoscat, Chronowolf, Glitchsprite |
| Mythic | 🌌 | 1% | Voidmatriarch, Solarlion, Nightweaver |
Weights are read from the rarity_weights map in vibe_creatures/data.json and passed directly to random.choices(), so changing the weights in that file is all that is required to retune drop rates.
Creature Properties
Every entry in the creatures array of data.json uses the following fields:
| Property | Type | Description |
|---|
id | string | Unique identifier used as the key in inventory storage (e.g. "gloomfox") |
name | string | Display name shown in the hunt card header |
emoji | string | Discord emoji that precedes the name in all containers |
description | string | Flavor text rendered below the name in the hunt card |
rarity | string | One of the six rarity tier strings (lowercase) |
mood | string | One of melancholy, chaotic, cozy, neutral, or sarcastic |
vibe | string | Vibe type label; rendered uppercased in the hunt card as 〔 VIBE 〕 |
power | integer | Numeric power value displayed with comma formatting in the hunt card |
art_file | string | Filename of the creature’s art image inside vibe_creatures/ (optional) |
A minimal data entry looks like this:
{
"id": "gloomfox",
"name": "Gloomfox",
"emoji": "🦊",
"description": "Haunts rainy forests and steals small joys.",
"rarity": "common",
"mood": "melancholy",
"vibe": "shadow",
"power": 120,
"art_file": "gloomfox.png"
}
Creature Moods
Each creature carries one of five mood values. A creature’s mood does two things: it selects the personality line tone used in the hunt card, and it controls which mood banner appears at the bottom of the container. If a creature’s mood has a dedicated banner, that banner overrides the rarity-based default.
| Mood | Mood Emoji | Banner Triggered |
|---|
melancholy | 🌧️ | melancholy.jpeg |
chaotic | ⚡ | chaotic.jpeg |
cozy | 🌿 | cozy.jpeg |
neutral | 🫧 | neutral.jpeg |
sarcastic | 🌑 | sarcastic.jpeg |
The hunt flow resolves the final banner with this priority logic (from cogs/hunt.py):
banner_path = face_manager.get_face_for_rarity(rarity)
creature_mood_banner = face_manager.get_face_for_creature_mood(creature.get("mood", "neutral"))
final_banner = creature_mood_banner or banner_path
The creature’s own mood banner always wins. Only if no mood-specific banner exists does the rarity banner take over.
Hunt Roll Mechanics
The hunt pipeline has three distinct rolls:
1. Roll rarity — roll_rarity()
def roll_rarity() -> str:
rarities = list(RARITY_WEIGHTS.keys())
weights = list(RARITY_WEIGHTS.values())
return random.choices(rarities, weights=weights, k=1)[0]
Rarity weights are loaded once at cog startup from vibe_creatures/data.json into the module-level RARITY_WEIGHTS dict.
2. Roll creature — roll_creature(rarity)
def roll_creature(rarity: str) -> dict:
pool = [c for c in CREATURES if c["rarity"] == rarity]
return random.choice(pool) if pool else random.choice(CREATURES)
All creatures of the rolled rarity are equal-chance within their tier. If the pool is somehow empty (e.g. a rarity key in the weights has no matching creatures), the bot falls back to any creature rather than erroring.
3. Roll rewards — roll_rewards(rarity)
Rewards are computed by multiplying a base range from config.json by a per-rarity multiplier. Glow Shards and Vibe Coins each have independent multipliers:
| Rarity | Glow Shards Mult. | Vibe Coins Mult. | Approx. GS Range | Approx. VC Range |
|---|
| Common | 1.0× | 1.0× | 5–25 | 1–5 |
| Uncommon | 2.0× | 1.5× | 10–50 | 2–8 |
| Rare | 4.0× | 3.0× | 20–100 | 4–15 |
| Epic | 8.0× | 6.0× | 40–200 | 8–30 |
| Legendary | 20.0× | 15.0× | 100–500 | 20–75 |
| Mythic | 50.0× | 40.0× | 250–1250 | 50–200 |
The “Approx. Range” columns assume the default base ranges of [5, 25] for Glow Shards and [1, 5] for Vibe Coins from config.json. Editing those base values scales all rarities proportionally.
The luck value attached to each rarity roll is used downstream by the personality engine to bias tone selection:
RARITY_LUCK = {
"common": 0.3, "uncommon": 0.5, "rare": 0.65,
"epic": 0.8, "legendary": 0.93, "mythic": 1.0,
}
Data File
All creature and weight data lives in a single JSON file:
Top-level structure:
{
"creatures": [
{
"id": "...",
"name": "...",
"emoji": "...",
"description": "...",
"rarity": "...",
"mood": "...",
"vibe": "...",
"power": 0,
"art_file": "..."
}
],
"rarity_weights": {
"common": 45,
"uncommon": 28,
"rare": 15,
"epic": 8,
"legendary": 3,
"mythic": 1
}
}
The file is loaded once at bot startup by utils/helpers.py::load_creatures() and cached in module-level constants inside cogs/hunt.py. Restart the bot after editing the file for changes to take effect.