Compare commits
6 Commits
feature/da
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 649b73b3f8 | |||
| cd41cb3312 | |||
| ecd094e2d7 | |||
| 5b4f3052a6 | |||
| 83301a1a8e | |||
| 77bd76f6f9 |
8
.vscode/tasks.json
vendored
8
.vscode/tasks.json
vendored
@@ -11,17 +11,19 @@
|
||||
{
|
||||
"label": "Build & Run TIC80",
|
||||
"type": "shell",
|
||||
"command": "make build && tic80 --fs=. impostor.lua"
|
||||
"command": "make build && tic80 --fs=. impostor.lua",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Export assets",
|
||||
"type": "shell",
|
||||
"command": "make export_assets"
|
||||
"command": "make export_assets",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Make build",
|
||||
"type": "shell",
|
||||
"command": "make build"
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ steps:
|
||||
- name: update
|
||||
image: alpine
|
||||
environment:
|
||||
UPDATE_SERVER: https://games.vps.teletype.hu
|
||||
UPDATE_SERVER: https://games.teletype.hu
|
||||
UPDATE_SECRET:
|
||||
from_secret: update_secret_key
|
||||
commands:
|
||||
|
||||
4
Makefile
4
Makefile
@@ -30,7 +30,7 @@ DROPAREA_HOST ?= vps.teletype.hu
|
||||
DROPAREA_PORT ?= 2223
|
||||
DROPAREA_TARGET_PATH ?= /home/drop
|
||||
DROPAREA_USER ?= drop
|
||||
UPDATE_SERVER ?= https://games.vps.teletype.hu
|
||||
UPDATE_SERVER ?= https://games.teletype.hu
|
||||
|
||||
all: build
|
||||
|
||||
@@ -164,6 +164,8 @@ export_assets:
|
||||
@$(call f_export_asset_awk,MAP,$(OUTPUT),$(ASSETS_LUA))
|
||||
@$(call f_export_asset_awk,SFX,$(OUTPUT),$(ASSETS_LUA))
|
||||
@$(call f_export_asset_awk,WAVES,$(OUTPUT),$(ASSETS_LUA))
|
||||
@$(call f_export_asset_awk,PATTERNS,$(OUTPUT),$(ASSETS_LUA))
|
||||
@$(call f_export_asset_awk,TRACKS,$(OUTPUT),$(ASSETS_LUA))
|
||||
|
||||
clean:
|
||||
@rm -f $(PROJECT)-*.tic $(PROJECT)-*.html.zip $(PROJECT)-*-docs.zip $(PROJECT)-docs.zip $(OUTPUT) $(OUTPUT_ORIGINAL)
|
||||
|
||||
@@ -23,7 +23,7 @@ function Audio.music_play_room_street_2() end
|
||||
function Audio.music_play_room_() end
|
||||
--- Plays room work music.
|
||||
--- @within Audio
|
||||
function Audio.music_play_room_work() end
|
||||
function Audio.music_play_room_work() music(0) end
|
||||
|
||||
--- Plays select sound effect.
|
||||
--- @within Audio
|
||||
|
||||
@@ -20,7 +20,8 @@ function Config.initial_data()
|
||||
meter_bg = 1
|
||||
},
|
||||
timing = {
|
||||
splash_duration = 120
|
||||
splash_duration = 120,
|
||||
minigame_win_duration = 180
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
@@ -78,7 +78,8 @@ function Minigame.get_default_ddr()
|
||||
current_song = nil,
|
||||
pattern_index = 1,
|
||||
use_pattern = false,
|
||||
return_window = nil
|
||||
return_window = nil,
|
||||
win_timer = 0
|
||||
}
|
||||
end
|
||||
|
||||
@@ -101,6 +102,7 @@ end
|
||||
--- * button_x (number) Button indicator X position.<br/>
|
||||
--- * button_y (number) Button indicator Y position.<br/>
|
||||
--- * button_size (number) Button indicator size.<br/>
|
||||
--- * win_timer (number) Timer for the win message overlay.<br/>
|
||||
function Minigame.get_default_button_mash()
|
||||
return {
|
||||
bar_fill = 0,
|
||||
@@ -120,7 +122,8 @@ function Minigame.get_default_button_mash()
|
||||
button_size = 12,
|
||||
focus_center_x = nil,
|
||||
focus_center_y = nil,
|
||||
focus_initial_radius = 0
|
||||
focus_initial_radius = 0,
|
||||
win_timer = 0
|
||||
}
|
||||
end
|
||||
|
||||
@@ -150,6 +153,7 @@ end
|
||||
--- * button_size (number) Button indicator size.<br/>
|
||||
--- * press_cooldown (number) Current cooldown timer.<br/>
|
||||
--- * press_cooldown_duration (number) Frames of press cooldown.<br/>
|
||||
--- * win_timer (number) Timer for the win message overlay.<br/>
|
||||
function Minigame.get_default_rhythm()
|
||||
return {
|
||||
line_position = 0,
|
||||
@@ -176,10 +180,28 @@ function Minigame.get_default_rhythm()
|
||||
press_cooldown_duration = 15,
|
||||
focus_center_x = nil,
|
||||
focus_center_y = nil,
|
||||
focus_initial_radius = 0
|
||||
focus_initial_radius = 0,
|
||||
win_timer = 0
|
||||
}
|
||||
end
|
||||
|
||||
--- Draws a unified win message overlay.
|
||||
--- @within Minigame
|
||||
function Minigame.draw_win_overlay()
|
||||
local text = "WELL DONE!"
|
||||
local tw = #text * 4
|
||||
local th = 6
|
||||
local padding = 4
|
||||
local box_w = tw + padding * 2
|
||||
local box_h = th + padding * 2
|
||||
local box_x = (Config.screen.width - box_w) / 2
|
||||
local box_y = (Config.screen.height - box_h) / 2
|
||||
|
||||
rect(box_x, box_y, box_w, box_h, Config.colors.dark_grey)
|
||||
rectb(box_x, box_y, box_w, box_h, Config.colors.white)
|
||||
Print.text_center(text, Config.screen.width / 2, box_y + padding, Config.colors.white)
|
||||
end
|
||||
|
||||
--- Configures DDR minigame.
|
||||
--- @within Minigame
|
||||
--- @param params table Optional parameters to override defaults (see Minigame.get_default_ddr).
|
||||
|
||||
@@ -305,13 +305,15 @@
|
||||
-- 033:000000010002000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d40000000004
|
||||
-- 044:0600f6000620f6000600f6000610f600f600f6000600f600f600f600f6000600060006000600060006000600060006000600060006000600060006004600000f0f00
|
||||
-- 045:0000f0000020f0000000f0000010f000f000f0000000f000f000f000f0000000000000000000000000000000000000000000000000000000000000004600000f0f00
|
||||
-- 057:000000010002000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d40000000004
|
||||
-- 058:41004110410041104100411041004110c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100100000080800
|
||||
-- 059:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000
|
||||
-- 048:090009000900090009000900090009000900090009000900090009000900090009000900090009000900090009000900090009000900090009000900400000000000
|
||||
-- 056:4100510061406140717081709100b100c100d100e100e100e100f100f100f100f100f100f100f100f100f100f100f100f100f100f100f100f100f100580000000600
|
||||
-- 057:000000010002000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c40000000004
|
||||
-- 058:41004110410041104100411041004110c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100c100400000080800
|
||||
-- 059:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000
|
||||
-- 060:220022002200820082008200820082008200820082008200820082008200820082008200820082008200820082008200820082008200820082008200100000000000
|
||||
-- 061:9f009f00bf00df00df00ef00ef00ef00ef00ef00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00400000000000
|
||||
-- 062:00000100010001000100510081008100910091009100a100a100a100a100a100b100b100b100b100c100c100c100d100d100d100e100e100e100f100484000000000
|
||||
-- 063:00b000100000000000000000100060009000b000c000d000d000e000e000e000f000f000f000f000f000f000f000f000f000f000f000f000f000f000405000000000
|
||||
-- 063:00b000100000000000000000100060009000b000c000d000d000e000e000e000f000f000f000f000f000f000f000f000f000f000f000f000f000f000200000000000
|
||||
-- </SFX>
|
||||
-- <WAVES>
|
||||
-- 000:bcceefceedddddc84333121268abaa99
|
||||
@@ -325,3 +327,11 @@
|
||||
-- 008:0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f
|
||||
-- 009:fff000fff000fff000fff000fff000ff
|
||||
-- </WAVES>
|
||||
-- <PATTERNS>
|
||||
-- 000:4008b50000000000000000001008c10000004008b50000001008c1000000000000000000e008b30000004008b50000001008c10000000008c10000000008c10000000000000000000000000000000000000000000000000000000000000000004008b50000000000000000001008c10000004008b50000001008c10000000008c1000000e008b30000004008b50000001008c10000000008c10000000008c10000000008c10000000008c10000000008c1000000000000000000000000000000
|
||||
-- 001:4008b50000000000000000001008c10000004008b50000001008c1000000000000000000e008b30000004008b50000001008c10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007008b50000007008b50000001008c10000007008b50000001008c10000000008c10000007008b50000009008b50000001008c10000009008b50000001008c10000009008b50000009008b50000001008c10000009008b50000001008c1000000
|
||||
-- 003:4008d30000000000000000000000000000000000000000004008d90000000000000000000000000000000000000000004008d30000000000000000000000000000004008d30000004008d90000000000000000000000000000000000000000004008d30000000000000000000000000000000000000000004008d90000000000000000000000000000000000000000004008d30000000000000000000000000000004008d30000004008d9000000000000000000000000000000000000000000
|
||||
-- </PATTERNS>
|
||||
-- <TRACKS>
|
||||
-- 000:100001200001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- </TRACKS>
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
--- @section AudioTestWindow
|
||||
AudioTestWindow = {
|
||||
index_menu = 1,
|
||||
index_func = 1,
|
||||
list_func = {},
|
||||
menuitems = {},
|
||||
last_pressed = false
|
||||
}
|
||||
AudioTestWindow.index_menu = 1
|
||||
AudioTestWindow.index_func = 1
|
||||
AudioTestWindow.list_func = {}
|
||||
AudioTestWindow.menuitems = {}
|
||||
AudioTestWindow.last_pressed = false
|
||||
|
||||
--- Generates menu items for audio test.
|
||||
--- @within AudioTestWindow
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
--- @section ConfigurationWindow
|
||||
ConfigurationWindow = {
|
||||
controls = {},
|
||||
selected_control = 1,
|
||||
}
|
||||
ConfigurationWindow.controls = {}
|
||||
ConfigurationWindow.selected_control = 1
|
||||
|
||||
--- Initializes configuration window.
|
||||
--- @within ConfigurationWindow
|
||||
|
||||
@@ -108,18 +108,25 @@ end
|
||||
--- @within MinigameDDRWindow
|
||||
function MinigameDDRWindow.update()
|
||||
local mg = Context.minigame_ddr
|
||||
|
||||
if mg.win_timer > 0 then
|
||||
mg.win_timer = mg.win_timer - 1
|
||||
if mg.win_timer == 0 then
|
||||
Meter.on_minigame_complete()
|
||||
Meter.show()
|
||||
Window.set_current(mg.return_window)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if mg.bar_fill >= mg.max_fill then
|
||||
Meter.on_minigame_complete()
|
||||
Meter.show()
|
||||
Window.set_current(mg.return_window)
|
||||
mg.win_timer = Config.timing.minigame_win_duration
|
||||
return
|
||||
end
|
||||
mg.frame_counter = mg.frame_counter + 1
|
||||
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
|
||||
Meter.on_minigame_complete()
|
||||
Meter.show()
|
||||
Window.set_current(mg.return_window)
|
||||
mg.win_timer = Config.timing.minigame_win_duration
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -265,4 +272,7 @@ function MinigameDDRWindow.draw()
|
||||
else
|
||||
Print.text_center("RANDOM MODE", Config.screen.width / 2, debug_y, Config.colors.blue)
|
||||
end
|
||||
if mg.win_timer > 0 then
|
||||
Minigame.draw_win_overlay()
|
||||
end
|
||||
end
|
||||
@@ -25,6 +25,18 @@ end
|
||||
--- @within MinigameButtonMashWindow
|
||||
function MinigameButtonMashWindow.update()
|
||||
local mg = Context.minigame_button_mash
|
||||
|
||||
if mg.win_timer > 0 then
|
||||
mg.win_timer = mg.win_timer - 1
|
||||
if mg.win_timer == 0 then
|
||||
Meter.on_minigame_complete()
|
||||
Meter.show()
|
||||
if mg.focus_center_x then Focus.stop() end
|
||||
Window.set_current(mg.return_window)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if Input.select() then
|
||||
mg.bar_fill = mg.bar_fill + mg.fill_per_press
|
||||
mg.button_pressed_timer = mg.button_press_duration
|
||||
@@ -33,10 +45,7 @@ function MinigameButtonMashWindow.update()
|
||||
end
|
||||
end
|
||||
if mg.bar_fill >= mg.max_fill then
|
||||
Meter.on_minigame_complete()
|
||||
Meter.show()
|
||||
if mg.focus_center_x then Focus.stop() end
|
||||
Window.set_current(mg.return_window)
|
||||
mg.win_timer = Config.timing.minigame_win_duration
|
||||
return
|
||||
end
|
||||
local degradation = mg.base_degradation + (mg.bar_fill * mg.degradation_multiplier)
|
||||
@@ -86,4 +95,8 @@ function MinigameButtonMashWindow.draw()
|
||||
Print.text_center("MASH Z!", Config.screen.width / 2, mg.bar_y + mg.bar_height + 10, Config.colors.light_grey)
|
||||
local percentage = math.floor((mg.bar_fill / mg.max_fill) * 100)
|
||||
Print.text_center(percentage .. "%", mg.bar_x + mg.bar_width / 2, mg.bar_y + 2, Config.colors.black)
|
||||
|
||||
if mg.win_timer > 0 then
|
||||
Minigame.draw_win_overlay()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -27,6 +27,18 @@ end
|
||||
--- @within MinigameRhythmWindow
|
||||
function MinigameRhythmWindow.update()
|
||||
local mg = Context.minigame_rhythm
|
||||
|
||||
if mg.win_timer > 0 then
|
||||
mg.win_timer = mg.win_timer - 1
|
||||
if mg.win_timer == 0 then
|
||||
Meter.on_minigame_complete()
|
||||
Meter.show()
|
||||
if mg.focus_center_x then Focus.stop() end
|
||||
Window.set_current(mg.return_window)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
mg.line_position = mg.line_position + (mg.line_speed * mg.line_direction)
|
||||
if mg.line_position > 1 then
|
||||
mg.line_position = 1
|
||||
@@ -57,10 +69,7 @@ function MinigameRhythmWindow.update()
|
||||
end
|
||||
end
|
||||
if mg.score >= mg.max_score then
|
||||
Meter.on_minigame_complete()
|
||||
Meter.show()
|
||||
if mg.focus_center_x then Focus.stop() end
|
||||
Window.set_current(mg.return_window)
|
||||
mg.win_timer = Config.timing.minigame_win_duration
|
||||
return
|
||||
end
|
||||
if mg.button_pressed_timer > 0 then
|
||||
@@ -107,4 +116,8 @@ function MinigameRhythmWindow.draw()
|
||||
circ(mg.button_x, mg.button_y, mg.button_size - 2, button_color)
|
||||
end
|
||||
Print.text_center("Z", mg.button_x - 2, mg.button_y - 3, button_color)
|
||||
|
||||
if mg.win_timer > 0 then
|
||||
Minigame.draw_win_overlay()
|
||||
end
|
||||
end
|
||||
|
||||
289
infra.md
289
infra.md
@@ -1,289 +0,0 @@
|
||||
# Server
|
||||
```mermaid
|
||||
graph TD
|
||||
Internet --> Nginx
|
||||
|
||||
Nginx --> Traefik
|
||||
Traefik --> Gitea
|
||||
Gitea --> GiteaDB[(Gitea data / SQLite)]
|
||||
|
||||
Traefik --> WoodpeckerServer
|
||||
WoodpeckerServer --> WoodpeckerDB[(Woodpecker data / SQLite)]
|
||||
WoodpeckerServer --> WoodpeckerAgent
|
||||
WoodpeckerAgent --> DockerSocket[(Docker)]
|
||||
|
||||
Traefik --> WebApp
|
||||
WebApp --> MySQL[(MySQL)]
|
||||
WebApp --> Softwares[(Volume)]
|
||||
|
||||
Droparea --> Softwares
|
||||
|
||||
Nginx --> Discourse
|
||||
Discourse --> ForumDB[(Postgres)]
|
||||
Discourse --> Redis[(Redis)]
|
||||
|
||||
Nginx --> Wiki
|
||||
Wiki --> WikiDB[(Postgres)]
|
||||
```
|
||||
|
||||
# TIC-80 Pipeline
|
||||
|
||||
This document describes the Woodpecker CI pipeline used to build, export, upload, and publish a TIC-80 game project.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The pipeline performs the following steps:
|
||||
|
||||
1. **Build** the TIC-80 project using a custom Docker image
|
||||
2. **Export** the game to `.tic` and HTML formats
|
||||
3. **Upload artifacts** to a remote server via SCP
|
||||
4. **Notify an update server** to publish the new version
|
||||
|
||||
The pipeline is driven by environment variables so it can be reused across projects.
|
||||
|
||||
---
|
||||
|
||||
## Global Environment
|
||||
|
||||
```yaml
|
||||
environment: &environment
|
||||
GAME_NAME: mranderson
|
||||
GAME_LANG: lua
|
||||
```
|
||||
|
||||
- **GAME_NAME**: Project name (used for all outputs)
|
||||
- **GAME_LANG**: Source language used by TIC-80 (Lua)
|
||||
|
||||
The anchor (`&environment`) allows reuse across steps.
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Build & Export
|
||||
|
||||
```yaml
|
||||
- name: build
|
||||
image: git.teletype.hu/internal/tic80pro:latest
|
||||
environment:
|
||||
<<: *environment
|
||||
XDG_RUNTIME_DIR: /tmp
|
||||
commands:
|
||||
- make build
|
||||
- make export
|
||||
```
|
||||
|
||||
**What it does:**
|
||||
|
||||
- Uses a custom TIC-80 Pro Docker image hosted in Gitea
|
||||
- Runs the Makefile `build` target to assemble source files
|
||||
- Runs the `export` target to generate:
|
||||
- `.tic` cartridge
|
||||
- `.html.zip` web build
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Artifact Upload
|
||||
|
||||
```yaml
|
||||
- name: artifact
|
||||
image: alpine
|
||||
environment:
|
||||
<<: *environment
|
||||
DROPAREA_HOST: vps.teletype.hu
|
||||
DROPAREA_PORT: 2223
|
||||
DROPAREA_TARGET_PATH: /home/drop
|
||||
DROPAREA_USER: drop
|
||||
DROPAREA_SSH_PASSWORD:
|
||||
from_secret: droparea_ssh_password
|
||||
commands:
|
||||
- apk add --no-cache openssh-client sshpass
|
||||
- mkdir -p /root/.ssh
|
||||
- sshpass -p $DROPAREA_SSH_PASSWORD scp -o StrictHostKeyChecking=no -P $DROPAREA_PORT \
|
||||
$GAME_NAME.$GAME_LANG \
|
||||
$GAME_NAME.tic \
|
||||
$GAME_NAME.html.zip \
|
||||
$DROPAREA_USER@$DROPAREA_HOST:$DROPAREA_TARGET_PATH
|
||||
```
|
||||
|
||||
**What it does:**
|
||||
|
||||
- Installs SCP tooling in a minimal Alpine container
|
||||
- Uploads:
|
||||
- Source file
|
||||
- TIC-80 cartridge
|
||||
- HTML export ZIP
|
||||
- Uses secrets for SSH authentication
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Update Notification
|
||||
|
||||
```yaml
|
||||
- name: update
|
||||
image: alpine
|
||||
environment:
|
||||
<<: *environment
|
||||
UPDATE_SERVER: https://games.vps.teletype.hu
|
||||
UPDATE_SECRET:
|
||||
from_secret: update_secret_key
|
||||
commands:
|
||||
- apk add --no-cache curl
|
||||
- curl "$UPDATE_SERVER/update?secret=$UPDATE_SECRET&name=$GAME_NAME&platform=tic80"
|
||||
```
|
||||
|
||||
**What it does:**
|
||||
|
||||
- Sends an HTTP request to the update server
|
||||
- Notifies that a new TIC-80 build is available
|
||||
- Uses a secret key to authorize the update
|
||||
|
||||
---
|
||||
|
||||
## Result
|
||||
|
||||
After a successful run:
|
||||
|
||||
- The game is built and exported
|
||||
- Artifacts are uploaded to the server
|
||||
- The public game index is updated automatically
|
||||
|
||||
This pipeline enables **fully automated TIC-80 releases** using open tools and infrastructure.
|
||||
|
||||
|
||||
# TIC-80 Makefile Project Builder
|
||||
|
||||
This Makefile provides a simple, reproducible workflow for building **TIC-80 Lua projects** from multiple source files. It is designed for small indie or experimental projects where the source code is split into logical parts and then merged into a single `.lua` cartridge.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The workflow is based on four core ideas:
|
||||
|
||||
- Source code is split into multiple Lua files inside an `inc/` directory
|
||||
- A project-specific `.inc` file defines the **build order**
|
||||
- All source files are concatenated into one final `.lua` file
|
||||
- TIC-80 is used in CLI mode to export runnable artifacts
|
||||
|
||||
This approach keeps the codebase modular while remaining compatible with TIC-80’s single-file cartridge model.
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
```text
|
||||
project-root/
|
||||
├── inc/
|
||||
│ ├── core.lua
|
||||
│ ├── player.lua
|
||||
│ └── world.lua
|
||||
├── mranderson.inc
|
||||
├── Makefile
|
||||
└── README.md
|
||||
```
|
||||
|
||||
- `inc/` contains all Lua source fragments
|
||||
- `<project>.inc` defines the order in which files are merged
|
||||
- `<project>.lua` is generated automatically
|
||||
|
||||
---
|
||||
|
||||
## The `.inc` File
|
||||
|
||||
The `.inc` file is a **plain text file** listing Lua source files in build order:
|
||||
|
||||
```text
|
||||
core.lua
|
||||
player.lua
|
||||
world.lua
|
||||
```
|
||||
|
||||
The order matters. Files listed earlier are concatenated first and must define any globals used later.
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
### Build (default)
|
||||
|
||||
```sh
|
||||
make build
|
||||
```
|
||||
|
||||
- Reads `mranderson.inc`
|
||||
- Concatenates files from `inc/`
|
||||
- Produces `mranderson.lua`
|
||||
|
||||
### Export (TIC-80)
|
||||
|
||||
```sh
|
||||
make export
|
||||
```
|
||||
|
||||
- Loads the generated Lua file into TIC-80 (CLI mode)
|
||||
- Saves a `.tic` cartridge
|
||||
- Exports an HTML build
|
||||
|
||||
### Export Assets
|
||||
|
||||
```sh
|
||||
make export_assets
|
||||
```
|
||||
|
||||
- **Purpose**: Extracts asset sections (PALETTE, TILES, SPRITES, MAP, SFX, MUSIC) from the compiled `<project>.lua` file.
|
||||
- **Mechanism**: Uses `sed` to directly parse the generated `<project>.lua` and saves the extracted data into `inc/meta/meta.assets.lua`. This file can then be used to embed the asset data directly into other parts of the project or for version control of visual assets.
|
||||
|
||||
### Import Assets
|
||||
|
||||
The `import_assets` target was considered during development but is currently not part of the build workflow. Asset handling for TIC-80 projects within this Makefile relies solely on direct extraction (`export_assets`) from the built Lua cartridge, rather than importing external asset definitions. This target may be implemented in the future if a need for pre-build asset injection arises.
|
||||
|
||||
### Watch Mode
|
||||
|
||||
```sh
|
||||
make watch
|
||||
```
|
||||
|
||||
- Performs an initial build
|
||||
- Watches the `inc/` directory and `.inc` file
|
||||
- Rebuilds automatically on any change
|
||||
|
||||
Requires `fswatch` to be installed.
|
||||
|
||||
---
|
||||
|
||||
## Generated Artifacts
|
||||
|
||||
| File | Description |
|
||||
|-----|-------------|
|
||||
| `<project>.lua` | Merged Lua source (input for TIC-80) |
|
||||
| `<project>.tic` | TIC-80 cartridge |
|
||||
| `<project>.html` | Web export |
|
||||
| `<project>.html.zip` | Packaged HTML build |
|
||||
|
||||
---
|
||||
|
||||
## Design Goals
|
||||
|
||||
- Keep TIC-80 projects modular
|
||||
- Avoid manual copy-paste between files
|
||||
- Enable fast iteration and experimentation
|
||||
- Remain fully compatible with open-source tooling
|
||||
|
||||
This Makefile is intentionally minimal and transparent, favoring simplicity over abstraction.
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
- `make`
|
||||
- `tic80` available in PATH
|
||||
- `fswatch` (only for watch mode)
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
MIT License — free to use, modify, and redistribute.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user