John Bintz is a frontend Web developer living in Baltimore, MD. When he's not writing sweet Internet codes, he's drawing comics or playing some sort of game.

Where to find me...

  1. Website for The Wizard and The Metalsmith is up!

    February 28th, 2016

    I finally finished up building the website for my fantasy/mystery comic The Wizard and The Metalsmith. I'd been delaying it for quite a while because the blog engine I wrote for this site started to become too much of a pain to work with.

    So I decided to rewrite the blog engine in ClojureScript, both the frontend and the backend. The backend is running on NodeJS, just like the current engine. Redoing it in ClojureScript gave me some advantages over the original JavaScript version:

    • I can still use all of the same Node modules I did on the backend. Adding them manually to project.clj also gets rid of any issues I've had with npm install --save adding caret versions for libraries, which I've had plenty of problems dealing with in the past.
    • I've avoided using Webpack, and I don't need Babel, and I've had so few issues with building code and keeping dependencies up to date. All of the client code uses libraries from CLJSJS, and I haven't needed to take any of the libraries I needed on the original JS version and rebuild them for CLJSJS. The server code can use libraries as it wishes, so no problems there.
    • Reagent is a much simpler way to use React. It's like stateless function components have become the default way of building everything, and that's awesome.
    • Figwheel is a very nice way of doing frontend development, though with isomorphic rendering I couldn't seem to take full advantage of it, and I think I still have some project structuring learning to do before I really get it right. It was nice to be able to see both client- and server-side compile errors be shown right in the browser.
    • I did get client- and server-side REPL integration working with weasel and vim-fireplace, but I started running into issues with weasel that I need to track down and fix.
    • core.async is crazy powerful, but there's all sorts of weird little timing things I had to deal with and learn about. Working with channels and channel open states was tough to wrap my head around at first, but once I had the basics of it, it was much nicer than callbacks and Promises (thoush I still use a callback here and there).

    As I said above, I'm using isomoprhic rendering on the site. I essentially rebuilt react-resolver in ClojureScript. It's a very simple reworking that uses the state of an atom to determine when to fire off the real rendering. I may take the time to break it out into a library that I can improve upon. It has made the site load much faster for end users and should definitely improve search rankings!

    So yeah, enough nerd talk. Head over to the site and download the first issue and read it and tell your friends to read it and just keep doing that over and over. You know you want to.

  2. Run Chantry's Twilight Struggle server on Docker!

    February 14th, 2016

    I'm a huge fan of Twilight Struggle, and when I found out about the Chantry service for playing Twilight Struggle, I was hooked. But, after some extended downtime about a year ago, I took a break. During that downtime I thought about getting the server running locally (it's all open sourced and approved by GMT Games), and I went at it with varying levels of success.

    After some time playing with it, I finally got it running inside of a Docker container. chantry-docker contains instructions on getting Twilight Struggle running on your own setup, so that you can control upgrades and downtime, and, more importantly, be matched up with friends so that youall can grow together as players before being thrust out into the Cold War with much more experienced opponents.

    So if you have a spare Docker instance running, take it for a spin!

  3. Blog rebuilt for the millionth time

    October 25th, 2015

    Yes, has been rebuilt. Now, instead of the huge-ass Rails app that did a bazillion things and was hard to work with after a while has been replaced with a much smaller Express server and with React for the frontend, and yes, I'm using universal JavaScript, so it's the same code on the frontend and backend. And it's super fast. I also deployed everything using Docker and Ansible, and it's way easy to deploy and update.

    We'll see how long this new version lasts.

  4. A Week with Docker on my Little Ol' Linux Server

    November 22nd, 2014

    Welcome to my server farm.

    On the right is my SheevaPlug, a 32 bit ARM v5 Linux server I've had for a few years now. It can run basic fileserving, minidlna, sshd, and other simple things like that. On the left is an Acer Aspire Revo HTPC that used to run XBMC until I replaced it with a Roku, which was way better. The SheevaPlug's been cranking away, the Revo's been in storage since last year.

    Lately, it's been much tougher to get upgrades and newer software for the SheevaPlug without going through a lot of headaches. I don't even think the Debian apt repo I was using before even works anymore! I've also hopped right on the Docker hype train, somewhere in the back by the food car where I can get hot dogs and expensive beers (you gotta do that when you're on a train). There's no way that Docker was going to run on there, let along anything really modern (I tried getting node.js to run there. Never again.), so I decided to break out the Revo and rebuild it so that, except for sshd, it only ran Docker containers for every useful service. That'll force me to learn real fast!

    The first thing was installing an OS I knew well. I put Kubuntu 14.04 on there, since configuring it initially via the GUI would be fast and easy. I then ran into my first problem: if the machine was left at the GUI login screen for too long, the on-board nVidia ION would lock up the machine. I changed my login to be text only via GRUB and made it so that tty1 logged me in and started htop on creation, since it's really neat and if you have physical access to the machine, I'm already compromised. No more lockups. I ordered a 7" monitor to use with the machine, because why not?

    Then it was on to Docker. I used the standard Ubuntu install method and was up and running in no time.

    Now to take all of the services that were important to me and start converting them to Dockerized services. The ones that I used the most were:

    • forked-daapd
    • minidlna
    • a cron job to update a DNS entry to point at my home's IP
    • a cron job to record a radio show from an MP3 stream every week

    And the new ones I wanted to run:

    • a Docker registry so I could host my own images
    • Docker UI
    • a Squid proxy for the local network

    I have my implementations of forked-daapd and minidlna up on GitHub. They're a little more configurable than the other images I've found, to better suit my setup of having a USB drive for serving the files. The cron containers use the approach outlined here for changing the container's time to the host machine's time. One thing I haven't done yet is use data-only containers. I still don't quite get them and I haven't had a need for one yet. Maybe I'll re-set up my Squid proxy to use one for the cache and see how it goes.

  5. A basic Capistrano recipe for deploying a simple Dockerized application

    November 17th, 2014

    I've been learning a few things at once right now: React.js for a different approach to front-end code, Express and the whole node.js ecosystem for simple back-end apps, and Docker for stupid-simple app deployment. I've gotten pretty far with all of these, to the point where I could write a simple little app that did its thing with just a few hundred lines of CoffeeScript and CJSX code. I put together a Dockerfile to bundle up the app, and could manually deploy it to the machine that was my media server until my Roku 3 took over. That server is now entirely for Dockerized daemons, including the little app I wrote.

    I really didn't want to deploy this app by hand every time I updated it while playing with new things, and there don't seem to be a lot of practical examples for bridging the local build to remote deploy gap in the Docker workflow, so I wrote this post. I reached for my old favorite Capistrano to handle the heavy lifting of coortinating tasks and running commands on my Docker server. Below is a simple deploy.rb file that you can drop into an app that you initialized with a Capfile that should get you most of the way.

  6. Search Engine Food: Applying Online for a Traders License in Maryland

    November 10th, 2014

    So much searching and a phone call to Baltimore County Circuit Court finally led me to this link, which lists the business license information you need for the state of Maryland, including traders licenses, and gives you online applications for the ones it can handle. A traders license is the one I may need to deal with in the future. Google barfed on trying to get me the best URL, and according to the clerk I talked to, this is the one. Index away!

  7. Game Design Journal: CDS game, post 2

    October 2nd, 2014

    So it's been a few weeks since I was able to do some solid work on the card-driven strategy game I've been putting together and hope to have ready for Unpub 5. The last version of it was very rough, with just written-on cards for what all of the individual card abilities were.

    During a slow time at Baltimore Comic-Con, I entered in all that textual data into the SVGGVS spreadsheet for the game and reworked the card template so that card effects and other information would show up properly:

    I played this version a few times by myself before subjecting my friend Gavin to the game, and I'm glad I did, becaue the experience of playing it with another person showed me just where all the flaws were, and most of them came down to complexity and inconsistency.

    One of the goals of this unnamed prototype is to bring in as much of the experience I enjoy from Twilight Struggle with much less overhead. The first things I found that made playing too complex were the following:

    • The text on the cards and all the different states I had to manage made it rough to keep track of what was going on. I even ended up making a ridiculously complex player aide that didn't do squat.
    • The method of invoking card powers that were "yours" was annoying.
    • The whole method for card power invocation was bad anyway.
    • Turn and year tracking was a pain.

    So, back to the drawing board. This time, I decided to switch out the card text with a series of simple icons:

    The icons allow you to do a number of resource/hand/discard pile manipulations, and in the Inkscape document, they're all clones, so when I polish up the icons, they'll all change at once. I make the generic Strength action (what would be an ops action in Twilight Struggle) a separate icon, so you didn't always have the option to do ops-y things. Finally, I decided to remove the dice for resolving certain events and use the dice card-like deck from Impulse to handle random chance things.

    By switching to dice cards, it opened up an opportunity to simplfy how all the dice-based actions work, which also provided this game's version of the "Space Race", allowing you to dump cards from your hand that you don't want to play. The original dice actions were:

    • Riots: Each player rolls 1 die. A player adds 1 to their roll if they have the most resources in the disputed location, and 1 for each adjacent location they own. Loser removes difference of resources from location. If still rioting, repeat.
    • Generate resources: Roll 1 die and add the Strength of the card you played. 6+ = 1 resource on your castle.
    • Remove cards from discard pile: Roll 1 die. If less than the Strength of the card, remove the diference between Strength and roll from your discard pile.

    Now, with dice cards:

    • Riots: Take 1 card, face down, for participating. Take an additional card if you have the most resources in the riot, or if you own an adjacent location. You may add 1 card from your hand to the riot pile. Flip all cards at once. Highest total card level wins and removes all opponent resources, and adds 1 card to their discard pile per resource removed this way. Silly player wins ties (since Serious player wins card reveal ties).
    • Generate resources: Using the Strength action on the card, flip that many cards from the deck. Total their levels and add that many resources to your castle.
    • Remove cards from discard pile: Same as generate resources, but remove discarded cards instead.

    This also eliminates the "All resources on board = you win" win condition, since it'd be too easy to dump all 45 resources on the board this way. Additionally, years and turns are not controlled by sliders. If a player has 1 or less cards in hand at the start of a turn, the year ends. 5 cards are set aside from the deck at the beginning of the game. At the end of the year, the winner of the "play War with your discarded cards" stage takes one of those cards into their hand and the loser removes 2 resources from the board.

    This second game went way faster, and was a lot smoother, and a lot more fun. We didn't finish a whole game, but we did move a lot faster through the game and had to deal with a lot fewer fiddly bits. The takeaway from this session was:

    • Removing the "all cards can be the board" mechanic. It's too much to worry about players purposely AP-ing if they have an idea of what's in the deck. I don't want that in this game. The less AP, the better. This means the board is now made out of a separate deck of cards, which will require coming up with some additional cards and bumping up the total card count to 126 to keep the costs in line, but that'll add 5 new game cards, which means I can have more generic Strength cards. Speaking of...
    • Gavin got a hand of cards that basically allowed him to do nothing of consequence. Several cards were "Opponent" or "Silly Lord" only (he was Serious) and he couldn't do anything with them, so he was boned. I don't want that to happen all the time, so I'm going to make sure each card has "You" as a target in some way.
    • The board is going to be smaller, 3x5 instead of 5x5. It should allow players to go more nuts on each other more quickly. This will mean I'll probably bump up the sizes of the locations, so you need more resources in there to butt heads. This would also allow me to easily design a 3 or 4 player expansion down the road.

    Finally, SVGGVS got some work done to it. I had a ton of clone in the Inkscape document I was working with, and the original code I used to decide if I neede to unclone an object (if it's text and there needs to be text replacement) decided to loop through every <svg:use> tag in the document, look at its type, and decide what to do, for every card that was build. With a document with around 500 <svg:use> tags, Nokogiri fell to its knees. I reworked that part of the code so that the type evaluation only happens during the first card, and the results are cached for all further cards. Took processing time down from about 5 minutes just to generate SVG files down to about 2. Nice.

  8. Scrum for One Week 17-18-19: Holy hand grenades, Batman, I've been busy!

    September 15th, 2014

    Sorry for the lack of updates. Things have been ridiculously busy. I've been falling behind on pretty much everything, so this week's sprint goal is Get Back on the Horse. This includes working on the CDS game (which I'll be playtesting with another human this week, neat), the mobile version rewrite of Can't Catch Me, Olivia! (which I'm now doing using Snap.svg, neat), and doing cleanup on the Can't Catch Me, Olivia! Kickstarter (I have cards to draw and people to track down, neat).

    My everything also exploded, so Keep Your Office Clean stays up as the kaizen.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20