Documentation
¶
Overview ¶
Package fairy provides a high-performance, modular Go library for fetching, parsing, enriching, and calculating combat stats for Zenless Zone Zero (ZZZ) player profiles via the EnkaNetwork API.
The raw response from Enka.Network contains raw Agent, W-Engine, and Drive Disc IDs. Fairy enriches these raw responses by:
- Translating IDs into full localized names for Agents, W-Engines, Drive Discs, Skills, and Mindscapes across 13 languages.
- Constructing complete Enka CDN URLs and inline base64 SVG data URIs for splash arts, avatars, namecards, badges, and stat icons.
- Calculating exact final combat stats according to the in-game formula (accounting for Agent levels, Promotions, Core Skill Enhancements, W-Engine growth curves, Drive Disc substats, and set bonuses).
- Evaluating Unity Rich Text formatting, button icon tags, and dynamic level-scaling formulas.
- Providing Drive Disc substat aggregation, set bonus evaluation, and build quality scoring tools.
- Validating player UID syntax and resolving server regions locally without network calls.
Key Features ¶
- Zero-Allocation Metadata Store: Embedded game data loaded once and shared across all queries with lazy-loaded localization.
- Full Localization: 13 officially supported languages with on-the-fly in-memory enrichment (Enrich, EnrichWithLang, EnrichAgent, EnrichAgentWithLang).
- Accurate Combat Math: Emulates the exact ZZZ stat calculations including base attributes, weapon scaling, and set bonuses.
- UI-Ready Stats Breakdown: Pre-calculated base, added, and total values formatted for frontends (UIStats, FormattedStatBreakdown).
- Rich Text Parsers: Convert game descriptions to clean HTML, Plain Text, or Markdown (Skill.FormatHTML, Skill.FormatPlainText, Skill.FormatMarkdown, SetEffect.FormatHTML).
- UID Validation & Region Discovery: Instant offline syntax verification (IsValidUID) and server region lookup (RegionFromUID).
- Cache Governance: Built-in upstream API cache TTL inspection via Profile.CacheTTL.
- Production-Grade Client: Supports HTTP timeouts, automatic exponential retries, Redis/in-memory caching, and custom User-Agents via zzz.Options.
Architecture & Data Flow ¶
The library separates network fetching, metadata mapping, and combat calculation:
Full Profile Flow:
[EnkaNetwork API]
│
▼ (HTTP Request via internal API client)
[zzz.Profile (Raw Upstream Model)]
│
▼ (Enrich / mapper using embedded MetadataStore)
[fairy.Profile (Enriched Domain Model)]
├── Account Info (UID, Nickname, InterknotLevel, Region, Title, Avatar, Badges)
└── Showcase Agents (max 6)
├── Agent Meta (Attribute, Specialty, Rarity, Skin, SplashArt, HighlightProps, RecommendedSubStats)
├── Skills & Groups (Basic, Dodge, Special, Chain, Assist, Passives)
├── Mindscape Cinema (Ranks 1–6 with unlocked status)
├── Potential Vision (Active nodes & descriptions)
├── Equipped W-Engine (MainStat, SecondaryStat, Modification)
├── Drive Discs (Slots 1–6 with roll counts, active 2-piece & 4-piece Set Bonuses)
└── Combat Stats Pipeline
├── BaseStats (Agent + W-Engine Base ATK)
├── Stats (Final calculated combat stats)
└── UIStats (Pre-formatted Base + Added = Total breakdowns)
Standalone Agent Flow:
[zzz.AvatarData (Raw Upstream Agent)]
│
▼ (EnrichAgent / mapper using embedded MetadataStore)
[fairy.Agent (Enriched Domain Model)]
Core Operations ¶
Fairy provides core operations for working with player profiles and individual agents:
- GetProfile: Fetch and enrich a player profile using the client's default language.
- GetProfileWithLang: Fetch and enrich a player profile with a specific language override for the request.
- GetRawProfile: Fetch the raw upstream API response (zzz.Profile) without enrichment.
- Enrich: Transform a raw zzz.Profile into an enriched Profile using the default language (zero additional network requests).
- EnrichWithLang: Transform a raw zzz.Profile into an enriched Profile in the specified language (zero additional network requests).
- EnrichAgent: Transform a raw zzz.AvatarData into an enriched Agent using the default language (zero additional network requests).
- EnrichAgentWithLang: Transform a raw zzz.AvatarData into an enriched Agent in the specified language (zero additional network requests).
- AgentHighlightProps: Retrieve the recommended combat property IDs for an agent profile by numeric ID.
- AllAgentHighlightProps: Retrieve a map of all agents' recommended profile combat property IDs indexed by agent ID.
- AgentRecommendedSubStats: Retrieve the recommended Drive Disc sub-stat property IDs for an agent by numeric ID.
- AllAgentRecommendedSubStats: Retrieve a map of all agents' recommended Drive Disc sub-stats indexed by agent ID.
Each operation is available as a global top-level function (using a shared thread-safe default client) and as a method on Client.
Quick Start ¶
For standard usage, use the global top-level functions:
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
profile, err := fairy.GetProfile(ctx, "1504687050")
if err != nil {
log.Fatalf("Failed to fetch profile: %v", err)
}
fmt.Printf("Player: %s (Inter-Knot Lv.%d, Server: %s, Cache TTL: %v)\n",
profile.Nickname, profile.InterknotLevel, profile.Region, profile.CacheTTL())
for _, agent := range profile.Agents {
fmt.Printf("• %-16s Lv.%-2d [%s / %s]\n",
agent.Name, agent.Level, agent.AttributeName, agent.SpecialtyName)
}
UID Validation & Server Region Detection ¶
Validate player UIDs and determine their game server region before making network calls:
const uid = "1504687050"
if !fairy.IsValidUID(uid) {
log.Fatalf("Invalid player UID format: %s", uid)
}
if region, ok := fairy.RegionFromUID(uid); ok {
fmt.Printf("Server region: %s\n", region) // "Europe"
}
Custom Client Configuration ¶
For production services, configure a custom Client with timeouts, retry policies, custom headers, or persistent caching:
client, err := fairy.NewClient(
fairy.WithDefaultLang(fairy.LangJA),
fairy.WithEnkaOptions(zzz.Options{
UserAgent: "MyZZZApp/1.0 (contact@example.com)",
HTTPClient: &http.Client{Timeout: 10 * time.Second},
Retry: &zzz.RetryOptions{
MaxAttempts: 3,
Delay: 1 * time.Second,
},
Cache: myCacheInstance, // Implements zzz.Cache interface
}),
)
if err != nil {
log.Fatalf("Failed to initialize client: %v", err)
}
profile, err := client.GetProfile(context.Background(), "1504687050")
In-Memory Multi-Language Enrichment ¶
If you need to present the same player profile in multiple languages, fetch the raw profile once and enrich it in memory with Enrich or EnrichWithLang without repeating network requests.
raw, err := fairy.GetRawProfile(ctx, "1504687050")
if err != nil {
log.Fatal(err)
}
// In-memory mapping — instant, no extra network overhead
enProfile, _ := fairy.Enrich(raw) // Default English
jaProfile, _ := fairy.EnrichWithLang(raw, fairy.LangJA)
ruProfile, _ := fairy.EnrichWithLang(raw, fairy.LangRU)
Individual agents can also be enriched directly without a full profile:
agentEN, _ := fairy.EnrichAgent(rawAvatar) agentJA, _ := fairy.EnrichAgentWithLang(rawAvatar, fairy.LangJA)
Combat Stat Breakdown & UI Display ¶
Each showcased Agent includes a pre-computed UIStats panel containing formatted breakdowns of base stats vs. added stats (from W-Engines, Drive Discs, and Set Bonuses):
for _, stat := range agent.UIStats.List() {
fmt.Printf("%-22s %8s (Base: %s + Added: %s)\n",
stat.Name, stat.Total, stat.Base, stat.Added)
}
Drive Disc & Set Bonus Analysis ¶
Fairy provides helper methods on DriveDiscs and Agent to inspect, evaluate, and score equipped Drive Discs:
// 1. Check active Drive Disc set bonuses (2-piece and 4-piece thresholds)
if agent.DriveDiscs.Has4Piece(fairy.SetPolarMetal) {
fmt.Println("Polar Metal 4-piece set bonus active!")
}
// 2. Group and sum substats across all 6 disc slots
totals := agent.DriveDiscs.SubStatTotals()
for _, sub := range totals {
fmt.Printf("%-20s +%-6s (%d rolls)\n", sub.Name, sub.DisplayValue(), sub.Rolls)
}
// 3. Detect recommended / highlighted sub-stats (matching in-game yellow highlights)
for _, disc := range agent.DriveDiscs.Slots {
for _, sub := range disc.SubStats {
if agent.IsRecommendedSubStat(sub.PropertyID) {
fmt.Printf("★ Highlighted: %s +%s\n", sub.Name, sub.DisplayValue())
}
}
}
// 4. Count effective substat rolls:
// Automatically evaluated against the agent's recommended sub-stats (RecommendedSubStats):
usefulRolls := agent.CountEffectiveRolls()
fmt.Printf("Recommended Substat Rolls: %d\n", usefulRolls)
// Or evaluated against custom priority stats (e.g. CRIT only):
critRolls := agent.CountEffectiveRolls(fairy.PropCritRate, fairy.PropCritDMG)
fmt.Printf("CRIT Substat Rolls: %d\n", critRolls)
In-Game Recommendation Data ¶
Recommended Drive Disc sub-stats accessed via AgentRecommendedSubStats, AllAgentRecommendedSubStats, and Agent.RecommendedSubStats are verified directly against the official Zenless Zone Zero in-game equipment recommendation system ("Recommend" / L3 build guide). They correspond precisely to the yellow highlight badges displayed next to sub-stats on Drive Discs in the in-game equipment UI.
Error Handling ¶
All API errors map to strongly-typed sentinel errors that can be inspected with errors.Is:
profile, err := fairy.GetProfile(ctx, uid)
if err != nil {
switch {
case errors.Is(err, fairy.ErrInvalidUID):
// Player UID format is invalid (must be 10 digits starting with 10, 13, 15, or 17)
case errors.Is(err, fairy.ErrProfileNotFound):
// Profile with specified UID does not exist on game servers
case errors.Is(err, fairy.ErrRateLimit):
// Rate limit reached (HTTP 429) — back off and retry
case errors.Is(err, fairy.ErrMaintenance):
// Upstream API or game servers are under maintenance
case errors.Is(err, fairy.ErrNetwork):
// Network timeout or connectivity issue
case errors.Is(err, fairy.ErrEnrichment):
// In-memory transformation, metadata mapping, or stat calculation failed
default:
// Other unexpected errors
}
}
Supported Languages ¶
Supported game languages are defined by the Language type constants: LangEN (English), LangRU (Russian), LangDE (German), LangES (Spanish), LangFR (French), LangID (Indonesian), LangJA (Japanese), LangKO (Korean), LangPT (Portuguese), LangTH (Thai), LangVI (Vietnamese), LangZHCN (Chinese Simplified), and LangZHTW (Chinese Traditional). Use AllLanguages to retrieve the full list programmatically.
Server Regions ¶
Player server regions are identified by the Region type constants: RegionEU (Europe), RegionNA (America), RegionAsia (Asia), and RegionTWHKMO (TW/HK/MO). Use AllRegions to retrieve the full list, or RegionFromUID to resolve a region from a player's UID.
Combat Attributes, Specialties & Drive Disc Sets ¶
Combat attributes, character classes, and equipment sets are defined by strongly-typed constants:
- Attribute: AttributePhysical, AttributeFire, AttributeIce, AttributeElectric, AttributeEther, and variants (AttributeHonedEdge, AttributeFrost, AttributeAuricInk, AttributeWind, AttributeLumiflux). Use AllAttributes to retrieve all.
- Specialty: SpecialtyAttack, SpecialtyStun, SpecialtyAnomaly, SpecialtySupport, SpecialtyDefense, SpecialtyRupture, and SpecialtyArmorer. Use AllSpecialties to retrieve all.
- Rarity: RarityS, RarityA, and RarityB. Use AllRarities to retrieve all.
- SetID: Drive Disc set identifiers (e.g. SetPolarMetal, SetWoodpeckerElectro, SetBranchBladeSong, etc.). Use AllSetIDs to retrieve all.
Index ¶
- Constants
- Variables
- func AllAgentHighlightProps() map[int][]PropertyID
- func AllAgentRecommendedSubStats() map[int][]PropertyID
- func GetRawProfile(ctx context.Context, uid string) (*zzz.Profile, error)
- func IsValidUID(uid string) bool
- type Agent
- type Attribute
- type Avatar
- type Badge
- type Client
- func (c *Client) AgentHighlightProps(agentID int) []PropertyID
- func (c *Client) AgentRecommendedSubStats(agentID int) []PropertyID
- func (c *Client) AllAgentHighlightProps() map[int][]PropertyID
- func (c *Client) AllAgentRecommendedSubStats() map[int][]PropertyID
- func (c *Client) Enrich(raw *zzz.Profile) (*Profile, error)
- func (c *Client) EnrichAgent(raw *zzz.AvatarData) (*Agent, error)
- func (c *Client) EnrichAgentWithLang(raw *zzz.AvatarData, lang Language) (*Agent, error)
- func (c *Client) EnrichWithLang(raw *zzz.Profile, lang Language) (*Profile, error)
- func (c *Client) GetProfile(ctx context.Context, uid string) (*Profile, error)
- func (c *Client) GetProfileWithLang(ctx context.Context, uid string, lang Language) (*Profile, error)
- func (c *Client) GetRawProfile(ctx context.Context, uid string) (*zzz.Profile, error)
- type DriveDisc
- type DriveDiscSetBonus
- type DriveDiscs
- func (d DriveDiscs) BySlot(slot int) *DriveDisc
- func (d DriveDiscs) CountEffectiveRolls(targetProps ...PropertyID) int
- func (d DriveDiscs) Has2Piece(setID SetID) bool
- func (d DriveDiscs) Has4Piece(setID SetID) bool
- func (d DriveDiscs) SetCounts() map[Set]int
- func (d DriveDiscs) SubStatTotals() []StatValue
- type FormattedStatBreakdown
- type FormattedStats
- type Language
- type MindscapeNode
- type Namecard
- type Option
- type Options
- type PotentialVision
- type PotentialVisionNode
- type Profile
- type PropertyID
- type Rarity
- type Region
- type Set
- type SetEffect
- type SetID
- type Skill
- type SkillGroup
- type SkillParam
- type SkillType
- type Skin
- type Specialty
- type StatValue
- type Stats
- type Title
- type UIStats
- type WEngine
Examples ¶
Constants ¶
const ( // EnkaAssetBaseURL is the base HTTPS URL for Enka.Network Zenless Zone Zero CDN UI assets // (such as agent splash arts, icons, badges, and W-Engine textures). EnkaAssetBaseURL = "https://enka.network/ui/zzz/" )
Variables ¶
var ( // ErrInvalidUID is returned when a provided player UID has an invalid format // (e.g. empty, non-numeric characters, length other than 10 digits, or unrecognized server prefix). ErrInvalidUID = api.ErrInvalidUID // ErrProfileNotFound is returned when the requested player profile with specified UID does not exist // or cannot be found by the upstream EnkaNetwork API (HTTP 404). ErrProfileNotFound = api.ErrProfileNotFound // ErrRateLimit is returned when requests exceed the EnkaNetwork API rate limit (HTTP 429 Too Many Requests). // Callers should apply exponential backoff or use a caching layer before retrying. ErrRateLimit = api.ErrRateLimit // ErrMaintenance is returned when the EnkaNetwork API or upstream game servers are undergoing maintenance, // experiencing an outage, or temporarily unavailable (HTTP 500, 502, 503, or 504). ErrMaintenance = api.ErrMaintenance // ErrNetwork is returned when a transport-level network error occurs while communicating with the API // (e.g. DNS resolution failure, connection refused, TLS handshake failure, or context timeout). ErrNetwork = api.ErrNetwork // ErrEnrichment is returned when in-memory transformation, metadata mapping, // or stat calculation fails on raw profile or avatar data. ErrEnrichment = errors.New("failed to enrich profile data") )
Sentinel errors returned by GetProfile, GetProfileWithLang, GetRawProfile, Enrich, EnrichWithLang, EnrichAgent, EnrichAgentWithLang, and *Client methods. Callers should inspect errors using standard errors.Is checks.
Example:
profile, err := fairy.GetProfile(ctx, uid)
if err != nil {
switch {
case errors.Is(err, fairy.ErrInvalidUID):
// Player UID format is invalid (must be 10 digits starting with 10, 13, 15, or 17)
case errors.Is(err, fairy.ErrProfileNotFound):
// Player profile does not exist on game servers
case errors.Is(err, fairy.ErrRateLimit):
// Rate limit exceeded (HTTP 429) — wait before retrying
case errors.Is(err, fairy.ErrMaintenance):
// Upstream API or game servers are under maintenance
case errors.Is(err, fairy.ErrNetwork):
// Network connection reset or request timeout
case errors.Is(err, fairy.ErrEnrichment):
// In-memory data transformation or metadata mapping failed
default:
// Other unexpected error
}
}
Functions ¶
func AllAgentHighlightProps ¶ added in v1.4.0
func AllAgentHighlightProps() map[int][]PropertyID
AllAgentHighlightProps returns a map of all agents' recommended combat property IDs indexed by agent ID, using the shared default client.
Example:
allProps := fairy.AllAgentHighlightProps()
for agentID, props := range allProps {
fmt.Printf("Agent %d: %v\n", agentID, props)
}
func AllAgentRecommendedSubStats ¶ added in v1.4.0
func AllAgentRecommendedSubStats() map[int][]PropertyID
AllAgentRecommendedSubStats returns a map of all known agents to their recommended Drive Disc sub-stats, matching the yellow sub-stat highlights shown in the in-game equipment UI, using the shared default client.
func GetRawProfile ¶
GetRawProfile fetches the un-enriched zzz.Profile directly from the EnkaNetwork API using the shared default client.
Use this function when you only need the raw numeric IDs from the upstream API without metadata enrichment, or when you want to fetch the upstream payload once and enrich it into multiple languages via EnrichWithLang.
The provided context.Context controls the HTTP request lifecycle, cancellation, and timeout. Returns sentinel errors such as ErrInvalidUID, ErrProfileNotFound, ErrRateLimit, ErrMaintenance, or ErrNetwork.
func IsValidUID ¶ added in v1.1.0
IsValidUID reports whether the provided string is a syntactically valid global Zenless Zone Zero UID (10 numeric digits starting with prefix 10, 13, 15, or 17).
Types ¶
type Agent ¶
type Agent struct {
// ID is the internal numeric identifier of the Agent.
ID int `json:"id"`
// Name is the localized display name of the Agent (e.g. "Ellen", "Zhu Yuan", "Miyabi").
Name string `json:"name"`
// Level is the current level of the Agent (1–60).
Level int `json:"level"`
// Promotion is the current Promotion (ascension) phase of the Agent (0–5).
Promotion int `json:"promotion"`
// MindscapeCinema is the unlocked Mindscape Cinema level of the Agent (0–6).
MindscapeCinema int `json:"mindscape_cinema"`
// CoreSkillEnhancement is the Core Skill Enhancement level of the Agent (0–6 / Core A–F).
CoreSkillEnhancement int `json:"core_skill_enhancement"`
// Attribute is the elemental combat damage type of the Agent (e.g. [AttributeIce], [AttributeEther]).
Attribute Attribute `json:"attribute"`
// AttributeName is the localized display name of the Agent's elemental attribute (e.g. "Ice", "Ether").
AttributeName string `json:"attribute_name"`
// Specialty is the combat role of the Agent (e.g. [SpecialtyAttack], [SpecialtyStun]).
Specialty Specialty `json:"specialty"`
// SpecialtyName is the localized display name of the Agent's combat specialty (e.g. "Attack", "Stun").
SpecialtyName string `json:"specialty_name"`
// Rarity is the rarity rank of the Agent ([RarityS] or [RarityA]).
Rarity Rarity `json:"rarity"`
// HighlightProps contains the recommended combat property IDs for this Agent
// displayed on the agent's profile screen (e.g. [PropBaseATK], [PropBaseCritRate], [PropBasePENRatio]).
// It is always initialized to a non-nil slice (empty [] if no recommendations exist).
HighlightProps []PropertyID `json:"highlight_props"`
// RecommendedSubStats contains the recommended Drive Disc sub-stat property IDs for this Agent
// (e.g. [PropCritRate], [PropCritDMG], [PropATKPercent]).
// These values reflect the official in-game Drive Disc recommendation system in Zenless Zone Zero
// (matching the yellow highlight badges displayed on disc sub-stats in the equipment UI).
// Used for Drive Disc sub-stat highlighting and calculating the in-game Active Modifier Count.
// It is always initialized to a non-nil slice (empty [] if no recommendations exist).
RecommendedSubStats []PropertyID `json:"recommended_sub_stats"`
// Skin is the currently equipped cosmetic outfit. May be nil if default appearance is used.
Skin *Skin `json:"skin"`
// SplashArtURL is the absolute HTTPS URL pointing to the Agent's full splash art on the EnkaNetwork CDN.
SplashArtURL string `json:"splash_art_url"`
// Skills is the flat list of all individual combat abilities and passives.
Skills []Skill `json:"skills"`
// SkillGroups contains the Agent's skills categorized into 6 UI groups matching in-game skill tabs.
SkillGroups []SkillGroup `json:"grouped_skills"`
// Mindscapes contains all 6 [MindscapeNode] levels (Cinema 1–6) with their unlocked status.
Mindscapes []MindscapeNode `json:"mindscapes"`
// PotentialVision holds Potential Vision upgrade status and nodes (nil if Agent has no Potential Vision).
PotentialVision *PotentialVision `json:"potential_vision"`
// WEngine is the currently equipped W-Engine. May be nil if no weapon is equipped.
WEngine *WEngine `json:"w_engine"`
// DriveDiscs holds the equipped Drive Discs (slots 1–6) and active set bonuses.
DriveDiscs DriveDiscs `json:"drive_discs"`
// BaseStats contains the Agent's innate combat stats (Agent level growth + W-Engine Base ATK).
BaseStats Stats `json:"base_stats"`
// Stats contains the Agent's final calculated combat stats after applying all gear and buffs.
Stats Stats `json:"stats"`
// UIStats contains pre-formatted combat stat breakdowns (Base + Added = Total) with localized names and icons ready for frontend rendering.
UIStats UIStats `json:"ui_stats"`
}
Agent represents an enriched Agent showcased on a player's Profile. A profile can showcase up to 6 agents. It aggregates combat metadata, equipped gear (WEngine, DriveDisc entries), active set bonuses, and final combat Stats.
func EnrichAgent ¶ added in v1.3.0
func EnrichAgent(raw *zzz.AvatarData) (*Agent, error)
EnrichAgent transforms a raw upstream zzz.AvatarData into an enriched Agent using the default Language (English).
This function operates completely in-memory using the embedded metadata store and makes ZERO network requests. It resolves all agent metadata, progression data, equipped gear (WEngine, DriveDisc entries), active set bonuses, computes scaled combat stats, and formats UI stats. Returns ErrEnrichment if the raw avatar payload is nil or refers to an unknown avatar ID.
Example ¶
ExampleEnrichAgent demonstrates enriching a standalone raw zzz.AvatarData payload directly into an enriched fairy.Agent model using fairy.EnrichAgent and fairy.EnrichAgentWithLang without needing a full profile.
package main
import (
"fmt"
"log"
"github.com/kirinyoku/enkanetwork-go/client/zzz"
"github.com/kirinyoku/fairy"
)
func main() {
rawAvatar := &zzz.AvatarData{
ID: 1011, // Anby Demara
Level: 60,
PromotionLevel: 5,
TalentLevel: 6,
CoreSkillEnhancement: 6,
}
// 1. Enrich into default language (English)
agentEN, err := fairy.EnrichAgent(rawAvatar)
if err != nil {
log.Fatalf("EnrichAgent failed: %v", err)
}
fmt.Printf("%s [%s / %s]\n", agentEN.Name, agentEN.AttributeName, agentEN.SpecialtyName)
// 2. Enrich into Japanese localization
agentJA, err := fairy.EnrichAgentWithLang(rawAvatar, fairy.LangJA)
if err != nil {
log.Fatalf("EnrichAgentWithLang (JA) failed: %v", err)
}
fmt.Printf("%s [%s / %s]\n", agentJA.Name, agentJA.AttributeName, agentJA.SpecialtyName)
}
Output:
func EnrichAgentWithLang ¶ added in v1.3.0
func EnrichAgentWithLang(raw *zzz.AvatarData, lang Language) (*Agent, error)
EnrichAgentWithLang transforms a raw upstream zzz.AvatarData into an enriched Agent in the requested Language.
This function operates completely in-memory using the embedded metadata store and makes ZERO network requests. It is ideal for multi-language applications that fetch player data once and render individual agents dynamically across different languages. Returns ErrEnrichment if the raw avatar payload is nil or refers to an unknown avatar ID.
func (*Agent) CountEffectiveRolls ¶
func (a *Agent) CountEffectiveRolls(customProps ...PropertyID) int
CountEffectiveRolls returns the total number of useful substat upgrade rolls across all equipped Drive Discs (matching the in-game "Active Modifier Count"). If customProps are provided, it evaluates against them via DriveDiscs.CountEffectiveRolls. If no arguments are passed, it evaluates against this Agent's recommended disc sub-stats (Agent.RecommendedSubStats) or falls back to Agent.HighlightProps if no disc sub-stats are configured.
func (*Agent) IsHighlightProp ¶ added in v1.4.0
func (a *Agent) IsHighlightProp(prop PropertyID) bool
IsHighlightProp reports whether the given property matches one of the recommended combat stats for this Agent's profile screen (Base Stats).
func (*Agent) IsRecommendedSubStat ¶ added in v1.4.0
func (a *Agent) IsRecommendedSubStat(prop PropertyID) bool
IsRecommendedSubStat reports whether the given Drive Disc sub-stat property is recommended for this Agent, corresponding to the yellow highlight indicator displayed on Drive Disc sub-stats in the in-game equipment UI. It matches percentage modifiers (ATK%, HP%, DEF%) and flat properties according to the Agent's specific sub-stat recommendations.
type Attribute ¶
type Attribute string
Attribute represents the elemental combat attribute (damage type) of an Agent.
const ( // AttributePhysical represents the Physical damage attribute. AttributePhysical Attribute = "Physical" // AttributeHonedEdge represents the Honed Edge attribute (Physical variant). AttributeHonedEdge Attribute = "HonedEdge" // AttributeFire represents the Fire damage attribute. AttributeFire Attribute = "Fire" // AttributeIce represents the Ice damage attribute. AttributeIce Attribute = "Ice" // AttributeFrost represents the Frost attribute (Ice variant). AttributeFrost Attribute = "Frost" // AttributeElectric represents the Electric damage attribute. AttributeElectric Attribute = "Electric" // AttributeEther represents the Ether damage attribute. AttributeEther Attribute = "Ether" // AttributeAuricInk represents the Auric Ink attribute (Ether variant). AttributeAuricInk Attribute = "AuricInk" // AttributeWind represents the Wind damage attribute. AttributeWind Attribute = "Wind" // AttributeLumiflux represents the Lumiflux damage attribute. AttributeLumiflux Attribute = "Lumiflux" )
Supported elemental combat attributes in Zenless Zone Zero.
func AllAttributes ¶ added in v0.10.0
func AllAttributes() []Attribute
AllAttributes returns a newly allocated slice containing all 10 supported Attribute constants. The returned slice is a defensive copy and can be safely mutated by the caller.
func (Attribute) BaseAttribute ¶ added in v0.6.0
BaseAttribute returns the core elemental attribute that this attribute deals damage as. For example, AttributeAuricInk deals Ether DMG, AttributeHonedEdge deals Physical DMG, and AttributeFrost deals Ice DMG.
func (Attribute) IconURL ¶ added in v0.5.0
IconURL returns a base64-encoded Data URI string ("data:image/svg+xml;base64,...") containing the attribute's SVG icon for direct use in web frontend <img> tags.
type Avatar ¶
type Avatar struct {
// ID is the internal numeric identifier of the avatar asset.
ID int `json:"id"`
// URL is the absolute HTTPS URL pointing to the avatar's image asset on the EnkaNetwork CDN.
URL string `json:"url"`
}
Avatar represents a player's equipped profile avatar (profile picture).
type Badge ¶
type Badge struct {
// ID is the internal numeric identifier of the badge icon.
ID int `json:"id"`
// Title is the localized title/name of the badge achievement.
Title string `json:"title"`
// Value is the progression value or score associated with the badge.
Value int `json:"value"`
// IconURL is the absolute HTTPS URL pointing to the badge's visual icon on the EnkaNetwork CDN.
IconURL string `json:"icon_url"`
}
Badge represents a collectible achievement medal displayed in a player's profile showcase.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client coordinates fetching player profile data from the EnkaNetwork API and enriching it with localized names, CDN asset URLs, and combat stat calculations using an embedded metadata store.
A Client is safe for concurrent use by multiple goroutines.
func NewClient ¶
NewClient creates a new configured Client instance.
If WithDefaultLang is omitted, the client defaults to English (LangEN). Returns an error if the embedded game metadata store fails to load its internal data files.
Example:
client, err := fairy.NewClient(
fairy.WithDefaultLang(fairy.LangJA),
fairy.WithEnkaOptions(zzz.Options{
UserAgent: "MyZZZApp/1.0 (contact@example.com)",
HTTPClient: &http.Client{Timeout: 10 * time.Second},
}),
)
Example ¶
ExampleNewClient demonstrates configuring a custom Client for production backend services with a custom User-Agent, HTTP client timeout, retry policy, caching layer, and default language.
package main
import (
"context"
"fmt"
"log"
"net/http"
"time"
"github.com/kirinyoku/enkanetwork-go/client/zzz"
"github.com/kirinyoku/fairy"
)
func main() {
// Optional: initialize a custom persistent or in-memory cache instance
// redisCache := NewRedisCache(rdb)
client, err := fairy.NewClient(
fairy.WithDefaultLang(fairy.LangJA),
fairy.WithEnkaOptions(zzz.Options{
UserAgent: "MyZZZApp/v1.0.0 (contact@example.com)",
HTTPClient: &http.Client{
Timeout: 10 * time.Second,
},
Retry: &zzz.RetryOptions{
MaxAttempts: 3,
Delay: 1 * time.Second,
},
// Cache: redisCache, // Plug in your cache implementation
}),
)
if err != nil {
log.Fatalf("Failed to initialize fairy client: %v\n", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
profile, err := client.GetProfile(ctx, "1504687050")
if err != nil {
log.Printf("Profile request failed: %v\n", err)
return
}
fmt.Printf("Player: %s\n", profile.Nickname)
for _, agent := range profile.Agents {
fmt.Printf(" • %s Lv.%-2d [%s / %s]\n",
agent.Name, agent.Level, agent.AttributeName, agent.SpecialtyName)
}
}
Output:
func (*Client) AgentHighlightProps ¶ added in v1.4.0
func (c *Client) AgentHighlightProps(agentID int) []PropertyID
AgentHighlightProps returns the recommended combat property IDs (PropertyID) for an Agent by their numeric ID, or nil if the agent is not found. The returned slice is a defensive copy and can be safely mutated by the caller.
func (*Client) AgentRecommendedSubStats ¶ added in v1.4.0
func (c *Client) AgentRecommendedSubStats(agentID int) []PropertyID
AgentRecommendedSubStats returns the recommended Drive Disc sub-stat property IDs (PropertyID) for an Agent by numeric ID. These values correspond directly to the official in-game Drive Disc recommendation system (yellow highlights in equipment UI).
func (*Client) AllAgentHighlightProps ¶ added in v1.4.0
func (c *Client) AllAgentHighlightProps() map[int][]PropertyID
AllAgentHighlightProps returns a map of all agents' recommended combat property IDs indexed by agent ID. This is useful for code generation, static tooling, or caching build recommendation tables.
func (*Client) AllAgentRecommendedSubStats ¶ added in v1.4.0
func (c *Client) AllAgentRecommendedSubStats() map[int][]PropertyID
AllAgentRecommendedSubStats returns a map of all known agents to their recommended Drive Disc sub-stats, matching the in-game equipment UI sub-stat highlights.
func (*Client) Enrich ¶ added in v1.0.0
Enrich transforms a raw upstream zzz.Profile into an enriched Profile using the client's configured default Language.
This method operates entirely in-memory using the client's metadata store and performs ZERO network calls. It resolves all progression data, computes scaled combat stats, parses Unity Rich Text into HTML, and assembles the full domain model. Returns ErrEnrichment if the raw profile payload is nil or corrupt.
func (*Client) EnrichAgent ¶ added in v1.3.0
func (c *Client) EnrichAgent(raw *zzz.AvatarData) (*Agent, error)
EnrichAgent transforms a raw upstream zzz.AvatarData into an enriched Agent using the client's configured default Language.
This method operates entirely in-memory using the client's metadata store and performs ZERO network calls. It resolves all agent metadata, progression data, equipped gear (WEngine, DriveDisc entries), active set bonuses, computes scaled combat stats, and formats UI stats. Returns ErrEnrichment if the raw avatar payload is nil or refers to an unknown avatar ID.
func (*Client) EnrichAgentWithLang ¶ added in v1.3.0
EnrichAgentWithLang transforms a raw upstream zzz.AvatarData into an enriched Agent using the specified Language localization.
This method operates entirely in-memory using the client's metadata store and performs ZERO network calls. It is ideal for multi-language applications that fetch player data once and render individual agents dynamically across different languages. Returns ErrEnrichment if the raw avatar payload is nil or refers to an unknown avatar ID.
func (*Client) EnrichWithLang ¶ added in v1.0.0
EnrichWithLang transforms a raw upstream zzz.Profile into an enriched Profile using the specified Language localization.
This method operates entirely in-memory using the client's metadata store and performs ZERO network calls. It is ideal for multi-language applications that fetch a player's raw profile once via Client.GetRawProfile and render it dynamically across different languages. Returns ErrEnrichment if the raw profile payload is nil or corrupt.
func (*Client) GetProfile ¶
GetProfile fetches a player profile by UID from the EnkaNetwork API and enriches it using the client's configured default Language.
The returned Profile contains:
- Player account details (UID, Nickname, Inter-Knot Level, Region, Title, Avatar, Badges).
- Showcase Agent list (up to 6 agents), where each agent contains:
- Metadata (localized name, Attribute, Specialty, Rarity, Skin, CDN asset URLs).
- Progression (categorized SkillGroup entries, MindscapeNode unlock states, PotentialVision).
- Equipped WEngine (with level-scaled stats and refinement modification effects).
- Equipped DriveDisc entries (slots 1–6 with roll counts) and active DriveDiscSetBonus thresholds.
- Pre-calculated combat Stats and frontend-ready UIStats breakdowns.
The provided context.Context controls the HTTP request lifecycle, cancellation, and timeout. Returns sentinel errors such as ErrInvalidUID, ErrProfileNotFound, ErrRateLimit, ErrMaintenance, ErrNetwork, or ErrEnrichment.
func (*Client) GetProfileWithLang ¶
func (c *Client) GetProfileWithLang(ctx context.Context, uid string, lang Language) (*Profile, error)
GetProfileWithLang fetches a player profile by UID from the EnkaNetwork API and enriches it using the specified Language localization.
This method overrides the client's default language for the single request without modifying the client instance, making it safe for concurrent multi-language usage.
The provided context.Context controls the HTTP request lifecycle, cancellation, and timeout. Returns sentinel errors such as ErrInvalidUID, ErrProfileNotFound, ErrRateLimit, ErrMaintenance, ErrNetwork, or ErrEnrichment.
func (*Client) GetRawProfile ¶
GetRawProfile fetches the raw, un-enriched zzz.Profile directly from the EnkaNetwork API.
Use this method if you only need the raw numeric IDs provided by the upstream API, or when you want to fetch the payload once and enrich it into multiple languages via Client.EnrichWithLang.
The provided context.Context controls the HTTP request lifecycle, cancellation, and timeout. Returns sentinel errors such as ErrInvalidUID, ErrProfileNotFound, ErrRateLimit, ErrMaintenance, or ErrNetwork.
type DriveDisc ¶
type DriveDisc struct {
// ID is the internal numeric identifier of the specific disc variation.
ID int `json:"id"`
// UID is the unique instance identifier of this specific Drive Disc piece.
UID string `json:"uid"`
// Set is the Drive Disc [Set] metadata this disc belongs to.
Set Set `json:"set"`
// Slot is the equip partition slot position (1 to 6).
Slot int `json:"slot"`
// Level is the current upgrade level of the Drive Disc (0–15).
Level int `json:"level"`
// Rarity is the rarity rank of the disc ([RarityS], [RarityA], or [RarityB]).
Rarity Rarity `json:"rarity"`
// IconPath is the absolute HTTPS URL pointing to the disc's partition icon on the EnkaNetwork CDN.
IconPath string `json:"icon_path"`
// MainStat is the primary stat provided by this disc, scaled by disc level.
MainStat StatValue `json:"main_stat"`
// SubStats is the list of randomly rolled sub-stats (up to 4), including upgrade roll counts.
SubStats []StatValue `json:"sub_stats"`
}
DriveDisc represents an equipped Drive Disc on an Agent.
An Agent can equip up to 6 Drive Discs across partition slots 1 through 6:
- Slots 1–3 have fixed main stats (Slot 1: Flat HP, Slot 2: Flat ATK, Slot 3: Flat DEF).
- Slots 4–6 have randomized main stats (e.g. CRIT Rate, CRIT DMG, Attribute DMG Bonus, Energy Regen, Anomaly Mastery).
func (*DriveDisc) CountEffectiveRolls ¶
func (d *DriveDisc) CountEffectiveRolls(targetProps ...PropertyID) int
CountEffectiveRolls returns the total number of sub-stat upgrade rolls on this specific DriveDisc that match any of the provided target property IDs.
Example:
// Count useful rolls for an Attack Agent on a single disc: rolls := disc.CountEffectiveRolls(fairy.PropCritRate, fairy.PropCritDMG, fairy.PropATKPercent)
type DriveDiscSetBonus ¶
type DriveDiscSetBonus struct {
// Set is the Drive Disc [Set] metadata (ID and localized name).
Set Set `json:"set"`
// Count is the total number of pieces from this set currently equipped on the Agent (e.g. 2, 4, 5).
Count int `json:"count"`
// Effects contains the 2-piece and 4-piece [SetEffect] thresholds with their activation status.
Effects []SetEffect `json:"effects"`
}
DriveDiscSetBonus represents an aggregated Drive Disc set equipped on an Agent, detailing the equipped piece count and active/inactive set threshold bonuses.
type DriveDiscs ¶ added in v1.0.0
type DriveDiscs struct {
// Slots is the list of equipped [DriveDisc] pieces (up to 6 discs, partition slots 1–6).
Slots []DriveDisc `json:"slots"`
// SetBonuses is the list of active 2-piece and 4-piece Drive Disc set bonuses.
SetBonuses []DriveDiscSetBonus `json:"set_bonuses"`
}
DriveDiscs represents the complete Drive Disc equipment layout on an Agent, containing the equipped discs in partition slots 1–6 and active 2-piece and 4-piece set bonuses.
func (DriveDiscs) BySlot ¶ added in v1.0.0
func (d DriveDiscs) BySlot(slot int) *DriveDisc
BySlot returns a pointer to the DriveDisc equipped in the specified partition slot (1–6), or nil if no disc is equipped in that slot.
func (DriveDiscs) CountEffectiveRolls ¶ added in v1.0.0
func (d DriveDiscs) CountEffectiveRolls(targetProps ...PropertyID) int
CountEffectiveRolls returns the total number of sub-stat upgrade rolls across all DriveDisc entries in the collection that match any of the provided target property IDs (also known as "effective" or "useful" rolls for build evaluation).
Example:
// Evaluate build quality on an Attack Agent across all 6 equipped discs:
rolls := agent.DriveDiscs.CountEffectiveRolls(fairy.PropCritRate, fairy.PropCritDMG, fairy.PropATKPercent)
fmt.Printf("Effective rolls: %d\n", rolls)
func (DriveDiscs) Has2Piece ¶ added in v1.0.0
func (d DriveDiscs) Has2Piece(setID SetID) bool
Has2Piece reports whether at least 2 pieces of the specified SetID are equipped.
Example:
if agent.DriveDiscs.Has2Piece(fairy.SetSwingJazz) {
fmt.Println("Swing Jazz 2-pc is active (+20% Energy Regen)")
}
func (DriveDiscs) Has4Piece ¶ added in v1.0.0
func (d DriveDiscs) Has4Piece(setID SetID) bool
Has4Piece reports whether at least 4 pieces of the specified SetID are equipped.
Example:
if agent.DriveDiscs.Has4Piece(fairy.SetWoodpeckerElectro) {
fmt.Println("Woodpecker Electro 4-pc is active")
}
func (DriveDiscs) SetCounts ¶ added in v1.0.0
func (d DriveDiscs) SetCounts() map[Set]int
SetCounts groups equipped discs by their Set and returns the count of pieces equipped for each set.
func (DriveDiscs) SubStatTotals ¶ added in v1.0.0
func (d DriveDiscs) SubStatTotals() []StatValue
SubStatTotals aggregates and sums sub-stat values and roll counts across all discs in the collection. It groups them by PropertyID and preserves the deterministic appearance order of the sub-stats.
Example:
totals := agent.DriveDiscs.SubStatTotals()
for _, stat := range totals {
fmt.Printf("%-20s +%-6s (%d rolls)\n", stat.Name, stat.DisplayValue(), stat.Rolls)
}
Example ¶
ExampleDriveDiscs_SubStatTotals demonstrates comprehensive gear and build quality analysis: detecting active 2-pc / 4-pc set bonuses, aggregating substats, and scoring priority rolls.
package main
import (
"context"
"fmt"
"time"
"github.com/kirinyoku/fairy"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
profile, err := fairy.GetProfile(ctx, "1504687050")
if err != nil || len(profile.Agents) == 0 {
return
}
agent := profile.Agents[0]
fmt.Printf("=== Drive Disc Analysis: %s ===\n", agent.Name)
// 1. Detect active Drive Disc Set Bonuses (2-piece and 4-piece thresholds)
fmt.Println("Active Set Bonuses:")
for _, bonus := range agent.DriveDiscs.SetBonuses {
fmt.Printf(" • %s (%d pieces equipped)\n", bonus.Set.Name, bonus.Count)
for _, effect := range bonus.Effects {
if effect.IsActive {
fmt.Printf(" [%d-Piece Active]: %s\n", effect.PieceCount, effect.FormatPlainText())
}
}
}
// 2. Aggregate substat totals and upgrade roll counts across all 6 equipped discs
fmt.Println("\nSubstat Totals Across All 6 Discs:")
for _, stat := range agent.DriveDiscs.SubStatTotals() {
fmt.Printf(" • %-22s +%-8s (%d rolls)\n",
stat.Name, stat.DisplayValue(), stat.Rolls)
}
// 3. Count effective upgrade rolls automatically evaluated against the agent's recommended stats (RecommendedSubStats)
usefulRolls := agent.CountEffectiveRolls()
fmt.Printf("\nBuild Rating: %d effective substat rolls on recommended stats\n", usefulRolls)
// Alternatively, evaluate against custom priority stats (e.g. only CRIT stats):
critRolls := agent.CountEffectiveRolls(fairy.PropCritRate, fairy.PropCritDMG)
fmt.Printf("CRIT Roll Rating: %d rolls on CRIT Rate / CRIT DMG\n", critRolls)
}
Output:
type FormattedStatBreakdown ¶
type FormattedStatBreakdown struct {
// PropertyID is the strongly-typed [PropertyID] of the stat.
PropertyID PropertyID `json:"property_id"`
// Name is the localized display name of the stat.
Name string `json:"name"`
// Base is the pre-formatted innate base stat value.
Base string `json:"base"`
// Added is the pre-formatted added stat value from W-Engines, Drive Discs, and set bonuses.
Added string `json:"added"`
// Total is the pre-formatted final combat stat value.
Total string `json:"total"`
// IconURL is the base64 Data URI string containing the stat's SVG icon.
IconURL string `json:"icon_url"`
}
FormattedStatBreakdown represents a single combat stat broken down into its base and added components, pre-formatted as human-readable strings ready for UI display.
type FormattedStats ¶
type FormattedStats struct {
// HP is the formatted Health Points string.
HP string `json:"hp"`
// ATK is the formatted Attack string.
ATK string `json:"atk"`
// DEF is the formatted Defense string.
DEF string `json:"def"`
// Impact is the formatted Impact string.
Impact string `json:"impact"`
// CritRate is the formatted Critical Rate percentage string (e.g. "50.0%").
CritRate string `json:"crit_rate"`
// CritDMG is the formatted Critical Damage percentage string (e.g. "150.0%").
CritDMG string `json:"crit_dmg"`
// AttributeDMGBonus is the formatted Attribute Damage Bonus percentage string (e.g. "30.0%").
AttributeDMGBonus string `json:"attribute_dmg_bonus"`
// AnomalyMastery is the formatted Anomaly Mastery string.
AnomalyMastery string `json:"anomaly_mastery"`
// AnomalyProficiency is the formatted Anomaly Proficiency string.
AnomalyProficiency string `json:"anomaly_proficiency"`
// PenRatio is the formatted Penetration Ratio percentage string (e.g. "24.0%").
PenRatio string `json:"pen_ratio"`
// PenFlat is the formatted Flat Penetration string.
PenFlat string `json:"pen_flat"`
// EnergyRegen is the formatted Energy Regeneration string (e.g. "1.20").
EnergyRegen string `json:"energy_regen"`
// SheerForce is the formatted Sheer Force string.
SheerForce string `json:"sheer_force"`
// SharpCritDMG is the formatted Laceration DMG string.
SharpCritDMG string `json:"sharp_crit_dmg"`
}
FormattedStats contains the agent's combat stats pre-formatted as human-readable strings. This is convenient for frontend rendering where formatted values (e.g. "50.0%", "3,120") are required directly.
type Language ¶
type Language string
Language represents a supported localization language for in-game text. It determines the translation strings retrieved from the embedded metadata store for Agent names, W-Engine titles, Drive Disc sets, Skill descriptions, Mindscape Cinema nodes, and combat stat labels.
const ( // LangEN represents English localization ("en"). LangEN Language = "en" // LangRU represents Russian localization ("ru"). LangRU Language = "ru" // LangDE represents German localization ("de"). LangDE Language = "de" // LangES represents Spanish localization ("es"). LangES Language = "es" // LangFR represents French localization ("fr"). LangFR Language = "fr" // LangID represents Indonesian localization ("id"). LangID Language = "id" // LangJA represents Japanese localization ("ja"). LangJA Language = "ja" // LangKO represents Korean localization ("ko"). LangKO Language = "ko" // LangPT represents Portuguese localization ("pt"). LangPT Language = "pt" // LangTH represents Thai localization ("th"). LangTH Language = "th" // LangVI represents Vietnamese localization ("vi"). LangVI Language = "vi" // LangZHCN represents Simplified Chinese localization ("zh-cn"). LangZHCN Language = "zh-cn" // LangZHTW represents Traditional Chinese localization ("zh-tw"). LangZHTW Language = "zh-tw" )
Supported in-game localization languages matching the official Zenless Zone Zero game clients.
func AllLanguages ¶ added in v0.10.0
func AllLanguages() []Language
AllLanguages returns a newly allocated slice containing all 13 supported Language localizations. The returned slice is a defensive copy and can be safely mutated by the caller.
type MindscapeNode ¶ added in v0.7.0
type MindscapeNode struct {
// Rank is the Mindscape Cinema level (1 to 6).
Rank int `json:"rank"`
// Name is the localized name of the Mindscape Cinema node.
Name string `json:"name"`
// Description is the localized description text of the Mindscape Cinema node effect.
Description string `json:"description"`
// FormattedHTML is the web-ready HTML description with inline CSS colors.
FormattedHTML string `json:"formatted_html,omitempty"`
// Unlocked indicates whether this Mindscape Cinema node is unlocked on the Agent (MindscapeCinema >= Rank).
Unlocked bool `json:"unlocked"`
}
MindscapeNode represents a single Mindscape Cinema level (M1–M6) for an Agent.
func (MindscapeNode) FormatHTML ¶ added in v0.7.0
func (m MindscapeNode) FormatHTML() string
FormatHTML returns the Mindscape Cinema node description formatted as HTML with inline CSS styling.
func (MindscapeNode) FormatMarkdown ¶ added in v0.7.0
func (m MindscapeNode) FormatMarkdown() string
FormatMarkdown returns the Mindscape Cinema node description formatted with Markdown syntax (bold highlights).
func (MindscapeNode) FormatPlainText ¶ added in v0.7.0
func (m MindscapeNode) FormatPlainText() string
FormatPlainText returns the Mindscape Cinema node description stripped of Unity Rich Text formatting.
type Namecard ¶
type Namecard struct {
// ID is the internal numeric identifier of the namecard asset.
ID int `json:"id"`
// URL is the absolute HTTPS URL pointing to the namecard's background asset on the EnkaNetwork CDN.
URL string `json:"url"`
}
Namecard represents a player's equipped background calling card image.
type Option ¶
type Option func(*Options)
Option defines a functional option for configuring a Client in NewClient.
func WithDefaultLang ¶
WithDefaultLang sets the default localization Language for the Client. If not specified, the client defaults to English (LangEN).
func WithEnkaOptions ¶
WithEnkaOptions configures the underlying enkanetwork-go client settings, including custom [http.Client] timeouts, User-Agent strings, retry policies (zzz.RetryOptions), and persistent caching implementations (zzz.Cache).
type Options ¶
type Options struct {
// DefaultLang specifies the default localization language used for profile enrichment.
// Defaults to [LangEN] if not specified.
DefaultLang Language
// EnkaOpts specifies configuration settings for the underlying EnkaNetwork HTTP client,
// such as custom HTTP transport, User-Agent, retry policies, and cache implementations.
EnkaOpts zzz.Options
}
Options holds configuration settings for initializing a Client.
type PotentialVision ¶ added in v0.7.0
type PotentialVision struct {
// IsUnlocked indicates whether the Potential Vision mechanic is unlocked.
IsUnlocked bool `json:"is_unlocked"`
// CurrentID is the currently active upgrade node ID.
CurrentID int `json:"current_id"`
// Nodes contains all Potential Vision upgrade nodes for the Agent.
Nodes []PotentialVisionNode `json:"nodes"`
}
PotentialVision holds Potential Vision upgrade mechanics and nodes for an Agent.
type PotentialVisionNode ¶ added in v0.7.0
type PotentialVisionNode struct {
// ID is the internal numeric identifier of the upgrade node.
ID int `json:"id"`
// Level is the level threshold of the node (1 to 6).
Level int `json:"level"`
// LevelName is the localized level title.
LevelName string `json:"level_name"`
// Title is the localized title of the upgrade effect.
Title string `json:"title"`
// Description is the localized effect description.
Description string `json:"description"`
// FormattedHTML is the web-ready HTML description with inline CSS colors.
FormattedHTML string `json:"formatted_html,omitempty"`
// IsActive indicates whether this upgrade node is currently active on the Agent.
IsActive bool `json:"is_active"`
}
PotentialVisionNode represents a single Potential Vision upgrade node.
func (PotentialVisionNode) FormatHTML ¶ added in v0.7.0
func (p PotentialVisionNode) FormatHTML() string
FormatHTML returns the PotentialVisionNode description formatted as HTML with inline CSS styling.
func (PotentialVisionNode) FormatMarkdown ¶ added in v0.7.0
func (p PotentialVisionNode) FormatMarkdown() string
FormatMarkdown returns the PotentialVisionNode description formatted with Markdown syntax.
func (PotentialVisionNode) FormatPlainText ¶ added in v0.7.0
func (p PotentialVisionNode) FormatPlainText() string
FormatPlainText returns the PotentialVisionNode description stripped of Unity Rich Text formatting.
type Profile ¶
type Profile struct {
// UID is the unique in-game identifier of the player (typically a 10-digit string).
UID string `json:"uid"`
// TTL indicates the remaining cache lifetime in seconds returned by the upstream EnkaNetwork API.
// Making repeated requests before this TTL expires consumes rate limit quota without yielding newer game data.
TTL int `json:"ttl"`
// Nickname is the display name chosen by the player. Can be empty if omitted by upstream API.
Nickname string `json:"nickname"`
// InterknotLevel is the player's overall account progression level (Inter-Knot Level).
InterknotLevel int `json:"interknot_level"`
// Region is the game server region hosting the player's account.
Region Region `json:"region"`
// Title is the active achievement title equipped on the profile. May be nil if no title is equipped.
Title *Title `json:"title"`
// Avatar is the active profile picture equipped by the player. May be nil if none is set.
Avatar *Avatar `json:"avatar"`
// Namecard is the active profile background image (calling card). May be nil if none is set.
Namecard *Namecard `json:"namecard"`
// Badges is the list of collectible showcase medals displayed on the profile. May be empty.
Badges []Badge `json:"badges"`
// Agents is the list of up to 6 showcased [Agent] entries configured by the player in-game.
// May be empty if the player's in-game showcase is empty or has details hidden.
Agents []Agent `json:"agents"`
}
Profile represents an enriched Zenless Zone Zero player profile. It aggregates account-level metadata and the player's showcased Agent lineup.
Example ¶
ExampleProfile demonstrates extracting and rendering player showcase customization data, such as avatar icons, namecard backgrounds, achievement badges, and two-color gradient titles.
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/kirinyoku/fairy"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
profile, err := fairy.GetProfile(ctx, "1504687050")
if err != nil {
log.Printf("Failed to fetch profile: %v\n", err)
return
}
fmt.Printf("=== Player Showcase: %s (UID: %s) ===\n", profile.Nickname, profile.UID)
fmt.Printf("Inter-Knot Level: %d | Server: %s\n", profile.InterknotLevel, profile.Region)
if profile.Avatar != nil && profile.Avatar.URL != "" {
fmt.Printf("Avatar URL: %s\n", profile.Avatar.URL)
}
if profile.Namecard != nil && profile.Namecard.URL != "" {
fmt.Printf("Namecard URL: %s\n", profile.Namecard.URL)
}
if profile.Title != nil {
// Generate an HTML gradient style using the Title's primary and secondary hex colors
gradientCSS := fmt.Sprintf("background: linear-gradient(90deg, %s, %s); -webkit-background-clip: text;",
profile.Title.PrimaryColorHex(), profile.Title.SecondaryColorHex())
fmt.Printf("Title: <span style=\"%s\">%s</span>\n", gradientCSS, profile.Title.Text)
}
if len(profile.Badges) > 0 {
fmt.Println("Showcased Badges:")
for _, badge := range profile.Badges {
fmt.Printf(" • %-24s Value: %-5d (Icon: %s)\n", badge.Title, badge.Value, badge.IconURL)
}
}
}
Output:
func Enrich ¶ added in v1.0.0
Enrich transforms a raw upstream zzz.Profile into an enriched Profile using the default Language (English).
This function operates completely in-memory using the embedded metadata store and makes ZERO network requests. It resolves all progression data, computes scaled combat stats, parses Unity Rich Text into HTML, and assembles the full domain model. Returns ErrEnrichment if the raw profile payload is nil or corrupt.
Example ¶
ExampleEnrich demonstrates fetching raw API data once with GetRawProfile, caching it, and enriching it into multiple languages in memory using Enrich and EnrichWithLang with zero additional network requests.
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/kirinyoku/fairy"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// 1. Fetch the raw upstream profile once over HTTP
rawProfile, err := fairy.GetRawProfile(ctx, "1504687050")
if err != nil {
log.Printf("Failed to fetch raw profile: %v", err)
return
}
// 2. Enrich in memory with zero extra network overhead
// Default English:
enProfile, err := fairy.Enrich(rawProfile)
if err != nil {
log.Printf("English enrichment failed: %v", err)
return
}
// Specific languages on the fly:
jaProfile, err := fairy.EnrichWithLang(rawProfile, fairy.LangJA)
if err != nil {
log.Printf("Japanese enrichment failed: %v", err)
return
}
ruProfile, err := fairy.EnrichWithLang(rawProfile, fairy.LangRU)
if err != nil {
log.Printf("Russian enrichment failed: %v", err)
return
}
fmt.Println("English Agent 0:", enProfile.Agents[0].Name, "—", enProfile.Agents[0].SpecialtyName)
fmt.Println("Japanese Agent 0:", jaProfile.Agents[0].Name, "—", jaProfile.Agents[0].SpecialtyName)
fmt.Println("Russian Agent 0:", ruProfile.Agents[0].Name, "—", ruProfile.Agents[0].SpecialtyName)
}
Output:
func EnrichWithLang ¶ added in v1.0.0
EnrichWithLang transforms a raw upstream zzz.Profile into an enriched Profile in the requested Language.
This function operates completely in-memory using the embedded metadata store and makes ZERO network requests. It is ideal for multi-language applications that fetch a player's raw profile once via GetRawProfile and render it dynamically across different languages. Returns ErrEnrichment if the raw profile payload is nil or corrupt.
func GetProfile ¶
GetProfile fetches a player profile by UID via the EnkaNetwork API and enriches it using the shared default client in English (LangEN).
The returned Profile contains:
- Player account details (UID, Nickname, Inter-Knot Level, Region, Title, Avatar, Badges).
- Showcase Agent list (up to 6 agents), where each agent contains:
- Metadata (localized name, Attribute, Specialty, Rarity, Skin, CDN asset URLs).
- Progression (categorized SkillGroup entries, MindscapeNode unlock states, PotentialVision).
- Equipped WEngine (with level-scaled stats and refinement modification effects).
- Equipped DriveDisc entries (slots 1–6 with roll counts) and active DriveDiscSetBonus thresholds.
- Pre-calculated combat Stats and frontend-ready UIStats breakdowns.
The provided context.Context controls the HTTP request lifecycle, cancellation, and timeout. Returns sentinel errors such as ErrInvalidUID, ErrProfileNotFound, ErrRateLimit, ErrMaintenance, ErrNetwork, or ErrEnrichment.
Example ¶
ExampleGetProfile demonstrates the standard quick-start workflow: fetching a player's showcase profile with a context timeout and handling sentinel errors with errors.Is.
package main
import (
"context"
"errors"
"fmt"
"log"
"time"
"github.com/kirinyoku/fairy"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
const uid = "1504687050"
profile, err := fairy.GetProfile(ctx, uid)
if err != nil {
switch {
case errors.Is(err, fairy.ErrProfileNotFound):
log.Printf("Player %s not found on game servers\n", uid)
case errors.Is(err, fairy.ErrRateLimit):
log.Printf("EnkaNetwork API rate limit reached, back off required\n")
case errors.Is(err, fairy.ErrMaintenance):
log.Printf("EnkaNetwork API or game servers are under maintenance\n")
case errors.Is(err, fairy.ErrNetwork):
log.Printf("Network transport or timeout error\n")
default:
log.Printf("Unexpected error fetching profile %s: %v\n", uid, err)
}
return
}
fmt.Printf("Player: %s (Inter-Knot Lv.%d, Server: %s)\n",
profile.Nickname, profile.InterknotLevel, profile.Region)
for _, agent := range profile.Agents {
weapon := "None"
if agent.WEngine != nil {
weapon = fmt.Sprintf("%s (Lv.%d, M%d)", agent.WEngine.Name, agent.WEngine.Level, agent.WEngine.Modification)
}
fmt.Printf(" • %-16s Lv.%-2d [%s / %s] W-Engine: %s\n",
agent.Name, agent.Level, agent.AttributeName, agent.SpecialtyName, weapon)
}
}
Output:
func GetProfileWithLang ¶
GetProfileWithLang fetches a player profile by UID via the EnkaNetwork API and enriches it using the specified Language localization.
This is identical to GetProfile, but overrides the default language for the single request without modifying the shared default client.
The provided context.Context controls the HTTP request lifecycle, cancellation, and timeout. Returns sentinel errors such as ErrInvalidUID, ErrProfileNotFound, ErrRateLimit, ErrMaintenance, ErrNetwork, or ErrEnrichment.
type PropertyID ¶
type PropertyID int
PropertyID represents a strongly-typed numeric identifier for combat attributes and stats in Zenless Zone Zero.
The naming conventions categorize stats into three distinct layers:
- Base: The innate foundational stat before gear multipliers (e.g. PropBaseATK, PropBaseHP).
- Percent: A percentage modifier applied to the base stat (e.g. PropATKPercent, PropHPPercent).
- Flat: A direct numerical addition applied after percentage scaling (e.g. PropATKFlat, PropHPFlat).
const ( // PropBaseHP represents the base Health Points stat. PropBaseHP PropertyID = 11101 // PropHPPercent represents a percentage increase to Health Points. PropHPPercent PropertyID = 11102 // PropHPFlat represents a flat increase to Health Points. PropHPFlat PropertyID = 11103 // PropHPPercentBonus represents an additional percentage bonus to Health Points. PropHPPercentBonus PropertyID = 11104 // PropHPFlatBonus represents an additional flat bonus to Health Points. PropHPFlatBonus PropertyID = 11105 // PropBaseATK represents the base Attack stat. PropBaseATK PropertyID = 12101 // PropATKPercent represents a percentage increase to Attack. PropATKPercent PropertyID = 12102 // PropATKFlat represents a flat increase to Attack. PropATKFlat PropertyID = 12103 // PropBaseDEF represents the base Defense stat. PropBaseDEF PropertyID = 13101 // PropDEFPercent represents a percentage increase to Defense. PropDEFPercent PropertyID = 13102 // PropDEFFlat represents a flat increase to Defense. PropDEFFlat PropertyID = 13103 // PropBaseImpact represents the base Impact stat (influences Daze build-up). PropBaseImpact PropertyID = 12201 // PropImpactPercent represents a percentage increase to Impact. PropImpactPercent PropertyID = 12202 // PropImpactFlat represents a flat increase to Impact. PropImpactFlat PropertyID = 12203 // PropBaseCritRate represents the base Critical Rate stat. PropBaseCritRate PropertyID = 20101 // PropCritRate represents an increase to Critical Rate. PropCritRate PropertyID = 20103 // PropBaseCritDMG represents the base Critical Damage stat. PropBaseCritDMG PropertyID = 21101 // PropCritDMG represents an increase to Critical Damage. PropCritDMG PropertyID = 21103 // PropBasePENRatio represents the base Penetration Ratio stat. PropBasePENRatio PropertyID = 23101 // PropPENRatio represents an increase to Penetration Ratio. PropPENRatio PropertyID = 23103 // PropBasePENFlat represents the base flat Penetration stat. PropBasePENFlat PropertyID = 23201 // PropPENFlat represents an increase to flat Penetration. PropPENFlat PropertyID = 23203 // PropBaseEnergyRegen represents the base Energy Regeneration stat. PropBaseEnergyRegen PropertyID = 30501 // PropEnergyRegenPercent represents a percentage increase to Energy Regeneration. PropEnergyRegenPercent PropertyID = 30502 // PropEnergyRegen represents an increase to Energy Regeneration. PropEnergyRegen PropertyID = 30503 // PropBaseAnomalyProficiency represents the base Anomaly Proficiency stat (scales Anomaly damage). PropBaseAnomalyProficiency PropertyID = 31201 // PropAnomalyProficiencyPercent represents a percentage increase to Anomaly Proficiency. PropAnomalyProficiencyPercent PropertyID = 31202 // PropAnomalyProficiency represents an increase to Anomaly Proficiency. PropAnomalyProficiency PropertyID = 31203 // PropBaseAnomalyMastery represents the base Anomaly Mastery stat (scales Anomaly build-up speed). PropBaseAnomalyMastery PropertyID = 31401 // PropAnomalyMasteryPercent represents a percentage increase to Anomaly Mastery. PropAnomalyMasteryPercent PropertyID = 31402 // PropAnomalyMastery represents an increase to Anomaly Mastery. PropAnomalyMastery PropertyID = 31403 // PropBaseSheerForce represents the base Sheer Force stat (for Rupture agents). PropBaseSheerForce PropertyID = 12301 // PropSheerForce represents an increase to Sheer Force. PropSheerForce PropertyID = 12303 // PropBaseRpRecover represents the base Adrenaline Auto-Accumulation stat (for Rupture agents). PropBaseRpRecover PropertyID = 32001 // PropRpRecoverPercent represents a percentage increase to Adrenaline Auto-Accumulation. PropRpRecoverPercent PropertyID = 32002 // PropRpRecover represents an increase to Adrenaline Auto-Accumulation. PropRpRecover PropertyID = 32003 // PropBaseEpRecover represents the base Automatic Sharpness Accumulation stat (for Armorer agents). PropBaseEpRecover PropertyID = 32401 // PropEpRecoverPercent represents a percentage increase to Automatic Sharpness Accumulation. PropEpRecoverPercent PropertyID = 32402 // PropEpRecover represents an increase to Automatic Sharpness Accumulation. PropEpRecover PropertyID = 32403 // PropBaseSharpCritDMG represents the base Laceration DMG stat. PropBaseSharpCritDMG PropertyID = 21301 // PropSharpCritDMG represents an increase to Laceration DMG. PropSharpCritDMG PropertyID = 21303 // PropPhysicalDMGBonus represents the Physical Damage Bonus stat. PropPhysicalDMGBonus PropertyID = 31505 // PropFireDMGBonus represents the Fire Damage Bonus stat. PropFireDMGBonus PropertyID = 31605 // PropIceDMGBonus represents the Ice Damage Bonus stat. PropIceDMGBonus PropertyID = 31705 // PropElectricDMGBonus represents the Electric Damage Bonus stat. PropElectricDMGBonus PropertyID = 31805 // PropEtherDMGBonus represents the Ether Damage Bonus stat. PropEtherDMGBonus PropertyID = 31905 // PropWindDMGBonus represents the Wind Damage Bonus stat. PropWindDMGBonus PropertyID = 32305 )
Strongly-typed PropertyID constants for all combat attributes.
func AgentHighlightProps ¶ added in v1.4.0
func AgentHighlightProps(agentID int) []PropertyID
AgentHighlightProps returns the recommended combat property IDs (PropertyID) for an Agent by their numeric ID, or nil if the agent is not found or fails to initialize the shared default client. The returned slice is a defensive copy and can be safely mutated by the caller.
Example:
props := fairy.AgentHighlightProps(1011) // Anby Demara // props -> [PropBaseImpact] (12201)
func AgentRecommendedSubStats ¶ added in v1.4.0
func AgentRecommendedSubStats(agentID int) []PropertyID
AgentRecommendedSubStats returns the recommended Drive Disc sub-stat property IDs for the given agent ID, using the shared default client.
These stats reflect the official in-game recommendation system in Zenless Zone Zero, matching the yellow highlight indicators displayed on Drive Disc sub-stats in the equipment and tuning UI for each specific agent.
If a curated list exists in [agentRecommendedSubStats], a defensive copy is returned. Otherwise, it computes a safe fallback from AgentHighlightProps, converting attributes to percentage-only sub-stats and excluding flat ATK, flat HP, flat DEF, and flat PEN.
func (PropertyID) IconURL ¶ added in v0.7.0
func (p PropertyID) IconURL() string
IconURL returns a base64-encoded Data URI string ("data:image/svg+xml;base64,...") containing the stat property's SVG icon for direct use in frontend <img> tags.
func (PropertyID) SVG ¶ added in v0.7.0
func (p PropertyID) SVG() string
SVG returns the raw inline SVG markup string for the stat property.
type Rarity ¶
type Rarity string
Rarity represents the rarity tier (rank) of an Agent, WEngine, or DriveDisc.
const ( // RarityS represents the S-Rank tier. RarityS Rarity = "S" // RarityA represents the A-Rank tier. RarityA Rarity = "A" // RarityB represents the B-Rank tier (used for W-Engines and Drive Discs). RarityB Rarity = "B" )
Supported rarity ranks in Zenless Zone Zero.
func AllRarities ¶ added in v0.10.0
func AllRarities() []Rarity
AllRarities returns a newly allocated slice containing all supported Rarity constants. The returned slice is a defensive copy and can be safely mutated by the caller.
type Region ¶
type Region string
Region represents the game server region hosting a player's account.
const ( // RegionEU represents the European game server region ("Europe"). RegionEU Region = "Europe" // RegionNA represents the North American game server region ("America"). RegionNA Region = "America" // RegionAsia represents the Asian game server region ("Asia"). RegionAsia Region = "Asia" // RegionTWHKMO represents the Taiwan / Hong Kong / Macau game server region ("TW/HK/MO"). RegionTWHKMO Region = "TW/HK/MO" )
Supported server region constants.
func AllRegions ¶ added in v0.10.0
func AllRegions() []Region
AllRegions returns a newly allocated slice containing all supported Region server constants. The returned slice is a defensive copy and can be safely mutated by the caller.
func RegionFromUID ¶ added in v1.1.0
RegionFromUID determines the game server Region from the prefix of a 10-digit international ZZZ UID without performing any network requests.
Recognized 10-digit prefixes:
- "10" -> RegionNA (America)
- "13" -> RegionAsia (Asia)
- "15" -> RegionEU (Europe)
- "17" -> RegionTWHKMO (TW/HK/MO)
Returns the matched Region and true, or empty string and false if the UID prefix is not recognized.
type Set ¶
type Set struct {
// ID is the unique numeric identifier of the Drive Disc set (see [SetID] constants, e.g. [SetWoodpeckerElectro]).
ID SetID `json:"id"`
// Name is the localized display name of the set (e.g. "Woodpecker Electro", "Polar Metal", "Fanged Metal").
Name string `json:"name"`
}
Set represents a Drive Disc equipment set. A Set grants bonus combat effects when an Agent equips 2 or 4 pieces belonging to the same set.
type SetEffect ¶ added in v0.7.0
type SetEffect struct {
// PieceCount is the required piece count threshold (2 or 4).
PieceCount int `json:"piece_count"`
// Description is the localized description text of the set bonus effect.
Description string `json:"description"`
// FormattedHTML is the web-ready HTML description with inline CSS colors.
FormattedHTML string `json:"formatted_html,omitempty"`
// IsActive indicates whether this set effect is currently active on the Agent (Count >= PieceCount).
IsActive bool `json:"is_active"`
}
SetEffect represents a specific Drive Disc set effect threshold (2-piece or 4-piece bonus).
func (SetEffect) FormatHTML ¶ added in v0.7.0
FormatHTML returns the set effect description formatted as HTML with inline CSS styling.
func (SetEffect) FormatMarkdown ¶ added in v0.7.0
FormatMarkdown returns the set effect description formatted with Markdown syntax.
func (SetEffect) FormatPlainText ¶ added in v0.7.0
FormatPlainText returns the set effect description as clean plain text with all Rich Text tags stripped.
type SetID ¶ added in v1.0.0
type SetID int
SetID represents the unique numeric identifier of a Drive Disc set.
const ( // SetWoodpeckerElectro represents the Woodpecker Electro set. SetWoodpeckerElectro SetID = 31000 // SetPufferElectro represents the Puffer Electro set. SetPufferElectro SetID = 31100 // SetShockstarDisco represents the Shockstar Disco set. SetShockstarDisco SetID = 31200 // SetFreedomBlues represents the Freedom Blues set. SetFreedomBlues SetID = 31300 // SetHormonePunk represents the Hormone Punk set. SetHormonePunk SetID = 31400 // SetSoulRock represents the Soul Rock set. SetSoulRock SetID = 31500 // SetSwingJazz represents the Swing Jazz set. SetSwingJazz SetID = 31600 // SetChaosJazz represents the Chaos Jazz set. SetChaosJazz SetID = 31800 // SetProtoPunk represents the Proto Punk set. SetProtoPunk SetID = 31900 // SetInfernoMetal represents the Inferno Metal set. SetInfernoMetal SetID = 32200 // SetChaoticMetal represents the Chaotic Metal set. SetChaoticMetal SetID = 32300 // SetThunderMetal represents the Thunder Metal set. SetThunderMetal SetID = 32400 // SetPolarMetal represents the Polar Metal set. SetPolarMetal SetID = 32500 // SetFangedMetal represents the Fanged Metal set. SetFangedMetal SetID = 32600 // SetBranchBladeSong represents the Branch & Blade Song set. SetBranchBladeSong SetID = 32700 // SetAstralVoice represents the Astral Voice set. SetAstralVoice SetID = 32800 // SetShadowHarmony represents the Shadow Harmony set. SetShadowHarmony SetID = 32900 // SetPhaethonsMelody represents the Phaethon's Melody set. SetPhaethonsMelody SetID = 33000 // SetYunkuiTales represents the Yunkui Tales set. SetYunkuiTales SetID = 33100 // SetKingOfTheSummit represents the King of the Summit set. SetKingOfTheSummit SetID = 33200 // SetDawnsBloom represents the Dawn's Bloom set. SetDawnsBloom SetID = 33300 // SetMoonlightLullaby represents the Moonlight Lullaby set. SetMoonlightLullaby SetID = 33400 // SetWhiteWaterBallad represents the White Water Ballad set. SetWhiteWaterBallad SetID = 33500 // SetShiningAria represents the Shining Aria set. SetShiningAria SetID = 33600 // SetBunnyInWonderland represents the Bunny in Wonderland set. SetBunnyInWonderland SetID = 33700 // SetNotesFromTheChained represents the Notes From the Chained set. SetNotesFromTheChained SetID = 33800 // SetWutheringSalon represents the Wuthering Salon set. SetWutheringSalon SetID = 33900 // SetTheSkyAblaze represents the The Sky Ablaze set. SetTheSkyAblaze SetID = 34000 // SetFeatheredFate represents the Feathered Fate set. SetFeatheredFate SetID = 34100 // SetThornedRose represents the Thorned Rose set. SetThornedRose SetID = 34200 )
Strongly-typed Drive Disc SetID constants for all equipment sets in Zenless Zone Zero.
type Skill ¶
type Skill struct {
// Level is the current progression level of the skill.
Level int `json:"level"`
// Name is the localized display name of the skill.
Name string `json:"name"`
// Description is the localized description text with Unity Rich Text formatting and formula tags.
Description string `json:"description"`
// FormattedHTML is the web-ready HTML description with inline colors, icon tags, and evaluated formulas.
FormattedHTML string `json:"formatted_html,omitempty"`
// Type is the categorized [SkillType] of the skill (basic, dodge, assist, special, chain, passive).
Type SkillType `json:"type"`
// TypeName is the localized name of the skill category (e.g. "Basic Attack", "EX Special Attack").
TypeName string `json:"type_name"`
// Params is the list of calculated numeric parameters and multipliers evaluated for the skill's current level.
Params []SkillParam `json:"params,omitempty"`
}
Skill represents an individual combat ability or passive effect of an Agent.
func (Skill) EvaluatedDescription ¶ added in v0.5.0
EvaluatedDescription returns the skill description with all dynamic scaling formulas ({CAL:...}) evaluated for the skill's current level.
func (Skill) FormatHTML ¶ added in v0.5.0
FormatHTML returns the skill description formatted as HTML with inline CSS styling, embedded Enka CDN icon tags, and scaling formulas evaluated for the skill's current level.
func (Skill) FormatMarkdown ¶ added in v0.5.0
FormatMarkdown returns the skill description formatted in Markdown (bold highlights for colored text) with scaling formulas evaluated for the skill's current level.
func (Skill) FormatPlainText ¶ added in v0.5.0
FormatPlainText returns the skill description as clean plain text with all Unity Rich Text tags stripped and scaling formulas evaluated for the skill's current level.
type SkillGroup ¶ added in v0.8.0
type SkillGroup struct {
// Type is the group category key ([SkillTypeBasic], [SkillTypeSpecial], etc.).
Type SkillType `json:"type"`
// TypeName is the localized category tab name.
TypeName string `json:"type_name"`
// Level is the progression level of the group (1–12 for active skills, 0–6 for core passives).
Level int `json:"level"`
// Skills is the list of individual [Skill] abilities belonging to this category group tab.
Skills []Skill `json:"skills"`
}
SkillGroup represents a categorized group of skills matching the 6 in-game UI skill tabs/buttons.
type SkillParam ¶ added in v0.8.0
type SkillParam struct {
// Name is the localized parameter label (e.g. "1-Hit DMG").
Name string `json:"name"`
// Value is the pre-formatted value string with level scaling evaluated (e.g. "124.5%").
Value string `json:"value"`
}
SkillParam represents a calculated numeric parameter or damage multiplier for a skill.
type SkillType ¶ added in v0.8.0
type SkillType string
SkillType represents a categorized category of combat skill matching in-game button inputs.
const ( // SkillTypeBasic represents Basic Attack combos. SkillTypeBasic SkillType = "basic" // SkillTypeDodge represents Dodge, Dash Attack, and Dodge Counter. SkillTypeDodge SkillType = "dodge" // SkillTypeAssist represents Quick Assist, Defensive Assist, and Evasive Assist. SkillTypeAssist SkillType = "assist" // SkillTypeSpecial represents Special Attack and EX Special Attack. SkillTypeSpecial SkillType = "special" // SkillTypeChain represents Chain Attack and Ultimate. SkillTypeChain SkillType = "chain" // SkillTypePassive represents Core Passive and Additional Ability. SkillTypePassive SkillType = "passive" )
Supported combat skill categories in Zenless Zone Zero.
func AllSkillTypes ¶ added in v0.10.0
func AllSkillTypes() []SkillType
AllSkillTypes returns a newly allocated slice containing all 6 supported SkillType categories. The returned slice is a defensive copy and can be safely mutated by the caller.
type Skin ¶
type Skin struct {
// ID is the internal numeric identifier of the skin.
ID int `json:"id"`
// Name is the localized name of the skin.
Name string `json:"name"`
// Description is the localized lore or description of the skin.
Description string `json:"description"`
// SplashArtURL is the absolute HTTPS URL pointing to the skin's splash art on the EnkaNetwork CDN.
SplashArtURL string `json:"splash_art_url"`
}
Skin represents an equipped cosmetic skin (outfit) of an Agent.
type Specialty ¶
type Specialty string
Specialty represents the combat role or class of an Agent.
const ( // SpecialtyAttack represents the Attack role. SpecialtyAttack Specialty = "Attack" // SpecialtyStun represents the Stun role. SpecialtyStun Specialty = "Stun" // SpecialtyAnomaly represents the Anomaly role. SpecialtyAnomaly Specialty = "Anomaly" // SpecialtySupport represents the Support role. SpecialtySupport Specialty = "Support" // SpecialtyDefense represents the Defense role. SpecialtyDefense Specialty = "Defense" // SpecialtyRupture represents the Rupture role. SpecialtyRupture Specialty = "Rupture" // SpecialtyArmorer represents the Armorer role. SpecialtyArmorer Specialty = "Armorer" )
Supported combat specialties in Zenless Zone Zero.
func AllSpecialties ¶ added in v0.10.0
func AllSpecialties() []Specialty
AllSpecialties returns a newly allocated slice containing all 7 supported Specialty constants. The returned slice is a defensive copy and can be safely mutated by the caller.
type StatValue ¶
type StatValue struct {
// PropertyID is the internal strongly-typed [PropertyID] (e.g. [PropATKPercent]).
PropertyID PropertyID `json:"property_id"`
// Name is the localized display name of the stat (e.g. "ATK", "CRIT Rate").
Name string `json:"name"`
// Value is the calculated numerical value of the stat. Percentage stats are stored in decimal format (e.g. 0.048 for 4.8%).
Value float64 `json:"value"`
// IsPercent indicates whether the stat represents a percentage value.
IsPercent bool `json:"is_percent"`
// Rolls is the number of times this stat was upgraded (1 for base roll, up to 5 with upgrades).
Rolls int `json:"rolls"`
// IconURL is the base64 Data URI string ("data:image/svg+xml;base64,...") containing the stat's SVG icon.
IconURL string `json:"icon_url"`
}
StatValue represents a single combat stat or sub-stat entry (such as a Drive Disc main stat or substat roll).
func (StatValue) DisplayValue ¶
DisplayValue returns the stat's value formatted as a human-readable string (e.g. "4.8%" or "310").
type Stats ¶
type Stats struct {
// HP is the total Health Points.
HP float64 `json:"hp"`
// ATK is the total Attack.
ATK float64 `json:"atk"`
// DEF is the total Defense.
DEF float64 `json:"def"`
// Impact is the Impact stat (influences Daze accumulation rate).
Impact float64 `json:"impact"`
// CritRate is the Critical Hit Rate as a decimal fraction (e.g. 0.05 for 5%).
CritRate float64 `json:"crit_rate"`
// CritDMG is the Critical Hit Damage as a decimal fraction (e.g. 1.50 for 150%).
CritDMG float64 `json:"crit_dmg"`
// AttributeDMGBonus is the matching elemental Damage Bonus as a decimal fraction (e.g. 0.30 for 30%).
AttributeDMGBonus float64 `json:"attribute_dmg_bonus"`
// AnomalyMastery is the Anomaly Mastery stat (influences Anomaly Buildup speed).
AnomalyMastery float64 `json:"anomaly_mastery"`
// AnomalyProficiency is the Anomaly Proficiency stat (scales Anomaly damage).
AnomalyProficiency float64 `json:"anomaly_proficiency"`
// PenRatio is the Penetration Ratio as a decimal fraction (ignores a percentage of enemy DEF).
PenRatio float64 `json:"pen_ratio"`
// PenFlat is the flat Penetration stat (ignores a flat amount of enemy DEF).
PenFlat float64 `json:"pen_flat"`
// EnergyRegen is the Energy Regeneration rate per second (e.g. 1.20).
EnergyRegen float64 `json:"energy_regen"`
// SheerForce is the Sheer Force stat (damage multiplier for Rupture agents, ignoring DEF).
SheerForce float64 `json:"sheer_force"`
// SharpCritDMG is the Laceration DMG stat (damage multiplier for Armorer agents, scaling with DEF).
SharpCritDMG float64 `json:"sharp_crit_dmg"`
// EnergyPropertyID is the specific property ID for the agent's energy regeneration mechanism
// (PropBaseEnergyRegen for standard agents, PropBaseRpRecover for Rupture, PropBaseEpRecover for Armorer).
EnergyPropertyID PropertyID `json:"energy_property_id,omitempty"`
}
Stats represents the complete aggregated numerical combat stats of an Agent.
Value representations:
- Percentage stats (Stats.CritRate, Stats.CritDMG, Stats.AttributeDMGBonus, Stats.PenRatio) are stored as decimals (e.g. 0.05 = 5%, 1.50 = 150%).
- Stats.EnergyRegen is stored as energy recovered per second (e.g. 1.20).
- Flat stats (Stats.HP, Stats.ATK, Stats.DEF, Stats.Impact, Stats.AnomalyMastery, Stats.AnomalyProficiency, Stats.PenFlat, Stats.SheerForce) are stored as raw floating-point numbers.
Use Stats.Formatted or Agent.UIStats to retrieve pre-formatted string representations.
func (*Stats) Formatted ¶
func (s *Stats) Formatted() FormattedStats
Formatted returns a new FormattedStats struct where all numerical stats are converted into precise, human-readable strings (e.g. "50.0%" instead of 0.5, "3120" instead of 3120.0).
type Title ¶
type Title struct {
// ID is the internal numeric identifier of the title.
ID int `json:"id"`
// Text is the fully localized title text.
Text string `json:"text"`
// PrimaryColor is the 6-character hex color code for the starting gradient color (without #).
PrimaryColor string `json:"primary_color"`
// SecondaryColor is the 6-character hex color code for the ending gradient color (without #).
SecondaryColor string `json:"secondary_color"`
}
Title represents an achievement or status title displayed on a player's profile.
Many titles in Zenless Zone Zero feature a two-color linear gradient. Use Title.PrimaryColorHex and Title.SecondaryColorHex to retrieve CSS-ready hex color strings.
func (*Title) PrimaryColorHex ¶
PrimaryColorHex returns the primary gradient color formatted as a standard CSS hex string (e.g. "#F7BA3F"). Returns an empty string if t is nil or if PrimaryColor is not set.
func (*Title) SecondaryColorHex ¶
SecondaryColorHex returns the secondary gradient color formatted as a standard CSS hex string (e.g. "#E74C3C"). Returns an empty string if t is nil or if SecondaryColor is not set.
type UIStats ¶
type UIStats struct {
// HP is the Health Points breakdown.
HP FormattedStatBreakdown `json:"hp"`
// ATK is the Attack breakdown.
ATK FormattedStatBreakdown `json:"atk"`
// DEF is the Defense breakdown.
DEF FormattedStatBreakdown `json:"def"`
// Impact is the Impact breakdown.
Impact FormattedStatBreakdown `json:"impact"`
// CritRate is the Critical Rate breakdown.
CritRate FormattedStatBreakdown `json:"crit_rate"`
// CritDMG is the Critical Damage breakdown.
CritDMG FormattedStatBreakdown `json:"crit_dmg"`
// AttributeDMGBonus is the matching elemental Damage Bonus breakdown.
AttributeDMGBonus FormattedStatBreakdown `json:"attribute_dmg_bonus"`
// AnomalyMastery is the Anomaly Mastery breakdown.
AnomalyMastery FormattedStatBreakdown `json:"anomaly_mastery"`
// AnomalyProficiency is the Anomaly Proficiency breakdown.
AnomalyProficiency FormattedStatBreakdown `json:"anomaly_proficiency"`
// PenRatio is the Penetration Ratio breakdown.
PenRatio FormattedStatBreakdown `json:"pen_ratio"`
// PenFlat is the Flat Penetration breakdown.
PenFlat FormattedStatBreakdown `json:"pen_flat"`
// EnergyRegen is the Energy Regeneration breakdown.
EnergyRegen FormattedStatBreakdown `json:"energy_regen"`
// SheerForce is the Sheer Force breakdown (for Rupture agents).
SheerForce FormattedStatBreakdown `json:"sheer_force"`
// SharpCritDMG is the Laceration DMG breakdown (for Armorer agents).
SharpCritDMG FormattedStatBreakdown `json:"sharp_crit_dmg"`
}
UIStats contains all combat stats broken down into Base + Added = Total components, with localized names and icon URLs, structured for frontend profile and agent inspect panels.
func (UIStats) List ¶ added in v0.11.0
func (u UIStats) List() []FormattedStatBreakdown
List returns all combat stat breakdowns as a slice in the canonical in-game display order.
Example ¶
ExampleUIStats_List demonstrates rendering an Agent's combat stats panel with pre-formatted Base + Added = Total breakdowns and localized stat names matching the in-game attributes screen.
package main
import (
"context"
"fmt"
"time"
"github.com/kirinyoku/fairy"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
profile, err := fairy.GetProfile(ctx, "1504687050")
if err != nil || len(profile.Agents) == 0 {
return
}
agent := profile.Agents[0]
fmt.Printf("=== Agent Stats: %s Lv.%d ===\n", agent.Name, agent.Level)
for _, stat := range agent.UIStats.List() {
fmt.Printf("%-24s %10s (Base: %s + Added: %s)\n",
stat.Name, stat.Total, stat.Base, stat.Added)
}
}
Output:
type WEngine ¶
type WEngine struct {
// ID is the internal numeric identifier of the W-Engine.
ID int `json:"id"`
// UID is the unique instance identifier of this specific W-Engine.
UID string `json:"uid"`
// Name is the localized display name of the W-Engine (e.g. "Deep Sea Visitor", "The Brimstone").
Name string `json:"name"`
// Level is the current progression level of the W-Engine (1–60).
Level int `json:"level"`
// Phase is the ascension / star phase of the W-Engine (0–5).
Phase int `json:"phase"`
// Modification is the refinement level of the W-Engine's passive skill (1–5 / M1–M5).
Modification int `json:"modification"`
// Rarity is the rarity tier of the W-Engine ([RarityS], [RarityA], or [RarityB]).
Rarity Rarity `json:"rarity"`
// Specialty is the recommended combat role for this W-Engine (e.g. [SpecialtyAttack], [SpecialtyStun]).
Specialty Specialty `json:"specialty"`
// SpecialtyName is the localized display name of the intended specialty.
SpecialtyName string `json:"specialty_name"`
// IconURL is the absolute HTTPS URL pointing to the W-Engine's visual icon on the EnkaNetwork CDN.
IconURL string `json:"icon_url"`
// MainStat is the primary stat provided by the W-Engine ([PropBaseATK]), scaled by level and phase.
MainStat StatValue `json:"main_stat"`
// SecondaryStat is the secondary stat provided by the W-Engine (e.g. CRIT Rate, ATK%, PEN Ratio), scaled by level.
SecondaryStat StatValue `json:"secondary_stat"`
// PassiveDescription is the localized description text of the W-Engine's passive ability.
PassiveDescription string `json:"passive_description"`
// FormattedHTML is the web-ready HTML description with inline CSS colors and evaluated modification parameters.
FormattedHTML string `json:"formatted_html,omitempty"`
}
WEngine represents an enriched W-Engine (weapon) equipped by an Agent. It provides base combat stats, scaling secondary stats, and a unique passive ability.
func (*WEngine) FormatHTML ¶ added in v0.6.0
FormatHTML returns the W-Engine passive description formatted as HTML with inline CSS styling. Returns an empty string if w is nil.
func (*WEngine) FormatMarkdown ¶ added in v0.6.0
FormatMarkdown returns the W-Engine passive description formatted with Markdown syntax. Returns an empty string if w is nil.
func (*WEngine) FormatPlainText ¶ added in v0.6.0
FormatPlainText returns the W-Engine passive description as clean plain text with all Rich Text tags stripped. Returns an empty string if w is nil.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
api
Package api provides a thin adapter layer over the upstream enkanetwork-go client.
|
Package api provides a thin adapter layer over the upstream enkanetwork-go client. |
|
assets
Package assets provides embedded binary data for the fairy library.
|
Package assets provides embedded binary data for the fairy library. |
|
store
Package store provides an abstraction over the Zenless Zone Zero datamined game data.
|
Package store provides an abstraction over the Zenless Zone Zero datamined game data. |
|
tools/extractor
command
|