2026-07-15 14:44:29 +09:00
"use strict" ;
const fs = require ( "fs" ) ;
const vm = require ( "vm" ) ;
const path = require ( "path" ) ;
const source = fs . readFileSync ( path . join ( _ _dirname , ".." , "js" , "achievements.js" ) , "utf8" ) ;
class ClassList {
constructor ( ) { this . values = new Set ( [ "hidden" ] ) ; }
add ( ... names ) { names . forEach ( name => this . values . add ( name ) ) ; }
remove ( ... names ) { names . forEach ( name => this . values . delete ( name ) ) ; }
contains ( name ) { return this . values . has ( name ) ; }
toggle ( name , force ) {
const next = force === undefined ? ! this . values . has ( name ) : Boolean ( force ) ;
if ( next ) this . values . add ( name ) ; else this . values . delete ( name ) ;
return next ;
}
}
class Element {
constructor ( id = "" , tagName = "div" ) {
this . tagName = String ( tagName || "div" ) . toUpperCase ( ) ;
this . open = false ;
this . id = id ;
this . className = "" ;
this . classList = new ClassList ( ) ;
this . dataset = { } ;
this . styles = new Map ( ) ;
this . style = {
setProperty : ( name , value ) => this . styles . set ( name , value ) ,
removeProperty : name => this . styles . delete ( name ) ,
} ;
this . children = [ ] ;
this . textContent = "" ;
this . tabIndex = - 1 ;
this . isConnected = true ;
}
append ( ... children ) { this . children . push ( ... children ) ; }
replaceChildren ( ... children ) { this . children = children ; }
setAttribute ( ) { }
addEventListener ( ) { }
focus ( ) { }
getBoundingClientRect ( ) { return { left : 0 , top : 0 , width : 100 , height : 30 } ; }
get offsetWidth ( ) { return 100 ; }
}
function createHarness ( existingStorage = null , search = "" , options = { } ) {
const storage = existingStorage || new Map ( ) ;
const elements = new Map ( ) ;
const ids = [
"achievementsBtn" , "achievementButtonCount" , "achievementsDialog" , "achievementDialogCount" ,
"achievementsCloseBtn" , "achievementsCloseIconBtn" , "achievementRefreshBtn" , "achievementResetBtn" , "achievementUnlockAllBtn" ,
"achievementList" , "achievementSharedStatus" , "achievementToast" , "achievementToastTitle" , "pauseBtn" ,
] ;
ids . forEach ( id => elements . set ( id , new Element ( id ) ) ) ;
elements . get ( "achievementsDialog" ) . classList . add ( "hidden" ) ;
elements . get ( "achievementToast" ) . classList . add ( "hidden" ) ;
let timerId = 0 ;
const context = {
console , Date , Intl , Math , JSON , Object , Array , Map , Set , WeakMap , Promise ,
Number , String , Boolean , Error , AbortController , encodeURIComponent , URLSearchParams ,
location : { protocol : options . protocol || "file:" , search } ,
crypto : { randomUUID : ( ) => "11111111-1111-4111-8111-111111111111" } ,
localStorage : {
getItem ( key ) { return storage . has ( key ) ? storage . get ( key ) : null ; } ,
setItem ( key , value ) { storage . set ( key , String ( value ) ) ; } ,
removeItem ( key ) { storage . delete ( key ) ; } ,
} ,
document : {
hidden : false ,
getElementById ( id ) { return elements . get ( id ) || null ; } ,
createElement ( tagName ) { return new Element ( "" , tagName ) ; } ,
addEventListener ( ) { } ,
} ,
TarinaiEvents : { emit ( ) { } } ,
showToast ( ) { } ,
audio : { uiClick ( ) { } } ,
setTimeout ( ) { timerId += 1 ; return timerId ; } ,
clearTimeout ( ) { } ,
setInterval ( ) { timerId += 1 ; return timerId ; } ,
clearInterval ( ) { } ,
fetch : options . fetch || ( async ( ) => { throw new Error ( "offline" ) ; } ) ,
2026-07-16 22:12:03 +09:00
TARINAI _VERSION : "39.16.65" ,
2026-07-15 14:44:29 +09:00
TarinaiGameDialogs : { confirm : async ( ) => true } ,
} ;
context . window = context ;
context . globalThis = context ;
vm . createContext ( context ) ;
vm . runInContext ( source , context , { filename : "achievements.js" } ) ;
return { context , api : context . TarinaiAchievements , storage , elements } ;
}
function assert ( condition , message ) { if ( ! condition ) throw new Error ( message ) ; }
function unlocked ( h , id ) { return h . api . isUnlocked ( id ) ; }
const expectedIds = [
"first_birth" , "natural_zunchi_slave" , "natural_tarinai_king" , "self_zunchi_death" ,
"natural_zunchi_slave_5_generations" , "natural_tarinai_king_3_generations" ,
"death_50_in_10_seconds" , "birth_50_in_60_seconds" , "great_mother_1000_births" , "lifespan_completed" ,
"soccer_ball_death" , "fight_pair_danger_kill" , "all_non_sleep_diseased_25" , "colony_happy" , "direct_feed_33" ,
"ignite_during_birth_ritual" , "laxative_starvation" , "idle_observer_5_minutes" ,
"placed_objects_100" , "mechanized_industry" , "safe_colony_25_5_minutes" ,
"ants_alive_25" , "ants_killed_100" , "secret_collection_9_slots" ,
"pause_spam_4_in_1_second" , "continuous_play_1_hour" , "below_absolute_zero_item" ,
"undo_mass_revival" , "robot_cleaner_100" , "held_30_seconds" , "minimalist_happy" ,
"overprotective" , "self_sufficient" , "unplanned_city_30" , "sauna_cold_plunge" ,
"rain_shelter_all" , "medicine_ledger_all" , "mercury_lifespan" , "enemy_enemy_friend" ,
"revolution" , "fuel_to_fire" , "undo_20" , "redo_20" ,
"eternal_history_generation_10" , "king_full_satisfaction" , "slave_zero_satisfaction" , "town_doctor_50" , "poke_plushie_fling" ,
"chaos_seeker_666_fights" , "clean_freak_robot_only" , "true_tarinai_observer" ,
2026-07-15 16:27:56 +09:00
"sniper_333_shots" , "megalopolis" , "fertility_seeker_721_love_births" ,
2026-07-16 22:12:03 +09:00
"low_fps_single_digit" , "continuous_play_24_hours" , "sandbox_five_toilets" ,
"park_ground_changed" , "ground_change_4_in_1_second" ,
"ant_nest_without_tarinai" , "sticky_bomb_15_passes" ,
"daily_play_7_days" , "wire_shock_7_tarinai" , "information_industry" ,
2026-07-15 14:44:29 +09:00
] ;
( async function run ( ) {
let h = createHarness ( ) ;
let storage ;
2026-07-16 22:12:03 +09:00
assert ( h . api . definitions . length === 64 , "definition count must be 64" ) ;
2026-07-15 14:44:29 +09:00
assert ( JSON . stringify ( h . api . definitions . map ( d => d . id ) ) === JSON . stringify ( expectedIds ) , "definition IDs mismatch" ) ;
const categorizedIds = h . api . categories . flatMap ( category => category . ids ) ;
assert ( categorizedIds . length === expectedIds . length , "achievement category count mismatch" ) ;
assert ( new Set ( categorizedIds ) . size === expectedIds . length , "achievement category contains duplicates" ) ;
assert ( expectedIds . every ( id => categorizedIds . includes ( id ) ) , "achievement category misses an ID" ) ;
h . api . open ( ) ;
const titles = Object . fromEntries ( h . api . definitions . map ( def => [ def . id , def . title ] ) ) ;
assert ( titles . natural _zunchi _slave === "ずんちどれい" , "slave title mismatch" ) ;
assert ( titles . natural _tarinai _king === "たりない王" , "king title mismatch" ) ;
assert ( titles . self _zunchi _death === "あぁ^~ たまらねぇぜ" , "self-zunchi title mismatch" ) ;
assert ( titles . natural _zunchi _slave _5 _generations === "末代までの恥" , "five-generation title mismatch" ) ;
assert ( titles . natural _tarinai _king _3 _generations === "華麗なる王族" , "three-generation title mismatch" ) ;
assert ( titles . death _50 _in _10 _seconds === "6番目の大量絶滅" , "mass-extinction title mismatch" ) ;
assert ( titles . birth _50 _in _60 _seconds === "ベビーブーム" , "baby-boom title mismatch" ) ;
assert ( titles . idle _observer _5 _minutes === "監視カメラ" , "observer title mismatch" ) ;
assert ( titles . laxative _starvation === "内臓全部出た" , "laxative title mismatch" ) ;
assert ( titles . colony _happy === "管理された楽園" , "happy colony title mismatch" ) ;
assert ( titles . soccer _ball _death === "豆野、殺ッカーやろうぜ!" , "soccer title mismatch" ) ;
assert ( titles . ants _alive _25 === "アリの惑星" , "ant planet title mismatch" ) ;
assert ( titles . all _non _sleep _diseased _25 === "緊急事態宣言" , "emergency title mismatch" ) ;
assert ( titles . secret _collection _9 _slots === "秘密のコレクション" , "save-slot title mismatch" ) ;
assert ( titles . pause _spam _4 _in _1 _second === "何やってるの?" , "pause-spam title mismatch" ) ;
assert ( titles . continuous _play _1 _hour === "めっちゃたりない観察" , "continuous-play title mismatch" ) ;
assert ( titles . below _absolute _zero _item === "物理法則を下側に超越" , "absolute-zero title mismatch" ) ;
assert ( titles . ignite _during _birth _ritual === "燃え上がる恋" , "ritual ignition title mismatch" ) ;
assert ( titles . safe _colony _25 _5 _minutes === "安全第一" , "safe colony title mismatch" ) ;
assert ( titles . great _mother _1000 _births === "大いなる母" , "great mother title mismatch" ) ;
assert ( titles . fight _pair _danger _kill === "喧嘩両成敗" , "fight-pair title mismatch" ) ;
assert ( titles . direct _feed _33 === "餌やりじいさん" , "feeding title mismatch" ) ;
assert ( titles . eternal _history _generation _10 === "悠久の歴史" , "generation title mismatch" ) ;
assert ( titles . king _full _satisfaction === "五体満足" , "king effect title mismatch" ) ;
assert ( titles . slave _zero _satisfaction === "零体満足" , "slave effect title mismatch" ) ;
assert ( titles . chaos _seeker _666 _fights === "混沌ヲ希求スル者" , "chaos seeker title mismatch" ) ;
assert ( titles . clean _freak _robot _only === "潔癖症" , "clean freak title mismatch" ) ;
assert ( titles . true _tarinai _observer === "真・たりない観察" , "completionist title mismatch" ) ;
2026-07-15 16:27:56 +09:00
assert ( titles . sniper _333 _shots === "狙撃手" , "sniper title mismatch" ) ;
assert ( titles . megalopolis === "メガロポリス" , "megalopolis title mismatch" ) ;
assert ( titles . fertility _seeker _721 _love _births === "豊穣ヲ希求スル者" , "fertility title mismatch" ) ;
2026-07-16 22:12:03 +09:00
assert ( titles . low _fps _single _digit === "スペックがたりない" , "low-fps title mismatch" ) ;
assert ( titles . continuous _play _24 _hours === "寝ろ" , "24-hour title mismatch" ) ;
assert ( titles . sandbox _five _toilets === "砂場" , "sandbox title mismatch" ) ;
assert ( titles . park _ground _changed === "そこ公共空間だよ?" , "park-ground title mismatch" ) ;
assert ( titles . ground _change _4 _in _1 _second === "破格の工事費用" , "ground-spam title mismatch" ) ;
assert ( titles . ant _nest _without _tarinai === "アリ観察" , "ant observation title mismatch" ) ;
assert ( titles . sticky _bomb _15 _passes === "命のバトン" , "sticky-bomb relay title mismatch" ) ;
assert ( titles . daily _play _7 _days === "毎日たりない観察" , "daily observation title mismatch" ) ;
assert ( titles . wire _shock _7 _tarinai === "抵抗器じゃない" , "wire shock title mismatch" ) ;
2026-07-15 14:44:29 +09:00
const descriptions = Object . fromEntries ( h . api . definitions . map ( def => [ def . id , def . description ] ) ) ;
assert ( descriptions . natural _zunchi _slave === "ずんちどれいが出現する。" , "slave description mismatch" ) ;
assert ( descriptions . natural _tarinai _king === "たりない王が出現する。" , "king description mismatch" ) ;
assert ( descriptions . self _zunchi _death === "おしり鋲を抜いた時、自分のずんちで自爆する。" , "self-zunchi description mismatch" ) ;
assert ( descriptions . natural _zunchi _slave _5 _generations === "5代連続でずんちどれい( 鎖なし) " , "five-generation description mismatch" ) ;
assert ( descriptions . natural _tarinai _king _3 _generations === "3代連続でたりない王( 王冠なし) " , "three-generation description mismatch" ) ;
assert ( descriptions . great _mother _1000 _births . includes ( "3333体" ) , "great mother description threshold mismatch" ) ;
assert ( descriptions . robot _cleaner _100 . includes ( "200個" ) , "cleaner description threshold mismatch" ) ;
assert ( descriptions . minimalist _happy . includes ( "6日目以降" ) , "minimalist start-day description mismatch" ) ;
2026-07-15 16:27:56 +09:00
assert ( descriptions . chaos _seeker _666 _fights . includes ( "けんか餅" ) && descriptions . chaos _seeker _666 _fights . includes ( "666回" ) , "chaos seeker description mismatch" ) ;
assert ( descriptions . sniper _333 _shots . includes ( "333発" ) , "sniper description mismatch" ) ;
assert ( descriptions . megalopolis . includes ( "10個" ) && descriptions . megalopolis . includes ( "15個" ) && descriptions . megalopolis . includes ( "100体" ) , "megalopolis description mismatch" ) ;
assert ( descriptions . fertility _seeker _721 _love _births . includes ( "へこ餅" ) && descriptions . fertility _seeker _721 _love _births . includes ( "721回" ) , "fertility description mismatch" ) ;
2026-07-16 22:12:03 +09:00
assert ( descriptions . idle _observer _5 _minutes === "5分間画面を見るだけ" , "observer description mismatch" ) ;
assert ( descriptions . safe _colony _25 _5 _minutes . includes ( "寿命以外で" ) , "safe-colony lifespan exclusion description mismatch" ) ;
assert ( descriptions . pause _spam _4 _in _1 _second . includes ( "何もない部分" ) , "empty-click description mismatch" ) ;
assert ( descriptions . low _fps _single _digit === "fpsを1桁にする。" , "low-fps description mismatch" ) ;
assert ( descriptions . park _ground _changed === "公園の地面を勝手に変更する。" , "park-ground description mismatch" ) ;
assert ( descriptions . ground _change _4 _in _1 _second === "地面を変えすぎて破産する。" , "ground-spam description mismatch" ) ;
assert ( descriptions . sauna _cold _plunge === "暑すぎる状態になったたりないを、15秒以内に寒すぎる状態にする。" , "sauna description mismatch" ) ;
assert ( descriptions . ant _nest _without _tarinai === "アリの巣があるが、たりないがいない。" , "ant observation description mismatch" ) ;
assert ( descriptions . sticky _bomb _15 _passes === "粘着ボムを爆発までに15回以上パスする。" , "sticky-bomb relay description mismatch" ) ;
2026-07-15 14:44:29 +09:00
assert ( ! source . includes ( "TarinaiTooltips" ) , "achievement tooltips were not removed" ) ;
assert ( source . includes ( "PRE_UNLOCK_DESCRIPTION_IDS" ) , "pre-unlock disclosure allowlist is missing" ) ;
function walk ( node , out = [ ] ) { for ( const child of node ? . children || [ ] ) { out . push ( child ) ; walk ( child , out ) ; } return out ; }
const cards = walk ( h . elements . get ( "achievementList" ) ) . filter ( node => node . dataset ? . achievementId ) ;
const firstBirthCard = cards . find ( node => node . dataset . achievementId === "first_birth" ) ;
const disclosedSlaveCard = cards . find ( node => node . dataset . achievementId === "natural_zunchi_slave" ) ;
const disclosedKingCard = cards . find ( node => node . dataset . achievementId === "natural_tarinai_king" ) ;
const disclosedRevolutionCard = cards . find ( node => node . dataset . achievementId === "revolution" ) ;
const disclosedLaxativeCard = cards . find ( node => node . dataset . achievementId === "laxative_starvation" ) ;
const eternalHistoryCard = cards . find ( node => node . dataset . achievementId === "eternal_history_generation_10" ) ;
2026-07-16 22:12:03 +09:00
const lowFpsCard = cards . find ( node => node . dataset . achievementId === "low_fps_single_digit" ) ;
const sleepCard = cards . find ( node => node . dataset . achievementId === "continuous_play_24_hours" ) ;
2026-07-15 14:44:29 +09:00
const hiddenCard = cards . find ( node => node . dataset . achievementId === "self_zunchi_death" ) ;
assert ( firstBirthCard . children [ 1 ] . children [ 0 ] . children [ 1 ] . textContent === descriptions . first _birth , "disclosed locked condition is not shown in the UI" ) ;
2026-07-16 22:12:03 +09:00
for ( const card of [ disclosedSlaveCard , disclosedKingCard , disclosedRevolutionCard , disclosedLaxativeCard , eternalHistoryCard , lowFpsCard , sleepCard ] ) {
2026-07-15 14:44:29 +09:00
assert ( card . children [ 1 ] . children [ 0 ] . children [ 1 ] . textContent !== "? ? ? " , "requested pre-unlock condition is hidden" ) ;
}
assert ( hiddenCard . children [ 1 ] . children [ 0 ] . children [ 1 ] . textContent === "? ? ? " , "undisclosed locked condition is not hidden as question marks" ) ;
const groups = h . elements . get ( "achievementList" ) . children ;
assert ( groups . length === 4 , "achievement UI must contain exactly four category groups" ) ;
assert ( JSON . stringify ( groups . map ( group => group . dataset . achievementGroup ) ) === JSON . stringify ( [ "ecology" , "experiment" , "construction" , "operation" ] ) , "achievement category order mismatch" ) ;
assert ( groups . every ( group => group . tagName === "DETAILS" ) , "achievement categories are not collapsible details" ) ;
const categoryTitles = h . api . categories . map ( category => category . title ) ;
assert ( JSON . stringify ( categoryTitles ) === JSON . stringify ( [ "生態" , "実験" , "建築" , "その他" ] ) , "achievement category titles mismatch" ) ;
2026-07-16 22:12:03 +09:00
const operationIds = h . api . categories . find ( category => category . id === "operation" ) . ids ;
assert ( JSON . stringify ( operationIds . slice ( - 2 ) ) === JSON . stringify ( [ "continuous_play_1_hour" , "true_tarinai_observer" ] ) , "observation achievements are not at the bottom of その他" ) ;
2026-07-15 14:44:29 +09:00
h . api . unlock ( "natural_zunchi_slave" ) ;
const rerenderedGroups = h . elements . get ( "achievementList" ) . children ;
const ecologyCards = walk ( rerenderedGroups [ 0 ] ) . filter ( node => node . dataset ? . achievementId ) ;
const allRenderedCards = rerenderedGroups . flatMap ( group => walk ( group ) . filter ( node => node . dataset ? . achievementId ) ) ;
assert ( ecologyCards [ 0 ] ? . dataset . achievementId === "natural_zunchi_slave" , "unlocked achievement was not moved to the top of its category" ) ;
assert ( allRenderedCards . filter ( card => card . dataset . achievementId === "natural_zunchi_slave" ) . length === 1 , "unlocked achievement is duplicated across categories" ) ;
assert ( await h . api . reset ( ) , "in-game achievement reset confirmation was not accepted" ) ;
assert ( ! h . api . isUnlocked ( "natural_zunchi_slave" ) , "achievement reset did not clear unlocked state" ) ;
assert ( source . includes ( 'card.style.setProperty("--achievement-rate"' ) , "achievement percentage bar is not wired" ) ;
h = createHarness ( ) ;
h . api . recordBirth ( { world : { time : 0 } } ) ;
assert ( unlocked ( h , "first_birth" ) , "first birth did not unlock" ) ;
h = createHarness ( ) ;
const birthWorld = { time : 0 } ;
for ( let i = 0 ; i < 29 ; i += 1 ) { birthWorld . time = i ; h . api . recordBirth ( { world : birthWorld } ) ; }
assert ( ! unlocked ( h , "birth_50_in_60_seconds" ) , "rapid birth unlocked before 30" ) ;
birthWorld . time = 59 ;
h . api . recordBirth ( { world : birthWorld } ) ;
assert ( unlocked ( h , "birth_50_in_60_seconds" ) , "rapid birth did not unlock at 30" ) ;
storage = new Map ( ) ;
h = createHarness ( storage ) ;
for ( let i = 0 ; i < 2000 ; i += 1 ) h . api . recordBirth ( { world : { time : i % 61 } } ) ;
assert ( ! unlocked ( h , "great_mother_1000_births" ) , "great mother unlocked before 3333" ) ;
h = createHarness ( storage ) ;
for ( let i = 0 ; i < 1332 ; i += 1 ) h . api . recordBirth ( { world : { time : i % 61 } } ) ;
assert ( ! unlocked ( h , "great_mother_1000_births" ) , "great mother unlocked at 3332" ) ;
h . api . recordBirth ( { world : { time : 1 } } ) ;
assert ( unlocked ( h , "great_mother_1000_births" ) , "great mother did not persist to 3333" ) ;
h = createHarness ( ) ;
const deathWorld = { time : 0 } ;
for ( let i = 0 ; i < 49 ; i += 1 ) { deathWorld . time = i * 0.19 ; h . api . recordDeath ( { world : deathWorld , reason : "accident" } ) ; }
assert ( ! unlocked ( h , "death_50_in_10_seconds" ) , "rapid death unlocked before 50" ) ;
deathWorld . time = 9.5 ;
h . api . recordDeath ( { world : deathWorld , reason : "accident" } ) ;
assert ( unlocked ( h , "death_50_in_10_seconds" ) , "rapid death did not unlock at 50" ) ;
h = createHarness ( ) ;
h . api . recordDeath ( { world : { time : 1 } , tarinai : { } , reason : "天寿を全うした" } ) ;
assert ( unlocked ( h , "lifespan_completed" ) , "lifespan did not unlock" ) ;
h = createHarness ( ) ;
h . api . recordDeath ( { world : { time : 1 } , tarinai : { _achievementLaxativeActiveThisFrame : true } , reason : "飢餓" } ) ;
assert ( unlocked ( h , "laxative_starvation" ) , "laxative starvation did not unlock" ) ;
h = createHarness ( ) ;
const slaveWorld = { } ;
[ 1 , 2 , 4 , 5 , 6 ] . forEach ( generation => h . api . recordNaturalZunchiSlave ( { world : slaveWorld , tarinai : { generation } } ) ) ;
assert ( ! unlocked ( h , "natural_zunchi_slave_5_generations" ) , "slave run ignored generation gap" ) ;
h . api . recordNaturalZunchiSlave ( { world : slaveWorld , tarinai : { generation : 3 } } ) ;
assert ( unlocked ( h , "natural_zunchi_slave_5_generations" ) , "slave five-generation run did not unlock" ) ;
h = createHarness ( ) ;
const kingWorld = { } ;
[ 4 , 5 , 6 ] . forEach ( generation => h . api . recordNaturalTarinaiKing ( { world : kingWorld , tarinai : { generation } } ) ) ;
assert ( unlocked ( h , "natural_tarinai_king_3_generations" ) , "king three-generation run did not unlock" ) ;
h = createHarness ( ) ;
const feedWorldA = { time : 0 , achievementDirectFeedCount : 0 } ;
for ( let i = 0 ; i < 32 ; i += 1 ) h . api . recordDirectFeed ( { world : feedWorldA } ) ;
assert ( ! unlocked ( h , "direct_feed_33" ) , "direct feed unlocked before 33" ) ;
const feedWorldB = { time : 0 , achievementDirectFeedCount : 0 } ;
h . api . recordDirectFeed ( { world : feedWorldB } ) ;
assert ( ! unlocked ( h , "direct_feed_33" ) , "direct-feed count survived a field reset" ) ;
h . api . recordDirectFeed ( { world : feedWorldA } ) ;
assert ( unlocked ( h , "direct_feed_33" ) , "direct feed did not unlock at 33 in one field" ) ;
h = createHarness ( ) ;
const diseased = Array . from ( { length : 25 } , ( ) => ( { fightDisease : true , dead : false } ) ) ;
h . api . evaluateWorld ( { tarinai : diseased , ants : [ ] , time : 0 } , { id : "relaxed" } ) ;
assert ( unlocked ( h , "all_non_sleep_diseased_25" ) , "disease colony did not unlock" ) ;
h = createHarness ( ) ;
const happyWorld = { tarinai : [ { dead : false } ] , ants : [ ] , items : [ ] , time : 600 , day : 6 } ;
h . api . evaluateWorld ( happyWorld , { id : "happy" } ) ;
happyWorld . time = 719.99 ;
h . api . evaluateWorld ( happyWorld , { id : "happy" } ) ;
assert ( ! unlocked ( h , "colony_happy" ) , "happy colony unlocked before one day" ) ;
happyWorld . time = 720 ;
h . api . evaluateWorld ( happyWorld , { id : "happy" } ) ;
assert ( unlocked ( h , "colony_happy" ) , "happy colony did not unlock after one day from day 6" ) ;
h = createHarness ( ) ;
const interruptedHappyWorld = { tarinai : [ { dead : false } ] , ants : [ ] , items : [ ] , time : 600 , day : 6 } ;
h . api . evaluateWorld ( interruptedHappyWorld , { id : "happy" } ) ;
interruptedHappyWorld . time = 650 ;
h . api . evaluateWorld ( interruptedHappyWorld , { id : "normal" } ) ;
interruptedHappyWorld . time = 700 ;
h . api . evaluateWorld ( interruptedHappyWorld , { id : "happy" } ) ;
interruptedHappyWorld . time = 819.99 ;
h . api . evaluateWorld ( interruptedHappyWorld , { id : "happy" } ) ;
assert ( ! unlocked ( h , "colony_happy" ) , "interrupted happiness did not restart the one-day timer" ) ;
interruptedHappyWorld . time = 820 ;
h . api . evaluateWorld ( interruptedHappyWorld , { id : "happy" } ) ;
assert ( unlocked ( h , "colony_happy" ) , "happy colony did not unlock one full day after restart" ) ;
h = createHarness ( ) ;
h . api . recordIgnition ( { } ) ;
h . api . recordSelfZunchiDeath ( { } ) ;
h . api . recordSoccerBallDeath ( { } ) ;
assert ( unlocked ( h , "ignite_during_birth_ritual" ) , "ritual ignition failed" ) ;
assert ( unlocked ( h , "self_zunchi_death" ) , "self zunchi failed" ) ;
assert ( unlocked ( h , "soccer_ball_death" ) , "soccer death failed" ) ;
h = createHarness ( ) ;
const dangerItem = { id : "danger-1" , type : "firecracker" , roles : { danger : true } } ;
const fighterA = { id : "a" , dead : true , fightTimer : 2 , fightTargetId : "b" , fightTargetIds : [ "b" ] } ;
const fighterB = { id : "b" , dead : false , fightTimer : 2 , fightTargetId : "a" , fightTargetIds : [ "a" ] } ;
const fightWorld = {
time : 5 ,
tarinai : [ fighterA , fighterB ] ,
fightPairKey ( a , b ) { return [ a . id , b . id ] . sort ( ) . join ( ":" ) ; } ,
isAlreadyFightingPair ( ) { return true ; } ,
} ;
fighterA . world = fightWorld ; fighterB . world = fightWorld ;
h . api . recordDamageSource ( fighterA , dangerItem , { world : fightWorld } ) ;
h . api . recordDeath ( { world : fightWorld , tarinai : fighterA , reason : "爆竹" , fromDamage : true } ) ;
assert ( ! unlocked ( h , "fight_pair_danger_kill" ) , "fight pair unlocked after only one death" ) ;
fightWorld . time = 6 ;
fighterB . dead = true ; fighterB . fightTimer = 0 ; fighterB . fightTargetId = null ; fighterB . fightTargetIds = [ ] ;
h . api . recordDamageSource ( fighterB , dangerItem , { world : fightWorld } ) ;
h . api . recordDeath ( { world : fightWorld , tarinai : fighterB , reason : "爆竹" , fromDamage : true } ) ;
assert ( unlocked ( h , "fight_pair_danger_kill" ) , "fight pair danger kill did not unlock" ) ;
h = createHarness ( ) ;
const falsePositiveA = { id : "fa" , dead : true , fightTimer : 2 , fightTargetId : "fb" , fightTargetIds : [ "fb" ] } ;
const falsePositiveB = { id : "fb" , dead : false , fightTimer : 2 , fightTargetId : "fa" , fightTargetIds : [ "fa" ] } ;
const falsePositiveWorld = {
time : 3 ,
tarinai : [ falsePositiveA , falsePositiveB ] ,
fightPairKey ( a , b ) { return [ a . id , b . id ] . sort ( ) . join ( ":" ) ; } ,
isAlreadyFightingPair ( ) { return true ; } ,
} ;
falsePositiveA . world = falsePositiveWorld ; falsePositiveB . world = falsePositiveWorld ;
h . api . recordDamageSource ( falsePositiveA , dangerItem , { world : falsePositiveWorld } ) ;
h . api . recordDeath ( { world : falsePositiveWorld , tarinai : falsePositiveA , reason : "飢餓" , fromDamage : false } ) ;
falsePositiveWorld . time = 4 ;
falsePositiveB . dead = true ;
h . api . recordDamageSource ( falsePositiveB , dangerItem , { world : falsePositiveWorld } ) ;
h . api . recordDeath ( { world : falsePositiveWorld , tarinai : falsePositiveB , reason : "爆竹" , fromDamage : true } ) ;
assert ( ! unlocked ( h , "fight_pair_danger_kill" ) , "non-lethal danger damage was misclassified as a danger kill" ) ;
h = createHarness ( ) ;
const generationWorld = { time : 0 , maxGeneration : 9 } ;
h . api . recordBirth ( { world : generationWorld , child : { generation : 9 , world : generationWorld } } ) ;
assert ( ! unlocked ( h , "eternal_history_generation_10" ) , "generation history unlocked before generation 10" ) ;
generationWorld . maxGeneration = 10 ;
h . api . recordBirth ( { world : generationWorld , child : { generation : 10 , world : generationWorld } } ) ;
assert ( unlocked ( h , "eternal_history_generation_10" ) , "generation history did not unlock at generation 10" ) ;
h = createHarness ( ) ;
const king = { dead : false , isTarinaiChampion : true , isZunchiSlave : false , powerItemMode : "protein" , sizeItemMode : "" , world : { } } ;
h . api . recordConsumableUse ( { tarinai : king , world : king . world , type : "protein" } ) ;
assert ( ! unlocked ( h , "king_full_satisfaction" ) , "king satisfaction unlocked without giant drug" ) ;
king . sizeItemMode = "giant_drug" ;
h . api . recordConsumableUse ( { tarinai : king , world : king . world , type : "giant_drug" } ) ;
assert ( unlocked ( h , "king_full_satisfaction" ) , "king satisfaction did not unlock with both effects" ) ;
h = createHarness ( ) ;
const slave = { dead : false , isTarinaiChampion : false , isZunchiSlave : true , powerItemMode : "niteropu" , sizeItemMode : "" , world : { } } ;
h . api . recordConsumableUse ( { tarinai : slave , world : slave . world , type : "niteropu" } ) ;
assert ( ! unlocked ( h , "slave_zero_satisfaction" ) , "slave satisfaction unlocked without dwarf drug" ) ;
slave . sizeItemMode = "dwarf_drug" ;
h . api . recordConsumableUse ( { tarinai : slave , world : slave . world , type : "dwarf_drug" } ) ;
assert ( unlocked ( h , "slave_zero_satisfaction" ) , "slave satisfaction did not unlock with both effects" ) ;
h = createHarness ( ) ;
const allExceptCompletionist = expectedIds . filter ( id => id !== "true_tarinai_observer" ) ;
for ( let i = 0 ; i < allExceptCompletionist . length - 1 ; i += 1 ) h . api . unlock ( allExceptCompletionist [ i ] ) ;
assert ( ! unlocked ( h , "true_tarinai_observer" ) , "completionist unlocked before every other achievement" ) ;
h . api . unlock ( allExceptCompletionist [ allExceptCompletionist . length - 1 ] ) ;
assert ( unlocked ( h , "true_tarinai_observer" ) , "completionist did not unlock with every other achievement" ) ;
h = createHarness ( ) ;
const idleWorld = { time : 300 , tarinai : [ ] , ants : [ ] , achievementLastInterventionAt : 0 , achievementNoDeathStartAt : - 1 } ;
h . api . evaluateWorld ( idleWorld , { id : "relaxed" } ) ;
assert ( unlocked ( h , "idle_observer_5_minutes" ) , "idle observer did not unlock" ) ;
storage = new Map ( ) ;
h = createHarness ( storage ) ;
for ( let i = 0 ; i < 60 ; i += 1 ) h . api . recordPlayerPlacement ( { world : { time : 1 } , item : { type : "grass" } } ) ;
assert ( ! unlocked ( h , "placed_objects_100" ) , "placement unlocked before 100" ) ;
h = createHarness ( storage ) ;
for ( let i = 0 ; i < 39 ; i += 1 ) h . api . recordPlayerPlacement ( { world : { time : 1 } , item : { type : "grass" } } ) ;
assert ( ! unlocked ( h , "placed_objects_100" ) , "placement unlocked at 99" ) ;
h . api . recordPlayerPlacement ( { world : { time : 1 } , item : { type : "grass" } } ) ;
assert ( unlocked ( h , "placed_objects_100" ) , "placement did not persist across field reset/reload to 100" ) ;
storage = new Map ( ) ;
h = createHarness ( storage ) ;
h . api . recordLinkPlaced ( "wire" , { world : { time : 1 } , item : { type : "wire" } } ) ;
h . api . recordLinkPlaced ( "insulated_wire" , { world : { time : 2 } , item : { type : "insulated_wire" } } ) ;
const wireProgress = JSON . parse ( storage . get ( "tarinai_achievements_v2" ) ) . progress ;
assert ( wireProgress . placementCount === 2 , "wire placements were not counted toward placed objects" ) ;
assert ( wireProgress . linkTypes . length === 0 , "wire placements incorrectly advanced mechanized link types" ) ;
h = createHarness ( ) ;
h . api . recordLinkPlaced ( "rope" , { world : { time : 1 } } ) ;
h . api . recordLinkPlaced ( "rod" , { world : { time : 1 } } ) ;
h . api . recordLinkPlaced ( "spring" , { world : { time : 1 } } ) ;
assert ( ! unlocked ( h , "mechanized_industry" ) , "mechanized industry unlocked without signal" ) ;
h . api . recordSignalActivation ( { world : { } , target : { type : "gate_fence" } } ) ;
assert ( unlocked ( h , "mechanized_industry" ) , "mechanized industry did not unlock after logical AND" ) ;
assert ( ! unlocked ( h , "signal_automation_first" ) && ! unlocked ( h , "link_craftsman" ) , "removed achievements remain accessible" ) ;
h = createHarness ( ) ;
const safeAlive = Array . from ( { length : 25 } , ( ) => ( { dead : false } ) ) ;
const safeWorld = { time : 0 , tarinai : safeAlive , ants : [ ] , achievementLastInterventionAt : 0 , achievementNoDeathStartAt : - 1 } ;
h . api . evaluateWorld ( safeWorld , { id : "relaxed" } ) ;
safeWorld . time = 300 ;
h . api . evaluateWorld ( safeWorld , { id : "relaxed" } ) ;
assert ( unlocked ( h , "safe_colony_25_5_minutes" ) , "safe colony did not unlock" ) ;
2026-07-16 22:12:03 +09:00
h = createHarness ( ) ;
const lifespanSafeAlive = Array . from ( { length : 25 } , ( ) => ( { dead : false } ) ) ;
const lifespanSafeWorld = { time : 100 , tarinai : lifespanSafeAlive , achievementNoDeathStartAt : 0 } ;
h . api . recordDeath ( { world : lifespanSafeWorld , reason : "天寿を全うした" , tarinai : { deathReason : "天寿を全うした" } } ) ;
assert ( lifespanSafeWorld . achievementNoDeathStartAt === 0 , "lifespan death reset safe-colony timer" ) ;
h . api . recordDeath ( { world : lifespanSafeWorld , reason : "事故" , tarinai : { deathReason : "事故" } } ) ;
assert ( lifespanSafeWorld . achievementNoDeathStartAt === 100 , "non-lifespan death did not reset safe-colony timer" ) ;
2026-07-15 14:44:29 +09:00
h = createHarness ( ) ;
const antWorld = { time : 1 , tarinai : [ ] , ants : Array . from ( { length : 25 } , ( ) => ( { dead : false } ) ) , achievementLastInterventionAt : 0 , achievementNoDeathStartAt : - 1 } ;
h . api . evaluateWorld ( antWorld , { id : "relaxed" } ) ;
assert ( unlocked ( h , "ants_alive_25" ) , "ant herd did not unlock at 25" ) ;
storage = new Map ( ) ;
h = createHarness ( storage ) ;
for ( let i = 0 ; i < 65 ; i += 1 ) h . api . recordAntKilled ( { world : { } } ) ;
assert ( ! unlocked ( h , "ants_killed_100" ) , "ant extermination unlocked before 100" ) ;
h = createHarness ( storage ) ;
for ( let i = 0 ; i < 34 ; i += 1 ) h . api . recordAntKilled ( { world : { } } ) ;
assert ( ! unlocked ( h , "ants_killed_100" ) , "ant extermination unlocked at 99" ) ;
h . api . recordAntKilled ( { world : { } } ) ;
assert ( unlocked ( h , "ants_killed_100" ) , "ant extermination did not persist to 100" ) ;
2026-07-16 22:12:03 +09:00
h = createHarness ( ) ;
const antObservationWorld = { tarinai : [ ] , ants : [ ] , items : [ ] } ;
h . api . evaluateWorld ( antObservationWorld , { } ) ;
assert ( ! unlocked ( h , "ant_nest_without_tarinai" ) , "ant observation unlocked without an ant nest" ) ;
antObservationWorld . items . push ( { type : "ant_nest" , dead : false } ) ;
antObservationWorld . tarinai . push ( { dead : false } ) ;
h . api . evaluateWorld ( antObservationWorld , { } ) ;
assert ( ! unlocked ( h , "ant_nest_without_tarinai" ) , "ant observation unlocked while a tarinai was alive" ) ;
antObservationWorld . tarinai [ 0 ] . dead = true ;
h . api . evaluateWorld ( antObservationWorld , { } ) ;
assert ( unlocked ( h , "ant_nest_without_tarinai" ) , "ant observation did not unlock with a nest and zero living tarinai" ) ;
h = createHarness ( ) ;
const stickyBomb = { type : "sticky_bomb" , dead : false } ;
for ( let i = 0 ; i < 14 ; i += 1 ) h . api . recordStickyBombPass ( stickyBomb , { } ) ;
assert ( ! unlocked ( h , "sticky_bomb_15_passes" ) , "sticky-bomb relay unlocked before 15 passes" ) ;
h . api . recordStickyBombPass ( stickyBomb , { } ) ;
assert ( unlocked ( h , "sticky_bomb_15_passes" ) , "sticky-bomb relay did not unlock at 15 passes" ) ;
2026-07-15 14:44:29 +09:00
h = createHarness ( ) ;
h . api . recordSaveSlotsFilled ( { filled : 8 } ) ;
assert ( ! unlocked ( h , "secret_collection_9_slots" ) , "save-slot collection unlocked before 9" ) ;
h . api . recordSaveSlotsFilled ( { filled : 9 } ) ;
assert ( unlocked ( h , "secret_collection_9_slots" ) , "save-slot collection did not unlock at 9" ) ;
h = createHarness ( ) ;
2026-07-16 22:12:03 +09:00
[ 0 , 250 , 500 ] . forEach ( now => h . api . recordEmptyClick ( { now } ) ) ;
assert ( ! unlocked ( h , "pause_spam_4_in_1_second" ) , "empty-click achievement unlocked before four clicks" ) ;
h . api . recordEmptyClick ( { now : 999 } ) ;
assert ( unlocked ( h , "pause_spam_4_in_1_second" ) , "empty-click achievement did not unlock within one second" ) ;
2026-07-15 14:44:29 +09:00
h = createHarness ( ) ;
2026-07-16 22:12:03 +09:00
[ 0 , 400 , 800 , 1201 ] . forEach ( now => h . api . recordEmptyClick ( { now } ) ) ;
assert ( ! unlocked ( h , "pause_spam_4_in_1_second" ) , "empty-click achievement unlocked outside one-second window" ) ;
2026-07-15 14:44:29 +09:00
h = createHarness ( ) ;
h . api . recordContinuousPlay ( { elapsedMs : 3599999 } ) ;
assert ( ! unlocked ( h , "continuous_play_1_hour" ) , "continuous play unlocked before one hour" ) ;
h . api . recordContinuousPlay ( { elapsedMs : 3600000 } ) ;
assert ( unlocked ( h , "continuous_play_1_hour" ) , "continuous play did not unlock at one hour" ) ;
2026-07-16 22:12:03 +09:00
assert ( ! unlocked ( h , "continuous_play_24_hours" ) , "24-hour play unlocked at one hour" ) ;
h . api . recordContinuousPlay ( { elapsedMs : 86399999 } ) ;
assert ( ! unlocked ( h , "continuous_play_24_hours" ) , "24-hour play unlocked early" ) ;
h . api . recordContinuousPlay ( { elapsedMs : 86400000 } ) ;
assert ( unlocked ( h , "continuous_play_24_hours" ) , "24-hour play did not unlock" ) ;
h = createHarness ( ) ;
h . api . recordLowFps ( { fps : 10 } ) ;
assert ( ! unlocked ( h , "low_fps_single_digit" ) , "low-fps achievement unlocked at 10 fps" ) ;
h . api . recordLowFps ( { fps : 9 } ) ;
assert ( unlocked ( h , "low_fps_single_digit" ) , "low-fps achievement did not unlock at 9 fps" ) ;
h = createHarness ( ) ;
const sandboxWorld = { items : Array . from ( { length : 4 } , ( ) => ( { type : "toilet" , dead : false } ) ) } ;
h . api . evaluateSandbox ( sandboxWorld ) ;
assert ( ! unlocked ( h , "sandbox_five_toilets" ) , "sandbox unlocked before five toilet sands" ) ;
sandboxWorld . items . push ( { type : "toilet" , dead : false } ) ;
h . api . evaluateSandbox ( sandboxWorld ) ;
assert ( unlocked ( h , "sandbox_five_toilets" ) , "sandbox did not unlock at five toilet sands" ) ;
h = createHarness ( ) ;
h . api . recordGroundChange ( { world : { fieldType : "garden" } , previous : "soil" , next : "ice" , now : 0 } ) ;
assert ( ! unlocked ( h , "park_ground_changed" ) , "park-ground achievement unlocked outside park" ) ;
h . api . recordGroundChange ( { world : { fieldType : "park" } , previous : "soil" , next : "ice" , now : 100 } ) ;
assert ( unlocked ( h , "park_ground_changed" ) , "park-ground achievement did not unlock in park" ) ;
h = createHarness ( ) ;
const groundWorld = { fieldType : "garden" } ;
[ 0 , 250 , 500 ] . forEach ( ( now , index ) => h . api . recordGroundChange ( { world : groundWorld , previous : ` g ${ index } ` , next : ` g ${ index + 1 } ` , now } ) ) ;
assert ( ! unlocked ( h , "ground_change_4_in_1_second" ) , "ground-spam achievement unlocked before four changes" ) ;
h . api . recordGroundChange ( { world : groundWorld , previous : "g3" , next : "g4" , now : 999 } ) ;
assert ( unlocked ( h , "ground_change_4_in_1_second" ) , "ground-spam achievement did not unlock within one second" ) ;
2026-07-15 14:44:29 +09:00
h = createHarness ( ) ;
const thermalWorld = {
time : 0 , tarinai : [ ] , ants : [ ] , items : [ { id : "cold" , x : 10 , y : 20 , dead : false } ] ,
temperatureAt ( ) { return - 273.15 ; } , achievementLastInterventionAt : 0 , achievementNoDeathStartAt : - 1 ,
} ;
h . api . evaluateWorld ( thermalWorld , { id : "relaxed" } ) ;
assert ( ! unlocked ( h , "below_absolute_zero_item" ) , "absolute-zero achievement unlocked at exactly absolute zero" ) ;
thermalWorld . temperatureAt = ( ) => - 273.16 ;
h . api . evaluateWorld ( thermalWorld , { id : "relaxed" } ) ;
assert ( unlocked ( h , "below_absolute_zero_item" ) , "absolute-zero achievement did not unlock below absolute zero" ) ;
storage = new Map ( ) ;
storage . set ( "tarinai_achievements_v2" , JSON . stringify ( {
unlocked : { signal _automation _first : 1000 , link _craftsman : 2000 } ,
pending : [ "signal_automation_first" , "link_craftsman" ] ,
progress : { linkTypes : [ "rope" , "rod" , "spring" ] } ,
} ) ) ;
h = createHarness ( storage ) ;
assert ( unlocked ( h , "mechanized_industry" ) , "legacy AND achievements were not migrated" ) ;
storage = new Map ( ) ;
storage . set ( "tarinai_achievements_v2" , JSON . stringify ( {
unlocked : { link _craftsman : 2000 } ,
pending : [ ] ,
progress : { } ,
} ) ) ;
h = createHarness ( storage ) ;
h . api . recordSignalActivation ( { world : { } , target : { type : "gate_fence" } } ) ;
assert ( unlocked ( h , "mechanized_industry" ) , "legacy link-craftsman progress was not reconstructed before a later signal" ) ;
storage = new Map ( ) ;
h = createHarness ( storage , "?debug=1" ) ;
assert ( h . elements . get ( "achievementUnlockAllBtn" ) . hidden === false , "debug all-achievements button was not shown" ) ;
h . api . debugUnlockAll ( ) ;
assert ( h . api . definitions . every ( def => unlocked ( h , def . id ) ) , "debug all-achievements button did not unlock all" ) ;
const debugState = JSON . parse ( storage . get ( "tarinai_achievements_v2" ) ) ;
assert ( debugState . pending . length === 0 , "debug unlocks were queued for shared statistics" ) ;
assert ( debugState . debugUnlocked . length === h . api . definitions . length , "debug unlocks were not marked as local-only" ) ;
h = createHarness ( storage , "" ) ;
assert ( h . api . definitions . every ( def => ! unlocked ( h , def . id ) ) , "debug-only unlocks leaked into normal play" ) ;
storage = new Map ( ) ;
storage . set ( "tarinai_achievements_v2" , JSON . stringify ( {
unlocked : { first _birth : 1700000000123 , lifespan _completed : 1700000000456 } ,
pending : [ ] ,
progress : { } ,
} ) ) ;
const recoveryRequests = [ ] ;
h = createHarness ( storage , "" , {
protocol : "https:" ,
fetch : async ( _url , options = { } ) => {
recoveryRequests . push ( JSON . parse ( options . body || "{}" ) ) ;
return { ok : true , async json ( ) { return { ok : true , totalPlayers : 1 , achievements : { } } ; } } ;
} ,
} ) ;
await h . api . refresh ( ) ;
assert ( recoveryRequests . length === 1 , "recovery sync did not issue exactly one request" ) ;
assert ( recoveryRequests [ 0 ] . action === "sync" , "recovery request did not use bulk sync" ) ;
2026-07-15 16:27:56 +09:00
assert ( recoveryRequests [ 0 ] . completionistEligible === false , "full recovery sync did not report completionist eligibility" ) ;
2026-07-15 14:44:29 +09:00
assert ( recoveryRequests [ 0 ] . unlocked . first _birth === 1700000000123 , "recovery sync omitted first birth timestamp" ) ;
assert ( recoveryRequests [ 0 ] . unlocked . lifespan _completed === 1700000000456 , "recovery sync omitted lifespan timestamp" ) ;
h = createHarness ( ) ;
for ( let i = 0 ; i < 49 ; i += 1 ) h . api . recordFirstAidRecovery ( { recovered : 10 } ) ;
assert ( ! unlocked ( h , "town_doctor_50" ) , "doctor unlocked before 50 recoveries" ) ;
h . api . recordFirstAidRecovery ( { recovered : 0 } ) ;
assert ( ! unlocked ( h , "town_doctor_50" ) , "zero recovery counted for doctor" ) ;
h . api . recordFirstAidRecovery ( { recovered : 1 } ) ;
assert ( unlocked ( h , "town_doctor_50" ) , "doctor did not unlock at 50 recoveries" ) ;
h = createHarness ( ) ;
h . api . recordPlushiePokeFling ( { } ) ;
assert ( unlocked ( h , "poke_plushie_fling" ) , "plushie poke achievement did not unlock" ) ;
storage = new Map ( ) ;
h = createHarness ( storage ) ;
const chaosWorld = { time : 0 } ;
2026-07-15 16:27:56 +09:00
for ( let i = 0 ; i < 700 ; i += 1 ) h . api . recordFightStarted ( { world : chaosWorld , a : { } , b : { } } ) ;
assert ( ! unlocked ( h , "chaos_seeker_666_fights" ) , "ordinary fights counted toward chaos seeker" ) ;
const fightMochiTarinai = { fightMochiTimer : 10 } ;
for ( let i = 0 ; i < 400 ; i += 1 ) h . api . recordFightStarted ( { world : chaosWorld , a : fightMochiTarinai , b : { } } ) ;
2026-07-15 14:44:29 +09:00
h = createHarness ( storage ) ;
2026-07-15 16:27:56 +09:00
for ( let i = 0 ; i < 265 ; i += 1 ) h . api . recordFightStarted ( { world : chaosWorld , a : fightMochiTarinai , b : { } } ) ;
assert ( ! unlocked ( h , "chaos_seeker_666_fights" ) , "chaos seeker unlocked at 665 influenced fights" ) ;
h . api . recordFightStarted ( { world : chaosWorld , a : fightMochiTarinai , b : { } } ) ;
assert ( unlocked ( h , "chaos_seeker_666_fights" ) , "chaos seeker did not persist to 666 influenced fights" ) ;
storage = new Map ( ) ;
h = createHarness ( storage ) ;
for ( let i = 0 ; i < 332 ; i += 1 ) h . api . recordShotFired ( { } ) ;
assert ( ! unlocked ( h , "sniper_333_shots" ) , "sniper unlocked before 333 shots" ) ;
h = createHarness ( storage ) ;
h . api . recordShotFired ( { } ) ;
assert ( unlocked ( h , "sniper_333_shots" ) , "sniper did not persist to 333 shots" ) ;
storage = new Map ( ) ;
h = createHarness ( storage ) ;
for ( let i = 0 ; i < 800 ; i += 1 ) h . api . recordLoveMochiBirth ( { loveMochiInfluenced : false } ) ;
assert ( ! unlocked ( h , "fertility_seeker_721_love_births" ) , "ordinary reproduction counted toward fertility seeker" ) ;
for ( let i = 0 ; i < 720 ; i += 1 ) h . api . recordLoveMochiBirth ( { loveMochiInfluenced : true } ) ;
assert ( ! unlocked ( h , "fertility_seeker_721_love_births" ) , "fertility seeker unlocked before 721 influenced reproductions" ) ;
h = createHarness ( storage ) ;
h . api . recordLoveMochiBirth ( { loveMochiInfluenced : true } ) ;
assert ( unlocked ( h , "fertility_seeker_721_love_births" ) , "fertility seeker did not persist to 721 influenced reproductions" ) ;
h = createHarness ( ) ;
const metroWorld = {
tarinai : Array . from ( { length : 99 } , ( ) => ( { dead : false } ) ) ,
items : [
... Array . from ( { length : 10 } , ( ) => ( { type : "duplicator" , dead : false } ) ) ,
... Array . from ( { length : 15 } , ( _v , i ) => ( { type : i % 3 === 0 ? "grass_bed" : ( i % 3 === 1 ? "nest_box" : "pipe" ) , dead : false } ) ) ,
] ,
} ;
h . api . evaluateMegalopolis ( metroWorld ) ;
assert ( ! unlocked ( h , "megalopolis" ) , "megalopolis ignored the 100-tarinai threshold" ) ;
metroWorld . tarinai . push ( { dead : false } ) ;
metroWorld . items [ 0 ] . dead = true ;
h . api . evaluateMegalopolis ( metroWorld ) ;
assert ( ! unlocked ( h , "megalopolis" ) , "megalopolis ignored the 10-duplicator threshold" ) ;
metroWorld . items [ 0 ] . dead = false ;
metroWorld . items [ 10 ] . dead = true ;
h . api . evaluateMegalopolis ( metroWorld ) ;
assert ( ! unlocked ( h , "megalopolis" ) , "megalopolis ignored the 15-shelter threshold" ) ;
metroWorld . items [ 10 ] . dead = false ;
h . api . evaluateMegalopolis ( metroWorld ) ;
assert ( unlocked ( h , "megalopolis" ) , "megalopolis did not unlock at exact thresholds" ) ;
2026-07-15 14:44:29 +09:00
h = createHarness ( ) ;
const cleaner = { type : "robot_cleaner" , dead : false , robotCleanerMask : 0x3f , robotCleanerHighSpeed : true , _signalDriven : true , _signalOn : false } ;
const cleanWorld = { items : [ cleaner ] , tarinai : [ ] , ants : [ ] , time : 0 } ;
h . api . evaluateCleanFreak ( cleanWorld ) ;
assert ( ! unlocked ( h , "clean_freak_robot_only" ) , "clean freak unlocked while signal-powered cleaner was off" ) ;
cleaner . _signalOn = true ;
cleanWorld . tarinai . push ( { dead : false } ) ;
h . api . evaluateCleanFreak ( cleanWorld ) ;
assert ( ! unlocked ( h , "clean_freak_robot_only" ) , "clean freak ignored a living tarinai" ) ;
cleanWorld . tarinai . length = 0 ;
cleanWorld . items . push ( { type : "grass" , dead : false } ) ;
h . api . evaluateCleanFreak ( cleanWorld ) ;
assert ( ! unlocked ( h , "clean_freak_robot_only" ) , "clean freak ignored another field item" ) ;
cleanWorld . items . pop ( ) ;
h . api . evaluateCleanFreak ( cleanWorld ) ;
assert ( unlocked ( h , "clean_freak_robot_only" ) , "clean freak did not unlock with all settings and robot-only field" ) ;
2026-07-16 22:12:03 +09:00
console . log ( "[OK] all 64 achievement definitions, categorized UI, inline disclosures, and recovery synchronization passed" ) ;
2026-07-15 14:44:29 +09:00
} ) ( ) . catch ( error => {
console . error ( error ) ;
process . exitCode = 1 ;
} ) ;