fairy

package module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2026 License: MIT Imports: 11 Imported by: 0

README

Fairy is a Go library for fetching, enriching, and calculating Zenless Zone Zero player game profiles via the EnkaNetwork API. Just like the AI assistant from New Eridu, it handles all the heavy lifting — mapping raw game IDs to localized names, building asset URLs, and computing final combat stats from scratch.

Go Reference Go Version

Table of Contents

Overview

The EnkaNetwork API returns player profiles as raw data — agents, W-Engines, and Drive Discs are represented by internal numeric IDs, stat values have no names, and there are no image URLs. To build anything user-facing, you'd need to maintain your own mapping tables, host localization files, implement stat calculations, and keep up with every game patch.

Fairy eliminates this entire layer. It takes a single UID, fetches the raw profile from Enka, and returns a fully enriched model — human-readable names in 13 languages, ready-to-use asset URLs, computed final stats, and Drive Disc roll analysis. One function call, zero boilerplate.

The comparison below shows what this looks like in practice: a raw API response on the left versus the enriched output Fairy produces on the right.

ENKANETWORK API RESPONSE FAIRY ENRICHED OUTPUT
{
  "Id": 1511,
  "Level": 60,
  "Exp": 0,
  "PromotionLevel": 6,
  "TalentLevel": 0,
  "SkinId": 3115111,
  "UpgradeId": 0,
  "CoreSkillEnhancement": 6,
  "Weapon": {
    "Id": 15388,
    "Level": 60,
    "StarMark": 1,
    "BreakLevel": 6
  },
  "EquippedList": [{
    "Slot": 1,
    "Equipment": {
      "Id": 33041,
      "Level": 15,
      "MainPropertyList": [{
        "PropertyId": 11103,
        "PropertyValue": 550
      }],
      "RandomPropertyList": [
        {"PropertyId": 12103, "PropertyValue": 19},
        {"PropertyId": 31203, "PropertyValue": 9},
        {"PropertyId": 11102, "PropertyValue": 300},
        {"PropertyId": 12102, "PropertyValue": 300}
      ]
    }
  }]
}
{
  "name": "Nangong Yu",
  "level": 60,
  "rarity": "S",
  "attribute_name": "Ether",
  "specialty_name": "Stun",
  "w_engine": {
    "name": "Neon Fantasies",
    "level": 60,
    "modification": 1,
    "rarity": "S",
    "main_stat": {
      "name": "Base ATK",
      "value": 713
    }
  },
  "drive_discs": [{
    "slot": 1,
    "set_name": "Phaethon's Melody",
    "level": 15,
    "main_stat": {"name": "HP", "value": 2200},
    "sub_stats": [
      {"name": "ATK",         "value": 38,   "rolls": 2},
      {"name": "Anomaly Prof","value": 27,   "rolls": 3},
      {"name": "Percent ATK", "value": 0.09, "rolls": 3}
    ]
  }],
  "stats": {
    "hp": 11188, "atk": 2866,
    "crit_rate": 0.074, "crit_dmg": 0.548,
    "pen_ratio": 0.24, "energy_regen": 1.2
  }
}

[!NOTE] The JSON examples above are simplified and shortened to highlight the key differences. The actual API responses and Fairy's models contain significantly more data.

Features

  • 🧮 Stat Calculation — Computes final combat stats (HP, ATK, DEF, CRIT, PEN, Energy Regen, and more) by combining agent base values, W-Engine scaling, Drive Disc main/sub stats, and set bonuses. All percentage stats are stored as decimals internally and can be formatted for display with a single call.

  • 🎨 UI-Ready Stat BreakdownFormattedUIStats() splits every stat into Base, Added, and Total components, pre-formatted as strings — matching exactly what players see in the in-game stat panel. Stats.Formatted() gives you a simpler flat view when you don't need the breakdown.

  • 🔍 Drive Disc AnalysisSubStatTotals() aggregates sub-stats across all six discs, grouping by property and summing values and rolls. CountEffectiveRolls() counts how many rolls landed on the stats you care about — available on both the agent (all discs) and individual disc level.

  • 🌍 13 Languages — Every string in the output — agent names, skill descriptions, stat labels, W-Engine passives, set bonus text, titles, and badges — is fully localized. Fetch raw data once, then call Localize() to produce the same profile in any supported language without extra network calls.

  • 🖼️ Asset URLs — Generates ready-to-use image URLs for agent splash arts, skins, W-Engine icons, Drive Disc icons, profile avatars, namecards, and badges. No manual URL construction needed.

  • 📦 Zero-Config Data — All game metadata (stat scaling tables, localization strings, item definitions) is embedded in the binary via go:embed. No external files, no database, no CDN — just go get and start building.

  • 🧩 Flexible Client — Functional options let you configure the default language, swap in a custom MetadataStore implementation, and pass through HTTP settings (timeouts, retries, User-Agent, caching) to the underlying enkanetwork-go client.

