# banner.yaml — schema definition for gacha banner definitions # # All rate tables are content-driven. No hardcoded pull rates in server code. # Banner end dates and pity rules must be visible to players per design spec. $schema: "xyvera/content-schema/banner/v1" type: object required: - id - name - type - pull_cost - pool - pity properties: id: type: string pattern: "^[a-z][a-z0-9_]*$" name: type: string type: type: string enum: [standard, featured, event] description: > standard = permanent evergreen with wishlist; featured = region or character banner with up/down rate; event = limited mega-event with spark currency. pull_cost: type: object required: [currency, single, multi] properties: currency: type: string description: "Resource ID used to pull. Usually 'diamond' or a banner-specific ticket." single: type: integer minimum: 1 multi: type: integer minimum: 1 description: "Cost for a 10-pull. Typically single * 10 minus one free pull." pool: type: array description: "All characters eligible from this banner." items: type: object required: [character_id, rarity, base_weight] properties: character_id: type: string rarity: type: string enum: [R, SR, SSR, UR] base_weight: type: number minimum: 0.0 description: "Relative weight before pity modifiers. Higher = more common." is_featured: type: boolean default: false pity: type: object required: [soft_pity_start, hard_pity, guaranteed_rarity] properties: soft_pity_start: type: integer minimum: 1 description: "Pull count at which SSR/UR rate starts increasing toward hard pity." hard_pity: type: integer minimum: 1 description: "Pull count that guarantees at least guaranteed_rarity." guaranteed_rarity: type: string enum: [SR, SSR, UR] featured_guarantee: type: object description: "50/50 featured character guarantee rules." properties: rate: type: number minimum: 0.0 maximum: 1.0 description: "Chance featured character is selected when SSR hits." guaranteed_after_loss: type: boolean default: true description: "If false on the 50/50, next SSR is guaranteed featured." spark_currency: type: object description: "Only applies to event-type banners." properties: currency_id: type: string spark_cost: type: integer description: "Amount of spark currency required to select a featured character." active_from: type: string format: date-time description: "ISO 8601 UTC datetime. Null means active from server start." active_until: type: string format: date-time description: "ISO 8601 UTC datetime. Null means permanent." rerun_policy: type: string enum: [permanent, will_rerun, no_rerun_planned, collaboration_locked] default: permanent description: "Displayed to players per the fair-visibility design pillar."