Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš‚ sl β€” Steam Locomotive

GitHub stars GitHub forks License: MIT Python Platform Dependencies Maintained Website

You typed sl. You meant ls. The railroad thanks you for your patronage.

      ====        ________                ___________
  _D _|  |_______/        \__I_I_____===__|_________|
   |(_)---  |   H\________/ |   |        =|___ ___|
   /     |  |   H  |  |     |   |         ||_| |_||
  |      |  |   H  |__--------------------| [___] |
  | ________|___H__/__|_____/[][]~\_______|       |
  |/ |   |-----------I_____I [][] []  D   |=======|__
__/ =| o |=-~~\  /~~\  /~~\  /~~\ ____Y___________|__
 |/-=|___|=    ||    ||    ||    |_____/~\___/
  \_/      \O=====O=====O=====O_/      \_/

Every other command punishes a typo with an error message. sl rewards it with a steam locomotive. The entire point is maximal output for minimal input β€” two mistyped letters buy you a train, and you will watch it cross your terminal, because that is the punishment and the prize.

This is a single-file, zero-dependency Python train that takes the joke entirely too seriously: a flicker-free double-buffered renderer, wheels that actually turn, smoke that drifts and dissipates, coal cars, a whistle, and a crash mode that earns its flag.

🎲 No two typos look alike

A bare sl β€” the classic fumbled ls β€” rolls the dice on everything: locomotive type, coal-car count, color livery (four named themes plus fully random one-offs), and speed. Sometimes it whistles. Rarely, it flies. Very rarely, it does not make it across.

Event Odds
βš“ The typo turns out to be nautical about 1 in 3
πŸ“£ The train (or ship) whistles 1 in 4
🐬 A dolphin escorts the voyage 1 in 5 sea voyages
✈️ The train takes flight 1 in 10
πŸ’₯ The journey does not reach its destination 1 in 20

Pass any flag and the dice are off β€” explicit options are fully deterministic, so your customizations always behave exactly as written.

βš“ New in 4.0: the rails end at a shoreline