Installation

Requires Go 1.22+

go get github.com/kirinyoku/fairy

Usage

Fetching a profile

The easiest way to get started is with the GetProfile function. It uses a default client with English localization and built-in game data.

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/kirinyoku/fairy"
)

func main() {
    profile, err := fairy.GetProfile(context.Background(), "1504687050")
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Player: %s (Inter-Knot Level: %d)\n", profile.Nickname, profile.InterknotLevel)

    for _, agent := range profile.Agents {
        fmt.Printf("  • %s  Lv.%d  %s %s\n", agent.Name, agent.Level, agent.AttributeName, agent.SpecialtyName)
    }
}

Custom client

Use NewClient to set a different default language, configure HTTP settings, retries, caching, or a custom User-Agent header (required by Enka.Network).

client, err := fairy.NewClient(
    // Change default language for all requests
    fairy.WithDefaultLang(fairy.LangJA),
    
    // Configure the underlying `github.com/kirinyoku/enkanetwork-go/client/zzz` client
    fairy.WithEnkaOptions(zzz.Options{
        UserAgent: "MyApp/1.0 (github.com/you/myapp)",
        HTTPClient: &http.Client{Timeout: 10 * time.Second},
        Retry:      &zzz.RetryOptions{MaxAttempts: 2, Delay: 2 * time.Second},
        Cache:      myCacheInstance,
    }),
)

You can also override the language on a per-request basis without recreating the client:

// Use the shared global client, but respond in Korean for this call
profile, err := fairy.GetProfileWithLang(ctx, "1504687050", fairy.LangKO)

Stat breakdown for UI

FormattedUIStats() returns every stat split into Base, Added, and Total, formatted exactly as they appear in the in-game stat panel.

agent := profile.Agents[0]
ui := agent.FormattedUIStats()

fmt.Printf("HP:        %s  (base %s + %s)\n", ui.HP.Total,        ui.HP.Base,        ui.HP.Added)
fmt.Printf("ATK:       %s  (base %s + %s)\n", ui.ATK.Total,       ui.ATK.Base,       ui.ATK.Added)
fmt.Printf("CRIT Rate: %s  (base %s + %s)\n", ui.CritRate.Total,  ui.CritRate.Base,  ui.CritRate.Added)
fmt.Printf("CRIT DMG:  %s  (base %s + %s)\n", ui.CritDMG.Total,   ui.CritDMG.Base,   ui.CritDMG.Added)
fmt.Printf("PEN Ratio: %s  (base %s + %s)\n", ui.PenRatio.Total,  ui.PenRatio.Base,  ui.PenRatio.Added)

Drive Disc analysis

Measure how many sub-stat rolls landed on stats that actually matter for your agent.

agent := profile.Agents[0]

// Count effective rolls for an Attack agent:
usefulRolls := agent.CountEffectiveRolls(
    fairy.PropCritRate,
    fairy.PropCritDMG,
    fairy.PropATKPercent,
)
fmt.Printf("Effective rolls: %d\n", usefulRolls)

// Full sub-stat breakdown across all 6 discs, grouped and summed:
for _, stat := range agent.SubStatTotals() {
    fmt.Printf("  %-20s %s  (×%d rolls)\n", stat.Name, stat.DisplayValue(), stat.Rolls)
}

Localize raw data yourself

To display the same profile in multiple languages, fetch the raw data once and localize it in memory — no extra network calls needed:

// 1. Fetch the raw data from the API just once
rawProfile, err := client.GetRawProfile(ctx, "1504687050")
if err != nil {
    log.Fatal(err)
}

// 2. Localize the same raw data into different languages without extra network calls
enProfile, _ := client.Localize(rawProfile, fairy.LangEN)
jaProfile, _ := client.Localize(rawProfile, fairy.LangJA)

Supported Languages

