(2024-10-14) Goodbye Bopher, hello BFG: a practical case of Tcl/Tk's GUI ------------------------------------------------------------------------ Tcl 8.6 is a powerful tool indeed, and I hope my previous post have shown why. As I have already written, I could see having my personal portfolio of small but useful Tk GUI apps. And, of course, I had to start somewhere. So, as my first "real" Tk application, I decided to write something that I myself would use a lot: a new Gopher browser instead of my pretty limited and unmaintainable Bopher-NG and the already bloated Lagrange. What I came up with is now called BFG ([1]), short for "Back/Forward/Go". Yes, I put it up on Codeberg because I might need some bugfixes and contributions from folks from the "outer web", who knows... Of course, I decided to replace Lagrange completely, which meant that my own replacement should at least support not only Gopher, but Gemini, Spartan and Nex too. And it does, along with Gopher-over-TLS if you ever need such a thing. Nex, by the way, is wonderful. In a way, it's even lighter than Gopher (because there are no complicated Gophermap-like directories) and borrows the only thing from Gemtext that I really like: its link format. The specification ([2]) is so short that I could copy and paste it right here, but I think I can rephrase it even shorter. Protocol-wise, Nex is fully identical to Gopher: you send a CRLF-terminated (although I think it can be just LF-terminated, the spec says nothing about line endings) selector path to the TCP server (the default port is 1900), and the server returns whatever content is under the path. For directories, the content is pure plain text with the exception of Gemini-like links, with the only difference from the Gemtext spec being that the space after => is mandatory. So, Nex links always start with these three characters "=> ", which makes writing Nex-only (Nexclusive?) clients even easier. The spec ends with the assumption that an empty path or a path finishing with / is a directory and that a document should be displayed based on the path's file extension. Without an extension or a trailing slash, plain text is assumed. And yes, that's really it. That's the kind of evolution I wanted to see instead of Gemini or Spartan in the first place. Nex is accompanied by a posting protocol called NPS, which is even more straightforward: connect on the port 1915 (by default), send raw text data and end the transmission by sending a line with a single dot. The server must respond with text and close the connection. Implementing NPS, however, is outside the scope of BFG (maybe a separate program will be created for it), I just mentioned it to highlight the simplicity of the overall idea. But I digress. When writing BFG, I learned a lot about the protocols and how stuff is done in Tk and Tcl in general. Even though I think my code is in no way optimal because I still am a noob in the language, I managed to pack the entire functionality I wanted to see into under 1000 SLOC, and I really want the codebase size to stay that way. Nevertheless, BFG is now my daily driver that really has replaced both Bopher-NG and Lagrange for the "small web" browsing purposes, and I really enjoyed writing and testing it on various resources. I hope whoever reads this post gives it a try as well. Now, onto the case number 2: a Sokoban game in Tcl/Tk. I called it BOXcl ([3]), and this is where I don't need outside contributions, so I placed it onto my own self-hosted Git. It doesn't even have a readme because it's a single Tcl script that contains everything. Yes, I even put the tile data in there (base64-encoded PNGs) and it still didn't exceed 500 SLOC. Which is awesome, I think. The thing is, I already did have my own prototype Sokoban engine written in JS, but that was it, an engine. Which means it defined the internal field representation format and move logic. Now, besides translating this logic into Tcl, I had to "draw the rest of the owl" and convert it into a playable game. This allowed me to learn how image import and composition works in Tk, as well as comprehend the basics of Tk's canvas. And, of course, I included an in-game help that can be called by pressing h or F1, and also made my game compatible with the huge databank of levelsets that can be downloaded from sourcecode.se ([4]) in the plaintext format (not the XML-based one though, maybe I'll create a format converter). By the way, I'm really thinking about rehosting all the levelsets somewhere around here, on Gopher or even Nex, along with a copy of the game script itself. --- Luxferre --- [1]: https://codeberg.org/luxferre/BFG [2]: https://nex.nightfall.city/nex/info/specification.txt [3]: https://git.luxferre.top/boxcl [4]: https://www.sourcecode.se/sokoban/levels.php