Perilar: Dark Weaver

Perilar was my favorite of my games, an original iPhone RPG (loosely inspired by Rogue, Ultima, & Zelda). Alas, the App Store is a pain in the ass to stay current in, and Perilar needed updates I wasn't willing to jump thru Apple's hoops to deliver, so it's been gone from the store for a few years. Does anyone even remember me?

Then I wrote & released Brigand, a stripped-down realtime roguelike, which apparently everyone got mad at either because it was too hard (it was, but I liked that), or cost $9.99 which is SO MUCH MONEY on the goddamned App Store. And again the App Store made it obsolete and it wasn't reasonable to update it.

So I got back to a new desktop version of Perilar. I wrote a JS prototype (Fallen Kingdom) that wasn't fast enough to be usable, but let me rapidly test a bunch of new things. Now in Scheme, after a very long time, I have a nice, fast, nearing-complete sequel to Perilar: Dark Weaver.

Where I am right now:

  • World has both hand-designed and random sectors, tho the latter need some smoothing out to look like real terrain. I can walk across the world, at least until I hit impassable sectors. Porting my complex map and dungeon generators in is the next task. I have spent the last 6 months building features in the Town of Amity, and I'm ready to move on!
  • Most of the tile art is from the DawnLike set, with a lot of customization and new art where needed, and I've stuck to the DawnLike palette, it really has a nice old-timey look, a little less garish than the Atari 800, brighter than C64.
  • Player art isn't going to be these sprites, but the paperdolls I have are 2-facing (East/West), and I'd prefer 4- or 8-facing (you can move diagonally!); so I still need to find or draw (oh no) those.
  • NPCs have dialogue trees, stores, and special abilities (like the Innkeeper healing you; they're not super-powered).
  • Combat, with multiple attack/defense options, works in my test area. I haven't spread monsters around the sectors yet, but they've been developed and tested in the JS prototype.
  • Loot is extensive, magical weapons and armor have all the complex options you'd expect. I'm being a hardass on encumbrance in this one, because you can drop loot anywhere and come back for it. (Not quite the hardest possible ass; gold doesn't count towards weight, which it does in tabletop RPGs!)
  • Spells beyond Magic Missile are not implemented at all yet; will probably ship with only the dozen basic spells from the original release, and advanced spells added in an update. You won't find anyone to teach those for a long time anyway. Despite that, Wizards are still useful with magic wands.
  • New bosses, boss arenas, deeper dungeons, main quest, and sidequests.
  • At least one sector will be user-modifiable, tho I don't know if it'll be in the first release. You can buy furniture and walls, and fix up your own town. There's useful things you'll be able to get from that. (The building mechanic half works now; gathering doesn't).
  • Currently tested on Mac, should be buildable with no or very few changes to Windows, Linux, BSD, etc., but I need to get proper test environments for all of those.
  • Will be for sale on itch.io sometime this year. Price TBD.

I feel super awkward about self-promotion, but I do have a Patreon, and for Gold level you'll get betas; I haven't explained this, but at any level, when you've paid up whatever the cover price of the game ends up being, you'll get a full release license for it, too.

darkweaver-2020-01-08-2
darkweaver-2020-01-08-3

Software Principles for 2020

This is both for myself, and to decide what software I'll tolerate in my presence in the future.

  1. No lag. All UI must respond and be responsive again within 100ms. Most everyone has many cores in their CPUs and a massively parallel GPU not doing that much, you can spare ONE to run your work thread. Stop with the long animation shit. 100ms is plenty to see a shadow moved from one place to another, where there is now an interactive UI.
  2. No load screens. If you can't preload "instantly", be functional, show a usable menu while background loading. Media streaming needs to buffer, but you can show a poster frame instead of empty space.
  3. No ads or spyware. If you can't subsidize your software some other way, don't ship software. Or as the late very lamented Bill Hicks said, "If anyone here is in advertising or marketing, kill yourself!" (and of course there's ads on youtube; so maybe I need to find a better video hosting system? I know there's a fediverse-based video thing)
  4. No custom binary formats. Save your data in JSON or some other common system (plist on Mac, etc), so users can export & manipulate it from their own tools.
  5. No sites without syndication. If you have a web site or blog, you MUST support RSS or Atom, or both. Failure to do so should have you removed from the Internet.
  6. No unsecure connections. I know it's hard to add https the first time, and some older services can't be easily wrapped, but every http connection is a chance for false information to be fed to you, your computer compromised, your information to be stolen.

Atheism Reading Assignment

The things that deconverted me as a child:

  • National Geographic Concise History of Religions: Either one of these is right, and it's not yours, or none of them are right. I'm particularly fond of the Aztecs, since they believed at a depth no rational person can comprehend… and were just totally wrong. Huitzilopochtli didn't end the world when the sacrifices stopped.
  • Carl Sagan's Cosmos, book (most importantly) and TV series (often streaming online, or get the boxed set). Explains the scientific method, and how we have learned what we know. I don't recommend Neil Degrasse Tyson's version, which is much more pop-culture.
  • Isaac Asimov's Guide to the Bible: Explains where the Bible came from and how it was written, and why.

Additional:

Adult Engineer Over-Optimization as the Motie Problem

Looking at my Scheme code and the way I customize it, I'm starting to see the real reason evil megacorps (and wannabe evil startups) won't hire even middle-aged programmers or use your favorite weirdo language, they just want young idiots who code Java or Go.

If you think about a standard software career, there's maybe 10 years of a submissive fool badly coding crap languages ^1 like Java, Go ^3, PHP, JavaScript ^4. They just got out of college or self-trained, and can barely copy existing algorithms, let alone think of one for themselves. This is why FizzBuzzTest ^5 is such a good novice coder test: It requires following directions exactly, and slightly competent logic skills, but not much more.

Then maybe 10 years of them being project managers and "architects", running waterfall and GANTT charts; they'll say they're "agile" but then have a giant JIRA repo of "backlog" features which have to be implemented before shipping, weekly 4-hour planning "backlog grooming" meetings, and unrealistic estimates. This is sufficient to build all kinds of horrible vertical prisons of the mind like Azkaban Facebook.

Then they either retire, or are "downsized", and now what? So they work on their own code, do maintenance on old systems, or leave the industry entirely.

If they work on their own, freed of evil megacorp constraints, they're going to end up in something idiosyncratic and expressive, like Scheme, LISP, Forth, or a custom language. Make their own weirdo environment that's perfectly fit to themself, and unusable/unreadable by anyone else.

Case in point, I needed an object model. There's one I like in Gerbil, and Gerbil's blazing fast, but I can't make a full SDL2 library for it yet (Gambit's FFI is hard, I've hit some bugs, and there's a LOT of library to interface to), and I'm using a bunch of other Chickenisms anyway, so I can't really move to it yet. Instead I just made my own simple object libary, with a couple macros to hide the ugly reality behind it:

(test-group "Object"
    (test "Object" 'Object (class-name Object))
    (let [ (obj (@new Object))  (bug )  (cow )  (duck ) ]
        (test "Object-to-string" "[Object]" (@call obj 'to-string))

        (define-class Animal Object)
        (define-field Animal 'legs 0)
        (define-field Animal 'color )
        (define-method Animal 'init (self legs color)
            (set! (@field self 'legs) legs)
            (set! (@field self 'color) color) )
        (define-method Animal 'speak (self)
            (sprintf "The ~A ~A with ~A legs says " (@field self 'color) (class-name (@class self)) (@field self 'legs)) )

        (set! bug (@new Animal 6 "green"))
        (test "bug-legs" 6 (@field bug 'legs))
        (test "bug-color" "green" (@field bug 'color))
        (test "Bug speak" "The green Animal with 6 legs says " (@call bug 'speak))

        (define-class Cow Animal)
        (define-method Cow 'init (self color)
            (@super self 'init 4 color) )
        (define-method Cow 'speak (self)
            (string-append (@super self 'speak) "MOO!") )
        (set! cow (@new Cow "brown"))

        ;; second class to make sure classes don't corrupt shared superclass
        (define-class Duck Animal)
        (define-method Duck 'init (self color)
            (@super self 'init 2 color) )
        (define-method Duck 'speak (self)
            (string-append (@super self 'speak) "QUACK!") )
        (set! duck (@new Duck "black"))

        (test "Cow speak" "The brown Cow with 4 legs says MOO!" (@call cow 'speak))
        (test "Cow to string" "[Cow color:brown;legs:4]" (@call cow 'to-string))
        (test "Duck speak" "The black Duck with 2 legs says QUACK!" (@call duck 'speak))
        (test "Duck to string" "[Duck color:black;legs:2]" (@call duck 'to-string))

        (test "instance-of?"  (instance-of? cow Cow))
        (test "instance-of? parent"  (instance-of? cow Animal))
        (test "instance-of? grandparent"  (instance-of? cow Object))
        (test "instance-of? cousin-false"  (instance-of? cow Duck))
        (test "instance-of? not an obj-false"  (instance-of? "wtf" Cow))
    )
)

The implementation code's not much longer than the tests, but it's not quite done for me to show off; I need to switch my macros into non-hygeinic forms so I can get rid of the (self) in define-method, and introduce an Objective-C-like _cmd field for self-reflection, and message-not-understood handling. There's always more tinkering to do.

Which is great for me, but makes my code an undocumented (mostly) new language, unusable by anyone normal. A giant pile of crap Java program, no matter how old, can be "worked on" (more crap piled on top) by any teenage Bro Coder.

All of which brought to mind The Mote in God's Eye, where the Motie Engineers over-optimize everything into a tangled mess, and the Watchmaker vermin are even worse, wiring up everything to everything to make new devices. The threat posed by and solution to Scheme programmers, in your usual authoritarian megacorp scenario, is similar to Watchmakers.


^1 Swift is intended to fit this niche much more than weirdo expressive Smalltalk+C Objective-C was, BDSM ^2 to prevent one from writing "bad" code, but it's not there yet; the reality of low-level software dev can't be simplified as much as Apple wants, and their C++ developers weren't up to the task anyway.

^2 Bondage-Domination-Sado-Masochism; aka strict type systems and code flow analysis, that prevent one from writing "bad" code at the cost of annotating everything with types instead of doing useful work. I'm not kink-shaming people who do that for sex, only those who do it to their own software.

^3 Rob Pike has openly said they can't give a powerful language to newbie Googlers, they mostly just know Java, C, C++, which is why Go is so limited and generic.

^4 Oddly, JS is basically a LISP with really shitty syntax. It's easy to make trivial, broken junk in it, but it's also powerful and expressive if you're an old maniac who understands the Self-based object system.

^5 Oh, fine, but only so I can demonstrate something:

(define (fizzbuzz-test i n s)  (if (zero? (modulo i n))  (begin (display s) )  ) )
(define (fizzbuzz i)
    (unless (any identity (list (fizzbuzz-test i 3 'Fizz) (fizzbuzz-test i 5 'Buzz)))  (display i))
    (newline) )
(for (i 1 100) (fizzbuzz i))

Totally different structure from the usual loop-if-else repetition and hardcoding of everything, because Scheme encourages coding in small pieces. Of course I wrote my own for macro which expands to a named let loop; there's many like it but this one is mine. More Motie engineering.

A Scheme of Gerbils Runnin' in a Wheel

Chicken's mediocre performance is causing me problems, so I'm taking yet another language tour/spike.

Looking at Gerbil Scheme, as a faster Scheme and as a bonus it's closer to R7RS. It has far less library support than Chicken, but does have a FFI, and compiles to a native binary through C, so I really don't need too many libraries.

Instead of the #!key #!optional #!rest keywords used in Chicken and some others, Gerbil uses a literal template style for functions:

;; Chicken: (define (foo a #!key (b 'bar) #!optional (c "see?") #!rest rest)
;; Gerbil:
(def (foo a b: (b 'bar) (c "see?") . rest)
    (print "a=" a " b=" b " c=" c " rest=" rest "\n")
)
(foo "Mark" 1 b: "bees!" 'what) ;; note out-of-order optional & keyword
;; a=Mark b=bees! c=1 rest=what

I like this style better, but I dislike the "def" keyword (which uses the enhanced lambda that does this) instead of "define" which uses "lambda%" (traditional lambda).

Gerbil uses [] for list construction, and {} for method dispatch, so goodbye to the nicely distinguishable braces I was using in Chicken. The spec says implementations can do what they want with those symbols, but I wish they wouldn't. Ah, well. I'll add a shitload more whitespace and some comments and it'll be fine.

The struct/object system in Gerbil is pretty nice, they're slightly upgraded records, but there's an (@ obj field) syntax instead of (MyClass-field obj), and (defmethod {mymethod MyClass} ...) creates a polymorphic {mymethod obj args} which finds the right method for any object, which is especially useful for inheritance.

I tried doing some VT100 graphics just to proof-of-concept, but it's doing something to the terminal, such that the same escape codes which work in Python don't clear the screen fully in Gerbil. After a short losing battle with stty and termcap, I give up on that and I'll jump right to writing a C FFI to SDL, because in 2019 that's easier than writing to a console.

Daily reminder that everything we have made since 1984 is overcomplicated junk. On an Atari 800, this took a few seconds to type, and you could start coding a nice UI instantly:

atari-is-awesome-graphics1

Alas, we live in a fallen world, so this is going to be trouble. Here's my Gerbil FFI template so far:

package: myffi

(import
    :std/foreign
)

(export )

(begin-ffi
    ;; names of all Scheme wrappers to expose
    (chello)

(c-declare #<<CDECLEND

 <stdio.h>

int chello(void) {
    printf("Hello this is C!\n");
    return 1;
}

CDECLEND
)

    (define-c-lambda chello () int "chello")

) ;; begin-ffi


; TODO for constants: (define FOO ((c-lambda () int "___result = FOO;")))

(define (main . args)
    (chello)
)

Gerbil has a Scheme-based build system, but I'm a caveman so I make another build.zsh:

#!/bin/zsh

function usage {
    echo "Usage: build.zsh MAIN.scm [LIBS] || -?"
    exit 1
}

if [[ $# -eq 0 || "$1" == "-?" || "$1" == "--help" ]]; then
    usage
fi

mkdir -p bin

main=`basename $1 .scm`

gxc -exe -static -O -o bin/$main "$@" || exit 1
echo "Built bin/$main"

Now:

% ./build.zsh myffi.scm
Built bin/myffi
% bin/myffi
Hello this is C!

Hooray! Unconditional success! Only took all afternoon and a half-pot of coffee!

Now I "merely" have to wrap all of SDL (well, just the parts I need) and get linking working and oh sweet merciless Cthulhu. And I still won't know how much this'll help my performance until I'm days into it. But, the first step is the hardest.

Project UFO

Which one is correct? Let's think about this from the other direction. Could we buzz another planet, today, in a way that makes "UFO sightings are ALIENS!" make any kind of sense?

Premise 1: It is incredibly unlikely that any "intelligent" species, having recently developed from hunter-gatherers to agriculture to technology in the span of a few thousand years, is smart enough to reach that technological stage without making their planet uninhabitable as we have, or discovering nuclear weapons and waging primitive tribal warfare with them. Even if anyone survives this century, or we colonize Mars, it may be centuries before we have this amount of available energy and economy again.

Therefore 1: Any "UFO" is probably from someone like us, just barely capable of doing it before going extinct. A last fireworks show before the Long Night.

This is going to take a while to work out. Get a coffee.

The nearest star is Proxima Centauri, 4.3 Light Years (272K AU, or 40.7 trillion km) away, and there is a potentially habitable planet.

If we stopped having wars (as if!), we'd have a few trillion dollar surplus; but I'll just suppose we redirect no more than half our military budget. You could easily recruit volunteers for a life-long mission.

A spaceship capable of keeping people alive to get there would be, as a minimum, the size and complexity of a nuclear submarine, 6800 tons displacement, 128 crew, and maybe 100x the cost: $150 billion. Let's handwave away with hydroponics and recycling that a real sub has to surface for supplies every 3 months, and the reactor lasts 30 years before it needs a refuel from recently-processed uranium. Neither are insurmountable engineering, the ship's going to be unpleasant to live in but it's about the best we can do.

SpaceX Falcon Heavy can lift 22.2 tons to orbit, displacement isn't exactly dry weight but close enough for an estimate so that's 300 launches at $100M+ each ($30 billion!) and then somehow assemble it in orbit.

Assembly would be easier if we had a space colony, with a giant machine shop, or even could still run the Space Shuttle (the space truck finally useful for something!), but that'll cost even more money and time to set up. At least another $1 billion on moving enough workers through ISS to finish the thing.

Now we need a space drive. Here we're kinda screwed.

As reference, see Atomic Rockets, menu at the bottom of the front page is where all the interesting stuff is, and in particular Slower Than Light. And a lot of the systems given there don't work in reality, or we don't have yet.

The "ALIENS!" enthusiasts are gonna say magic spacedrive, or fusion torch, or whatever, but we can't make any of those, and fuel's still not adequate for constant burn. You can't magic up extra fuel. There is no such thing as faster than light travel. And see premise 2 later.

Bussard Ramjets would be perfect, even with the 0.12 C speed limit they would actually have… but we aren't within decades of making one.

The nuclear reactor could power an ion drive, which we know how to make and fuel, very very low thrust but constant acceleration, scratch pad shows decades to reach halfway and start decelerating, except we can't carry enough reaction mass and there's none in deep space. Great for in-system maneuvering if you're patient, useless for interstellar travel.

Orion drive, firing nuclear bombs at a heavy plate under your ass, is an act of war in our own Solar System, and a giant whiplash and cancer machine for the crew. 100% buildable, but nobody's that stupid.

Charles Pellegrino's Flying to Valhalla has a reasonable proposal for a sorta clean antimatter drive that'd get there in about 5 years, we just need to plate Mercury in solar cells to power particle colliders to make the shit. Avatar is a stupid, terrible, stupid movie, but Pellegrino designed the starship in it, which is perfectly reasonable. So, that's a century or two off. No good.

Solar sails and laser launchers should work, and we can make these. We'll know for sure in a couple weeks. Making them big enough for a huge ship (1000 km across!) is a challenge, but this is a matter of engineering, not fundamental science. This would take 20 years to reach halfway and 20 years to slow down, but some original crew and their kids could get there.

The lasers are the infinitely expensive part, where you can just sink all money forever into and not be done, but good news is A) they stay put in the Solar System, B) you can build and launch them one at a time over years as a satellite array zapping a lens which projects onto the sail, and C) they're useful anti-asteroid tools (not by burning, but put another sail on an asteroid, and you can push it out of harmful orbits). The bad news is D) the people back home may be dead/forget about you/not be able/be unwilling to continue running them in 20+ years, and E) lasers in orbit can be turned against ground targets, almost literally a lightning bolt from "god" striking down your enemies. Quis custodiet…

Worst case is the lasers go quiet, and the laser sail ship becomes a much slower solar sail ship, which has to make a couple of slowdown passes at AC. If our recycling is good enough, maybe that works, maybe we die alone in the cold of space.

Now we're cruising slowly thru the system, find a habitable planet. We can't land the ship, but have a complement of drones that can fly into atmosphere. An unmanned drone could maneuver faster than any aircraft, and would even be hard for primitive radar to spot, just like our UFO stories.

But is there anyone there? Humans have existed for ~1 million years, about 5,000 of that civilized enough to be worth talking to, 100 years capable of radio, before probable nuclear or environmental extinction. Out of 3.5 billion years of Earth being a life-bearing planet so far, and maybe 6.6 billion years ahead where life can exist, that's a 1 in 2 million chance of there being anyone to talk to.

The ship would be very visible, with sails out decelerating in, it'd be the brightest object in the sky. If the autochthons have radio, they can be called; but we'd have already heard their broadcasts here on Earth. Maybe blinking lights to talk to a more primitive culture? Land a drone and talk over a radio speaker?

There's no easy way to land, abduct redneck autochthons, probe their cloaca-like entries, and return. Even if there was space for a couple Falcons as landers (strapped to the sides as maneuvering thrusters?), they'd need fuel to get back up. It may be possible to do a one-time water landing of the spaceship without killing everyone.

The only reason we would ever have gone there is to meet them and share information, tell them about our home and what we're like. Show them Pulp Fiction and The Ramones and Heinlein's The Green Hills of Earth. We wouldn't be trying to keep it a secret, even aside from the physical impossibility of hiding the spaceship. Nor would the aliens cover it up; no matter what they are, we'd be the most important new source of science, technology, and entertainment.

But landing presents political problems even with public disclosure, they might go to war over who "gets the Earthers", and possession is 9/10ths of interstellar law. Hopefully there's some competent diplomats. There's a lot more ways first contact can go wrong than anything in the flight. Really think very carefully before landing.

Colonization is difficult anyway, the atmosphere's not likely to be the mix we need, the native life may be digestible into basic materials (most life is probably CHON ) but will lack any vitamins; we'll need to keep eating hydroponics. We'd be immune to local viruses but might have no immune reaction to local bacteria & fungi equivalents, nor would any native life to ours. Staying in orbit or colonizing a barren rock is safer.

There will be no alien hybrids, no half-Vulcan Mr Spocks, and the aliens won't look anything like a Human with a latex mask. First, do you consider mating with chimps, crocodiles, squids, tulips, or…? No, stop, I don't wanna know! Baka! Ecchi!! But those are genetically related to us and yet no offspring is possible because we don't have enough compatible genes. If panspermia is real, actual aliens would be more distantly related than fungi, and if not then it would be like screwing a rubber toy.

Conclusion 1: Any plausible alien spaceship scenario is going to look almost nothing like the UFO contact stories. We'd see them coming. They'd have to talk to us on the radio. No secret bases. No abductions. They'd be weird alien pop stars with agoraphobia and unused to gravity, constantly on PR tours and eating alien food because ours is useless.

Premise 2: So Pellegrino's matter-antimatter drive? The point of Flying to Valhalla was that a near-C space drive is a one-shot planet-killing weapon. You'd briefly see an X-ray burst, then the ship's front shield would shatter like a shotgun shell so you can't just redirect it, then the planet would explode, in the space of hours or minutes as the ship chases up behind its light. And you could set one up with a deadman switch to kill whoever killed your planet.

Therefore 2: We're not dead yet, and nobody's contacted us to say "listen up, these are the rules!" Mutual assured destruction means they have to assume we'll do it to them. They don't have to fire first, just make sure we know the threat exists.

Conclusion 2: Nobody within 50 light years of us has advanced technology and has heard our radio signals (50 years there, 50 years for the weapon to come kill us).

Any other scenario isn't science, isn't even science fiction, it's just fantasy. I like fantasy as much as the next guy who isn't wearing a My Little Pony shirt, but it's not real.

The Machine Stops

The problem with the Internet… and here I'm referring to (sweeps hand across everything in view) all of this, but to take just current events Google blocking ad-blockers in Chrome, Google downtime locking people out of their Nest thermostats and "Home"-controlled security systems, horrible prisons of the mind like Twitter and Facebook, and the cacophony of Fediverse drama over Eugen adding features (better features are already in Pleroma and glitch-soc Fediverse servers), Gab forking Mastodon, client devs making unilateral decisions to block domains despite helpless users complaining, or anyone having "free speech" (which Eugen in particular is opposed to; I strongly advise against using mastodon.social, find another instance). These are just a point-in-time examples, it's been going on for decades (oh, USENET, how we don't miss your flamewars) and will only end with us.

… is people using software they didn't write themselves. No understanding, education, or discipline required. Just install something and it works! It's a product, not a skill! But they don't know how, or why, or why they should not.

"It didn't take any discipline to acquire", in the words of Ian Malcolm/Michael Crichton.

Until the software they rely on shuts down, literally like E.M. Forster's "The Machine Stops", and then weak unskilled mole-people crawl out of the wreckage of machines they never learned to understand, make, or repair, and then die.

My solution is drastic but logically unavoidable: No more software installs. As a child, you get a bare machine with nothing but a machine-language monitor. You learn ML first. You type in a language compiler or interpreter. You build up your own tools. We return to type-in program listings like Compute!, but no binary blobs, it must all be readable, comprehensible source, with design and implementation documentation.

If you want to share software, you need to build up your toolchain to that point yourself. Hopefully by then you've learned to read all patches you install.

Should this be extended to all technology? Information technology has the unique ability to coerce how and what you think; an automobile or an antibiotic does not. There's an argument (in "The Notebooks of Lazarus Long", for instance) that a citizen should be able to make all their own things, "specialization is for insects". But insects are the most successful clade on Earth, and will long outlive us; some specialization is probably acceptable, as long as it's not in the part that controls how you think.

I don't think this civilization can ever do that, it will not make hard changes that inconvenience anyone. I think this horrible Machine will lumber on a few more decades and then we'll all die from it. But maybe isolated tribes will survive, or intelligence will arise in the Machines, or in a few million years another intelligence will evolve, and build new things the right, responsible way. Their history books will describe us as being as foolish and self-destructive as the Easter Islanders.

Support Me on Patreon!

With the BBS going public, and soon a real release of Perilar Fallen Kingdom, it's time for you to help me keep doing this!

Become a Patron!

I'd at least like to get my hosting costs under control, and anything over that goes to me making cool games and apps for art, instead of boring things to survive.

The Best SF Author of All Time

So, I can't actually pick one, or even rank ten, but by decade (when they made the works most important to me) it's down to a short list:

  • 1830s: Edgar Allen Poe
  • … long empty stretch …
  • 1890s: H.G. Wells
  • … shorter empty stretch …
  • 1930s: H.P. Lovecraft
  • 1940s: A.E. Van Vogt
  • 1950s: H. Beam Piper, Clifford Simak
  • 1960s: Brian Aldiss, Robert A. Heinlein, Zenna Henderson, Frank Herbert, Andre Norton
  • 1970s: Marion Zimmer Bradley, Katherine Kurtz, Fritz Leiber, Anne McCaffrey, Michael Moorcock, "James Tiptree, Jr", Roger Zelazny
  • 1980s: Mary Gentle, William Gibson, Elizabeth Moon, Rudy Rucker, John Shirley, Bruce Sterling, Walter Jon Williams
  • 1990s: Pat Cadigan, Greg Egan, Neal Stephenson
  • 2000s: Neal Asher, Peter F. Hamilton, Alastair Reynolds
  • 2010s: Mira Grant (aka Seanan McGuire), Martha Wells

I can make an argument for almost any of them to be "my favorite" depending on mood, but Piper might be the winner in a bracket contest. I suspect I'd get down to something like Piper vs. Egan and my head would explode trying to compare Space Viking with Diaspora.

My first pass at this, there were only 3 female authors (Pat Cadigan, Mira Grant, and Martha Wells). Several were only fantasy: Which I think less of, but I do read—and Leiber and Moorcock's science fiction are not their best works.

Many only had a few great books or short stories surrounded by a giant midlist of dullness, but that's also why Niven, Pournelle, Steven Barnes, Iain M. Banks, Dan Simmons, and Poul Anderson never made it. Several I do list produced dullness after their peak, like Gibson objectively only wrote one short story collection & 2 thin novels worth reading, one should not read McCaffrey's post-trilogy extended sequels, and anything Stephenson wrote after The Diamond Age needed an aggressive editor to cut out about 2/3 of his text. And yet many continue to write exactly what I like, decades later.

The '60s-'80s really produced a LOT of SF I liked. Was it objectively better? Or was it just "the golden age of SF is 12" which was 1982, so I read what was still in print?

Terminal Condition

I spend half my time, easily, in a command-line terminal running zsh. So a new one, even one on an OS I don't run, is interesting:

There are some modern, nice conveniences in this. It's a little ways behind Mac Terminal.app (based on the NeXTstep Terminal from 1990), and vastly far behind iTerm2, but it's more advanced than the usual Linux terminals like rxvt, urxvt, or cross-platform Alacritty or Hyper.

Between this and WSL2 being a full Linux, it's plausible that the best Linux dev environment now (well, this summer when it's released) is Windows. The Year of the Linux Desktop is 2019, and it is owned by Microsoft®. Can you hear the tiny, distant screams of the FSF cultists?

Comparison based on code, reviews, and reddit thread with MS devs involved:

  • Scrollback: The single most important thing a terminal can do. MS does this, but doesn't have logging.

    Surprisingly, a lot of them only support a few pages. I keep mine at 10,000 lines or so, which is probably wasteful but so handy; I don't bother logging since my .zhistory keeps everything I typed, and I have Terminal.app and iTerm2 set to not close tabs automatically.

    Alacritty only just added scrollback last year.

  • Prompt Marking: Nope.

    This is a feature it's hard to live without once you've had it, no more paging up trying to see prompt lines (I have a red ANSI-colored prompt and it's still hard to see). In Terminal.app, Edit, Marks, Automatically Mark Prompt Lines, and then ⌘↑ and ⌘↓ move between them. iTerm2 has it enabled by default, and ⇑⌘↑ ⇑⌘↓ are the keys, which took me some re-learning.

    Nothing else has this, as far as I've seen.

  • Fonts: MS has programming ligatures and displays emoji, finally. Does not support RTL languages.

    I use Fira Code in all my editors and shells, and it's enormously helpful, more readable, and catches bugs: I look for === as a fat-equals symbol in JS, etc.

    Hyper, urxvt, Alacritty support Unicode fonts. rxvt stopped development almost 20 years ago so it barely shows 8-bit fonts correctly.

  • Tabs: MS has tabs! They're currently invisible until you add a second tab, same shit Terminal.app does, which annoys the hell out of me; I don't like UI that reshapes itself, reminds me of T-1000 Terminators (also makes it hard to tile my windows up correctly when they get resized).

    It's not clear if you can drag Windows Terminal tabs around to different windows.

    In iTerm2, I normally keep: First window with tabs for home shell, ssh into my server (running screen, so that has many open shells). Second window with 2 tabs for REPL, editor/running/compiling tasks, and sometimes a third tab for reading local docs. If I need more shells, I usually open them on the first window. I rarely open a third window for monitoring some long-running task; I just drag a tab out to its own window. All terminal windows are stacked on the left side of my screen, because there's no icons under that side of the Desktop.

    urxvt has tabs, but they're kind of a hack, not fully usable.

    Hyper has tabs, but they replace the title bar. Which is cool but also awful like a lot of things it does.

    rxvt and Alacritty don't do tabs, because they insist you use screen or tmux. Which sucks if you want to move a process from one window to another.

  • Profiles: MS supports multiple profiles, so you can use different ones for each task.

    So does Terminal.app, iTerm2, urxvt (but it's buried in a text file config).

    Alacritty, rxvt, and Hyper have a single profile and no UI for changing anything, hope you like editing text files and reloading.

    As far as I can tell, nothing else does automatic profile switching like iTerm2; when I cd to my ~/Code/CodeScheme folder, iTerm2 switches to my dark red transparent profile, including Scheme-specific triggers and copy/paste filtering.

    You can probably do that in urxvt's Perl(!) scripting, but it's not normal or easy.

  • Copy/Paste Filtering: Nope.

    iTerm2 and urxvt both let you set a bunch of regexp to run over lines to get selections correctly matching boundaries, not just space-delimited.

  • URL Highlighting: Nope.

    iTerm2, Hyper, and urxvt notice URLs and filenames, and let you click on them. In iTerm2, hold down ⌘ and click on any URL or path (like in an ls or find result!) and it does some useful action: Opens the URL in your browser or file path in your editor, by default, but you can configure that in the profile.

  • Custom Keybindings: Sorta? Doesn't seem complete, no idea if there's UI for it, but it does exist in their config.

    Most terminals can do this, but most can only remap a few actions. I like iTerm2's, as usual, which lets you bind any action, menu, or run a program on any keybinding. I mostly just use it to launch different profiles with starting paths & scripts.

    Terminal.app only lets you send specific text for a key.

  • Images: Sorta? Only if they're embedded in fonts.

    This is a neat trick in iTerm2: images. I use imgls all the time to see a thumbnail of every file with details (protip: I changed ls -ld in the script to ls -1Fskd for a more concise listing), and then ⌘-click to open what I want in Acorn; it's better than opening Finder and trying to read a long filename under a thumbnail.

    I'm unaware of anyone else being able to do this.