Compare commits

..

2 Commits

Author SHA1 Message Date
c279b98800 Merge pull request '[MASTER] 1.0 RELEASE' (#52) from develop into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: http://git.teletype.hu/games/impostor/pulls/52
2026-04-30 15:55:21 +00:00
8b9b31ab29 Merge pull request '[MASTER] 1.0-beta2' (#47) from develop into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: http://git.teletype.hu/games/impostor/pulls/47
2026-04-09 19:55:14 +00:00
17 changed files with 34 additions and 39 deletions

View File

@@ -53,7 +53,7 @@ steps:
- name: update - name: update
image: alpine image: alpine
environment: environment:
UPDATE_SERVER: https://teletypegames.org UPDATE_SERVER: https://games.teletype.hu
UPDATE_SECRET: UPDATE_SECRET:
from_secret: update_secret_key from_secret: update_secret_key
commands: commands:

View File

@@ -30,7 +30,7 @@ DROPAREA_HOST ?= vps.teletype.hu
DROPAREA_PORT ?= 2223 DROPAREA_PORT ?= 2223
DROPAREA_TARGET_PATH ?= /home/drop DROPAREA_TARGET_PATH ?= /home/drop
DROPAREA_USER ?= drop DROPAREA_USER ?= drop
UPDATE_SERVER ?= https://teletypegames.org UPDATE_SERVER ?= https://games.teletype.hu
all: build all: build

View File

@@ -2,7 +2,6 @@
## Installation ## Installation
This game is designed for the TIC-80 fantasy computer. To play, follow these steps: This game is designed for the TIC-80 fantasy computer. To play, follow these steps:
1. **Download and Install TIC-80:** If you don't already have it, download the TIC-80 fantasy computer from its official website: [https://tic80.com/](https://tic80.com/) 1. **Download and Install TIC-80:** If you don't already have it, download the TIC-80 fantasy computer from its official website: [https://tic80.com/](https://tic80.com/)

View File

@@ -135,7 +135,7 @@ end
--- @within Ascension --- @within Ascension
function Ascension.draw_flash() function Ascension.draw_flash()
if not _flash_active then return end if not _flash_active then return end
_flash_timer = _flash_timer + Context.dt60 _flash_timer = _flash_timer + 1
local sw = Config.screen.width local sw = Config.screen.width
local sh = Config.screen.height local sh = Config.screen.height
@@ -160,7 +160,7 @@ end
--- @within Ascension --- @within Ascension
function Ascension.update_fade() function Ascension.update_fade()
if not _fade_active then return end if not _fade_active then return end
_fade_timer = _fade_timer + Context.dt60 _fade_timer = _fade_timer + 1
if _fade_timer >= FADE_DURATION then if _fade_timer >= FADE_DURATION then
_fade_active = false _fade_active = false
end end

View File

@@ -105,14 +105,14 @@ function Focus.update()
if driven then return end if driven then return end
if closing then if closing then
radius = radius - speed * Context.dt60 radius = radius - speed
if radius <= 0 then if radius <= 0 then
local cb = on_complete local cb = on_complete
Focus.stop() Focus.stop()
if cb then cb() end if cb then cb() end
end end
else else
radius = radius + speed * Context.dt60 radius = radius + speed
if radius >= max_radius(center_x, center_y) then if radius >= max_radius(center_x, center_y) then
local cb = on_complete local cb = on_complete
Focus.stop() Focus.stop()

View File

@@ -23,7 +23,7 @@ function Glitch.draw()
if not Context or not Context.glitch or not Context.glitch.enabled then return end if not Context or not Context.glitch or not Context.glitch.enabled then return end
-- Update state timer -- Update state timer
Context.glitch.timer = Context.glitch.timer - Context.dt60 Context.glitch.timer = Context.glitch.timer - 1
if Context.glitch.timer <= 0 then if Context.glitch.timer <= 0 then
if Context.glitch.state == "active" then if Context.glitch.state == "active" then
Context.glitch.state = "waiting" Context.glitch.state = "waiting"

View File

@@ -96,7 +96,7 @@ function Meter.update()
local in_minigame = string.find(Window.get_current_id(), "^minigame_") ~= nil local in_minigame = string.find(Window.get_current_id(), "^minigame_") ~= nil
if not in_minigame then if not in_minigame then
if m.combo > 0 then if m.combo > 0 then
m.combo_timer = m.combo_timer + Context.dt60 m.combo_timer = m.combo_timer + 1
if m.combo_timer >= COMBO_TIMEOUT_FRAMES then if m.combo_timer >= COMBO_TIMEOUT_FRAMES then
m.combo = 0 m.combo = 0
m.combo_timer = 0 m.combo_timer = 0

View File

@@ -28,7 +28,7 @@ function Timer.update()
local in_minigame = string.find(Window.get_current_id(), "^minigame_") ~= nil local in_minigame = string.find(Window.get_current_id(), "^minigame_") ~= nil
if not in_minigame then if not in_minigame then
t.progress = t.progress + (Context.delta_time / (timer_duration / 60)) t.progress = t.progress + (1 / timer_duration)
if t.progress >= 1 then if t.progress >= 1 then
t.progress = t.progress - 1 t.progress = t.progress - 1
end end

View File

@@ -110,7 +110,7 @@ function Trigger.update()
for id, state in pairs(Context.triggers) do for id, state in pairs(Context.triggers) do
local trigger = triggers[id] local trigger = triggers[id]
if trigger then if trigger then
state.elapsed = state.elapsed + Context.dt60 state.elapsed = state.elapsed + 1
if state.elapsed >= trigger.duration then if state.elapsed >= trigger.duration then
table.insert(fired, id) table.insert(fired, id)
end end

View File

@@ -4,5 +4,5 @@
-- desc: Life of a programmer -- desc: Life of a programmer
-- site: https://git.teletype.hu/games/impostor -- site: https://git.teletype.hu/games/impostor
-- license: MIT License -- license: MIT License
-- version: 1.0.1 -- version: 1.0
-- script: lua -- script: lua

View File

@@ -177,7 +177,7 @@ end
local state = STATE_TEXT local state = STATE_TEXT
local text_y = Config.screen.height local text_y = Config.screen.height
local text_speed = 25 -- pixels per second local text_speed = 12 -- pixels per second
local day_timer = 0 local day_timer = 0
local day_display_seconds = 2 local day_display_seconds = 2
local text_done = false local text_done = false

View File

@@ -26,7 +26,6 @@ function TIC()
Context.delta_time = (now - Context.last_frame_time) / 1000 Context.delta_time = (now - Context.last_frame_time) / 1000
end end
Context.last_frame_time = now Context.last_frame_time = now
Context.dt60 = Context.delta_time * 60
cls(Config.colors.black) cls(Config.colors.black)
local handler = Window.get_current_handler() -- Get handler from Window manager local handler = Window.get_current_handler() -- Get handler from Window manager

View File

@@ -7,8 +7,8 @@ local TEXTBOX_Y = math.floor((Config.screen.height - TEXTBOX_H) / 2 - 8)
local TEXTBOX_MAX_CHARS = 30 local TEXTBOX_MAX_CHARS = 30
local DISCUSSION_LINE_HEIGHT = 8 local DISCUSSION_LINE_HEIGHT = 8
local PADDING = 4 local PADDING = 4
local AUTO_SCROLL_DELAY = 8 local AUTO_SCROLL_DELAY = 12
local AUTO_SCROLL_STEP = 2 local AUTO_SCROLL_STEP = 1
--- Draws the discussion window. --- Draws the discussion window.
--- @within DiscussionWindow --- @within DiscussionWindow
@@ -61,7 +61,7 @@ function DiscussionWindow.update()
if max_scroll > 0 then if max_scroll > 0 then
if Context.discussion.auto_scroll then if Context.discussion.auto_scroll then
Context.discussion.scroll_timer = Context.discussion.scroll_timer + Context.dt60 Context.discussion.scroll_timer = Context.discussion.scroll_timer + 1
if Context.discussion.scroll_timer >= AUTO_SCROLL_DELAY then if Context.discussion.scroll_timer >= AUTO_SCROLL_DELAY then
Context.discussion.scroll_timer = 0 Context.discussion.scroll_timer = 0
Context.discussion.scroll_y = Context.discussion.scroll_y + AUTO_SCROLL_STEP Context.discussion.scroll_y = Context.discussion.scroll_y + AUTO_SCROLL_STEP

View File

@@ -1,6 +1,6 @@
--- @section BriefIntroWindow --- @section BriefIntroWindow
BriefIntroWindow.y = Config.screen.height BriefIntroWindow.y = Config.screen.height
BriefIntroWindow.speed = 45 -- pixels per second BriefIntroWindow.speed = 30 -- pixels per second
BriefIntroWindow.text = [[ BriefIntroWindow.text = [[
Norman Reds everyday life Norman Reds everyday life
seems ordinary: work, seems ordinary: work,

View File

@@ -339,9 +339,8 @@ function MinigameDDRWindow.update()
local mg = Context.minigame_ddr local mg = Context.minigame_ddr
if mg.win_timer > 0 then if mg.win_timer > 0 then
mg.win_timer = mg.win_timer - Context.dt60 mg.win_timer = mg.win_timer - 1
if mg.win_timer <= 0 then if mg.win_timer == 0 then
mg.win_timer = 0
Audio.music_stop() Audio.music_stop()
Meter.apply_ddr_reward(mg.total_misses) Meter.apply_ddr_reward(mg.total_misses)
if not Context.game_in_progress then return end if not Context.game_in_progress then return end
@@ -360,7 +359,7 @@ function MinigameDDRWindow.update()
return return
end end
mg.frame_counter = mg.frame_counter + Context.dt60 mg.frame_counter = mg.frame_counter + 1
if mg.use_pattern and mg.current_song and mg.current_song.end_frame then if mg.use_pattern and mg.current_song and mg.current_song.end_frame then
if mg.frame_counter > mg.current_song.end_frame and #mg.arrows == 0 then if mg.frame_counter > mg.current_song.end_frame and #mg.arrows == 0 then
@@ -382,7 +381,7 @@ function MinigameDDRWindow.update()
end end
end end
else else
mg.arrow_spawn_timer = mg.arrow_spawn_timer + Context.dt60 mg.arrow_spawn_timer = mg.arrow_spawn_timer + 1
if mg.arrow_spawn_timer >= mg.arrow_spawn_interval then if mg.arrow_spawn_timer >= mg.arrow_spawn_interval then
spawn_arrow() spawn_arrow()
mg.arrow_spawn_timer = 0 mg.arrow_spawn_timer = 0
@@ -392,7 +391,7 @@ function MinigameDDRWindow.update()
-- move arrow downwards -- move arrow downwards
local arrows_to_remove = {} local arrows_to_remove = {}
for i, arrow in ipairs(mg.arrows) do for i, arrow in ipairs(mg.arrows) do
arrow.y = arrow.y + mg.arrow_fall_speed * Context.dt60 arrow.y = arrow.y + mg.arrow_fall_speed
if check_miss(arrow) then if check_miss(arrow) then
table.insert(arrows_to_remove, i) table.insert(arrows_to_remove, i)
mg.bar_fill = math.max(0, mg.bar_fill - mg.miss_penalty) mg.bar_fill = math.max(0, mg.bar_fill - mg.miss_penalty)
@@ -407,13 +406,13 @@ function MinigameDDRWindow.update()
for dir, _ in pairs(mg.input_cooldowns) do for dir, _ in pairs(mg.input_cooldowns) do
if mg.input_cooldowns[dir] > 0 then if mg.input_cooldowns[dir] > 0 then
mg.input_cooldowns[dir] = mg.input_cooldowns[dir] - Context.dt60 mg.input_cooldowns[dir] = mg.input_cooldowns[dir] - 1
end end
end end
for dir, _ in pairs(mg.button_pressed_timers) do for dir, _ in pairs(mg.button_pressed_timers) do
if mg.button_pressed_timers[dir] > 0 then if mg.button_pressed_timers[dir] > 0 then
mg.button_pressed_timers[dir] = mg.button_pressed_timers[dir] - Context.dt60 mg.button_pressed_timers[dir] = mg.button_pressed_timers[dir] - 1
end end
end end

View File

@@ -36,7 +36,7 @@ function MinigameButtonMashWindow.init_context()
target_points = 100, target_points = 100,
fill_per_press = 8, fill_per_press = 8,
base_degradation = 0.15, base_degradation = 0.15,
degradation_multiplier = 0.003, degradation_multiplier = 0.006,
button_pressed_timer = 0, button_pressed_timer = 0,
button_press_duration = 8, button_press_duration = 8,
instruction_text = "MASH Z!", instruction_text = "MASH Z!",
@@ -103,9 +103,8 @@ function MinigameButtonMashWindow.update()
local mg = Context.minigame_button_mash local mg = Context.minigame_button_mash
if mg.win_timer > 0 then if mg.win_timer > 0 then
mg.win_timer = mg.win_timer - Context.dt60 mg.win_timer = mg.win_timer - 1
if mg.win_timer <= 0 then if mg.win_timer == 0 then
mg.win_timer = 0
if mg.meter_on_complete then if mg.meter_on_complete then
mg.meter_on_complete(mg.elapsed_sec or 0) mg.meter_on_complete(mg.elapsed_sec or 0)
else else
@@ -143,13 +142,13 @@ function MinigameButtonMashWindow.update()
mg.win_timer = Config.timing.minigame_win_duration mg.win_timer = Config.timing.minigame_win_duration
return return
end end
local degradation = (mg.base_degradation + (mg.bar_fill * mg.degradation_multiplier)) * Context.dt60 local degradation = mg.base_degradation + (mg.bar_fill * mg.degradation_multiplier)
mg.bar_fill = mg.bar_fill - degradation mg.bar_fill = mg.bar_fill - degradation
if mg.bar_fill < 0 then if mg.bar_fill < 0 then
mg.bar_fill = 0 mg.bar_fill = 0
end end
if mg.button_pressed_timer > 0 then if mg.button_pressed_timer > 0 then
mg.button_pressed_timer = mg.button_pressed_timer - Context.dt60 mg.button_pressed_timer = mg.button_pressed_timer - 1
end end
if mg.focus_center_x then if mg.focus_center_x then
Focus.set_percentage(mg.bar_fill / mg.target_points) Focus.set_percentage(mg.bar_fill / mg.target_points)

View File

@@ -71,9 +71,8 @@ function MinigameRhythmWindow.update()
local mg = Context.minigame_rhythm local mg = Context.minigame_rhythm
if mg.win_timer > 0 then if mg.win_timer > 0 then
mg.win_timer = mg.win_timer - Context.dt60 mg.win_timer = mg.win_timer - 1
if mg.win_timer <= 0 then if mg.win_timer == 0 then
mg.win_timer = 0
Meter.on_minigame_complete(false) Meter.on_minigame_complete(false)
if not Context.game_in_progress then return end if not Context.game_in_progress then return end
if mg.focus_center_x then Focus.stop() end if mg.focus_center_x then Focus.stop() end
@@ -87,7 +86,7 @@ function MinigameRhythmWindow.update()
return return
end end
mg.line_position = mg.line_position + (mg.line_speed * mg.line_direction * Context.dt60) mg.line_position = mg.line_position + (mg.line_speed * mg.line_direction)
if mg.line_position > 1 then if mg.line_position > 1 then
mg.line_position = 1 mg.line_position = 1
mg.line_direction = -1 mg.line_direction = -1
@@ -96,11 +95,11 @@ function MinigameRhythmWindow.update()
mg.line_direction = 1 mg.line_direction = 1
end end
if mg.press_cooldown > 0 then if mg.press_cooldown > 0 then
mg.press_cooldown = mg.press_cooldown - Context.dt60 mg.press_cooldown = mg.press_cooldown - 1
end end
local mouse_on_button = Mouse.zone_circle({ x = mg.button_x, y = mg.button_y, r = mg.button_size }) local mouse_on_button = Mouse.zone_circle({ x = mg.button_x, y = mg.button_y, r = mg.button_size })
if (Input.select() or mouse_on_button) and mg.press_cooldown <= 0 then if (Input.select() or mouse_on_button) and mg.press_cooldown == 0 then
mg.button_pressed_timer = mg.button_press_duration mg.button_pressed_timer = mg.button_press_duration
mg.press_cooldown = mg.press_cooldown_duration mg.press_cooldown = mg.press_cooldown_duration
local target_left = mg.target_center - (mg.target_width / 2) local target_left = mg.target_center - (mg.target_width / 2)
@@ -124,7 +123,7 @@ function MinigameRhythmWindow.update()
return return
end end
if mg.button_pressed_timer > 0 then if mg.button_pressed_timer > 0 then
mg.button_pressed_timer = mg.button_pressed_timer - Context.dt60 mg.button_pressed_timer = mg.button_pressed_timer - 1
end end
if mg.focus_center_x then if mg.focus_center_x then
Focus.set_percentage(1 - mg.score / mg.max_score) Focus.set_percentage(1 - mg.score / mg.max_score)