Kartones Blog

Be the change you want to see in this world

Course Review: Node.js Essential Training (LinkedIn Learning)

As I now have access to LinkedIn Learning full catalog, I'm going to use it alongside other resources so expect more course reviews in the upcoming months.


Node.js Essential Training takes around 2 hours to complete, and includes the basics of Node, I/O (interacting with the terminal and with the filesystem), eventEmitter, exports and modules, and executing & spawning child processes.

The code examples are simple but very effective. Oh, and the examples are built first using callbacks, but in the sixth chapter are also shown with streams. Sadly there is no promises version, but still not bad for such a compact course.

Recommended, and I'm going to actually take other courses from the author, Alex Banks, as I like how he explains each topic.

Logging visit stats with NGINX

I recently migrated my server to a new, newer instance, and decided to do some housekeeping and rethinking of the stuff I had running on it. One of the things that I had was a subdomain to store very basic visits stats, a tiny Python website done using Flask. Other than some small data formatting, it really wasn't doing anything else, so I thought: "If I'm using nginx and really don't need to format the data on save, why using anything else? why not reducing it to the bare minimum?".

After checking the documentation and some basic experiments, indeed for simple logging you don't really need anything else than filtering by the subdomain and an extra logger with a custom format.

I'll first show how to do it, then briefly explain the results:

On the specific stats.mydomain.test nginx configuration, inside the server block:

# server name must match with the one defined at `nginx.conf`
server_name stats.mydomain.test;

location / {
    # allow GETs from Javascript calls
    if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET';

    add_header 'Cache-Control' 'no-store';
    # As there's nothing to return, better 204 than 200
    return 204;

And on the general nginx.conf file, inside the http block:

# desired format, e.g. resembling a double-quoted fields CSV (without headers)
log_format statsformat '"$time_iso8601","$request_uri","$http_referer","$http_user_agent"';

# conditional mapping...
map $server_name $isstats {
    stats.mydomain.test 1;
    default 0;

# ... allows to do conditional logging
access_log /some/path/my_stats.log statsformat if=$isstats;

With just those lines, what you get is that any GET call to stats.mydomain.test will append a line to my_stats.log in the web server, but won't mess with calls to mydomain.test, somewhere.mydomain.test or any other subdomain on your server.

Logs allow for different configurations, like different buffer sizes (or no buffer at all) or compression. Check the official docs for more info.

Setting up my IndieWeb information

I love the concept of an open, accessible and interlinked world wide web, but I think that we're slowly going more and more inside a walled gardens model, where your data, your content and even fragments of your online persona (of your digital self) is contained inside fortified silos like social networks. That's the main reason why I've kept this dumb blog for more than 15 years (at the time of writing this post), and will keep doing so for as long as I can.

When recently Davidfq wrote me and told me that he liked my blog and "all the IndieWeb thingy" I wondered what was that indie web movement. I won't go into what's about, so go check indieweb.org and come back once you've read the basics.

I already have some microformats setup for my blog posts, but I wasn't using the h-card anywhere, so following the getting started guide I've now fixed both my landing page and both posts and pages from this blog.

I think the IndieWeb is a great initiative, and everything is decided openly, so if you keep a personal blog I encourage you to give it a try.

This isn't worth a post

"This isn't worth a post" is lately a common answer I give to myself when thinking about writing or not.

To me, it's becoming harder and harder to strike a balance between posting at least minimally interesting stuff and not keeping to myself tiny bits that might be of use to others.

The best example is a recent scenario: My Linux laptop and the current house's internet router don't get along 100%, after some inactivity the wi-fi connection would go down and take a while to reconnect. Some network troubleshooting later, disabling wi-fi power saving seems to have solved the problem.

Should I have posted about it to help others? Searching at DuckDuckGo at least, you need to either include iwconfig in the search terms, or dig in the first page of results and read them to find a clear & concise & up to date answer. But on the other hand askubuntu.com has 99% of answers to any issues I've ever had, and I think it is good to learn about finding things around the net and finding decent sources of information, even if it takes a few attempts. You will learn how to use the site and be a little less dependant on search engine ranking algorithms.

At least in some cases it's quite clear: My reviews, my experiments, my pet projects and the like are a clear "yes"; I'm learning some modern Javascript, NodeJS and related topics, but as there are so many good tutorials, courses and articles out there I won't post anything general related with the language as it is hard to add any value.

But often, I feel the contents won't add enough substance, so I discard them. Anyway, the "genuine" posts will still be written so I guess this is more of a rant than a real problem to solve 😃.

Book Review: Sid Meier's Memoir!


Sid Meier's Memoir! book cover

Title: Sid Meier's Memoir! A Life in Computer Games

Author(s): Sid Meier

Sid Meier and Will Wright are, alongside John Carmack, probably the most influential Game Development-related people regarding my favourite titles. I've already read a few books about id Software, so this title looked very appealing to me.

It covers four decades of videogame design and development by the author, an amazing feat by itself, but considering he created Railroad Tycoon, Pirates, Civilization, Alpha Centauri and other jewels of the computer gaming market... becomes clear that Sid is a clever guy that knows and loves what he does.

We'll learn from the beginnings of MicroProse, focusing at first just in flight simulators, and how initially side projects, less ambitious titles in which not many believed slowly became the main focus of the company. With ups and downs, with good and bad decisions, challenges and problems derived of growing and being acquired, but in the end with happy endings almost every time.

The book is not only very enjoyable, easy to read and often fun, but also, at least for an uninitiated in game development like me, full of interesting design advices, stories of initially bad decisions (thankfully) corrected and how they became pivotal points in simulation games history. As an example, Sid initially opposed to Civilization II being moddable, but a colleague slipped the data files in plain text, and it proved critical, as users created countless mods and "total conversions" for the game:

I knew that modding was a great way to ensure that Civilization never saw a third installment. I was so wrong, on all counts.

It's great to read how small inspirations like "The Princess Bride” could spawn combat systems for Pirates! (and Monkey Island, but that's another story), how they cheat the battle outcomes in favour of the player, or the process behind each iteration of the Civilization series:

Civ designers traditionally follow a rule of thirds. One-third of the previous version stays in place, one-third is updated, and one-third is completely new. These days, "updated” is a synonym for "scaled back to make room for the new things,” because we don’t want the game to become too complicated for someone who’s never played.

A comment from The Digital Antiquarian serves as a good complement of the initial issues with Avalon Hill, as the book's version claims to have the boardgames at the office but not have actually played them:

Put very crudely, then, Railroad Tycoon can be seen as 1830 with a SimCity-like railroad simulation grafted on in place of the board game’s pure abstractions. Bill Stealey claims that Eric Dott, the president of Avalon Hill, actually called him after Railroad Tycoon‘s release to complain that "you’re doing my board game as a computer game.” Stealey managed to smooth the issue over; "well, don’t let it happen again” were Dott’s parting words. (This would become a problem when Meier and Shelley promptly did do it again, creating a computer game called Civilization that shared a name as well as other marked similarities with the Avalon Hill board game Civilization.)

Regarding this particular point, things would get uglier years later:

[Avalon Hill and Activision] jointly sued MicroProse for copyright infringement. Avalon Hill couldn’t have afforded the suit on their own, and Activision had no legal standing without Avalon Hill, but together they hoped to gain control of one of the most successful names in gaming history. The executives at MicroProse responded with an equally winner-take-all attitude. Instead of countersuing, they went overseas to Hartland Trefoil, the original owner of the British board game, and bought the company out entirely. MicroProse now owned the ongoing licensing deal that had been granted to Avalon Hill in the first place, and judiciously rescinded it—along with every other Avalon Hill contract.

Ironically, Sid left MicroProse and the company he founded, Firaxis Games, would handle all future Civilization games (plus Alpha Centauri, and even the X-Com series!) after MicroProse disappeared.

The book is such an amazing journey that made me want to play again all the great titles mentioned. Inspiring, enthusiastic and very interesting.

A few more interesting sentences to close up:

  • The primary job of a game designer is not to make something fun, but to find the fun
  • Rewriting history, not reliving it [...] simplified
  • One of my big rules [regarding features] has always been, "double it, or cut it in half”
  • "Simple plus simple equals complex"
  • People play games to feel good about themselves
  • Imagination never diminishes reality; it only heightens
  • If you present players with options A, B, and C, and 90 percent of them choose A, then it’s not a well-balanced set—an interesting decision has no clear right or wrong answers. [...] If players are evenly distributed among A, B, and C, but they all chose within three seconds, then it’s not a very meaningful decision. Any answer would have worked.
  • Good games teach us that there are tradeoffs to everything, actions lead to outcomes, and the chance to try again is almost always out there.
  • Ideas are cheap; execution is valuable.

Previous entries