Skip to content

Wife3 Scoring System.hx

AutisticLulu edited this page Oct 18, 2025 · 8 revisions

Wife3 Scoring Script for Psych Engine

HScript-based scoring system that implements Etterna's Wife3 accuracy calculation into Psych Engine.

Wife3 Scoring System - API Reference

Wife3 (Wife version 3) is Etterna's timing-based accuracy algorithm. This script provides 15 global callback functions accessible from any Lua or HScript.


📖 Table of Contents


Configuration Functions

wife3_setEnabled(enabled: Bool)

Enable or disable Wife3 scoring system.

wife3_setEnabled(true)   -- Enable (default)
wife3_setEnabled(false)  -- Disable

wife3_setJudgePreset(judgeNum: Int)

Set difficulty preset (1-9). See Judge Presets for details.

wife3_setJudgePreset(4)  -- J4 = Standard difficulty
wife3_setJudgePreset(9)  -- J9 = JUSTICE (hardest)

wife3_setJudgeScale(scale: Float)

Manually set judge scale value (advanced users).

wife3_setJudgeScale(1.0)   -- Same as J4
wife3_setJudgeScale(0.4)   -- Same as J9

Note: Scale range is 0.009 to 0.090. Values outside this range are clamped.

wife3_resetAccuracy()

Reset all Wife3 counters to zero. Useful for practice mode or custom restart mechanics.

wife3_resetAccuracy()

Data Getter Functions

wife3_getAccuracy(): Float

Returns current accuracy percentage (0-100) based on notes hit so far.

local accuracy = wife3_getAccuracy()
-- Example: 98.45

wife3_getScore(): Int

Returns current song score (Wife3 calculated).

local score = wife3_getScore()
-- Example: 987654

wife3_getGrade(percent: Float): String

Returns letter grade for a given percentage value.

local currentGrade = wife3_getGrade(wife3_getAccuracy())
-- Returns: 'AAAAA', 'AAAA', 'AAA', 'AA', 'A', 'B', 'C', 'D', or 'F'

local hypotheticalGrade = wife3_getGrade(97.5)
-- Calculate grade for any percentage

wife3_getJudgeScale(): Float

Returns the current judge scale value.

local scale = wife3_getJudgeScale()
-- Example: 1.0 (J4)

wife3_getJudgePreset(): Float

Returns the current judge preset as a number (can be fractional for custom scales).

local preset = wife3_getJudgePreset()
-- Returns: 4.0 for J4, 7.25 for custom scale between J7 and J8, etc.

Judgement Counters

Get the number of hits in each timing window:

wife3_getMarvelousHits(): Int

Returns number of Marvelous hits (≤ 22ms × judge scale).

wife3_getPerfectHits(): Int

Returns number of Perfect hits (≤ 45ms × judge scale).

wife3_getGreatHits(): Int

Returns number of Great hits (≤ 90ms × judge scale).

wife3_getGoodHits(): Int

Returns number of Good hits (≤ 135ms × judge scale).

wife3_getBadHits(): Int

Returns number of Bad hits (≤ 180ms × judge scale).


Utility Functions

wife3_getTimingWindow(windowType: String): Float

Get a timing window (in ms) based on current judge scale.

local marvelousWindow = wife3_getTimingWindow('marvelous')  -- ~22ms * scale
local perfectWindow = wife3_getTimingWindow('perfect')      -- ~45ms * scale
local greatWindow = wife3_getTimingWindow('great')          -- ~90ms * scale
local goodWindow = wife3_getTimingWindow('good')            -- ~135ms * scale
local badWindow = wife3_getTimingWindow('bad')              -- ~180ms * scale

Valid window types: 'marvelous', 'perfect', 'great', 'good', 'bad'

wife3_formatPercent(value: Float): String

Format a number to 2 decimal places.

local formatted = wife3_formatPercent(98.456789)
-- Returns: '98.45'

Judge Presets

Judge presets control the timing window difficulty. Lower numbers are easier (wider timing windows), higher numbers are harder (tighter timing windows).

Preset Judge Scale Value Description Typical Use Case
1 J1 4.0 Easiest Casual play, story mode
2 J2 3.0 Very Easy Beginner friendly
3 J3 2.0 Easy Learning new charts
4 J4 1.0 Standard Default/Competitive baseline
5 J5 0.9 Slightly Hard Intermediate challenge
6 J6 0.75 Hard Advanced players
7 J7 0.6 Very Hard Expert challenge
8 J8 0.5 Extremely Hard Mastery testing
9 J9 0.4 JUSTICE Hardest possible

Setting Judge Preset

wife3_setJudgePreset(4)  -- Standard (default)
wife3_setJudgePreset(9)  -- JUSTICE (hardest)

Manual Scale Setting

For fine-tuned control, use wife3_setJudgeScale():

wife3_setJudgeScale(1.0)   -- J4 equivalent
wife3_setJudgeScale(0.6)   -- J7 equivalent
wife3_setJudgeScale(0.85)  -- Custom (between J5 and J6)

Grading System

Wife3 uses Etterna's letter grade system based on accuracy percentage:

Grade Min % Description Tier
AAAAA 99.70% Quadstar Nearly perfect
AAAA 99.50% Quad Exceptional
AAA 99.00% Triple Excellent
AA 98.00% Double Very Good
A 96.50% Single Good
B 93.00% B Tier Above Average
C 90.00% C Tier Average
D 80.00% D Tier Below Average
F < 80.00% Failed Needs Improvement

Grade Calculation

Grades are calculated using the wife3_getGrade(percent) function:

local currentGrade = wife3_getGrade(wife3_getAccuracy())
-- Returns current grade based on accuracy

local hypotheticalGrade = wife3_getGrade(97.5)
-- Calculate grade for any percentage

UI Examples

The Wife3 Scoring System is designed to be UI-agnostic, providing only the calculation backend. Here are complete UI implementation examples for both Lua and HScript.

Lua

Here's a minimal Lua example:

function onCreatePost()
    makeLuaText('wife3Display', '', 0, 0, getProperty('scoreTxt.y') + 25)
    setTextSize('wife3Display', 18)
    setTextFont('wife3Display', 'vcr.ttf')
    setTextBorder('wife3Display', 1, '000000')
    setProperty('wife3Display.fieldWidth', screenWidth)
    setTextAlignment('wife3Display', 'center')
    setObjectCamera('wife3Display', 'hud')
    addLuaText('wife3Display')
end

function updateWife3()
    local acc = wife3_formatPercent(wife3_getAccuracy())
    local grade = wife3_getGrade(wife3_getAccuracy())
    local score = wife3_getScore()
    
    setTextString('wife3Display', 'Wife3: ' .. score .. ' | ' .. acc .. '% (' .. grade .. ')')
end

function goodNoteHit(id, data, type, sustain)
    if not sustain then updateWife3() end
end

function noteMiss()
    updateWife3()
end

Available Functions Summary

This script provides the following 15 global callback functions:

Configuration:

  • wife3_setEnabled(enabled: Bool)
  • wife3_setJudgePreset(judgeNum: Int)
  • wife3_setJudgeScale(scale: Float)
  • wife3_resetAccuracy()

Data Getters:

  • wife3_getAccuracy(): Float
  • wife3_getScore(): Int
  • wife3_getGrade(percent: Float): String
  • wife3_getJudgeScale(): Float
  • wife3_getJudgePreset(): Float

Judgement Counters:

  • wife3_getMarvelousHits(): Int
  • wife3_getPerfectHits(): Int
  • wife3_getGreatHits(): Int
  • wife3_getGoodHits(): Int
  • wife3_getBadHits(): Int

Utilities:

  • wife3_getTimingWindow(windowType: String): Float
  • wife3_formatPercent(value: Float): String

Clone this wiki locally