Welcome! :-)

This is both a wiki (a website editable by all) and a blog (an online diary about the stuff Alex Schroeder reads and does). If you’re a friend or relative, you might be interested in reading Life instead of this page. If you’ve come here from an RPG blog, you might want to head over to RPG. There are other similar categories to be found on the SiteMap.

Für Rollenspieler gibt es ebenfalls eine eigene RSP Kategorie.

2018-01-16 Browser Alternatives

lynx is a text browser with support for Gopher.

w3m is a text browser with better table layout.

links is a text browser with better table layout.

q is just using html2text in a script:

#!/usr/bin/env bash
curl -s $1 | html2text -width 67 -style pretty | less

dillo is a graphical browser with its own renderer.

next is keyboard controlled

surf is a simple, embeddable web browser based on WebKit2/GTK+.

uzbl is based on WebkitGtk+ and scriptable.


Add Comment

2018-01-14 Productivity

Wow, what a great post on how keeping a detailed todo list can get you down by Horsemans.


Add Comment

2018-01-14 NOYB

NOYB plans to use the new EU data protection regulation (GDPR): targeted and strategic litigation to maximize the impact on the future of your right to privacy, but also PR and media initiatives.


Add Comment

2018-01-14 Counterspells

Declaring the intent to counterspell or delaying actions makes me uneasy: another round lost, more time lost at the table. I think for spell duels what we need is a kind of bullet time where all the spells go off at the same time, all of them cancelling each other as far as possible.

Thus, the basic rule is this: if you haven’t acted this round and a spell it being cast at you, you can use your action to react with any spell in your repertoire, aiming to counterspell. The side with initiative declares first.

Consequently, if you have already cast a spell this round and none of your opponents decided to counterspell, then they cannot cast a spell at you this round because your spells would have cancelled as far as possible. If you didn’t cast a spell, or if they are attacking you with other means, no problem.

Effectively, all the spell casting happens in the same moment.


When somebody casts magic missile at you and you haven’t acted yet, cast shield to defend yourself. This is a perfect counterspell.

When somebody casts fireball at you and you haven’t acted yet, cast lightning bolt to defend yourself. Both sides roll damage and only the difference gets applied to the loser. This works even when there are multiple people attacking each other. The winner gets to decide how effects are distributed amongst multiple losers.

In this case we’re assuming that all damage dealing spells are somewhat alike. Over time you’ll build a collection of rulings as to which effects can cancel each other like that.

Whenever spell effects cannot be compared directly, the simplest solution would be to have both sides roll their saving throws, if any. When both make their saves, nothing happens. When only one side fails their save, they are affected by the other’s spell. If both sides fail their saving throws, the spell of the higher circle wins: hold person (2nd circle) beats charm person (1st circle) if both sides fail their saving throws.

Similarly, if one side casts hold person and the other side casts fireball, both need to roll a save — one to avoid being held, the other for half damage. If both casters fail their saves, fireball (3rd circle) beats hold person (2nd circle).

And finally, if one side casts sleep and their victim can be affected, the other side is simply considered to have already failed their save.

This also means that it can be disadvantageous to attack with weaker spells because the counterspell might simply cancel whatever you threw at your opponent and thus you effectively gave away the initiative.


Add Comment

2018-01-14 Command Line Gopher Clients

In the spirit of Edbrowse, here are two command line gopher clients.

VF-1 is written in Python.

cgo is written in C and apparently presupposes all selectors must start with a slash so it doesn’t actually work on this site.


Comments on 2018-01-14 Command Line Gopher Clients

I’ve made some changes to VF-1 and contacted Solderpunk...

– Alex 2018-01-16 15:45 UTC

@solderpunk I just made some changes to VF-1 in order to handle my wiki, alexschroeder.ch. Are you OK with me putting it all up on GitHub? I'd also like to put your intro from gopher://sdf.org:70/0/users/solderpunk/phlog/introducing-vf1.txt into the README file. What do you think? I'd use "Solderpunk" + your sdf email address for the first commit.

