termfront 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6d91fa7b7758b2151fc31bb9f7862dbda3ad311edea638aa9b11ca50a8b9a8d
4
- data.tar.gz: 3a8ce081de76ddd04c45949c490ba4b513f42eb94eb39fce37fef292abdbb004
3
+ metadata.gz: 7e7d185736b70057b93c85c4196ddc96b63693b3f31fd58f9cf9e83cb96e10fa
4
+ data.tar.gz: 4583088200b878c1d0b51ef44123b6bf49891501c67aecadb1c8af93fbd4b64e
5
5
  SHA512:
6
- metadata.gz: a79ab596683eea6f8914c17cf88ad000d7a1b33453820526310f25fd43dbabb1f21e6f65f16a390fa92e491d6cd2da86e981c17bc971161316a6d4f7b431c98a
7
- data.tar.gz: 556667b34ba430c7af848fca7d31f5937e24d328480a29a3191db88ca4286d579081b0f6e18c34622d87cb9ea401c20e19da6aaf0a6fbc2b892f15fdbb9f7b76
6
+ metadata.gz: 49eb38ea263659290eb41fe10b6719fd4d9201528ee583badc1d511239b7abd364b60109c849fad983d15636bfa8f9ae64152308a700d45587556dfaee5da3a6
7
+ data.tar.gz: 955636242f49453baf156dc44caf6c9815f836fcbab68d0825471dae0d7e86c9832b858c0a9e45920e07fca9d77e07293f8fd1c8ba96019e7900fa073c80593c
data/CHANGELOG.md CHANGED
@@ -6,6 +6,16 @@ The format is based on Keep a Changelog, and this project follows Semantic Versi
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.1.8] - 2026-05-26
10
+
11
+ ### Fixed
12
+
13
+ - Stop the `AudioManager` BGM and looping-SE threads from spinning at 100 % CPU when the audio player spawns but exits immediately (e.g. no usable audio device, codec missing, or backend not running). The non-looping playback loops now bail out if `spawn_player` returns `nil` or if the previous playback finished in under 500 ms, instead of relentlessly respawning a process that never plays anything. On a tester's CPU-bound host this was over 95 % of the process's CPU budget, making the renderer look heavy when the real culprit was the audio thread
14
+
15
+ ### Changed
16
+
17
+ - Adapt the in-game render rate to the host's headroom: an `AdaptiveRenderRate` module tracks how often a frame exceeds 85 % of the 60 Hz budget and, after 30 consecutive over-budget frames, downshifts the singleplayer / Wavesfight render rate to 30 Hz; if the host catches back up for 60 consecutive frames it upshifts back to 60 Hz. Capable machines keep running at 60 Hz, while testers on lower-spec CPUs / TDP-throttled laptops fall back to a steady 30 Hz instead of a stuttering 60 Hz, and the rate resets on every new game loop entry so a freshly launched match starts at 60 Hz
18
+
9
19
  ## [0.1.7] - 2026-05-26
10
20
 
11
21
  ### Changed
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Termfront
4
+ module AdaptiveRenderRate
5
+ OVER_BUDGET_RATIO = 0.85
6
+ UNDER_BUDGET_RATIO = 0.5
7
+ DOWNSHIFT_FRAMES = 30
8
+ UPSHIFT_FRAMES = 60
9
+
10
+ @current_dt = Config::RENDER_DT
11
+ @over_budget_count = 0
12
+ @under_budget_count = 0
13
+
14
+ class << self
15
+ def current_dt
16
+ @current_dt
17
+ end
18
+
19
+ def observe(spent)
20
+ if spent > Config::FRAME_DT * OVER_BUDGET_RATIO
21
+ @over_budget_count += 1
22
+ @under_budget_count = 0
23
+ if @over_budget_count >= DOWNSHIFT_FRAMES && @current_dt < Config::RENDER_DT_LOW
24
+ @current_dt = Config::RENDER_DT_LOW
25
+ end
26
+ elsif spent < Config::FRAME_DT * UNDER_BUDGET_RATIO
27
+ @under_budget_count += 1
28
+ @over_budget_count = 0
29
+ if @under_budget_count >= UPSHIFT_FRAMES && @current_dt > Config::RENDER_DT
30
+ @current_dt = Config::RENDER_DT
31
+ end
32
+ end
33
+ end
34
+
35
+ def reset!
36
+ @current_dt = Config::RENDER_DT
37
+ @over_budget_count = 0
38
+ @under_budget_count = 0
39
+ end
40
+ end
41
+ end
42
+ end
@@ -41,9 +41,13 @@ module Termfront
41
41
  loop do
42
42
  break if channel_stopped?(:bgm)
43
43
 
44
+ start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
44
45
  @bgm_pid = spawn_player(@bgm_player, path, loop_playback: false)
46
+ break unless @bgm_pid
47
+
45
48
  wait_for_channel(:bgm)
46
49
  break if channel_stopped?(:bgm)
50
+ break if Process.clock_gettime(Process::CLOCK_MONOTONIC) - start < 0.5
47
51
  end