Language Language
🇬🇧 English 🇰🇷 Korean
🇷🇺 Russian 🇵🇹 Portuguese
🇩🇪 German 🇹🇭 Thai
🇪🇸 Spanish 🇻🇳 Vietnamese
🇫🇷 French 🇨🇳 Chinese (Simplified)
🇮🇩 Indonesian 🇹🇼 Chinese (Traditional)
🇯🇵 Japanese

License

Licensed under the MIT License.

Documentation

Overview

Package fairy provides a highly modular and extensible Go library for fetching, parsing, and enriching Zenless Zone Zero player profiles via the EnkaNetwork API.

The raw response from Enka.Network provides basic IDs for agents, W-Engines, and Drive Discs. Fairy takes care of the heavy lifting by replacing raw IDs with full localized names for agents, weapons, discs, and skills, building full URLs for splash arts, icons, and avatars, and calculating precise final combat stats taking into account base stats, weapon scalings, disc substat rolls, and set bonuses across 13 supported languages.

Quick Start

The easiest way to get started is by using the global functions. By default, this uses the embedded metadata store and English localization:

profile, err := fairy.GetProfile(context.Background(), "1504687050")
if err != nil {
	log.Fatal(err)
}
fmt.Printf("Player: %s (Level %d)\n", profile.Nickname, profile.InterknotLevel)

Custom Client

If you are building a multi-language application or want to configure custom HTTP settings, you should create a dedicated client:

client, err := fairy.NewClient(
	fairy.WithDefaultLang(fairy.LangJA), // Default to Japanese
)
if err != nil {
	log.Fatal(err)
}

See https://github.com/kirinyoku/fairy for more advanced features.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrProfileNotFound is returned when the requested UID does not exist.
	ErrProfileNotFound = api.ErrProfileNotFound
	// ErrRateLimit is returned when the client exceeds the API rate limit.
	ErrRateLimit = api.ErrRateLimit
	// ErrMaintenance is returned when the API is undergoing maintenance or temporarily unavailable.
	ErrMaintenance = api.ErrMaintenance
	// ErrNetwork is returned when there is a network error.
	ErrNetwork = api.ErrNetwork
)

Functions

func EvaluateFormulas added in v0.5.0

func EvaluateFormulas(text string, skillLevel int) string

EvaluateFormulas evaluates and replaces all Unity skill calculation formulas in the format {CAL:expr,mult,precision} with calculated values for the given skill level.

func FormatHTML added in v0.5.0

func FormatHTML(text string, skillLevel ...int) string

FormatHTML converts Unity Rich Text tags (e.g. <color=#2BAD00>20%</color> and <IconMap:Icon_Special>) into web-compatible HTML with inline CSS styling, Enka CDN icon image tags, and break tags (<br>). If an optional skillLevel is passed, any {CAL:...} scaling formulas in text are evaluated automatically.

func FormatMarkdown added in v0.5.0

func FormatMarkdown(text string, skillLevel ...int) string

FormatMarkdown converts Unity Rich Text tags into Markdown-formatted text. Colored values are wrapped in bold (**text**), IconMap placeholders are replaced with bold labels (**[Ultimate]**), and original text layout is preserved for platforms like Discord, Telegram, or Slack. If an optional skillLevel is passed, any {CAL:...} scaling formulas in text are evaluated automatically.

func FormatPlainText added in v0.5.0

func FormatPlainText(text string, skillLevel ...int) string

FormatPlainText strips all Unity Rich Text tags, color tags, and icon placeholders from text, replacing IconMap tags with clean readable labels (e.g. [Ultimate], [Special Attack]), returning clean, human-readable plain text without any markup. If an optional skillLevel is passed, any {CAL:...} scaling formulas in text are evaluated automatically.

func GetRawProfile

func GetRawProfile(ctx context.Context, uid string) (*zzz.Profile, error)

GetRawProfile fetches the raw zzz.Profile by UID without applying any localization using a shared, global client.

Types

type Agent

type Agent struct {
	ID                   int                 `json:"id"`                     // The internal ID of the agent.
	Name                 string              `json:"name"`                   // The localized name of the agent (e.g., "Ellen").
	Level                int                 `json:"level"`                  // The current level of the agent (1-60).
	Promotion            int                 `json:"promotion"`              // The promotion/ascension phase of the agent (0-5).
	MindscapeCinema      int                 `json:"mindscape_cinema"`       // The unlocked Mindscape Cinema level (0-6).
	CoreSkillEnhancement int                 `json:"core_skill_enhancement"` // The Core Skill enhancement level (0-6).
	Attribute            Attribute           `json:"attribute"`              // The elemental damage type (e.g., Ice).
	AttributeName        string              `json:"attribute_name"`         // The localized name of the attribute.
	Specialty            Specialty           `json:"specialty"`              // The combat role (e.g., Attack).
	SpecialtyName        string              `json:"specialty_name"`         // The localized name of the specialty.
	Rarity               Rarity              `json:"rarity"`                 // The rarity tier (S or A).
	Skin                 *Skin               `json:"skin"`                   // The currently equipped skin (can be nil if not found).
	SplashArtURL         string              `json:"splash_art_url"`         // The URL to the agent's splash art.
	Skills               []Skill             `json:"skills"`                 // The agent's skills and passives.
	WEngine              *WEngine            `json:"w_engine"`               // The currently equipped W-Engine (can be nil).
	DriveDiscs           []DriveDisc         `json:"drive_discs"`            // The equipped Drive Discs (up to 6).
	ActiveSetBonuses     []DriveDiscSetBonus `json:"active_set_bonuses"`     // The active 2-piece or 4-piece set bonuses.
	BaseStats            Stats               `json:"base_stats"`             // The agent's base combat stats before gear/buffs.
	Stats                Stats               `json:"stats"`                  // The agent's final combat stats including all gear/buffs.
}

Agent represents an enriched agent (character) showcased on a player's profile. A profile can showcase a maximum of 6 agents. It contains the agent's combat metadata, equipped gear, and final stats.

func (*Agent) CountEffectiveRolls

func (a *Agent) CountEffectiveRolls(targetProps ...PropertyID) int

CountEffectiveRolls returns the total number of sub-stat rolls across all Drive Discs that match any of the provided target property IDs (also known as "effective" or "useful" rolls).

func (*Agent) FormattedUIStats

func (a *Agent) FormattedUIStats() UIStats

FormattedUIStats generates a complete breakdown of base vs added stats for UI display. This structure precisely matches the visual representation and layout seen in the in-game stat panel or on platforms like Enka.Network.

func (*Agent) SubStatTotals

func (a *Agent) SubStatTotals() []StatValue

SubStatTotals calculates the sum of all sub-stats across all equipped Drive Discs. It groups them by PropertyID and sums the Rolls and Values. The returned slice is guaranteed to preserve the initial appearance order of sub-stats.

type Attribute

type Attribute string

Attribute represents the elemental attribute of an agent.

const (
	// AttributePhysical represents the agent's Physical attribute.
	AttributePhysical Attribute = "Physical"
	// AttributeHonedEdge represents the agent's Honed Edge attribute.
	AttributeHonedEdge Attribute = "HonedEdge"
	// AttributeFire represents the agent's Fire attribute.
	AttributeFire Attribute = "Fire"
	// AttributeIce represents the agent's Ice attribute.
	AttributeIce Attribute = "Ice"
	// AttributeFrost represents the agent's Frost attribute.
	AttributeFrost Attribute = "Frost"
	// AttributeElectric represents the agent's Electric attribute.
	AttributeElectric Attribute = "Electric"
	// AttributeEther represents the agent's Ether attribute.
	AttributeEther Attribute = "Ether"
	// AttributeAuricInk represents the agent's Auric Ink attribute.
	AttributeAuricInk Attribute = "AuricInk"
	// AttributeWind represents the agent's Wind attribute.
	AttributeWind Attribute = "Wind"
	// AttributeLumiflux represents the agent's Lumiflux attribute.
	AttributeLumiflux Attribute = "Lumiflux"
)

func (Attribute) IconURL added in v0.5.0

func (a Attribute) IconURL() string

IconURL returns the base64-encoded Data URI string containing the attribute's SVG icon.

func (Attribute) SVG added in v0.5.0

func (a Attribute) SVG() string

SVG returns the raw inline SVG markup string for the attribute.

type Avatar

type Avatar struct {
	ID  int    `json:"id"`  // The internal ID of the avatar.
	URL string `json:"url"` // The URL to the avatar's image asset.
}

Avatar represents a selectable proxy avatar (profile picture).

type Badge

type Badge struct {
	ID      int    `json:"id"`       // The internal ID of the badge.
	Title   string `json:"title"`    // The localized name/title of the badge.
	Value   int    `json:"value"`    // The progression value associated with the badge.
	IconURL string `json:"icon_url"` // The URL to the badge's visual icon.
}

Badge represents a collectible medal or badge displayed on the profile.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client coordinates fetching data from the API and enriching it using a metadata store. It serves as the main entry point for the fairy library.

func NewClient

func NewClient(opts ...Option) (*Client, error)

NewClient creates a new instance of Client. If opts.Store is nil, it will automatically load the default store via store.Default(). If opts.DefaultLang is empty, it defaults to LangEN. Returns an error if the fallback default store fails to load its internal files.

func (*Client) GetProfile

func (c *Client) GetProfile(ctx context.Context, uid string) (*Profile, error)

GetProfile fetches the game profile from the EnkaNetwork API and localizes it using the client's default language. The provided context controls the HTTP request timeout and cancellation.

func (*Client) GetProfileWithLang

func (c *Client) GetProfileWithLang(ctx context.Context, uid string, lang Language) (*Profile, error)

GetProfileWithLang fetches the game profile from the EnkaNetwork API and localizes it with a specific language. The provided context controls the HTTP request timeout and cancellation.

func (*Client) GetRawProfile

func (c *Client) GetRawProfile(ctx context.Context, uid string) (*zzz.Profile, error)

GetRawProfile fetches the raw zzz.Profile without localization. Use this if you only need the raw data structure provided by the EnkaNetwork API. The provided context controls the HTTP request timeout and cancellation.

func (*Client) Localize

func (c *Client) Localize(raw *zzz.Profile, lang Language) (*Profile, error)

Localize maps a raw zzz.Profile into an enriched Profile using the specified language. This is highly useful when you want to fetch the raw profile once, but display it in multiple different languages.

type DriveDisc

type DriveDisc struct {
	ID       int         `json:"id"`        // The internal ID of the specific disc variation.
	UID      string      `json:"uid"`       // The unique instance ID of this specific Drive Disc.
	Set      Set         `json:"set"`       // The equipment set this disc belongs to.
	Slot     int         `json:"slot"`      // The equip slot number (1 to 6). Slots 1-3 have fixed main stats, while 4-6 are randomized.
	Level    int         `json:"level"`     // The upgrade level of the disc (0-15).
	Rarity   Rarity      `json:"rarity"`    // The rarity tier (S, A, B).
	IconPath string      `json:"icon_path"` // The URL to the disc's icon.
	MainStat StatValue   `json:"main_stat"` // The primary stat provided by this disc.
	SubStats []StatValue `json:"sub_stats"` // The randomly rolled sub-stats (up to 4).
}

DriveDisc represents an enriched Drive Disc (artifact/equipment).

func (*DriveDisc) CountEffectiveRolls

func (d *DriveDisc) CountEffectiveRolls(targetProps ...PropertyID) int

CountEffectiveRolls returns the total number of sub-stat rolls on this specific Drive Disc that match any of the provided target property IDs.

type DriveDiscSetBonus

type DriveDiscSetBonus struct {
	Set         Set    `json:"set"`         // The set granting the bonus.
	PieceCount  int    `json:"piece_count"` // The number of pieces equipped from this set (typically 2 or 4).
	Description string `json:"description"` // The localized HTML description of the set bonus from game data.
}

DriveDiscSetBonus represents an active set bonus from equipped Drive Discs.

type FormattedStatBreakdown

type FormattedStatBreakdown struct {
	Base  string `json:"base"`
	Added string `json:"added"`
	Total string `json:"total"`
}

FormattedStatBreakdown represents a single stat broken down into its base and added components, pre-formatted as human-readable strings for UI display.

type FormattedStats

type FormattedStats struct {
	HP                 string `json:"hp"`
	ATK                string `json:"atk"`
	DEF                string `json:"def"`
	Impact             string `json:"impact"`
	CritRate           string `json:"crit_rate"`
	CritDMG            string `json:"crit_dmg"`
	AnomalyMastery     string `json:"anomaly_mastery"`
	AnomalyProficiency string `json:"anomaly_proficiency"`
	PenRatio           string `json:"pen_ratio"`
	PenFlat            string `json:"pen_flat"`
	EnergyRegen        string `json:"energy_regen"`
	SheerForce         string `json:"sheer_force"`
}

FormattedStats contains the agent's combat stats pre-formatted as human-readable strings. This is extremely useful for UI/Frontend developers who just want to display the values.

type Language

type Language string

Language represents the localization language for game strings.

const (
	LangEN   Language = "en"    // English
	LangRU   Language = "ru"    // Russian
	LangDE   Language = "de"    // German
	LangES   Language = "es"    // Spanish
	LangFR   Language = "fr"    // French
	LangID   Language = "id"    // Indonesian
	LangJA   Language = "ja"    // Japanese
	LangKO   Language = "ko"    // Korean
	LangPT   Language = "pt"    // Portuguese
	LangTH   Language = "th"    // Thai
	LangVI   Language = "vi"    // Vietnamese
	LangZHCN Language = "zh-cn" // Chinese (Simplified)
	LangZHTW Language = "zh-tw" // Chinese (Traditional)
)

Supported language constants matching the in-game localizations. These determine which translation strings are pulled from the metadata store.

type Namecard

type Namecard struct {
	ID  int    `json:"id"`  // The internal ID of the namecard.
	URL string `json:"url"` // The URL to the namecard's background asset.
}

Namecard represents a profile background image.

type Option

type Option func(*Options)

Option defines a functional option for the fairy Client.

func WithDefaultLang

func WithDefaultLang(lang Language) Option

WithDefaultLang sets the default language for the Client.

func WithEnkaOptions

func WithEnkaOptions(enkaOpts zzz.Options) Option

WithEnkaOptions sets the underlying enkanetwork-go client options.

func WithStore

func WithStore(s store.MetadataStore) Option

WithStore sets the metadata store for the Client.

type Options

type Options struct {
	DefaultLang Language            // The default language for string localization.
	Store       store.MetadataStore // The store providing game metadata.
	EnkaOpts    zzz.Options         // Configuration for the underlying enkanetwork-go client.
}

Options holds the configuration for the fairy Client.

type Profile

type Profile struct {
	UID            string    `json:"uid"`             // The unique identifier of the player (typically a 9-digit string).
	Nickname       string    `json:"nickname"`        // The player's chosen nickname. Can be empty if the API returned no name.
	InterknotLevel int       `json:"interknot_level"` // The player's overall account level.
	Region         Region    `json:"region"`          // The server region the player belongs to.
	Title          *Title    `json:"title"`           // The active title displayed on the profile. May be nil if none is equipped.
	Avatar         *Avatar   `json:"avatar"`          // The active avatar (profile picture) displayed. May be nil.
	Namecard       *Namecard `json:"namecard"`        // The active background namecard. May be nil.
	Badges         []Badge   `json:"badges"`          // The showcase badges selected by the player. Can be empty.
	Agents         []Agent   `json:"agents"`          // The list of agents showcased on the profile (max 6). Can be empty.
}

Profile represents the enriched user profile data. It contains player-level metadata and the showcased agents.

func GetProfile

func GetProfile(ctx context.Context, uid string) (*Profile, error)

GetProfile fetches the game profile by UID and localizes it into the default language using a shared, global client.

func GetProfileWithLang

func GetProfileWithLang(ctx context.Context, uid string, lang Language) (*Profile, error)

GetProfileWithLang fetches the game profile by UID and localizes it into the specified language using a shared, global client.

func Localize

func Localize(raw *zzz.Profile, lang Language) (*Profile, error)

Localize maps a raw zzz.Profile into an enriched Profile using the specified language. It uses the global default client's metadata store for the conversion.

type PropertyID

type PropertyID int

PropertyID represents a strongly-typed ID for combat properties. The naming convention follows: - Base: The character's innate foundational stat. - Percent / PercentBonus: A percentage modifier applied to the base stat. - Flat / FlatBonus: A direct numerical addition applied after percentages.

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.
	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

	// PropBaseAnomalyMastery represents the base Anomaly Mastery stat.
	PropBaseAnomalyMastery PropertyID = 31201
	// PropAnomalyMastery represents an increase to Anomaly Mastery.
	PropAnomalyMastery PropertyID = 31203
	// PropBaseAnomalyProficiency represents the base Anomaly Proficiency stat.
	PropBaseAnomalyProficiency PropertyID = 31401
	// PropAnomalyProficiencyPercent represents a percentage increase to Anomaly Proficiency.
	PropAnomalyProficiencyPercent PropertyID = 31402
	// PropAnomalyProficiency represents an increase to Anomaly Proficiency.
	PropAnomalyProficiency 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
)

type Rarity

type Rarity string

Rarity represents the rarity tier of agents and equipment.

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.
	RarityB Rarity = "B"
)

func (Rarity) IconURL added in v0.5.0

func (r Rarity) IconURL() string

IconURL returns the official Enka CDN icon URL for the rarity tier.

type Region

type Region string

Region represents the game server region (e.g., Europe, America).

const (
	RegionEU     Region = "Europe"   // European server region.
	RegionNA     Region = "America"  // North American server region.
	RegionAsia   Region = "Asia"     // Asian server region.
	RegionTWHKMO Region = "TW/HK/MO" // Taiwan/Hong Kong/Macau server region.
)

type Set

type Set struct {
	ID   int    `json:"id"`   // The internal ID of the set.
	Name string `json:"name"` // The localized name of the set (e.g., "Woodpecker Electro").
}

Set represents a specific Drive Disc equipment set. A Set grants bonus effects when an agent equips 2 or 4 pieces of the same set.

type Skill

type Skill struct {
	Level       int    `json:"level"`       // The level of the skill.
	Name        string `json:"name"`        // The localized name of the skill.
	Description string `json:"description"` // The localized description of the skill.
}

Skill represents an agent's combat skill or passive ability.

func (Skill) EvaluatedDescription added in v0.5.0