@kensanata Hey, thanks for getting in touch, I appreciate you asking about this instead of just going ahead and doing it. I am pleasantly surprised that somebody has been so quick to hack it!

I think I will set up my own account under this name and create a repo for VF-1, you can then submit a pull request and I will happily look at it. I will let you know when I have done this.

@kensanata Great! Waiting on the account confirmation email to my SDF address now...

I take it you found the prototype not too horrible to use, then? While testing it, I kept flipping back and forth between thinking "this is so cool!" and "this is crazy, nobody wants to browse like this".

@solderpunk I'm mostly interested in command line interfaces out of curiosity. My personal favorite Gopher client to hack is the Emacs Gopher client, for the moment.
But VF-1 reminded my of cgo and Python is definitely easier to hack than C!
The interest in comamnd line interfaces dates back to my fascination with ed and edbrowse.
Sadly, the edbrowse site is down so Wikipedia will have to do.

@solderpunk Oh, here it is. I guess it's just HTTPS that isn't working. edbrowse.org/

@kensanata The Python standard library's "cmd" module makes writing command line interfaces an absolute breeze, I am a big fan.

@solderpunk Yeah. I'm usually not a Python person but when I was shown how to rewrite my Mastodon Archive application as a command line script using console_script, I liked it very much. Like cmd, the help commands and all that come for free.

@solderpunk @kensanata it's actually quite nice to browse with vf-1.

@psztrnk @kensanata Very glad to hear it! :)

@solderpunk @kensanata I'm not sure that I count in this matter though. I'm a tech-pervert.

@psztrnk @solderpunk Next feature request would be a command to add ('a') the current document to a bookmark file which is actually just a local gophermenu like ~/.vf-1-bookmarks and a command to quickly visit that file ('v')…

@kensanata @solderpunk that actually sounds useful.

@psztrnk @kensanata Yes, bookmarks are the next feature I plan to add.

Followed, perhaps, by the ability to "subscribe" to URLs, which will store a hash of a URL's content and let you poll for updates, creating a menu of updated phlogs - letting everybody build their own mini Bongusta, basically.

But that's probably it. I don't want it to get bloated.

@solderpunk @psztrnk for my own use, I'll probably add support for the "write" item type I've been experimenting with. My goal being a Gopher Wiki. :)

@kensanata @psztrnk Oh yeah, that reminds me, I also need to add standard query support (itemtype 7).

@kensanata I've accepted your pull request, many thanks! Good luck with the Gopher Wiki project.

@kensanata @psztrnk Quick implementation of bookmarking is in:

"add" or "a" to bookmark current page, with an optional alternative name (e.g. "add Bongusta aggregator"). If no alternative name is given, the name from the index by which you arrived at the page is used.

"bookmarks" or "bm" to view bookmarks. May use "v" for this once I'm sure there are no other more important commands that character might be used for.

@solderpunk @psztrnk cool! The reason I went with v is that this is similar to what lynx uses and I feared that it would make b for back non-unique. But if that works, no problem.

Add Comment

2018-01-13 No Google Plus

A while ago I discovered Mastodon and loved it. I didn’t worry too much about being tracked. Everything and everybody was new. Posts were shorter. And I basically switched. I’m no longer a big Google+ poster.

I had joined Google+ because of all the other RPG people. The Old School Renaissance (OSR) folks had all collectively moved their talking from blogs to Google+, I felt. But in recent months I have often felt that many posts on Google+ were about politics, and they were getting me down. The orange pumpkin US president also didn’t help (Trump, in case I come back to this blog post many years later and have forgotten who it was). I wanted to read about politics but it was getting me down. I wanted to read about role-laying games but that was getting me down, too!

It’s hard to explain. Some posts were too long. Huge! Others were just linkspam, sometimes nothing but a link, or sometimes a very short sentence or two, plus a link, sometimes posted in multiple Google Communities. Even though that didn’t affect me much, it still made me a little angry. It’s stupid, I know.

Mastodon has a 500 character limit and no markup. Those limitations are stupid, too. But strangely, I feel more comfortable in this environment. And I noticed something else: I am quite comfortable posting about code and programming, something I had mostly kept out of my Google+.

Perhaps that’s because the RPG instance I am on, dice.camp, isn’t too interesting as far as the OSR goes. And so I did not post too much over there.

I thought the change would be hard. But it turns out it isn’t.


Add Comment

2018-01-11 Wall of Text

These days I often start the Gopher client on my phone or tablet when I want to read something longer, stranger, and I visit the Phlogosphere. And I’m starting to notice a pattern, comparing the posts over there with my own. I’m an obsessive linker. And they are not because links aren’t easy to follow from a text file. You need to copy and paste.

A wall of text actually works better if you have a client that is focused on plain text instead of hypertext. And now I’m not longer sure whether hypertext is the best. Is it? Or is hypertext a symptom of our fragmented mindset, a product of a Zeitgeist that sees everything connected to everything but everything is shallow in itself. There’s no time to read, no time to write, just click and follow the ever enticing trail and just don’t stop.


Comments on 2018-01-11 Wall of Text

A feed reader written in bash: ridi. These Gopher people are going to drive me back to ratpoison and terminals, I’m telling you.

– Alex 2018-01-12 22:35 UTC

Add Comment

2018-01-11 UTF-8 Gopher

If you use lynx to browse Gopherspace, you will run into UTF-8 problems. Here’s an example where the search returns a selector containing an Umlaut. It is displayed correctly in the terminal.

Search returns selector with Umlaut

But when you follow the link, it doesn’t work:

Following the link shows a truncated page name

Why? Because lynx doesn’t send those bytes:

$ tail -n 1 farm/gopher-server.log
Serving 2017-04-12_Preise_f as  bytes of text

Where as using gopher.el works better. Look at this beauty using Arabic characters in both the selector and the text file content:

Emacs gopher.el showing some Arabic

Compare this to the original page: Die Partikel قَدْ.

So, using gopher.el is good enough, for now. :)

If you want to check it out yourself, using your favorite Gopher client:


Add Comment

2018-01-10 Encrypted Gopher

Sure, we could do Gophers like HTTPS. Or... we could create a new item type.

How about e for encrypted? Like the w for write type, it depends on the client sending more information.

For example:

$ echo "Alex/menu" | cat - ~/.gnupg/key.asc | nc alexschroeder.ch 70


So... we wouldn’t keep the requests a secret, but we’d keep the data sent back a secret, encrypted for the individual making the request. And the server itself can have a public key. The response is both encrypted and signed, and possibly includes the public key, and so we “know” the identity of the server.

As the client, we need the following:

  1. we need access to gpg
  2. we need to import the public signature of the server when we get our first reponse
  3. we need to warn the user when the public key of the server changed between requests

Keeping our requests secret would require the server to not hang up, or it would require us to send the selector as part of the encrypted package. Doable, I guess? This needs more thought.

As I now have a Gopher server (for this wiki) and a Gopher client (for Emacs) to hack, I should make some experiments.

I guess here is how it would work:

We need to get the public key of the server, for example using this:

$ echo Site_GPG_Key \
  | nc alexschroeder.ch 70 \
  | gpg --import

Then we need a message containing our own public key and our request, encrypted for the server.

$ (gpg --export --armor DF9446EB7B7846387CCC018BC78CA29BACECFEAE; \
   echo Alex | gpg --encrypt --armor --recipient alexschroeder.ch; ) \
   > message.txt

The message now contains a PGP PUBLIC KEY BLOCK and a PGP MESSAGE.

This is what we send to the server, using a special selector to indicate That we have an encrypted payload.

$ echo do/gpg | cat - message.txt | nc alexschroeder.ch 70

On the server side, we need to import the key of the person making the request:

$ gpg --import < message.txt
gpg: key ACECFEAE: public key "Alex Schroeder <kensanata@keybase.io>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

We need to remember this key for later!

So how about extracting this from the message:

