This document explains how TR Tier Tagger fetches and processes player tier data from the backend API.
Base URL: https://loratech.dev/api
The mod uses Java's built-in HttpClient to make asynchronous HTTP requests to the API.
Endpoint: GET /overall-ranking
Full URL: https://loratech.dev/api/overall-ranking
Description: Fetches all players and their tier rankings across all game modes (kits).
Endpoint: GET /users/profiles/minecraft/{username}
Full URL: https://api.mojang.com/users/profiles/minecraft/{username}
Description: Fetches player UUID from Mojang API for skin loading.
Response Format:
{
"name": "PlayerName",
"id": "069a79f444e94726a5befca90e38aaf5"
}The id field is the UUID without dashes, which is then formatted to standard UUID format.
Endpoint: GET /body/{uuid}/right
Full URL: https://mc-heads.net/body/{uuid}/right
Description: Fetches player skin render (full body, right-facing view) as PNG image.
The API returns a JSON array of player objects:
[
{
"name": "PlayerName",
"totalPoints": 350,
"kitTiers": {
"sword": "HT1",
"pot": "LT2",
"axe": "HT3",
"uhc": "LT1"
},
"region": "TR",
"position": 5,
"title": {
"name": "Combat Master",
"points": 250
}
},
{
"name": "AnotherPlayer",
"totalPoints": 120,
"kitTiers": {
"sword": "LT3",
"gapple": "HT4"
},
"region": "EU",
"position": 42,
"title": {
"name": "Combat Ace",
"points": 100
}
}
]| Field | Type | Description |
|---|---|---|
name |
String | Player's Minecraft username |
totalPoints |
Integer | Total points earned across all kits |
kitTiers |
Object | Map of kit IDs to tier strings (e.g., "HT1", "LT2") |
region |
String | Player's region code (TR, EU, NA, AS, etc.) |
position |
Integer | Overall ranking position |
title |
Object | Player's title information |
title.name |
String | Title name (e.g., "Combat Master") |
title.points |
Integer | Points required for this title |
Tier strings follow the format: [H/L]T[1-5]
- First character:
H(High) orL(Low) - Second character: Always
T(Tier) - Third character: Tier number (1-5, where 1 is best)
Examples:
HT1= High Tier 1 (best possible rank)LT1= Low Tier 1HT2= High Tier 2LT5= Low Tier 5 (lowest rank)
When the mod starts, it calls TRTierCache.init() which:
- Sends GET request to
/overall-ranking - Validates HTTP 200 response
- Parses JSON array into
List<TRTierPlayer>objects - Stores players in a concurrent hash map (indexed by lowercase username)
- Extracts all unique kit IDs from player data
- Creates
GameModeobjects for each kit
The mod uses several model classes to represent data:
record TRTierPlayer(
String name,
int totalPoints,
Map<String, String> kitTiers, // kitId -> tierString (e.g., "HT1")
String region,
int position,
TitleInfo title
)record Ranking(
int tier, // 1-5 (extracted from "HT1" -> 1)
int pos, // 0=High, 1=Low (extracted from "HT1" -> 0)
Integer peakTier,
Integer peakPos,
long attained,
boolean retired
)The mod parses tier strings like "HT1" into structured data:
// "HT1" becomes:
// tier = 1 (from "T1")
// pos = 0 (from "H", where H=0, L=1)
// "LT3" becomes:
// tier = 3 (from "T3")
// pos = 1 (from "L")The mod recognizes these kit IDs and displays them with custom icons:
| Kit ID | Display Name | Icon |
|---|---|---|
sword |
Sword | ⚔️ |
pot |
Pot | 🧪 |
axe |
Axe | 🪓 |
uhc |
UHC | ❤️ |
mace |
Mace | 🔨 |
nethpot |
Neth Pot | 🔥 |
gapple |
Gapple | 🍎 |
crystal |
Crystal | 💎 |
smp |
SMP | 🌍 |
diasmp |
Dia SMP | 💠 |
Players are color-coded by region:
| Region | Color (Hex) | Description |
|---|---|---|
| TR | #ff0000 |
Turkey (Red) |
| EU | #6aff6e |
Europe (Green) |
| NA | #ff6a6e |
North America (Pink) |
| AS | #c27ba0 |
Asia (Purple) |
| SA | #ff9900 |
South America (Orange) |
| AU | #f6b26b |
Australia (Tan) |
| ME | #ffd966 |
Middle East (Yellow) |
| AF | #674ea7 |
Africa (Dark Purple) |
Players receive titles based on total points:
| Points | Title | Color |
|---|---|---|
| 400+ | Combat Grandmaster | Gold |
| 250+ | Combat Master | Orange |
| 100+ | Combat Ace | Pink |
| 50+ | Combat Specialist | Purple |
| 20+ | Combat Cadet | Blue |
| 10+ | Combat Novice | Light Blue |
| 1+ | Rookie | Gray |
| 0 | Unranked | White |
The mod maintains several caches:
-
Players by Name:
Map<String, TRTierPlayer>- Key: Lowercase username
- Value: Full player data
-
Player Rankings by UUID:
Map<UUID, Map<String, Ranking>>- Key: Player UUID
- Value: Map of kit IDs to rankings
-
Game Modes:
List<GameMode>- All available kits/game modes
-
UUID Cache:
Map<String, String>(in UUIDFetcher)- Key: Lowercase username
- Value: Formatted UUID string
- Prevents repeated Mojang API calls
-
Skin Texture Cache:
Map<String, Identifier>(in SkinTextureLoader)- Key: Lowercase UUID
- Value: Minecraft texture identifier
- Prevents re-downloading skin images
- Initialization: On mod startup
- Refresh: Can be triggered manually (not automatic)
- Lookup: O(1) username lookups via hash map
- Thread-Safe: Uses
ConcurrentHashMapfor concurrent access
The mod handles various error scenarios:
- HTTP Errors: Logs warning if status code != 200
- Invalid JSON: Validates response starts with
[ - Empty Response: Checks for null/empty body
- Network Failures: Catches exceptions and logs errors
- Missing Data: Returns empty optionals for unknown players
When viewing the player list (Tab menu):
- Mod gets player's username
- Looks up player in cache by name
- Retrieves tier for currently selected game mode
- Displays tier prefix before username (e.g., "HT1 | PlayerName")
Players can search for specific users:
- Enter username in search screen
- Mod looks up player in local cache
- Displays all tiers, region, points, and title
- Shows tier icons and colors
Users can configure:
- API URL: Custom API endpoint (default:
https://loratech.dev/api) - Game Mode: Which kit to display in player list
- Show Retired: Whether to show retired tiers
- Tier Colors: Custom colors for each tier level
- Show Icons: Toggle kit icons on/off
-
Mod Starts
TRTier.init() → TRTierCache.init() → fetchAllPlayers() -
API Request
GET https://loratech.dev/api/overall-ranking -
Response Received
[{"name": "Kynux", "totalPoints": 350, "kitTiers": {"sword": "HT1"}, ...}] -
Data Parsed
TRTierPlayer(name="Kynux", totalPoints=350, kitTiers={sword=HT1}) -
Stored in Cache
PLAYERS_BY_NAME.put("kynux", playerData) -
Player Joins Server
getPlayerByName("Kynux") → Returns cached data -
Display in Tab List
"HT1 | Kynux" (with colored tier and icon)
-
User Opens Player Info Screen
searchPlayer("Kynux") called -
Fetch UUID from Mojang
GET https://api.mojang.com/users/profiles/minecraft/Kynux Response: {"name": "Kynux", "id": "069a79f444e94726a5befca90e38aaf5"} -
Format UUID
"069a79f444e94726a5befca90e38aaf5" → "069a79f4-44e9-4726-a5be-fca90e38aaf5" -
Create PlayerInfo with UUID
PlayerInfo(uuid="069a79f4-44e9-4726-a5be-fca90e38aaf5", name="Kynux", ...) -
Load Skin Texture
GET https://mc-heads.net/body/069a79f4-44e9-4726-a5be-fca90e38aaf5/right Response: PNG image data -
Register Texture
NativeImage.read(inputStream) → NativeImageBackedTexture TextureManager.registerTexture(identifier, texture) -
Display in Screen
Render player info with skin texture on left side
- HTTP Client: Java 11+
java.net.http.HttpClient - JSON Parser: Google Gson
- Async Processing:
CompletableFuturefor non-blocking requests - Thread Safety:
ConcurrentHashMapfor concurrent access - Locale Handling: All username lookups use
toLowerCase(Locale.ROOT)
If the API structure changes, update these files:
TRTierCache.java- Main fetching logicTRTierPlayer.java- API response modelPlayerInfo.java- Processed data modelGameMode.java- Kit/mode definitionsUUIDFetcher.java- UUID fetching from MojangSkinTextureLoader.java- Skin texture loading