func (s Skill) EvaluatedDescription() string

EvaluatedDescription returns the skill description with all scaling formulas ({CAL:...}) evaluated for the skill's current level.

func (Skill) FormatHTML added in v0.5.0

func (s Skill) FormatHTML() string

FormatHTML returns the skill description formatted as HTML with inline CSS colors, semantic icon spans, and scaling formulas evaluated for the skill's current level.

func (Skill) FormatMarkdown added in v0.5.0

func (s Skill) FormatMarkdown() string

FormatMarkdown returns the skill description formatted in Markdown (bold tags for colored values) with scaling formulas evaluated for the skill's current level.

func (Skill) FormatPlainText added in v0.5.0

func (s Skill) FormatPlainText() string

FormatPlainText returns the skill description as clean plain text with all tags stripped and scaling formulas evaluated for the skill's current level.

type Skin

type Skin struct {
	ID           int    `json:"id"`             // The internal ID of the skin.
	Name         string `json:"name"`           // The localized name of the skin.
	Description  string `json:"description"`    // The localized description of the skin.
	SplashArtURL string `json:"splash_art_url"` // The URL to the skin's splash art.
}

Skin represents the equipped 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 combat role.
	SpecialtyAttack Specialty = "Attack"
	// SpecialtyStun represents the Stun combat role.
	SpecialtyStun Specialty = "Stun"
	// SpecialtyAnomaly represents the Anomaly combat role.
	SpecialtyAnomaly Specialty = "Anomaly"
	// SpecialtySupport represents the Support combat role.
	SpecialtySupport Specialty = "Support"
	// SpecialtyDefense represents the Defense combat role.
	SpecialtyDefense Specialty = "Defense"
	// SpecialtyRupture represents the Rupture combat role.
	SpecialtyRupture Specialty = "Rupture"
)

