1
0
Эх сурвалжийг харах

Rebalance stars against simulated win times

Par was a straight ramp capped at 120 s and two stars meant within 2x
par, so 62% of simulated wins earned three stars, only 5% earned one,
and high levels were easier to three-star than mid ones.

Par now follows the measured win times: 60 s for levels 0-10, rising
to about 105 s at level 75, then easing back to 85 s by level 125 (long
runs at high levels tend to end in a lost ball, so winning runs are
shorter). Two stars now means within 1.75x par. On two separate Pixel
simulation runs, levels 15-400 give three stars to 37-53% of wins and
one star to 13-21%.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Gabriel Capella 5 өдөр өмнө
parent
commit
b41bd5473d
3 өөрчлөгдсөн 12 нэмэгдсэн , 4 устгасан
  1. 1 1
      README.md
  2. 1 1
      scripts/game.gd
  3. 10 2
      scripts/params.gd

+ 1 - 1
README.md

@@ -89,7 +89,7 @@ uma fase não se arraste.
 Cada bloco quebrado vale 10 pontos, multiplicados pelo combo: a cada 3 blocos
 seguidos sem a bola tocar na pá, o multiplicador sobe (até ×5). Ao vencer, a
 fase dá de 1 a 3 estrelas conforme o tempo (3 estrelas dentro do tempo-alvo,
-2 dentro do dobro). A melhor pontuação e as estrelas ficam salvas.
+2 dentro de 1,75× o tempo-alvo). A melhor pontuação e as estrelas ficam salvas.
 
 A pá direciona a bola: no centro ela sobe reta, nas pontas sai inclinada até 60°.
 

+ 1 - 1
scripts/game.gd

@@ -212,7 +212,7 @@ func _win() -> void:
 	_shake(0.8)
 	var seconds := _now() - _started
 	var par := Params.par_seconds(level)
-	var stars := 3 if seconds <= par else (2 if seconds <= 2.0 * par else 1)
+	var stars := 3 if seconds <= par else (2 if seconds <= Params.TWO_STAR_FACTOR * par else 1)
 	_clear_play_field()
 	await blocks.core.explode()
 	Progress.save_stars(level, stars)

+ 10 - 2
scripts/params.gd

@@ -66,6 +66,7 @@ const CORE_PULL_REACH := 120.0 # px beyond the outer ring
 const POINTS_PER_BREAK := 10
 const BREAKS_PER_COMBO_STEP := 3
 const MAX_COMBO := 5
+const TWO_STAR_FACTOR := 1.75 # two stars within this many times par
 
 # Feel
 const SHAKE_MAX := 14.0 # px at full trauma
@@ -135,9 +136,16 @@ static func special_segment_share(level: int) -> float:
 	return minf(0.5, 0.06 + (level - FIRST_SPECIAL_LEVEL) * 0.0012)
 
 
-## Seconds to win a level within for three stars; twice that for two.
+## Seconds to win a level within for three stars; TWO_STAR_FACTOR times that for two.
+## Fitted to simulated win times so about 40-50% of wins earn three stars and 15-20%
+## one, from level 15 up; levels 0-10 are easy while learning. Winning runs get shorter
+## past level 75 (long ones there tend to end in a lost ball), so par eases back too.
 static func par_seconds(level: int) -> float:
-	return 60.0 + minf(60.0, level * 0.8)
+	if level <= 10:
+		return 60.0
+	if level <= 75:
+		return 60.0 + (level - 10) * 0.7
+	return maxf(85.0, 105.5 - (level - 75) * 0.4)
 
 
 ## Chance of a power-up drop every POWER_UP_INTERVAL seconds.