$ gpg --import < message.txt 2>&1 \
  | sed -n 's/.*key \([^:]*\).*/\1/p'
$ sed -n "/-----BEGIN PGP MESSAGE-----/,/-----END PGP MESSAGE-----/p" \
  < message.txt \
  | gpg --decrypt --passphrase-file passphrase.txt --output request.txt
Reading passphrase from file descriptor 3    

You need a passphrase to unlock the secret key for
user: "alexschroeder.ch"
2048-bit RSA key, ID B4E46A78, created 2018-01-12 (main key ID AC23889A)

gpg: encrypted with 2048-bit RSA key, ID B4E46A78, created 2018-01-12

And now we have our request on the server side here:

$ cat request.txt

And for the reply:

$ gpg --encrypt --armor --sign --recipient ACECFEAE \
  --passphrase-file passphrase.txt --trust-model always \
  < haiku.txt
Reading passphrase from file descriptor 3

You need a passphrase to unlock the secret key for
user: "alexschroeder.ch"
2048-bit RSA key, ID AC23889A, created 2018-01-12

Version: GnuPG v1


This message gets sent back over the wire and I can decrypt it.

$ gpg --decrypt < response.txt
gpg: verschl"usselt mit 8192-Bit RSA Schl"ussel, ID 11C583644529A45C, erzeugt 2015-03-01
      "Alex Schroeder <kensanata@keybase.io>"

    old pond
    frog leaps in
    water's sound 
gpg: Signatur vom Fri Jan 12 15:54:53 2018 CET
gpg:                mittels RSA-Schl"ussel 9F8EE9F5AC23889A
gpg: Korrekte Signatur von "alexschroeder.ch" [unbekannt]
gpg: WARNUNG: Ein Schl"ussel ohne gesichertes Vertrauen wird benutzt!

I guess we want to delete the key on the server after sending the reply, right? The sad part is that ideally, the client would generate a new key every now and then, and these would be throwaway keys, of course. We don’t actually want to help prove which requests we sent to the server.

It might work.

It might be too much work.


Comments on 2018-01-10 Encrypted Gopher

Maybe we should use TLS after all. I just noticed that there is a Perl 5 library called Protocol::TLS::Server. Then again, since I’m using Net::Server, I should probably take a closer look at Net::Server::HTTP which has support for SSL.

– Alex Schroeder 2018-01-15 08:34 UTC

Add Comment

2018-01-10 Encrypted Email

I can only read encrypted mail when I’m at home where my secret key is. Sometimes this is maddening. That’s how used we have become to IMAP. Remember POP3? You could only read email on one machine. Once you downloaded your mail, it was gone from the server.

And that’s another reason why I think instant messaging is the new mail.


Comments on 2018-01-10 Encrypted Email

ssh + gpg-agent

rtsn 2018-01-10 22:01 UTC

Heh. My days of running my own mail server are over. It was simply too much of a hassle. I had it working for my Raspberry Pi for a while (Raspberry Pi als privater Email Server) but there were so many things to consider:

  • get ipv6 right
  • get exim4 config right
  • get SpamAssassin config right
  • get dovecot config right
  • get dovecot-sieve config right
  • get dovecot-lda config right
  • get DKIM setup right
  • get user creation right
  • get fetchmail setup right
  • get dynamic IP number right
  • get ssh setup right
  • get upgrades right when security issues arise

I decided that the risk of me getting it wrong was higher than the cost of me using Gmail. Specially since all the personal stuff happens elsewhere.

– Alex 2018-01-11 06:33 UTC

Add Comment



Please make sure you contribute only your own work, or work licensed under the GNU Free Documentation License. See Info for text formatting rules. You can edit this page if you need to fix typos. You can subscribe to updates by email without leaving a comment.

To save this page you must answer this question:

Please say HELLO.

Referrers: rsp-blogs.de Gothridge Manor rsp-blogs.de Planet Emacsen ZENOPUS ARCHIVES Dreams of Mythic Fantasy Diary Akiyama's Blog ZENOPUS ARCHIVES