func (Specialty) IconURL added in v0.5.0

func (s Specialty) IconURL() string

IconURL returns the official Enka CDN icon URL for the specialty.

type StatValue

type StatValue struct {
	PropertyID PropertyID `json:"property_id"` // The internal property ID (e.g., 12102 for ATK%).
	Name       string     `json:"name"`        // The localized name of the stat.
	Value      float64    `json:"value"`       // The final calculated value of the stat.
	IsPercent  bool       `json:"is_percent"`  // Indicates if the stat is a percentage.
	Rolls      int        `json:"rolls"`       // The number of times this stat was upgraded (1 for base, up to 5 for max upgrades).
}

StatValue represents a single combat stat (main or sub stat).

func (StatValue) DisplayValue

func (s StatValue) DisplayValue() string

DisplayValue returns the stat's value formatted as a human-readable string. Percentages are multiplied by 100 and formatted with a '%' sign.

type Stats

type Stats struct {
	HP                 float64 `json:"hp"`                  // Total Health Points.
	ATK                float64 `json:"atk"`                 // Total Attack.
	DEF                float64 `json:"def"`                 // Total Defense.
	Impact             float64 `json:"impact"`              // Impact (influences Daze build-up).
	CritRate           float64 `json:"crit_rate"`           // Critical Hit Rate (as a decimal, e.g., 0.05 for 5%).
	CritDMG            float64 `json:"crit_dmg"`            // Critical Hit Damage (as a decimal, e.g., 1.50 for 150%).
	AnomalyMastery     float64 `json:"anomaly_mastery"`     // Anomaly Mastery (influences Anomaly Buildup rate).
	AnomalyProficiency float64 `json:"anomaly_proficiency"` // Anomaly Proficiency (influences Anomaly Damage).
	PenRatio           float64 `json:"pen_ratio"`           // Penetration Ratio (ignores a percentage of enemy DEF).
	PenFlat            float64 `json:"pen_flat"`            // Flat Penetration (ignores a flat amount of enemy DEF).
	EnergyRegen        float64 `json:"energy_regen"`        // Energy Regeneration rate (as a decimal, e.g., 1.20).
	SheerForce         float64 `json:"sheer_force"`         // Sheer Force (damage multiplier for Rupture agents, ignoring DEF).
}

