• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

orion-ecs / keen-eye / 30138674683

25 Jul 2026 01:31AM UTC coverage: 63.89% (-0.9%) from 64.782%
30138674683

push

github

tyevco
feat(samples): Add NOVAFALL Phase C - floor personalities, Flashover, Adrenaline Save, modes, persistence, TestBridge

Phase C of the NOVAFALL flagship sample: modes and meta on top of the
Phase A core and Phase B juice, plus a determinism test project.

- Floor personalities (deterministic per (seed, floor index), phased in
  by depth, ~25% combined cap): Brittle (crack telegraph 0.65s >= the
  0.6s telegraph contract, then crumbles into the smash fragment
  vocabulary), Bumper (elastic upward launch, wobble + boing), Pulse
  (gap breathes on the music-clock beat; the shrinking-edges telegraph
  IS the hitbox via a shared EffectiveGapWidth function)
- Flashover Surge: triggers every 40 cleared floors (floor index, not
  time), 10 music-clock seconds of scroll spike + smash-at-any-tier +
  white-hot palette override + surge lead stem (new 4.75s sample-locked
  WAV), +1000 Surge Sweep for 5+ smashes in one window
- Adrenaline Save: once per run, converts the crush kill into 1.5 REAL
  seconds (raw-dt timer, still simulate-deterministic) at 20% time with
  music duck, desaturated palette, vignette, thicker trail, HUD pip
- Modes as RunConfig configuration, not code paths: FREEFALL,
  DAILY INFERNO (3-minute limit, yyyyMMdd-through-splitmix64 seed,
  3 attempts/day, local depth medals, mid-air heat decay, denser floors,
  halved smash cost), EMBER GARDEN (no crusher, fixed gentle scroll,
  ducked pad-only mix, heat drives visuals only)
- Ready-screen menu keeps the one-axis grammar: Left/Right cycles the
  active row, Tab switches mode <-> cosmetic style, Space/Enter dives
- Persistence via KeenEyes.Persistence: versioned profile world
  (schema header + per-mode bests + daily records) saved to app-data;
  corrupt/first-run loads fresh; cosmetic unlocks derived from bests;
  --simulate never touches the disk (hermetic CI)
- TestBridge: windowed mode serves pipe KeenEyes.NovaFall.TestBridge
  (TestBridgePlugin + IpcBridgeServer, editor integration pattern... (continued)

8874 of 13117 branches covered (67.65%)

Branch coverage included in aggregate %.

305 of 852 new or added lines in 23 files covered. (35.8%)

9 existing lines in 4 files now uncovered.

52569 of 83053 relevant lines covered (63.3%)

1.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

41.03
/samples/KeenEyes.Sample.NovaFall/Systems/CrushSystem.cs
1
namespace KeenEyes.Sample.NovaFall;
2

3
/// <summary>
4
/// Resolves the ball touching the Furnace ceiling: death — unless the run's
5
/// one Adrenaline Save is still unspent, in which case the kill converts into
6
/// a 20%-speed last chance (see <see cref="AdrenalineSystem"/>). In Ember
7
/// Garden the crusher is configured off and the ceiling merely clamps.
8
/// </summary>
9
public sealed class CrushSystem : SystemBase
10
{
11
    /// <inheritdoc />
12
    public override void Update(float deltaTime)
13
    {
14
        ref var state = ref World.GetSingleton<GameState>();
1✔
15
        if (state.Phase != GamePhase.Playing)
1✔
16
        {
17
            return;
×
18
        }
19

20
        var settings = World.GetSingleton<RunConfig>().Settings;
1✔
21

22
        foreach (var entity in World.Query<Ball, Position2D>())
1✔
23
        {
24
            ref readonly var ball = ref World.Get<Ball>(entity);
1✔
25
            ref var position = ref World.Get<Position2D>(entity);
1✔
26

27
            if (position.Y - ball.Radius > Tuning.CeilingY)
1✔
28
            {
29
                break;
1✔
30
            }
31

32
            // Ember Garden: no crusher, no death — the ceiling is just a wall.
33
            if (!settings.CrusherEnabled)
1✔
34
            {
35
                position.Y = Tuning.CeilingY + ball.Radius;
1✔
36
                break;
1✔
37
            }
38

NEW
39
            ref var adrenaline = ref World.GetSingleton<AdrenalineState>();
×
40

41
            // The frame this would kill, the unspent Adrenaline Save fires
42
            // instead: time snaps to 20% for 1.5 real seconds — one last steer.
NEW
43
            if (settings.AdrenalineEnabled && adrenaline.Available)
×
44
            {
NEW
45
                adrenaline.Available = false;
×
NEW
46
                adrenaline.Active = true;
×
NEW
47
                adrenaline.RealSecondsRemaining = Tuning.AdrenalineRealSeconds;
×
NEW
48
                World.GetSingleton<TimeScale>().Value = Tuning.AdrenalineTimeScale;
×
NEW
49
                World.GetSingleton<FrameEvents>().AdrenalineTriggered = true;
×
NEW
50
                World.GetSingleton<RunEventCounters>().AdrenalineSavesUsed++;
×
51
                break;
×
52
            }
53

54
            // While the save window is open the Furnace holds its breath;
55
            // when it expires with the ball still here, this branch stops
56
            // being taken and the next line runs.
NEW
57
            if (adrenaline.Active)
×
58
            {
NEW
59
                break;
×
60
            }
61

NEW
62
            state.Phase = GamePhase.Dead;
×
63

NEW
64
            ref var score = ref World.GetSingleton<ScoreState>();
×
NEW
65
            score.Best = Math.Max(score.Best, (int)score.Score);
×
66

67
            // Only death resets heat.
NEW
68
            ResetHeat();
×
NEW
69
            break;
×
70
        }
71
    }
1✔
72

73
    private void ResetHeat()
74
    {
75
        ref var heat = ref World.GetSingleton<HeatState>();
×
76
        heat.Heat = 0f;
×
77
        heat.Tier = 0;
×
78
    }
×
79
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc