-
Notifications
You must be signed in to change notification settings - Fork 0
Wife3 Scoring System.hx
HScript-based scoring system that implements Etterna's Wife3 accuracy calculation into Psych Engine.
Wife3 (Wife version 3) is Etterna's timing-based accuracy algorithm. This script provides 15 global callback functions accessible from any Lua or HScript.
- Configuration Functions
- Data Getter Functions
- Utility Functions
- Judge Presets
- Grading System
- UI Examples
Enable or disable Wife3 scoring system.
wife3_setEnabled(true) -- Enable (default)
wife3_setEnabled(false) -- DisableSet difficulty preset (1-9). See Judge Presets for details.
wife3_setJudgePreset(4) -- J4 = Standard difficulty
wife3_setJudgePreset(9) -- J9 = JUSTICE (hardest)Manually set judge scale value (advanced users).
wife3_setJudgeScale(1.0) -- Same as J4
wife3_setJudgeScale(0.4) -- Same as J9Note: Scale range is 0.009 to 0.090. Values outside this range are clamped.
Reset all Wife3 counters to zero. Useful for practice mode or custom restart mechanics.
wife3_resetAccuracy()Returns current accuracy percentage (0-100) based on notes hit so far.
local accuracy = wife3_getAccuracy()
-- Example: 98.45Returns current song score (Wife3 calculated).
local score = wife3_getScore()
-- Example: 987654Returns 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 percentageReturns the current judge scale value.
local scale = wife3_getJudgeScale()
-- Example: 1.0 (J4)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.Get the number of hits in each timing window:
Returns number of Marvelous hits (≤ 22ms × judge scale).
Returns number of Perfect hits (≤ 45ms × judge scale).
Returns number of Great hits (≤ 90ms × judge scale).
Returns number of Good hits (≤ 135ms × judge scale).
Returns number of Bad hits (≤ 180ms × judge scale).
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 * scaleValid window types: 'marvelous', 'perfect', 'great', 'good', 'bad'
Format a number to 2 decimal places.
local formatted = wife3_formatPercent(98.456789)
-- Returns: '98.45'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 |
wife3_setJudgePreset(4) -- Standard (default)
wife3_setJudgePreset(9) -- JUSTICE (hardest)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)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 |
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 percentageThe 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.
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()
endThis 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(): Floatwife3_getScore(): Intwife3_getGrade(percent: Float): Stringwife3_getJudgeScale(): Floatwife3_getJudgePreset(): Float
Judgement Counters:
wife3_getMarvelousHits(): Intwife3_getPerfectHits(): Intwife3_getGreatHits(): Intwife3_getGoodHits(): Intwife3_getBadHits(): Int
Utilities:
wife3_getTimingWindow(windowType: String): Floatwife3_formatPercent(value: Float): String