Architecture¶
cl-sl splits pure simulation state from real terminal I/O, and splits its
library from its CLI front end, into two packages.
Packages¶
CL-SL-- the library: train/world state,world-advance, art data, andrun(the real-terminal loop).CL-SL/CLI-- the thincl-cliwrapper:make-sl-app,main,image-entry-point.
Files¶
src/art-train.lisp-- the frame-table engine: normalizing raw multi-line sprite text so every animation frame of a variant reports identical dimensions, and the%define-train-variantmacro, which runs a variant's raw art through that normalization and registers the result for%train-framesto look up. No sprite art lives in this file.src/art-train-data.lisp-- the original art data itself: each variant declared through%define-train-variant, plus the accident sprite's standing/splat pair. A fourth variant is nothing but another%define-train-variantblock here -- no mechanism to also touch, and a variant cannot go missing from dispatch the way a forgottencaseclause could, since the macro call both defines and registers it.src/train.lisp-- thetrainstruct andtrain-advance, its one pure transition. No I/O.src/world.lisp-- theworldstruct,world-advance,world-apply-key-event(s),world-quitp. No I/O.src/collision.lisp-- the one possible collision: train versus the-aaccident sprite.src/render.lisp-- painting aworldonto acl-tty-kitscreen, the clear and every sprite blit coalesced into one screen generation viacl-tty-kit:with-screen-batch.src/app.lisp-- the only file with real I/O: raw mode, alternate screen, the realtime tick loop, and resize/input polling composed fromcl-tty-kit:make-terminal-size-pollerandcl-tty-kit:make-stream-input-pollerdirectly (no local reimplementation).src/cli.lisp-- thecl-cliapp spec and the two entry points.
This split is what lets every pure-logic test in t/ run without a real
terminal: world-advance is called directly, or driven a fixed number of
times through cl-tty-kit:tick-loop-run, for an exactly reproducible final
state.