48
52
  end
49
53
  rescue StandardError
@@ -101,9 +105,13 @@ module Termfront
101
105
  loop do
102
106
  break if channel_stopped?(:loop_se)
103
107
 
108
+ start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
104
109
  @loop_se_pid = spawn_player(@loop_se_player, path, loop_playback: false)
110
+ break unless @loop_se_pid
111
+
105
112
  wait_for_channel(:loop_se)
106
113
  break if channel_stopped?(:loop_se)
114
+ break if Process.clock_gettime(Process::CLOCK_MONOTONIC) - start < 0.5
107
115
  end
108
116
  end
109
117
  rescue StandardError
@@ -4,6 +4,7 @@ module Termfront
4
4
  module Config
5
5
  FRAME_DT = 1.0 / 60.0
6
6
  RENDER_DT = 1.0 / 60.0
7
+ RENDER_DT_LOW = 1.0 / 30.0
7
8
  MAX_DT = 1.0 / 20.0
8
9
  FOV = 66.0 * Math::PI / 180.0
9
10
  PLAYER_RADIUS = 0.2
@@ -130,9 +130,10 @@ module Termfront
130
130
  end
131
131
 
132
132
  def run_game_loop(show_complete_banner: true)
133
+ AdaptiveRenderRate.reset!
133
134
  STDIN.raw do |stdin|
134
135
  last_time = clock
135
- last_render = last_time - Config::RENDER_DT
136
+ last_render = last_time - AdaptiveRenderRate.current_dt
136
137
 
137
138
  loop do
138
139
  now = clock
@@ -149,7 +150,7 @@ module Termfront
149
150
  end
150
151
 
151
152
  update(dt)
152
- if now - last_render >= Config::RENDER_DT
153
+ if now - last_render >= AdaptiveRenderRate.current_dt
153
154
  @renderer.render(
154
155
  player: @player, map: @map,
155
156
  enemies: @enemies, projectiles: @projectiles,
@@ -180,9 +181,10 @@ module Termfront
180
181
  end
181
182
 
182
183
  def run_wavesfight_loop
184
+ AdaptiveRenderRate.reset!
183
185
  STDIN.raw do |stdin|
184
186
  last_time = clock
185
- last_render = last_time - Config::RENDER_DT
187
+ last_render = last_time - AdaptiveRenderRate.current_dt
186
188
 
187
189
  loop do
188
190
  now = clock
@@ -199,7 +201,7 @@ module Termfront
199
201
  end
200
202
 
201
203
  update(dt)
202
- if now - last_render >= Config::RENDER_DT
204
+ if now - last_render >= AdaptiveRenderRate.current_dt
203
205
  @renderer.render(
204
206
  player: @player, map: @map,
205
207
  enemies: @enemies, projectiles: @projectiles,
@@ -220,7 +222,7 @@ module Termfront
220
222
  show_wave_clear
221
223
  start_wavesfight_wave
222
224
  last_time = clock
223
- last_render = clock - Config::RENDER_DT
225
+ last_render = clock - AdaptiveRenderRate.current_dt
224
226
  end
225
227
 
226
228
  cap_frame(now)
@@ -659,6 +661,7 @@ module Termfront
659
661
 
660
662
  def cap_frame(frame_start)
661
663
  spent = clock - frame_start
664
+ AdaptiveRenderRate.observe(spent)
662
665
  remain = Config::FRAME_DT - spent
663
666
  sleep(remain) if remain > 0
664
667
  end
@@ -907,6 +907,7 @@ module Termfront
907
907
 
908
908
  def cap_frame(frame_start)
909
909
  spent = clock - frame_start
910
+ AdaptiveRenderRate.observe(spent)
910
911
  remain = Config::FRAME_DT - spent
911
912
  sleep(remain) if remain > 0
912
913
  end
@@ -406,6 +406,7 @@ module Termfront
406
406
 
407
407
  def cap_frame(frame_start)
408
408
  spent = clock - frame_start
409
+ AdaptiveRenderRate.observe(spent)
409
410
  remain = Config::FRAME_DT - spent
410
411
  sleep(remain) if remain > 0
411
412
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Termfront
4
- VERSION = "0.1.7"
4
+ VERSION = "0.1.8"
5
5
  end
data/lib/termfront.rb CHANGED
@@ -4,6 +4,7 @@ require "io/console"
4
4
 
5
5
  require_relative "termfront/version"
6
6
  require_relative "termfront/config"
7
+ require_relative "termfront/adaptive_render_rate"
7
8
  require_relative "termfront/color"
8
9
  require_relative "termfront/map"
9
10
  require_relative "termfront/weapon/base"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: termfront
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - S-H-GAMELINKS
@@ -51,6 +51,7 @@ files:
51
51
  - exe/termfront
52
52
  - exe/termfront-server
53
53
  - lib/termfront.rb
54
+ - lib/termfront/adaptive_render_rate.rb
54
55
  - lib/termfront/async_writer.rb
55
56
  - lib/termfront/audio_manager.rb
56
57
  - lib/termfront/color.rb