The Mother of All Demos

December 9, 1968, Douglas Engelbart's presentation of NLS and teleconferencing:

  • Youtube: This is at 360p, most other uploads are at 240p fuzzy mud, I'd love to have a good HD one where I can read the text. Alas.
  • TheDemo@50

"If in your office, you as an intellectual worker were supplied with a computer display, backed up by a computer that was alive for you all day, and was instantly responsible—responsive—to every action you had, how much value would you derive from that?"

Of course, in reality what we mostly do with that is look at social media, hardly any better than watching TV. But we could do more.

It's been years since I've watched this, and some things jump out at me as I rewatch:

The keyboard beep is infuriating, it's what I consider an error sound. And Doug's fumbling a few times, which suggests the keybindings aren't visible, well-organized, or practiced yet. We see later that they're just code mapped to keys in a resource list.

The NLS word demo is somewhat like a modern programmer's editor with code folding; but notably I don't ever use folding, it's slow (even on 1 million times faster machines!) and error-prone, sucking up far more text than expected. It's also a lot like outliners like OmniOutliner; but while I do sometimes use OO to organize thoughts, I would never keep permanent data in it, because I can't get it into anything else I use. Dumb text is still easier and more reliable; I put my lists in Markdown lists:

- Produce
    + Banana
        * Skinless

Maybe the answer is we should have better tools and APIs for managing outlines? Right now I can manage dumb text from the shell, or any scripting language, or with a variety of GUI tools. OmniOutliner's "file format" is a bundle folder with some preview images and a hideous XML file with lines like:

    <item id="kILRUkulXwk" expanded="yes">
      <values>
        <text>
          <p>
            <run>
              <lit>Stuff</lit>
            </run>
          </p>
        </text>
      </values>
      <children>

Nothing sane can read that; even if I use an xml-tree library, it's still item.values[0].text.p.run.lit to get a single value out!

If I export it to OPML, it loses all formatting and everything else nice, but I get a more acceptable:

    <outline text="Stuff">

Back to the demo.

The drawing/map editor's interesting. This is pretty much what Hypercard was about, and why it's so frustrating that nobody can make a good modern Hypercard.

Basically every document seems to be a single page, fixed on screen. If a list gets too long, what happens? It doesn't scroll, just fully page forward/back.

Changing the view parameters is basically CSS; CSS for the editor! Which is what makes Atom so powerful, but it's not easy to switch between them, probably have to make your own theme plugins, or just a script to alter the config file and then reload the editor view.

Inline links to other documents in your editor, is interesting. Obviously we can write HTML links, but they have to be rendered out and no editor can figure out where a reference goes and let you click on it. Actually, this does work in Vim's help system, but nowhere else.

The mouse changed three ways since then: The tail moved to the top, the wheels became a ball which drives two roller-potentiometers inside, and then was replaced with a laser watching movement under a window. Don't look into the butthole of your mouse with remaining eye. But the basic principle of relative movement of a device moving the pointer, rather than a direct touch like Don Sutherland's Sketch light pen, or modern touch screens, or a Bluetooth stylus, remains unchanged and still the fastest way to point at a thing on a screen. Oh, and the pointer was called a "bug" and pointed straight up, Xerox copied this directly in their Star project, while everyone since Apple has used an angled arrow pointer.

The chording keyboard never took off, and I've used a few, and see why: It's incredibly hand-cramping. While a two-handed keyboard is awkward with a mouse, you have room to spread your fingers out, and only half the load of typing is borne by each hand. On a chord, each finger is doing heavy work every character.

The remote screen/teleconferencing setup is hilarious: a CRT being watched by a TV camera, which runs to a microwave transmitter; they couldn't send it over phone lines, acoustic coupler modems were only 300 baud (bits per second, roughly) at the time.

As with Skype today, every chat starts with "I can't hear you, can you hear me? Fucking (voice chat system)." Later, audio drops out, and all Doug can do is wave his mouse at the other presenter. I've joked before that the most implausible thing in Star Trek isn't FTL, even though that's physically impossible; it's not aliens indistinguishable from humans with pointy ears, half black/white makeup, or bumpy foreheads; it's that you meet an alien starship and can instantly set up two-way video conferencing.

They seem to have a mess of languages; MOL (Machine Oriented Language) is a macro assembler in modern terms. All the languages have to be adapted to NLS, they couldn't just use LISP or FORTRAN. Since changes are recorded by userid, they had git blame!

Split screen! That's a thing I love, and few editors do. You can drag a bar down from the top in BBEdit, and Atom has "Split up/down/left/right" for panes, but then you have to re-open the document in each and it's a pain.

Messaging is a public board (or rather, an outline with each statement as a message), with #INITIALS for addressing, like @USERNAME in the Twitters and such. Like those, there's too much data to process for live updating, everything runs as a batch job that can crash the database. War Computing never changes.

Cold & hot retrieval are just file search; on the Mac we have Spotlight, and can search by keywords or filename. Though I have some problems with the cmd-space search these days, and mostly open Finder and search from there to get a list of files matching various requirements, or sometimes use mdfind whatever|less from shell, then winnow down "whatever" until I have only a few results. On Windows or Linux, you're fucked; get used to very long slow full-text searches.


What NLS Did, and How We Can Do That

  1. Mouse, Keyboard, bitmapped displays: We have that.
  2. Teleconferencing: Still sucks.
  3. System-Wide Search: Mac users have that, everyone else is boned.
    • It's faster on Linux or Windows to search Google for another copy of existing data than to search the local machine.
  4. Outlining to enter hierarchical data: Nope.
    • All data goes into outlines contained in files.
    • Code as data: Some data is program instructions, in a variety of languages, which can operate on outlines.
    • To enter this outline, I had to keep adjusting my numbers, because I'm writing it in markdown text.

As mentioned above, OmniOutliner is logically very similar, but it's a silo, a trap for your data. The pro version (WHY not every version?!) lets you use Omni Automation, which is basically AppleScript using JavaScript syntax; the problem is waiting for an app to launch, then figuring out where your data is hidden inside some giant structure like app.documents[0].canvases[0].graphics[2] (example from omni docs ), just so you can extract it for your script.

Brent Simmons is working on Rainier/Ballard, which is a reimagining of Dave Winer's Frontier. I think building a new siloed language and system doesn't solve the real problem, but maybe it'll get taken up by others.

I have for some time been toying with enhancing my Learn2JS shell into an Electron application that would let you write, load, save, and run scripts in a common framework, without any of the boilerplate it needs now. A pure JS shell is just too limited around file and network access, and node by itself is too low-level to get any useful work done. I'm not sure how that works with everything else in your system. While browser localStorage of 2MB or so is sufficient for many purposes, you really want to save local files. While this doesn't force data into outlines, it makes code-as-data easy, and JavaScript Object Notation (JSON) encourages storing everything as big trees of simple objects, which your functions operate on.

(I'm having fun with Scheme as a logic puzzle; but it's not anything I'd inflict on a "normal" person trying to work on data that matters).

If you want to talk about doing more with this, reach me @mdhughes@cybre.space on Fediverse.

China, Shenzen, and Quality Control

And much more. There's a good lesson there, and it's not just in China, they're only the worst-case end scenario. I look at this shit and see us in 20 years.

Beer (since they bring that up in the first video) is in a precarious place. Since the '80s, we've had some great microbreweries come up like Ninkasi, Big Sky, Deschutes. We used to have good regional beers like Rainier and Lucky, but then they were bought by giant breweries and turned into fake labels. The "mainstream" beers are garbage, mildly contaminated water you wouldn't wet a pigsty down with, sold entirely on marketing budgets and association with sportsball. If I see someone drinking Coors or Bud, I know they're tasteless and scream at hooligans on TV giving each other concussions. Microbreweries are often on shoestring budgets and one downturn can kill them; happily it's easy to homebrew and start a new microbrewery, but it's a thin line keeping us from going dry or drinking fucking Pabst.

We've very stupidly sent all our electronics manufacturing over to China. If you want good hardware from China, you have to stand over them and QA everything like Apple does, and then get accused of using slave labor, which it is (best-paying slave labor in China, but still so unethical it makes me nauseous). Huawei's CFO has been arrested, and many places aren't using their equipment now because they almost certainly have CCP spyware, but it's still the only place that makes most electronics. This is civilization-ending-level stupidity.

We should have our own Shenzen SEZ (I'm not suggesting loosening our environmental or worker protections, weak as they are under the hideous cheeto person's administration; but some tax incentives would be great), and be making our own hardware for secure systems, but even if we could get workers to do it, we don't have anyone to train them. We used to have Radio Shack for learning to make electronics, but RS fucked it up by selling garbage consumer toys (mostly sourced from China), so they were driven out of business by cheaper online ordering of garbage consumer toys. So we're at the mercy of another country being driven into self-destruction.

US physical infrastructure is crumbling in many places, and entire cities like Detroit are unsafe to inhabit, because politicians have no reason to do anything about it; all money goes back to the companies that bribed them into office, while poor people in cities by definition don't have enough money to bribe them (PR con artists call these bribes "campaign finances"; I call them malfeasance and we should hang them all). The culture of "not my problem" is just as endemic here, in non-"Communist" countries; if we haven't collapsed as far yet it's because most of our buildings are under 100 years old and we build over things faster than they rot.

In software, we do it to ourselves. I dislike/distrust most software, because we have absolutely zero quality control; people ship any damn thing, and even these "walled gardens" don't do anything to stop it. There's so much garbage on the Apple App Store, basically just screenshots and RSS scrapers, or recompiled demo or tutorial book projects, named to take advantage of Apple's shitty search and advertising interfaces, and nobody cares because you can't set a decent price. So only scammers and ad companies and loot-box sellers can make money there. Why does anyone buy a $1000 iPhone when almost all the software on it is shit? Google Play is 100x worse, it's essentially nothing but viruses and scams, because Google's not just uninterested in QA, but profits better from spyware.

Commercial desktop software isn't much better, I think harder about wasting $20 on software than I would on a $100+ non-electronic physical object. In the last 2 years, I have literally upgraded two programs (somewhat reluctantly in one case; old version didn't work on Mojave or I'd've kept using it forever, and the new version can take 5-10 seconds to start, with a splash screen) and bought nothing new, because everything new that I try is shit. I'm using a free thing called "LimeChat" for IRC, because Adium's half-broken by neglect, and it's awful, but slightly better than command-line irc; I wouldn't pay for this.

There's some quasi-commercial stuff where "open source" means you can use the tool but there's ways for the corporation who supports it to make money, and some of these aren't the worst software ever made. WordPress, obviously. Atom's in a dangerous position where it's supported by GitHub, which was making a little money on services, and is now owned by Microsoft, who makes Quality Job #NaN. Will Atom get the performance rewrite finished before Microsoft shutters GitHub? Will it keep working? Nobody knows! Fucking Slack is appallingly bad, not because it's Electron but because non-corporate customers don't matter to them.

Free software is mostly garbage, and we get things like the npm event-stream takeover because nobody maintains their own shit, just make junk and throw it away, and then we're SHOCKED when criminals see this as an opportunity.

As usual, I don't have solutions, only problems. I write my own software so I don't have to rely on other people's software. I ought to grow my own food, dig a well, and stockpile guns and ammo, but I'll probably just turn Reaver if I survive the coming collapse of everything.

Resize Windows with Applescript

So I downloaded it with youtube-dl (after more annoyances with MacPorts updates ) and a helper script ytplaylist:

youtube-dl -i --yes-playlist --restrict-filenames -o '%(playlist)s/%(playlist_index)s-%(title)s.%(ext)s' "$1"
osascript -e 'display notification "Youtube playlist downloaded"'

where $1 is the actual playlist URL; "show video list" under the video player or pick from DNA Lounge playlists

Now I have a folder full of properly-named videos. VLC can be opened from the shell with:

~/Applications/VLC.app/Contents/MacOS/VLC jwz_mixtape_200 &

Frustrated by VLC constantly resizing, I then ignored the problem for most of the morning, finally wrote resizeWindow.applescript:

#!/usr/bin/osascript

global appName
global windowX, windowY, windowW, windowH

on run argv
    parseArgs(argv)
    wrapCoords()
    resizeWindow()
end run

on parseArgs(argv)
    set argc to (count of argv)
    if argc ≠ 5 then
        display dialog "Usage: resizeWindow.applescript APPNAME X Y W H"
        error number -128 -- User canceled
    end if
    set appName to item 1 of argv
    set windowX to item 2 of argv as number
    set windowY to item 3 of argv as number
    set windowW to item 4 of argv as number
    set windowH to item 5 of argv as number
end parseArgs

-- Wrap negative coords around to other side
on wrapCoords()
    tell application "Finder"
        set desktopBounds to bounds of window of desktop
    end tell
    if windowX ≥ 0 then
        -- no changes
    else
        set windowX to windowX + (item 3 of desktopBounds) - windowW
    end if
    if windowY ≥ 0 then
        set windowY to windowY + 24 -- menu bar
    else
        set windowY to windowY + (item 4 of desktopBounds) - windowH
    end if
end wrapCoords

on resizeWindow()
    tell application "System Events"
        tell process appName
            set frontWindow to the first window
            set appPos to position of frontWindow
            set appSize to size of frontWindow
            -- display dialog ("front window of " & appName & ": " & (item 1 of appPos) & ", " & (item 2 of appPos) & ", " & (item 1 of appSize) & ", " & (item 2 of appSize))
            -- display dialog (appName & " at " & windowX & ", " & windowY & ", " & windowW & ", " & windowH)
            set size of frontWindow to {windowW, windowH}
            set position of frontWindow to {windowX, windowY}
        end tell
    end tell
end resizeWindow

Now I can just leave it running to update every 5 seconds:

while true; do resizeWindow.applescript VLC 0 -64 720 640; sleep 5; done

Slight annoyance, sometimes it's still expanding the size further down than it should until I size it smaller, and then it works. Fucking software.

I don't know that what I've done is productive in any way, but I have my MTV.

The kids are disco-dancing
They're tired of rock and roll
I try to tell them, "Hey, that drum machine ain't got no soul"
But they don't want to listen, no
They think they've heard it all
They trade those guitars in for drum machines and disco balls
We can't rewind now; we've gone too far
Internet killed the video star
—The Limousines, "Internet Killed the Video Star"

The Stubbornness of Windows Users

What we've got here is, a total failure to understand the purpose of the device or the OS.

A somewhat long sidebar here, state of the world in desktop operating systems:

  • Windows: Redmond still ships a garbage toy OS which is the bastard child of VMS and MS-DOS, that costs a lot of money, but runs on cheap (but not sub-$200) computers, many of which come in every shape and size. In order to run Windows, you need to have a total lack of aesthetic sense, a willingness to put up with "updates" that brick your computer, a tolerance for Microsoft-Quality™ software ("let's add more buttons to a ribbon bar and ship it!"), and a willingness to use junk hardware that consumes twice as much power as needed and makes noise all the time.
    Slightly positive, the graphics and sound systems work, and you get all the games; if that's all you're after, though, a PS4 or Xbox OnePlus+Ultra/190 (whatever the name is) is a better deal. You can generally browse the web on Windows, and you'll get some viruses and ransomware but it works. Dev tools on Windows are expensive and shitty, so in order to get real dev work done, Redmond now also ships Linux inside Windows. My bias shows, sure: I've never owned a Microsoft product in my life, and I'd eat broken glass before doing so, but I've had to use them in some workplaces. Dire, but minimally functional.

  • Linux: Distros ship a garbage OS for free that runs on garbage computers, including sub-$200 microcontrollers. In order to run Linux, you need to be masochistic, technically educated, not have any need for desktop apps, sound support, graphics support, games (some Steam stuff now works, sometimes, on higher-end machines!). As a server or microcontroller OS, or a very nerdy dev machine (emacs and C), it's adequate and somewhat supported. Only insane people use Linux as a working desktop. I say that as someone who ran it as a working desktop for a decade, and I loathed it.

  • FreeBSD, OpenBSD, NetBSD: Great server OS's, that ship for free and run on slightly more demanding computers. Only the most technical nerds will even know that these exist. Software, you basically write your own or port from other POSIX systems, which half the time is written for broken Linux APIs and so doesn't work right. On the bright side, they have such limited sound and graphics driver support that if you do have compatible hardware, you'll have working sound and graphics. If Mac OS X didn't exist, I'd be using FreeBSD.

  • Haiku (aka BeOS): Seriously, they shipped a working beta, and it seems nice. Great desktop, graphics and sound support if you're on compatible hardware. Down side, minimal software for it, and if you want to write your own the APIs are in C++. Fuck that, no. But… I do like BeOS, probably tolerable as a nerdy dev computer.

  • Mac OS X (or "tacOS", er, "macOS" as they now style it): The last of the UNIX® workstation OS's, that only runs on expensive devices Apple makes (it's possible to "Hackintosh" a garbage computer to run Mac OS X, but half the services won't work; don't do it unless you're nerdier than a FreeBSD user). Everything actually fucking works. Sound has no latency, and always works. Graphics, aside from low-end devices having a shitty Intel GPU, always works; I'm unhappy with them deprecating OpenGL and going with Metal instead of Vulkan, but Vulkan libraries have been ported. It's fine.
    There are games, Elder Scrolls Online and World of Warcraft in particular, and Steam's full of Mac games. Desktop applications on the Mac are adequate to amazing; there's no "you must use this one shitty program because it's all we've got" like GIMP on Linux. As a dev machine, it's unmatched. I don't touch Xcode unless I have to anymore, but that's what you use to make iOS and Mac apps, and it has some good dev tools like Xcode Server.

Of course, I say that, and:

libswiftcore-crash Good job, Apple, ship it.

So, end sidebar, the reason you buy Mac hardware is to run Mac OS X, the least bad hardware/software combination available in this horrible century.

What you'd use a Mac Mini for is what you'd use an iMac for, but cheaper and often hidden away:

  • Switch to the Mac from another OS. Steal the keyboard and screen from your garbage computer. You may need some dongles to convert the cables. Learn how to use a Mac. Buy something better when you need it, and re-sell the Mini, which will still be worth 2/3 or more of the original price.

  • Run a multimedia display. Put a playlist of music, photos, or videos on one or a bunch of LCD panels; you can't do this with a Linux microcontroller like Peter suggests, because their graphics and sound don't work worth a fuck. Just try playing a random folder of media on Linux, you'll throw it through the window. It's worth $800 to not fight with Linux.

  • Run a build farm for Xcode Server. Probably need a mid-priced Mini for this, but speed won't matter much because it's an invisible server. It can't be rack-mounted, because not every workplace has a machine room with racks, they just need a little device in some (well-ventilated) cupboard to support the developers.

  • Streaming audio, video, or other server. Put this in a colo farm with a static IP, and deliver whatever media you want. Your podcast and web site has to live somewhere. Now, you can do that with AWS/EC2 and other shared servers, much cheaper, but you don't control the computer, they mostly run Linux (ugh), and often you've written software for the Mac.
    I have an old Mini at colo that runs Minecraft, some file shares, holds backups, used to run Xcode builds but I don't need that now, sometimes runs one-off networking services I want to try out. I may upgrade to a new one, but my needs aren't quite as heavy on it as they were. Invalidstream is currently run from an old Mac pro, but I think he'd be fine on a higher-end Mini now.

  • Literally any other use that doesn't require using it on the move, or extremely heavy CPU or GPU loads. Not a top-of-the-line gaming, Photoshop, or movie editing device by itself, but an external GPU could put it on par with an iMac, maybe even an iMac Pro for some jobs. Probably not a stage DJ device, there they'd use a MacBook Air or even an iPad, but ideal for sticking in an audio booth and doing podcast recording and mixing. Unlike a garbage computer, you can be in the room with a Mini and not be blasted off the air by the overheating fans and clicking drives, and unlike a MacBook it has enough ports.

Most of those tasks require it to be small, quiet, and still attractive if it is visible.

The $799 base model is for only the most minimal uses. For $1,599, you can get:

3.2GHz 6‑core 8th‑generation Intel Core i7 (Turbo Boost up to 4.6GHz)
8GB 2666MHz DDR4
Intel UHD Graphics 630
512GB SSD storage
10 Gigabit Ethernet (Nbase-T Ethernet with support for 1Gb, 2.5Gb, 5Gb, and 10Gb Ethernet using RJ‑45 connector)

That seems like a reasonable Mac workstation, if it had more RAM. +$200 to get 16GB RAM is OK, +$600 to get 32GB RAM is overpriced, +$1400 for 64GB is "bend over and squeal like a pig". You can get 64GB of the same RAM for under $500, and there's a Snazzy Labs RAM Upgrade Tutorial and Teardown; the disassembly doesn't look fun, but worth doing if you're going to use it as a server. A casual user can live on somewhat less RAM with the Apple RAM tax.

lain-s1e3-open navi

Windows and Linux users, people who've only used garbage computers, are confused by Apple's attitude on pricing, upgrades, and repairs because they've never thought about non-garbage computing.

Apple doesn't price based on hardware costs (except for RAM, which they tax 50-300% over cost), but on where it fits in a Portability/Power chart, starting at $1000, because you're buying "machine that runs Mac OS X", not "random collection of parts that does not run Mac OS X". You'll never see Apple micro-adjust prices day to day as part prices or exchange rates change, because it has nothing to do with that.

If you want to upgrade an Apple device, other than RAM in some models, you sell it at a high resale value and buy a better one. Garbage computers are useless in a couple years, cost more to replace parts than they're worth, and have no resale value at all.

If you want to repair an Apple device, it's either free for as long as your AppleCare lasts, or $100 in most cases. Don't keep open containers of liquid on your desk (*), don't abuse your expensive hardware, and the repair isn't a problem (notably, the same guy at Snazzy Labs fucked up his iMac Pro and Apple unsurprisingly told him to go piss up a rope).

*: I wanted to link in the atp.fm episodes where John warns about this, and then gets to say "I told you so", but I can't find them with obvious keywords.

Site Redesign

As part of my site redesign, I'm moving everything off my old "markdamonhughes.com" and "markrollsdice.wordpress.com" domains into this site: Software Gallery, Tools, and RPG. Take a look at the front page, browse around, see if you like it. I'm open to advice at this point. I know I haven't done anything too weird with art and design yet, that's coming.

Content management in WordPress isn't trivial, but it's better than the ad-hoc pile of folders and PHP scripting I was doing. I'm still getting by with the standard media folder, but I'm usually disciplined about naming images so search works; there's advanced media manager plugins but I won't let it get to that point.

Many of the software pages are just "museums" right now. My iPhone software is not currently available (and likely never will be on the iPhone again; Apple's "everything is free" sabotage of developers means it's not possible to charge what software costs to make), but I will rerelease some of it as Mac/Marzipan ports when I get around to it. There's a couple of very cool apps like DungeonJournal (replacement for DungeonDice, but with a mapping & journaling tool!) that were never released properly, and I'd like to get those out. Brigand got adapted back into PerilarFK, so I'm not bothering with it.

I may import the old markrollsdice and dev blog/not-a-blog posts, still pondering on that.

World of Warcraft Classic

This is pretty exciting.

  • I started in original World of Warcraft as a Dwarf Hunter (IIRC, I made a Nelf Rogue first, but that did NOT work for me), determined quickly that I hated Alliance as a bunch of juvenile Nazi-wannabes and switched to the real heroes, The Horde!, played an Undead Mage, didn't progress as much as I'd like due to real life but had fun.
  • Burning Crusade was great, and rather stereotypically I started over with a Blood Elf Warlock (selama ashal'anore!) and maxed out, did some raiding, loved that version of the game. Outland is amazing, that's some of the best content WoW or any game ever made.
  • Lich King was OK but kind of same-y and grindy—why make Dalaran when Shattrath exists and is better? Why are there two indistinguishable forest zones and two indistinguishable undead zones?
  • Cataclysm wrecked everything in the world and in character; it did add some detail to areas that needed it, but it's not worth it.
  • Pandaria had a nice setting and the Monk was a fun class, with beer as a powerup drink!, but letting the Pandas choose their faction made no sense (Goblins in particular, and all the neutral-ish races in general, should've been able to choose, too!), and the higher-level content is trash.
  • Everything after is even worse. After 15 years, what we've learned is that Blizzard can't improve content, only make it worse; everyone good left after Classic and Burning Crusade, and institutionally they aren't able to hire best-of-breed writers or game designers. Restoring Classic is really the only option they have.

So, I've been following this WoW Classic thing a while, since in 2016 when the Nostalrius, RIP and Elysium private servers let me play classic "vanilla" World of Warcraft again; I was frustrated by bugs, and basically couldn't use airships or ships because they'd drop me halfway in an out-of-level zone or the ocean, but it was interesting to have a version of WoW that didn't suck. As previously, I played an Undead Mage; that or Warlock seems most likely when Classic goes live. I am what I am, which is an evil sorcerous corpse.

Crendor and ClassiCast have done excessively exhaustive dialogues of what they want from Classic, which is a super-conservative "No Changes!". I'm much more moderate about this. If they add achievements (added in Lich King), pet battles (added in Pandaria), barbershop (added in Lich King), and use new models (added in Warlords of Draenor), I'd be fine with that; those improve the game without changing any balance. Dungeon/Raid Finder wouldn't bother me, I likely wouldn't use them, since I loathe PUGs (pick-up groups, not tiny inbred dogs), but they're a boon to people in no guild or a small guild that can't organize those things. The actual gameplay should be like the last patch of Classic, or the last patch of Burning Crusade when/if they add that content.

I'd totally be up for getting a "Virtual Ticket" for Blizzcon just to try the demo, except it's $50! That's like, a case of beer and a bottle of whiskey, which is a far more entertaining weekend (please drink more responsibly than me). Minecon on Saturday is free; it's not a real convention anymore (I went to Minecon Vegas back when the audience was much more adult). How the fuck does Blizzard justify $50 for some videos?! So anyway guess I'll just watch Youtubes of the demo when they come out.

Rules for the OSR (Old-School Renaissance)

Housekeeping note: I'm still too busy with programming on the new Perilar, and some other things, to get back to my tabletop and/or online chat games regularly, but I'll be moving all my RPG stuff over to this blog from Mark Rolls Dice, I'd like to have one site to maintain which I own.

So, start with basic principles. How do I run games.

I'm a caveman from the '70s and '80s, so my Old-School is literally old and from school, as noted in Five Games. The Old-School Renaissance is my frozen caveman ass being thawed out to do it again.

There's a bunch of guides to how to do this, but they're kind of bullshit. Matt Finch's Quick Primer for Old-School Gaming is close to my view, and has gameplay dialogue examples which can be read in funny voices, but it goes on too long about irrelevant stuff. Principia Apocrypha and a bunch of other bloviating diatribes just go on forever, I started to nod off, make a little hand-puppet with my hand and flap its mouth up and down.

Here's my OSR principles:

  1. Let the dice fall where they may. ( Knights of the Dinner Table's Law )
  2. Be excellent to each other. ( Bill & Ted's Law, the inverse of Wheaton's Law )
  3. The Referee is always right, but the players can choose to stay or leave.
  4. Rules are just recordings of what we've previously done. We can change them at any time.

Like the Three Laws of Robotics, each principle is tempered by the ones previous: The Referee can override new rules. But, be excellent to each other. But, don't cheat and take away risk.

Don't Be a Dick

So, Wil Wheaton ( previously "I Hate Twitter" ) was just chased off the Fediverse (he still has an account on a siloed non-federating instance, which isn't really useful to anyone else). His last statement's pretty clear, so I put that down below.

"Please do your very best to be kind to each other. The world is a terrible place right now, and that's largely because it is what we make it."

I know some of the people doing the harassing. There's no point in even arguing with them: They've decided he's in Two Minutes Hate, perhaps because he has a friend whom they don't like, and won't consider "Don't be a Dick", or having empathy, tolerance, or self-awareness that some of them aren't such great friends to have, for one hot second.

While Gargron has condemned harassment, it doesn't fix the problem, since there are entire instances where 4chan-like behavior is accepted; all you can do is block accounts or those entire instances, and it still poisons the Federated timeline for a while.

I'm not sure any level of moderation fixes this shit.

This is why I highly recommend owning your own blog, and broadcasting that out to other services where people can read it; even better, read this and many other blogs in your RSS aggregator or RSS reader ( currently free! ) of choice. It's OK to put some ephemeral chat on other services, but remember those are owned by other people, and are easily attacked by angry, stupid mobs. If a stupid mob shows up here, I don't approve their comments and it's done. It's the Castle Doctrine of online posting.

Wil Wheaton @wilw@mastodon.cloud August 29, 2018, 3:02 PM https://mastodon.cloud/@wilw/100635779449174251 (will be a dead link soon)
I have been notified by an Admin here that they are getting 60 reports a day about my account. As far as I can tell, I'm not breaking any rules, and I've done my best to be a good person here. But this admin is going to suspend my account.

It's the Admin's instance, so I fully support their choice to eliminate a source of frustration, but something to consider: a person who is doing nothing wrong can be run off one instance by a mob from another instance. That seems ... not cool. 1/x

But it's been made very, very clear to me that I am not welcome in the Fediverse, and I hear you. I hoped to find an alternative to the birdsite where I could find the same fun community that existed over there in the beginning, and it's clear to me that I won't be finding that. Before I leave, I want to just make something very clear, because I've spent most of my life being yelled at by people who don't know me at all, and I want the record to be clear. 2/x

During GamerGate, I was dogpiled and mobbed and brigaded and attacked by thousands of accounts. I started using a blocklist that was supposed to help stop that. I did not know that the blocklist I signed up for also had a lot of trans women on it. When I found out, I did everything I could to remove those women from the list I shared. When there were still innocents on the list, I stopped sharing the list entirely. Despite this, a mob has decided that I'm anti-trans. 3/x

This lie that I am anti-trans, or anti-LGBQ, is deeply hurtful to me (I know it's nothing like the pain LGBTQ people deal with every day, as they simply try to exist in a world that treats them so badly, but it is still hurtful in its own way to me). I just want to make it extremely clear: that is a lie, and the people spreading it are misinformed.

So I'm leaving the Fediverse, which has treated me with more cruelty, vitriol, hatred, and contempt than than anyone on the birdsite ever did. 4/x

I know that I'm well-off, well-known, and as a CIS white hetro dude in America, I live life on the lowest difficulty setting. I know that I have very little to complain about.

But I still have feelings, and I really do care about the world and the people in it. What I see is a lot of anger and cruelty directed at the IDEA of me, from people who I just hope don't realize that it really does hurt me, in my heart, to be accused of being someone I am not, and to be the target of a hateful mob. 5/x

Anyway, take your victory lap and collect your prizes. You've made it clear that I'm not welcome here, and even though I disagree with the action this Admin is taking (banning me when I didn't break any rules doesn't seem right), I respect and support the Admin's decision to run their instance the way they see fit.

Please do your very best to be kind to each other. The world is a terrible place right now, and that's largely because it is what we make it.

Bye.

6/end

What I'm Watching: Star Wars the Last Jedi

In the "that took a long time" category, I finally hit play on SWTLJ in my Netflix queue. I've been disappointed in all the new ones, so I didn't expect to like this. I'm drinking cheap wine and not in a great mood, perfect.

SPOILING THE ENTIRE MOVIE STOP DO NOT CONTINUE UNLESS YOU DON'T CARE, WHICH IS TOTALLY REASONABLE. THIS SUCKS

Holy shit this starts dumb, with Poe crank-calling Hux. I thought that was a joke meme, but no, it's actually a scene with "Admiral Hugs" and "your mother" jokes. The single fighter vs giant starship point defenses thing is nonsense especially since they should have learned since the Death Star. The bombers have really shitty fire control systems, and then somehow are gravity-fed. In space. They're not missiles, they're "bombs" which drop "down". What is down? So stupid.

Old Man Luke is annoying, but he's doing the Yoda thing, so annoying is in character for once. That's the only plot- and character-consistent thing I see in this shitshow.

Drinking intensifies.

The long tail chase with the few Resistance and First Order ships, and the centralized command system they use where one shot can behead the fleet, is so stupid. Scatter the ships to the wind, with randomized meetup locations, and no amount of tracking will help. Everyone in here is an idiot; Finn's attempt to flee is the only sign of sanity.

Now let's zoom off to a sidequest at a casino, like I do in JRPGs; sure, sure, fate of the world, first I have to race and breed Chocobos. The casino should be fun, altho it looks too much like a modern Vegas casino. Instead it's preachy because Rose hates fun. Also there's no way these scruffy degenerates get into a classy casino with a dress code. Also nobody in this will be implanted with Ovion eggs, or have Cait Sith join their party, which is what they deserve.

The endless "psychic phone calls" between Rey and Kylo are like a teenage soap opera, and the low-tech camera cutting is awful. Can't be bothered to even project force ghosts in the scene? Actually, now that I think of it, there are very few scene wipes for transitions in this, which is why it feels so jarring. It's all hard cuts with no context. The director's incompetent.

Burning down the Jedi "library" is typically ham-fisted metaphor for Disney Star Wars burning all the Expanded Universe and classic Star Wars. They don't care, and the callow youts of today aren't capable of reading. Yoda drones on and on, which is not at all Yoda-like, but the writer's a moron and doesn't know or care.

The mutiny is terribly executed. Admiral Bligh, er, Holdo is incompetent, but Poe has no idea how to use handcuffs or a brig? Abandoning warships so you can hide, when the First Order fleet still has scanners, is moronic. Instead of all but 6 ships exploding, it really should be all.

Drinking intensifies.

Snoke's always been a bad ripoff of the Emperor, but at least the hologram in The Force Awakens left the possibility he'd be 1m like Yoda; nope, he's human-sized, and basically parrots the Emperor's lines from Return of the Jedi. The duel in the throne room isn't bad, not amazing but the only good, Star Wars-like content in this film so far.

The only characters with any chemistry in the entire movie are Poe and BB-8. In The Force Awakens, it looked like Poe and Finn were gonna hump right on camera; they barely look at each other here. Rose tries to pull off a relationship with Finn, but it's not there.

I look back at Star Wars, and the love quadrangle between Luke, Leia, Han, and Chewie was amazing. They were junkies hooked on each other. Leia and Luke only meet once in this movie and it's a quick, tired goodbye. Chewie has some cameos (and a bizarre infestation of CGI animals) but is never around Leia, and then vanishes. R2-D2 and C-3PO also get one line together.

The CGI animals and rocks in multiple scenes are so awful, they make Lucas' "special editions" look tasteful. This isn't quite Star Wars Rebels level of shitty cartoon CGI, but it's bad, very inappropriate.

Luke's death is pointless, repetitive of Kenobi's duel with Vader, because the moron writer can't write anything new, only recycle. The Just For Men beard before that is preposterous, though (worse than fake-young CLU in TRON: Legacy, which at least A) was set in a videogame, and B) is a vastly better film than this).

I knew going in that this would be bad, Extruded Star Wars-Like Product, but holy fuck. It's one of the worst-written, worst-acted things I've seen in forever.

In The Last Star Wars Movie, I suggested terminating the franchise, but still ranked TLJ above the Prequels-Which-Don't-Exist. I may have overestimated this trash.

★☆☆☆☆ and may the Force not ever be with you, Rian Johnson.

Julia

Interesting language, originally a math/statistics package but now as general-purpose as any lang. More or less Pythonic, though it has some type-annotation stuff, and heavily-optimized Julia looks like a mess of annotations with your code buried somewhere inside.

The Mac version comes as a dmg with an app (which I'd prefer for easy install/uninstall), or brew (which I prefer not to use). The app just launches a single command in a new Terminal window; add that path/bin to the PATH in your .profile, e.g.:

export JULIA_HOME="$HOME/Applications/Julia-1.0.app/Contents/Resources/julia"
export MANPATH="$MANPATH:$JULIA_HOME/share/man"
export PATH="$PATH:$JULIA_HOME/bin"

And now in Terminal:

% echo 'println("Hello, world!")' >hello.jl
% julia hello.jl
Hello, world!

The only way I can see to make it compile to a binary is embedding, and I'm not clear on how you package that with a full Julia distribution yet. That's unfortunate. I like REPL workflows as much as anyone, but binaries are what "normal" people run.

Getting Started

<voice tone="excessively chipper"> Let's read the manual! </voice>

Syntax is nicer than usual: function/end, if/elseif/else/end, for/end, while/end, begin/end, let/end, which beats the hell out of Python's def, if/elif/else; to say nothing of abominations like Swift's "func". No do/while loop, which is annoying especially for file processing, but I suspect that can be fixed with macros.

There's a lot of ways to write functions, which is nice but allows some ugly choices. Anonymous functions are x->x^2 or function(x) x^2 end; named functions can just be assigned f(x)=x^2 or written in full:

function f(x)
    return x^2
end

Whitespace is not significant, and indentation is not enforced, which is a major bummer for style-enforcing-structure, but I'm sure sloppy jerks will love that.

You can use tuples for multiple returns, or as ad-hoc structures:

> point(x, y) = (x=x, y=y)
point (generic function with 1 method)
> p = point(13, 2)
(x = 13, y = 2)
> a, b = p
(x = 13, y = 2)
> a
13

It's pass-by-reference, not copying, so be careful with mutable data.

My only real kvetch so far is that arrays are 1-indexed and column-major, like FORTRAN, not 0-indexed and row-major, like C. For a numeric package, that makes sense, but for other programming tasks it's frustrating and error-prone, see EWD 831.

This is a functional language, and there are no classes/inheritance/methods, however "methods" are functions which are overloaded based on types, and can be used like class methods:

> quack(x::Int64) = "int $x"
> quack(x::Float64) = "float $x"
> quack(1)
"int 1"
> quack(6.66)
"float 6.66"

As well, you can use closures to make pseudo-classes, the same way you do in Scheme:

let state = 0
    global counter() = (state += 1)
    global counterReset() = (state = 0)
end

struct (immutable) and mutable struct make "Composite types", and can make objects the usual way:

struct Point
    x
    y
end
pointDist(p::Point) = sqrt(p.x^2 + p.y^2)
Base.show(io::IO, p::Point) = print(io, "{$(p.x),$(p.y)}")

> p = Point(6, 6)
{6,6}
> pointDist(p)
8.48528137423857

The default constructor can be overridden at the end of the field list, it's defined as Point(x,y) = new(x,y). The "toString" equivalent there is ugly as hell, but there's a ton of options for overloading it by type of output.

There's a lot of fucking around with generics and strong typing (for weak minds), but ignore all that crap.

Interfaces are a somewhat messy use of several methods to create pseudo-types; define the basic interface methods for your type, and most things calling those interface methods will work. So, a couple iter() functions and you have an iterable, and so on. This would work much better if Julia had an actual OOP class system and real interfaces, but Python half-asses interfaces the same way and aside from being 1000x slower than you'd like, it gets by.

Quickly skimming modules, seems pretty standard import mechanism, but I don't see any way to make something private. OK, I'm bored of reading docs. Let's do something. Something semi-practical here, my standard RPN calculator, one command per line.

Docs/libraries are kind of a mess, Vector is discussed in Base.Arrays, push!/pop! methods are discussed in Collections (an interface). parse is under Numbers, not Strings, as one might expect.

eof() does the extremely unfortunate thing of blocking for input, so it's utterly useless in a main interactive loop.

… About 30 minutes later, I have a working, final version. Well, that was pretty easy, and it's a clean implementation, other than the interactive loop.

Next time I open this, I'll put it in a module, and tokenize the line instead of requiring just one token per line, and have some command-line argument to suppress help and prompts.

I should also investigate IJulia which is a Jupyter notebook, which seems like the "expected" way to make it interactive and handle graphics or media.

RPNCalc.jl

#!/usr/bin/env julia
# RPNCalc.jl
# Copyright ©2018 by Mark Damon Hughes. All Rights Reserved.

stack = Vector()

function checkStack(n)
    if length(stack) < n
        error("Stack underflow: Needs $n values")
    end
end

function parseLine(s)
    s = strip(s)
    if s == "+"
        checkStack(2)
        b = pop!(stack); a = pop!(stack)
        push!(stack, a + b)
    elseif s == "-"
        checkStack(2)
        b = pop!(stack); a = pop!(stack)
        push!(stack, a - b)
    elseif s == "*"
        checkStack(2)
        b = pop!(stack); a = pop!(stack)
        push!(stack, a * b)
    elseif s == "/"
        checkStack(2)
        b = pop!(stack); a = pop!(stack)
        push!(stack, a / b)
    elseif s == "="
        checkStack(1)
        println(stack[end])
    else
        push!(stack, parse(Float64, s) )
    end
end

function main()
    println("RPN Calc: Type numbers or operators (+, -, *, /) one at a time, = to show top of the stack, ^D to end.")
    while true
        print("> "); flush(stdout)
        s = readline(stdin, keep=true)
        if s == ""
            println("Goodbye")
            break
        end
        try
            parseLine(s)
        catch e
            println(e.msg)
        end
    end
end

main()