Stats represents the aggregated combat stats of an agent. This structure keeps fields minimal and flat for easy access. Internal representation of percentages is in decimal form (e.g., CritRate 0.05 = 5%). EnergyRegen is also represented as its divided final value (e.g., 1.20). Precise calculations and final formulas are opt-in via the calc package.

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).

type Title

type Title struct {
	ID             int    `json:"id"`              // The internal ID of the title.
	Text           string `json:"text"`            // The localized text of the title.
	PrimaryColor   string `json:"primary_color"`   // The primary color hex (without #).
	SecondaryColor string `json:"secondary_color"` // The secondary color hex (without #).
}

Title represents an achievement or status title chosen by the player. Titles often have gradients represented by two hex colors. To properly display this gradient, use the PrimaryColorHex() and SecondaryColorHex() helpers.

func (*Title) PrimaryColorHex

func (t *Title) PrimaryColorHex() string

PrimaryColorHex returns the primary gradient color formatted as a standard hex string (#RRGGBB).

func (*Title) SecondaryColorHex

func (t *Title) SecondaryColorHex() string

SecondaryColorHex returns the secondary gradient color formatted as a standard hex string (#RRGGBB).

type UIStats

type UIStats struct {
	HP                 FormattedStatBreakdown `json:"hp"`
	ATK                FormattedStatBreakdown `json:"atk"`
	DEF                FormattedStatBreakdown `json:"def"`
	Impact             FormattedStatBreakdown `json:"impact"`
	CritRate           FormattedStatBreakdown `json:"crit_rate"`
	CritDMG            FormattedStatBreakdown `json:"crit_dmg"`
	AnomalyMastery     FormattedStatBreakdown `json:"anomaly_mastery"`
	AnomalyProficiency FormattedStatBreakdown `json:"anomaly_proficiency"`
	PenRatio           FormattedStatBreakdown `json:"pen_ratio"`
	PenFlat            FormattedStatBreakdown `json:"pen_flat"`
	EnergyRegen        FormattedStatBreakdown `json:"energy_regen"`
	SheerForce         FormattedStatBreakdown `json:"sheer_force"`
}

UIStats contains all combat stats broken down into base and added components, ready to be displayed on a frontend profile page (like Enka.Network).

type WEngine

type WEngine struct {
	ID                 int       `json:"id"`                  // The internal ID of the W-Engine.
	UID                string    `json:"uid"`                 // The unique instance ID of this specific W-Engine.
	Name               string    `json:"name"`                // The localized name of the W-Engine.
	Level              int       `json:"level"`               // The current level of the W-Engine (1-60).
	Phase              int       `json:"phase"`               // The star level from the API (ascension phase).
	Modification       int       `json:"modification"`        // The refinement/upgrade level of the passive (1-5).
	Rarity             Rarity    `json:"rarity"`              // The rarity tier (S, A, or B).
	Specialty          Specialty `json:"specialty"`           // The intended role specialty for this W-Engine.
	SpecialtyName      string    `json:"specialty_name"`      // The localized name of the specialty.
	IconURL            string    `json:"icon_url"`            // The URL to the W-Engine's visual icon.
	MainStat           StatValue `json:"main_stat"`           // The primary stat provided by the W-Engine.
	SecondaryStat      StatValue `json:"secondary_stat"`      // The secondary stat provided by the W-Engine.
	PassiveDescription string    `json:"passive_description"` // The localized description of the passive skill.
}

WEngine represents an enriched W-Engine equipped by an agent.

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.
tools/extractor command
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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL