8 Commits

Author SHA1 Message Date
swipelab
31d1012806 shed local vendors: stb + kb_text_shape + file_utils now ship with sx
The local vendors/ copies existed because the old modules/ffi/stb*.sx
resolved C paths CWD-relative, forcing every consumer to carry
identically-named copies. sx now ships these as proper library vendors
(#import "vendors/<name>/<name>.sx"), so the copies and the retired
ffi module imports both go. Verified: sx build --target ios-sim
bundles M3te.app; tools/run_tests.sh 23/23.
2026-06-12 18:35:12 +03:00
swipelab
6f7d2f4db2 lang migration: rename signed integer types sN -> iN
Mechanical sweep of all .sx sources, plan docs, and tests/expected
snapshots for the sx language rename (s8/s16/s32/s64 -> i8/i16/i32/i64).
Verified: tools/run_tests.sh 23/23.

Note: the ios-sim build has 2 pre-existing 'restart' dot-call errors
from the sx opt-in UFCS change (sx a47ea14) — independent of this
rename (present pre-sweep); migrated in the follow-up commit.
2026-06-12 09:36:51 +03:00
swipelab
1ab74c7d08 migrate allocator calls to alloc_bytes / libc_free 2026-06-12 09:34:13 +03:00
swipelab
38815c7d50 migrate to the restructured sx stdlib paths
modules/compiler.sx -> modules/build.sx; stb/stb_truetype/opengl/sdl3 ->
modules/ffi/; modules/process.sx -> modules/std/process.sx. Rebuilt for
macos + ios-sim; 23/23 logic snapshots pass.
2026-06-11 08:46:32 +03:00
swipelab
d043319d00 P13.1: fix F2 — retire stale procedural synth, doc the real Triple Treat DSP path
The README audio-regeneration section called tools/synth_audio.py the
'build-time DSP path', but that script is the original P10.1 procedural
synthesizer: its main() overwrites assets/audio/*.wav with note-frequency
synthetic audio. Following the documented path would clobber the curated
Triple Treat pack cues. Remove the script (cleanest resolution — kills the
clobber hazard) and rewrite the README to describe the actual production:
real pack clips (per-cue source in assets/audio/LICENSE.txt) down-mixed,
trimmed, faded, peak-normalized to ~-15 dBFS, re-wrapped via afconvert;
combo ladder = real Match FX ordered by brightness (P10.9); cascade one cue
per round (P10.10). measure_pitch.py kept (read-only verification, never
writes a WAV). WAVs/.sx/goldens byte-unchanged.
2026-06-06 09:23:20 +03:00
swipelab
7f23bc8b19 P10.1: candy-vibe higher-pitched SFX bank (sx / iOS assets)
Produce the first deliverable of the Candy-Crush vibe pass: a bank of bright,
glossy, higher-pitched SFX WAVs under assets/audio/, all in the exact canonical
iOS System-Sound format clear.wav uses (mono, 44100 Hz, signed-16-bit PCM).

Bank: swap, match, combo1..combo5 (ascending pentatonic run C6 D6 E6 G6 A6),
win (ascending arpeggio), lose (descending stinger). Every cue sits above
clear.wav's ~784 Hz fundamental; combo1<..<combo5 step strictly upward
(1047<1175<1319<1568<1760 Hz). Each loads via AudioServicesCreateSystemSoundID
with status 0.

Synthesized by the build-time tools/synth_audio.py (pure-Python additive
synthesis; the app never runs it) and converted with afconvert. Pitch verified
with tools/measure_pitch.py. Provenance (CC0) recorded in LICENSE.txt. No sx
code changes — engine wiring is P10.2/P10.3.
2026-06-05 19:28:11 +03:00
swipelab
c2548aa854 P6.2: score popups & match FX (sx, iOS sim)
Add a purely-visual, transient juice layer over a committed move — score
popups + a tinted particle/flash burst at the clears — with no change to the
model, score, moves, or settled board.

- assets/fx/particle.png: key the painted transparency checkerboard out of the
  provided particle art to real alpha (8-connected border flood fill +
  smooth luminance falloff that preserves the soft glow), downscaled to a
  256x256 RGBA white sparkle. tools/key_particle.sx is the reproducible tool.
- board_fx.sx: BoardFx (live particle bursts + one "+points" popup) and
  BoardFxAssets. The engine image path samples texture*white (no draw-time
  tint), so the white sprite is tinted per gem colour at LOAD time into one
  texture per colour; a burst animates by scale (grow -> shrink) and the soft
  texture edges carry the fade. Combos (cascade depth > 1) burst bigger and the
  popup is larger + gold. All driven by delta_time and self-pruning.
- board_anim.sx: AnimMove carries the model's cascade.awarded so the popup
  shows the real payout without re-deriving any scoring in the view.
- board_view.sx / main.sx: wire BoardFx + the tinted assets, tick each frame,
  spawn on a legal commit, and render bursts (clipped to the grid) under the
  popups (drawn on top). Input-lock (BoardAnim.active) is untouched; FX never
  gate input and may outlast the move slightly before vanishing.

Goldens (iPhone-17-class sim, iOS 26): p6_fx.png (combo: gold "+480" + bursts
mid-cascade), p6_fx_match.png (single match: "+30" + red burst), p6_fx_after.png
(settled board, FX fully gone). Gate: ios-sim build links, 15/15 logic tests
green (scoring/cascade goldens unchanged).
2026-06-05 02:18:55 +03:00
swipelab
6d9aee67ba P0.4: wire the logic verification gate (sx assert helper + snapshot runner)
Add a real logic-test gate so future pure-sx game logic fails the build on a
bad assertion:

- tests/test.sx: `expect(cond, msg)` assert helper — prints a greppable
  `FAIL <file>:<line>: <msg>` and exits non-zero via process.exit on failure.
- tools/run_tests.sh: snapshot runner mirroring sx/tests/run_examples.sh; runs
  each tests/<name>.sx and diffs stdout + exit code against tests/expected/.
  Exits 0 iff all tests pass.
- tests/arith.sx (+ expected snapshots): seed passing sanity test.
- README.md: document both halves of the gate — logic runner and the
  reproducible ios-sim build/launch sequence (with device discovery).
2026-06-04 18:57:21 +03:00