Four vessels join the roster. Type sl -t galleon and a three-masted pirate ship crosses your terminal on an animated sea β€” flapping Jolly Roger, turning nothing, fearing nothing, figurehead shaped like a rubber duck. Her name is SQUEAKY. She has gunports.

                                     |~~~~~~,
                             ` ` ` ` |x_x__/
                   ` ` ` ` `         |     ` ` `
                 |>                  |           ` ` `
             .___|___.           .___|___.             |>
             (   |   \           (   |   \             |
            (    |    \         (    |    \       .____|____.
           (___________\       (___________\      (  ( | )  \
         `       |                   |           (  (  |  )  \
            .____|____.         .____|____.     (  (   |   )  \
       `    (  ( | )  \         (  ( | )  \    (__)_________(__\
     ` /|  (  (  |  )  \       (  (  |  )  \           |
      / | (  (   |   )  \     (  (   |   )  \         /|    _____
   ` /  |(__)_________(__\   (__)_________(__\       / | __|~ ~ ~|
    /   |       /|\                 /|\             /  ||  o  o  |
<o)_/___|      / | \               / | \           /   || o  o   |
  \__\__________________________________________________|________|
    |=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=|
    \   []    []    []    []    []    []    []    []    []      |
     \_________S Q U E A K Y____________________________________/
      \=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_/

The fleet:

  • πŸ΄β€β˜ οΈ galleon β€” the Jolly Roger flaps on a 4-frame cycle, pennants flick, and the sea shimmers under her hull
  • πŸ›ž steamer β€” a sternwheeler whose paddle wheel actually turns (same 4-frame machinery as the locomotive wheels), churn streaming aft
  • β›΅ sloop β€” a racing yacht for narrow terminals
  • 🚒 tug β€” drawn in three-quarter perspective, so it travels diagonally, on the angle its art implies, growing as it approaches

Sea voyages come with bow spray, stern wake, hull bob, and per-vessel whistles (-w): the steamer HOOOONKs, the galleon goes YARRR!. At sea, -a finds an iceberg β€” crunch, bubbles, and a dignified descent. -F is the Flying Dutchman. And on special request, -d summons a dolphin that dives ahead of the ship, cut cleanly at the waterline.

✨ Features

  • 🎲 Surprise mode β€” a bare sl randomizes the whole show, every run
  • πŸš‚ Four locomotives β€” Classic, Small, D51, and C51 (-t)
  • βš“ Four vessels β€” Galleon, Steamer, Sloop, and Tug (-t), with an animated sea, spray, wake, and a dolphin on request (-d)
  • πŸ›ž Animated wheels β€” a 4-frame rotation cycle on every engine
  • πŸ’¨ Particle smoke β€” drifts behind the train and dissipates, with grayscale shading on 256-color terminals
  • πŸšƒ Coal cars β€” couple up to 8 tenders behind the engine (-n)
  • ✈️ Flying mode β€” smoothstep climb with a stardust trail (-F)
  • πŸ’₯ Accident mode β€” screen shake, a spark shower, and a proper BOOM (-a)
  • πŸ“£ Whistle β€” the train toots as it passes (-w)
  • πŸ–₯️ Flicker-free β€” double-buffered frames on the alternate screen; your terminal contents come back when the train has passed
  • 🎨 Respectful of your eyes β€” honors NO_COLOR and --no-color; sl | cat prints a static train instead of escape-code soup
  • πŸ“ Terminal-aware β€” live resize handling, clean Ctrl+C, monotonic frame pacing that doesn't drift
  • πŸͺΆ Zero dependencies β€” one file, pure Python standard library

πŸ“¦ Installation

git clone https://github.com/developtheweb/slTrain.git
cd slTrain
sudo make install

That installs to /usr/local/bin/sl. Prefer to do it by hand?

sudo cp sl /usr/local/bin/ && sudo chmod +x /usr/local/bin/sl

Requirements: Python 3.6+, a Unix-like terminal with ANSI escape support, and a sense of humor. Nothing else β€” see requirements.txt, which is proudly empty.

Uninstall

sudo make uninstall

The train will remember this.

πŸš€ Usage

You don't use sl. You commit a typo, and sl happens to you:

$ sl              # 🎲 Surprise! Random train, livery, cars, and speed

But if you insist on driving:

$ sl -t classic   # The classic engine, no surprises
$ sl -l           # Long train: D51 pulling coal cars
$ sl -n 8         # Maximum coal. The economy is booming
$ sl -F           # Flight
$ sl -a           # Tragedy
$ sl -w -c        # A whistling C51
$ sl -s 2.0       # You have somewhere to be
$ sl -s 0.1       # You do not

Options

Option Long Form Description
-a --accident An accident occurs partway through
-F --fly Make the train fly through the sky
-l --long Use a longer train (D51 pulling coal cars)
-c --C51 Use the C51 train type
-t --type Type: classic, small, d51, c51, galleon, steamer, sloop, tug (overrides -l/-c)
-n --cars Number of coal cars to pull, up to 8 (default: 0; rail only β€” coal cars do not float)
-d --dolphin A dolphin joins the voyage (implies a vessel)
-w --whistle Sound the whistle as the train or ship passes
-s --speed Animation speed multiplier, 0.1–20 (default: 1.0)
--no-color Disable colors (NO_COLOR is also honored)
-v --version Show version information
-h --help Show help message

Any flag disables surprise mode. The dice only roll for a naked typo.

πŸ”§ How it works

For a joke, it's built like it matters:

  • Double-buffered rendering. Each frame is composed into an off-screen cell buffer and emitted as a single write β€” no clear-screen between frames, so nothing flickers, ever.
  • The alternate screen. The animation runs on the terminal's alternate buffer, the same trick vim and less use. When the train is gone, your scrollback is exactly as you left it. Like it never happened. It happened.
  • A particle system. Smoke, crash sparks, and stardust are particles with velocity, drag, and gravity, aging through character ramps (@ β†’ O β†’ o β†’ * β†’ .) as they dissipate.
  • Monotonic pacing. Frame timing is anchored to a monotonic clock, so the train's speed doesn't drift with render cost or system load.
  • An honest fallback. If stdout isn't a terminal, you get a static train in plain text. sl | cat is a train. sl > file.txt is a train. There is no escaping the train, only escape codes, and those are omitted.

πŸ€” Why does this exist?

We've all done it β€” typed sl when we meant ls. Instead of command not found, why not a gentle reminder in the form of a steam locomotive chugging across your terminal?

  • πŸ“š Typing discipline through consequences β€” muscle memory training, enforced by rail
  • πŸ˜„ Whimsy in the command line β€” terminals can be fun too
  • 🎭 Coworker delight β€” watch confusion turn to joy, then back to confusion when it crashes
  • 🧘 Mandatory micro-breaks β€” the train cannot be skipped, only awaited

❓ FAQ

Can I stop the train? Ctrl+C works and exits cleanly. Learning to type ls also works, but nobody has ever managed it.

The train crashed. Is that a bug? If you passed -a, that's a feature. If you didn't, that's a 1-in-20 roll of surprise mode, and honestly, it's a little bit on you for typing sl.

Why would a train fly? 1-in-10 odds say you'll find out.

I asked for a dolphin and got a ship. A dolphin will not follow a train. Requesting one books sea passage.

Why does the tug move diagonally? It was drawn in three-quarter perspective, so it sails the angle its art implies β€” toward you. It appears to grow because it is, in the only sense that matters, getting closer.

Is this compatible with the original sl? The spirit, the D51/C51 art heritage, and the -a/-F/-l/-c flags are all honored. The renderer, particles, and surprise mode are new.

🀝 Contributing

Contributions are welcome β€” new locomotives, new liveries, new disasters. See the Contributing Guidelines.

git clone https://github.com/YOUR_USERNAME/slTrain.git
cd slTrain
git checkout -b feature/amazing-feature
./sl -F                  # test your changes
git commit -m "Add amazing feature"
git push origin feature/amazing-feature

πŸ’– Support the Project

  • ⭐ Star this repository β€” it helps others discover the train
  • πŸ› Report bugs β€” open an issue
  • πŸ’‘ Suggest features β€” new train types, animations, or calamities
  • 🌐 Visit my website β€” StevenMilanese.com
  • β˜• Buy me a coffee β€” buymeacoffee.com/strangequark

πŸ“ License

MIT β€” see LICENSE. The train is free. The train has always been free.

πŸ‘¨β€πŸ’» Author

Reverend Steven Milanese

πŸ™ Acknowledgments

  • Inspired by the original sl by Toyoda Masashi (1993), who understood that the punishment for a typo should be beautiful
  • The coal car art is adapted from the original sl
  • Thanks to all contributors
  • Special thanks to the first stargazer who inspired this update ⭐

πŸ“Š Project Stats

GitHub commit activity GitHub last commit GitHub code size


It's not a bug, it's a locomotive. πŸš‚

Made with ❀️ by Reverend Steven Milanese
Visit StevenMilanese.com for more projects

About

slTrain is a fun and nostalgic Python script inspired by the classic sl steam locomotive command. This script animates a charming steam locomotive chugging across your terminal, complete with a dynamic smoke trail and colorful ASCII art. It's perfect for adding a bit of old-school charm to your terminal sessions.

Topics

Resources

Code of conduct

Contributing

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages