Best Train Simulator 2019

I have some personal enthusiasm for trains, and last years part of that has been playing Train Simulator on PC. That is the game that used to be called Railworks and that currently is named Train Simulator 2019. While I have spent much time with it I also have mixed feelings.

In 2019 there are two alternatives to TS2019 that I have tested and that I will write about: Train Sim World and Trainz Railroad Simulator 2019.

My experience with Dovetail Train Simulator (2019)

I got Train Simulator because I wanted to try to drive trains. The game has developed over the years but there are some annoyances.

The game has some quirks and bugs. The physics, engines, wagons, signals, AI and scenario conditions sometimes don’t work in a way you would expect.

The game is also rather unforgiving. One little mistake can ruin a scenario so you can’t even continue. If that was passing a red light, ok. But sometimes I am just a little late, a little early, I connected or disconnected the wrong wagon, I went into the wrong siding or something like that.

The combination of bugs and being unforgiving is rather frustrating. When there is a little inperfection in the game I can perhaps accept the lack of good simulation experience, but if it ruins the scenario completely, it is worse.

The game has a competitive aspect (it is a game) where you drive scenarios and get scores. This is particularly unforgiving. Decouple a wagon and for some reason (bug?) I get “operational error”, being penalised with -750 points (1000 is max), and I have no choice but aborting the scenario. Also, speeding is penalised heavily. This is annoying for two reasons: first the time table is often ridiculously tight, second it is not uncommon that maximum allowed speed changes unexpectedly.

You can read about the outdated graphics of TS2019 and that is true, but it does not ruin my experience. You can read about all the expensive DLC, but that is your choice (I bought some, but most everything on sales). What I find more annoying is that I buy a nice piece of DLC and it comes with very few scenarios. That is where the (Steam) workshop comes in and there are quite many scenarios (of varying quality) do download.

I found that creating scenarios was often more fun than driving myself and I have contributed some 44 scenarios on Steam Workshop. If driving is quirky, creating scenarios is kind of black magic (the problem is I need to test it, and when it fails after 40 minutes, I need to guess whats wrong and drive again for 40 minutes until I know if it works – a horrible development and debugging experience).

It seems to me it would be very possible to deliver a better Train Simulator game!

On Realism

It is easy to talk about realism. But is it really what we want. My experience…

  • Some routes allow for long eventless sessions. That is the realistic truth about driving a train, but how entertaining is it?
  • A real challenge when driving a train is breaking and planning your breaking. The weight and length of the train matters, as long as other factors. In the real world a train engineer makes calculations about breaking distances. They are not going to be driving a new train, with unknown weight, on a new track on a tight time schedule. Yet in a train simulator this is what we do, because we want (much) variation (it is a somewhat boring game anyways).
  • A real engineer knows the line well, and has special physical documentation about the line available. And he has studied this before. You don’t do that in a train simulator.
  • A real engineer spends much time checking things like breaks and wheels. And there is much waiting.
  • You can have a realistic “regulator”, that you can operate in the locomotive cab. That will look realistic in one way. But a real engineer would not point and look at it with a mouse, he just happens to have his hand there in the first place. User-friendly, where man-machine becomes one, is good simulation to me.
  • Real(istic) timetables are good, but not when it is almost impossible to arrive on time in the simulator.

My point is that I don’t want a realistic simulator. I want a simulator that gives me the feeling I am driving a train. And I want the time I spend with my computer to be more eventful, entertaining and challenging that the average work hour of a train engineer. And also somewhat more forgiving and I want support with things that are easier in the real world.

Train Sim World

Train Sim World is produced by the same company (Dovetail) as Train Simulator 2019. It appears they thought of it as a replacement for Train Simulator 2019, but it also appears that for now the games exist side by side. It is not clear that Train Sim World will ever replace, or even survive, Train Simulator 2019.

The good:

  • It looks (the graphics) better than the alternatives.
  • It may be the most “polished” option (also available for Playstation and Xbox, which gives you a hint).
  • If you get a “package” at discounted price on Steam (EUR25 for 4 routes) it is quite good value.

The bad:

  • It does not look that good; it is still computer graphics with obvious artifacts and problems. Also, the sound is not too convincing and the surroundings are pretty dead.
  • Walking around (in the scenarios) does not appeal to me, and it is not well made enough to add to the realism of the game.
  • Menus are a bit messy.
  • Quite limited number of scenarios, but plenty of “services”, but I think that contributes to (even) less events, action and storytelling.
  • The routes seem small, and very little action or room outside the mainline (like very linear).
  • Occational glitches like “what do I do now”, “what happens next” or “how do I do that”? (driving a service, I was done, told to get off, the train drove away by itself with no visible driver or no comments, and then nothing… had to just quit).
  • It lacks something. Like its not a bit dirty, noisy and rough… but just too smooth and clean.
  • So far, no possibility for user generated content. It is promised, and it will be based on Unreal, so it seems to be very technically demanding. I myself would prefer to be able to make scenarios with a story easily, without changing anything about the route or the other assets at all.
  • Unreal (which is to thank for the better graphics) seems to be a more complex (expensive) development environment, and perhaps this will limit in the future the availability or routes and assets, and make the price high (pure speculation).

I did give Train Sim World a first try, wrote a very negative review, refunded it, but after a few weeks I gave it a new try, and now I have a more balanced opinion about it.

Trainz Railroad Simulator 2019

Years ago I obviously did research and opted for Train Simulator rather than Trainz. Now that I was a bit disappointed with Train Simulator and rather disappointed with Train Sim World I felt I had to give Trainz 2019 a try.

My expectations based on marketing and what I read was:

  • Better graphics than Train Simulator, but perhaps not as good as Train Sim World.
  • More creator-, community- and sharing oriented (which appealed to my preference to making scenarios).
  • It’s a railroad simulator, rather than a train driver simulator.

I must say right away that I am quite disappointed. I ended up paying EUR 70 for Trainz, and EUR 25 for Train Sim World, and that does not reflect the value of what I got.

Download Station

Trainz comes with “its own Steam Workshop, Download Station”. This is the worst part of it. Hundreds of assests, organised alphabetically, with virtually no filtering and no community/feedback/rating function. Unless I completely missed something, this is shit. My use case is that I want to see if someone created a nice 30 min session for one of the premium routes that came with my purchase (and that has no extra dependencies). Trainz seems to live in the world where people download zip-files from ftp-servers and spend the effort of maintaining their virtual asset library like the stock portfolio. I am tempted to make a few sessions myself, and sharing them here, on my blog, but why?

Graphics

There is something idyllic, picturesque, beautiful and friendly about Trainz that is missing in Train Simulator and Train Sim World. There are gorgeous screenshots from Trainz out there. But when it comes to actual game performance on my actual computer (a NUC Hades Canyon) Trainz is the worst. I have been spending not so little time optimizing my graphics settings (and there are many settings to play with).

Quality

To my disappointment the routes come with quite few sessions. The beatiful route from Edinburg to Aberdeen (perhaps just to Dundee) has two sessions: a passenger service with the same Deltic locomotive going both ways. These two scenarios both take 1h30min each to drive. And the one I did try did not work in CAB (realistic) drive mode, because for some reason the Deltic can not pull those wagons with any speed whatsoever. Isn’t it reasonable to expect when a new EUR 70 release is made after 7 years, that the sessions are tested at least once, and working?

Then there was another beautiful session on the Cornish mainline where a 2MT steam locomotive pulls ~25 freight wagons and it just can’t make it up the grades. I asked in the forum and I had managed to get further than most people, but the suggestion was to just try another locomotive (edit the session). Why release a session with the wrong locomotive in the first place?

If driving steam locomotives in realistic mode can be a challenge in Train Simulator (often a frustrating one), in Trainz it feels… not realistic. Perhaps I need more practice, but it is very… unsmooth.

Other things

There is no support for a Gamepad (although I found a little software called AntiMicro) which works decently well for my purposes.

I really miss the look-out-throw-the-side-window camera view.

I appreciate that I can see the status of the next signal in the HUD.

When I have completed a session it does not remember (marked as completed) so I made my own list

A good thing about Trainz is that it is more forgiving than Train Simulator. I ran out of boiler pressure, but then I could switch to simple driving mode and at least complete the session.

I get the feeling that for people who already own and love the old Trainz this is an upgrade. But for a new player it is a rough experience.

Conclusion and recommendation

Unfortunately I think none of the games I have written about live up to the expections you should allow yourself to have in 2019. And I am not aware of a better game in the genre.

Clearly this genre appeals to enthusiasts who want to make their own assets and modify the game, and clearly Train Simulator and Trainz are based on old technology that have not aged too well (and people are reluctant to abandon their assets). Train Sim World, being based on Unreal, has not been able to deliver a workshop- or sharing-experience at all, yet.

If you are curious about how it is to drive a train, get Train Sim World (and an Xbox controller if you get it on PC, I know nothing about the Playstation/Xbox experience). Sit comfortably, turn up the volume, have some coffee (or whatever you drink) and do your best to enjoy the experience. Spend time with the tutorials and dont get too frustrated if you get stuck.

If you want to have your own digital train layout, and play with it (dispatch and control multiple trains), get Trainz, and make sure to have a powerful enough computer.

If you think that Steam workshop is a nice idea where you can share scenarios (and other assets) and communicate with other people about them get Train Simulator 2019. Cost/price aside, there are very many routes (and extra locomotives) available for Train Simulator 2019.

Train Simulator 2019 now supports 64-bit mode. Technically its not… hot… but it is being improved. Train Sim World looks better, but it is not that much better. Honestly, folks who make a living reviewing computer games say: “TS2019 looks so old, but TSW is built on Unreal like all the other cool games, much better.” But for your total train simulation experience, the difference is… marginal.

I would not be too surprised if the Train Sim World Editor never happens. If it is released I would not be surprised if it is too complex and a critical portion of contributors and enthusiasts never switch. The advice to enthusiasts to “Download the UE4 Editor from Epic and start learning”, I am sceptical about it. I doubt I will contribute scenarios if I have to get into a real 3D studio to place some trains and make some timetables/rules.

I would hope that Trainz gets a real workshop experience where you can easily share assets in a social way and where you don’t need to worry too much about dependencies. And I would hope that Trainz manages to polish their game, test it properly, and provide a solid graphics experience.


Trainz Log

I decided to try Trainz (now that 2019 is out) and I think it is useful to keep track of my progress, so I will do it here.

Gamepad

I prefer to drive my train with a gamepad. I found a little free software called AntiMicro which allowed me to map my Xbox gamepad to relevant Trainz keys. It was easy and I recommend it.

Graphics

My computer is a NUC Hades Canyon. It has an Intel Core i7 CPU, AMD Radeon RX Vega M GPU, 16GB or RAM and 512GB SSD. This computer can not at all play Trainz 2019 in “Ultra”, instead I have to tune down the performance settings quite much. I have found (and I may change opinion when I have experimented more) that I want to run Trainz in full resolution (1920×1080) and I think the lowest anti aliasing (2x) makes most sense. I allow myself to use “Clutter + Turf FX” and High details. Different routes are supposed to be demanding on the GPU.

Cornish Mainline and Branches

A trip to Falmouth: Completed with 2 stars.
Freight Delivery: This session is tricky and I started a thread on the Trainz forum. I dont think the 2MT is capable of pulling 23 wagons all the way, I got completely stuck after 7 miles in a 2%+ grade. I modified the session and used a 4200 tank locomotive instead but I got two new problems: 1) AI trains going in the other direction all stand still, 2) When I have finally arrived the session never ends (or continues). Perhaps I broke something when I modified it.
Helston freight run: Completed with 5 stars.
Helston passenger run: Completed with 4 stars.
Mainline passenger service: Completed with 1 star (!), on time, gorgeous!
St Ives passenger run: Completed with 5 stars.

ECML Edinburgh – Dundee

09-10 Dundee – Kings Cross: Completed with 5 starts (but can’t drive in realistic CAB mode)

Sebino Lake

Maintenance Service: Completed with 5 stars (in DCC, can’t get the train rolling in Cab mode)

Train Sim World Review

I have been playing Train Simulator (up to 2019 just recently) for some years and I have mixed feelings for it. So I decided to try the “successor” Train Sim World. I will get straight to the point and say that I requested a refund from Steam after 104 minutes (despite getting the Digital Deluxe edition at 55% discount). Perhaps you may think I can not properly judge a game after just 104 minutes? Perhaps 104 minutes was more time than I should have spent.

The Graphics
The big thing about Train Sim World is supposed to be its state-of-the-art Unreal 4 graphics engine, compared to the “outdated” engine of Train Simulator. I think… it looks better, but not that much better. I think TS2019 with a decent GPU and 64-bit-edition looks pretty decent. And TSW did not look that amazing. But that was not the problem…

1st person perspective
In TSW you can walk around. You can enter and exit your locomotive. Thats ok, but I don’t really care. However in the first Scenario (Great Western Express) I had to take a local service to Paddington. So I had to, in game, spend 10 min on a commuter train. I could not figure out how to sit down, so I could not really look out through the windows and enjoy the view. And the interior of that commuter train was not amazing and there were some reflexes (I guess) that gave pretty ugly artifacts. It took me 20 minutes in a mostly empty commuter train and walking around in a mostly empty Paddington station until I was actually in my drivers seat. Not fun.

The Driving UI
The view from the drivers seat looks good. Both in TS and TSW there are basically four ways to do (the most common) things:

  1. Using the mouse to click/drag in the HUD
  2. Using the keyboard
  3. Using an Xbox gamepad
  4. Using the mouse/pointer to manipulate the actual instruments, buttons and levers in the cabin.

This is listed in the order I learnt it in Train Simulator. The HUD was easy to start with but not too comfortable. The keyboard was more comfortable and the gamepad even more so. For long relaxed drives I sit back using the gamepad. But for intense and precise shunting operations I bring out the mouse. I never really bothered with #4.

But #1 does not work in TSW. The HUD is view-only. So there is no button on the screen that clearly loads/unloads passengers. You have to click TAB to get a menu in the middle of the screen. I think it was great in TS that there was a simple control-with-mouse interface at the bottom of the screen that had everything I needed! Then I could use keyboard, gamepad or the cabin buttons as I preferred.

TS had an interactive and useful HUD at the bottom of the screen. And a task menu to the left that could be opened when needed. But TWS clutters the forward, outward, view with information. It is not pretty. The markers (for speed and signal color) completely destroy the beautiful view. You can turn it off but you need that information somewhere. You can get it in the HUD, but it shows up covering the landscape outside.

Its possibly I spent too little time with the new UI. But I really didn’t like it. And it was hard to use and learn.

Scenario Tasks
For some reason you can not see all your tasks from the beginning. What is that!? Isn’t the train driver supposed to know the timetable in advance to be able to plan ahead? And I did have problems completing tasks. In the EM2000 freight scenario “Aggregate Industries” I was supposed to activate Slow Speed Control. Not only was it unheard of, and I needed to find a little button with the right tooltip (not knowing if I am in a hurry or not), but clicking the button never completed the task and I could not complete (or even begin, actually) the scenario.

Scenarios and Services
The Great Western Express DLC comes with 3 locomotives and 5 scenarios! Perhaps more can be unlocked, but what is that? On the other hand there are very many “services”, being able to run any train on the time schedule. Thats ok, but then no information about duration or difficulty.

Conclusion
Well, this was just some of my impressions. But I was disappointed and frustrated after almost two hours with TSW and I feel relieved that my refund was accepted.

Since TSW is also for consoles (Xbox, PS) I would have expected a nice, smooth, beautiful, polished driving experience where I could relax with my gamepad and see, hear almost feel the power of the engine and the landscape flying by. Instead I got a slow boring confused first-person-shooter-experience where I felt lost in a runaway train.

Lambda Functions considered Harmful

Decades ago engineers wrote computer programs in ways that modern programmers scorn at. We learn that functions were long, global variables were used frequently and changed everywhere, variable naming was poor and gotos jumped across the program in ways that were impossible to understand. It was all harmful.

Elsewhere matematicians were improving on Lisp and functional programming was developed: pure, stateless, provable code focusing on what to do rather than how to do it. Functions became first class citizens and they could even be anonymous lambda functions.

Despite the apparent conflict between object oriented, functional and imperative programming there are some universally good things:

  • Functions that are not too long
  • Functions that do one thing well
  • Functions that have no side effects
  • Functions that can be tested, and that also are tested
  • Functions that can be reused, perhaps even being general
  • Functions and variables that are clearly named

So, how are we doing?

Comparing different styles
I read code and I talk to people who have different opinions about what is good and bad code. I decided to implement the same thing following different principles and discuss the different options. I particularly want to explore different ways to do functional programming.

My language of choice is JavaScript because it allows different styles, it requires quite little code to be written, and many people should be able to read it.

My artificial problem is that I have two arrays of N numbers. One number from each array can be added in NxN different ways. How many of these are prime? That is, for N=2, if I have [10,15] and [2,5] i get [12,15,17,20] of which one number (17) is prime. In all code below I decide if a number is prime in the same simple way.

Old imperative style (imperative)
The old imperative style would use variables and loops. If I had goto in JavaScript I would use goto instead of setting a variable (p) before I break out of the inner loop. This code allows for nothing to be tested nor reused, although the function itself is testable, reusable and pure (for practical purposes and correct input, just as all the other examples).

  const primecount = (a1,a2) => {
    let i, j;
    let d, n, p;
    let retval = 0;


    for ( i=0 ; i<a1.length ; i++ ) {
      for ( j=0 ; j<a2.length ; j++ ) {
        n = a1[i] + a2[j];
        p = 1;
        for ( d=2 ; d*d<=n ; d++ ) {
          if ( 0 === n % d ) {
            p = 0;
            break;
          }
        }
        retval += p;
      }
    }
    return retval;
  }

Functional style with lambda-functions (lambda)
The functional programming equivalent would look like the below code. I have focused on avoiding declaring variables (which would lead to a mutable state) and rather using the higher order function reduce to iterate over the two lists. This code also allows for no parts to be tested or reused. In a few lines of code there are three unnamed functions, none of them trivial.

  const primecount = (a1,a2) => {
    return a1.reduce((sum1,a1val) => {
      return sum1 + a2.reduce((sum2,a2val) => {
        return sum2 + ((n) => {
          for ( let d=2 ; d*d<=n ; d++ ) if ( 0 === n % d ) return 0;
          return 1;
        })(a1val+a2val);
      }, 0);
    }, 0);
  };

Imperative style with separate test function (imperative_alt)
The imperative code can be improved by breaking out the prime test function. The advantage is clearly that the prime function can be modified in a more clean way, and it can be tested and reused. Also note that the usefulness of goto disappeared because return fulfills the same task.

  const is_prime = (n) => {
    for ( let d=2 ; d*d<=n ; d++ ) if ( 0 === n % d ) return 0;
    return 1;
  };

  const primecount = (a1,a2) => {
    let retval = 0;
    for ( let i=0 ; i<a1.length ; i++ )
      for ( let j=0 ; j<a2.length ; j++ )
        retval += is_prime(a1[i] + a2[j]);
    return retval;
  };

  const test = () => {
    if ( 1 !== is_prime(19) ) throw new Error('is_prime(19) failed');
  };

Functional style with lambda and separate test function (lambda_alt)
In the same way, the reduce+lambda-code can be improved by breaking out the prime test function. That function, but nothing else, is now testable and reausable.

  const is_prime = (n) => {
    for ( let d=2 ; d*d<=n ; d++ ) if ( 0 === n % d ) return 0;
    return 1;
  };

  const primecount = (a1,a2) => {
    return a1.reduce((sum1,a1val) => {
      return sum1 + a2.reduce((sum2,a2val) => {
        return sum2 + is_prime(a1val+a2val);
      }, 0);
    }, 0);
  };

  const test = () => {
    if ( 1 !== is_prime(19) ) throw new Error('is_prime(19) failed');
  };

I think I can do better than any of the four above examples.

Functional style with reduce and named functions (reducer)
I don’t need to feed anonymous functions to reduce: I can give it named, testable and reusable functions instead. Now a challenge with reduce is that it is not very intuitive. filter can be used with any has* or is* function that you may already have. map can be used with any x_to_y function or some get_x_from_y getter or reader function that are also often useful. sort requires a cmpAB function. But reduce? I decided to name the below functions that are used with reduce reducer_*. It works quite nice. The first one reducer_count_primes simply counts primes in a list. That is (re)useful, testable all in itself. The next function reducer_count_primes_for_offset is less likely to be generally reused (with offset=1 it considers 12+1 to be prime, but 17+1 is not), but it makes sense and it can be tested. Doing the same trick one more time with reducer_count_primes_for_offset_array and we are done. These functions may not be reused. But they can be tested and that is often a great advantage during development. You can build up your program part by part and every step is a little more potent but still completely pure and testable (I remember this from my Haskell course long ago). This is how to solve hard problems using test driven development and to have all tests in place when you are done.

  const is_prime = (n) => {
    for ( let d=2 ; d*d<=n ; d++ ) if ( 0 === n % d ) return 0;
    return 1;
  };

  const reducer_count_primes = (s,n) => {
    return s + is_prime(n);
  };

  const reducer_count_primes_for_offset = (o) => {
    return (s,n) => { return reducer_count_primes(s,o+n); };
  };

  const reducer_count_primes_for_offset_array = (a) => {
    return (s,b) => { return s + a.reduce(reducer_count_primes_for_offset(b), 0); };
  };

  const primecount = (a1,a2) => {
    return a1.reduce(reducer_count_primes_for_offset_array(a2), 0);
  };

  const test = () => {
    if ( 1 !== [12,13,14].reduce(reducer_count_primes, 0) )
      throw new Error('reducer_count_primes failed');
    if ( 1 !== [9,10,11].reduce(reducer_count_primes_for_offset(3), 0) )
      throw new Error('reducer_count_primes_for_offset failed');
    if ( 2 !== [2,5].reduce(reducer_count_primes_for_offset_array([8,15]),0) )
      throw new Error('reducer_count_primes_for_offset_array failed');
  };

Using recursion (recursive)
Personally I like recursion. I think it is easier to use than reduce, and it is great for acync code. The bad thing with recursion is that your stack will eventually get full (if you dont know what I mean, try my code – available below) for recursion depths that are far from unrealistic.  My problem can be solved in the same step by step test driven way using recursion.

  const is_prime = (n) => {
    for ( let d=2 ; d*d<=n ; d++ ) if ( 0 === n % d ) return 0;
    return 1;
  };

  const primes_for_offset = (a,o,i=0) => {
    if ( i === a.length )
      return 0;
    else
      return is_prime(a[i]+o) + primes_for_offset(a,o,i+1);
  }

  const primes_for_offsets = (a,oa,i=0) => {
    if ( i === oa.length )
      return 0;
    else
      return primes_for_offset(a,oa[i]) + primes_for_offsets(a,oa,i+1);
  }

  const primecount = (a1,a2) => {
    return primes_for_offsets(a1,a2);
  };

  const test = () => {
    if ( 2 !== primes_for_offset([15,16,17],2) )
      throw new Error('primes_with_offset failed');
  };

Custom Higher Order Function (custom_higher_order)
Clearly reduce is not a perfect fit for my problem since I need to nest it. What if I had a reduce-like function that produced the sum of all NxN possible pairs from two arrays, given a custom value function? Well that would be quite great and it is not particularly hard either. In my opinion this is a very functional approach (despite its implemented with for-loops). All the functions written are independently reusable in a way not seen in the other examples. The problem with higher order functions is that they are pretty abstract, so they are hard to name, and they need to be general enough to ever be reused for practical purposes. Nevertheless, if I see it right away, I can do it. But I don’t spend time inventing generic stuff instead of solving the actual problem at hand.

  const is_prime = (n) => {
    for ( let d=2 ; d*d<=n ; d++ ) if ( 0 === n % d ) return 0;
    return 1;
  };

  const combination_is_prime = (a,b) => {
    return is_prime(a+b);
  };

  const sum_of_combinations = (a1,a2,f) => {
    let retval = 0;
    for ( let i=0 ; i<a1.length ; i++ )
      for ( let j=0 ; j<a2.length ; j++ )
        retval += f(a1[i],a2[j]);
    return retval;
  };

  const primecount = (a1,a2) => {
    return sum_of_combinations(a1,a2,combination_is_prime);
  };

  const test = () => {
    if ( 1 !== is_prime(19) )
      throw new Error('is_prime(19) failed');
    if ( 0 !== combination_is_prime(5,7) )
       throw new Error('combination_is_prime(5,7) failed');
    if ( 1 !== sum_of_combinations([5,7],[7,9],(a,b)=> { return a===b; }) )
       throw new Error('sum_of_combinations failed');
  };

Lambda Functions considered harmful?
Just as there are many bad and some good applications for goto, there are both good and bad uses for lambdas.

I actually dont know if you – the reader – agrees with me that the second example (lambda) offers no real improvement to the first example (imperative). On the contrary, it is arguably a more complex thing conceptually to nest anonymous functions than to nest for loops. I may have done the lambda-example wrong, but there is much code out there, written in that style.

I think the beauty of functional programming is the testable and reusable aspects, among other things. Long, or even nested, lambda functions offer no improvement over old spaghetti code there.

All the code and performance
You can download my code and run it using any recent version of Node.js:

$ node functional-styles-1.js 1000

The argument (1000) is N, and if you double N execution time shall quadruple. I did some benchmarks and your results my vary depending on plenty of things. The below figures are just one run for N=3000, but nesting reduce clearly comes at a cost. As always, if what you do inside reduce is quite expensive the overhead is negligable. But using reduce (or any of the built in higher order functions) for the innermost and tightest loop is wasteful.

 834 ms  : imperative
874 ms  : custom_higher_order
890 ms  : recursive
896 ms  : imperative_alt
1015 ms  : reducer
1018 ms  : lambda_alt
1109 ms  : lambda

Other findings on this topic
Functional Programming Sucks


Fix broken Marshall Stanmore

First I want to be clear, this post is about fixing a broken Marshall Stanmore speaker by turning it into an active loudspeaker. It is not about repairing it to its original functionality.

My Marshall Stanmore died after about two years of little use. One day it simply did not turn on. Completely dead. It seems to be a common fate of those loudspeakers and there seems to be no easy fix. I opened up the loudspeaker and quite quickly decided that I would not be able to repair it.

I felt very certain that the loudspeaker elements themselves were not broken. The loudspeaker looks and sounds quite good and it is against my nature to just throw such a thing away. So I started looking for ways to make a working active loudspeaker of it (allowing to use it with an iPhone or as a computer speaker). Since I thought this was a fun project I was willing to put some time and effort into it. But a brand new Marshall Stanmore is 200 Euros so the fix had to be significantly cheaper than that.

2.1
The Stanmore is a 2.1-loudspeaker. It has two tweeters and one woofer. The cutoff frequency is 2500Hz meaning that the tweeters are responsible for higher than 2500Hz frequencies and the woofer for the lower frequencies. There are different ways to properly produce 2.1 audio from a 2.0 signal. If I remember correctly the tweeters are rated at 2x20W and the woofer at 40W. I don’t know the impendance (Ohm).

The thing not to do
It is not a good idea to just simply connect L+R and connect it to the woofer. Regardless whether you do this before or after the amplifier you will drive current into components that are only supposed to produce a signal and this can destroy your equipment (your smartphone or computer pre-amp, or your amplifier).

Cutoff filters
There are special cutoff filters to split a signal into a lower and a higher part. I looked into this first, but it seemed a bit to advanced (expensive and complicated) for my project, and the problem with mixing L+R remains.

2.1 Amplifiers
There are 2.1 amplifiers to buy. The problem is that they are designed for use with a subwoofer (very low frequencies), not our 2500Hz woofer. This may or may not be a problem.

Mono
If I had a mono amplifier (that accepts stereo input and produce mono output) I could connect all the three loudspeakers to the same output. Since the distance between the tweeters is less than 25cm I don’t think the lack of stereo-tweeters will matter. However, it was not very easy to find suitable mono amplifiers (or “bridged amplifiers” that can be used as a mono amplifier).

Two-trick-solution
In the end I decided to go for a simple solution based on two parts.

First, pre-amp, it is very easy to convert stereo to mono. The only thing needed is two resistors (470 Ohm, or something close to that).

Second, a 2.0 amplifier can drive the tweeters on one channel and the woofer on the other (that is 40W on each channel).

Cleaning out the Stanmore
I removed (unscrewed) the back of my Stanmore. When I was done with it, the only thing that remained (and in place) was:

  • The box itself (except the back of it).
  • The three loudspeaker elements, and as long cables as possible.
  • The top golden colored control panel (because removing it would not make anything pretty) and the board attached to it (because it was hard to remove).
  • The cable (black+white+red) from the 3.5mm connection on top of the loudspeaker.
  • The 4 red cables from the on/off-switch.

What I also needed
This is a list of other components I used

Assembly
I neatly connected everything in a way that it fits nicely inside the Stanmore.

  • DC-power to two red cables connected to Stanmore power switch
  • The other two red cable to Jtron board (make sure to no reverse!)
  • One Jtron channel connected to yellow+black of woofer
  • One Jtron channel connected to red/blue+black of tweeters
  • Black of 3.5mm connector to Jtron input (middle)
  • Red/white of 3.5mm connector connected via two 470 Ohm resistors
  • From between the resistors, connect to Jtron input (left and right)

This is what I got:

As you can see the Jtron is pretty small.

For now my laptop DC supply is outside the Stanmore and there is just a little hole in the back for the cable.

Operating
The power switch on top is operational and I connect my audio source to the 3.5mm connection on top. The Jtron knobs work as expected (there is no balance).

About the Jtron
The Jtron was very good price and I thought 2x50W was kind of optimal for me. Also, it is a digital amplifier with high power efficiency (little excess heat). There are obviously many other options.

Serial vs Parallell
I connected my tweeters in parallell. I suppose they could have been used in series instead. Perhaps serial would have been more safe: impendence would be 4x higher, which would be less demanding on the Jtron.

Review
Well, I shall not review my own work. To be honest I have not fixed a new back plane yet and I think not having it in place is far from optimal for audio quality. Despite that, the Stanmore sounds very decent. It plays loud enough for me (perhaps louder than before). You probably want to experiment with bass/treble until satisfied. The way I use it (with an iPhone) I will set preset volume to loud, and mostly use the iPhone to control volume.

What I have lost compared to the original Stanmore is RCA-input, bluetooth and volume/treble/bass on top of the unit. I can live with it.




Making use of Nokia N8 in 2019

I made a serious a attempt to make good use of my Nokia N8 in 2014 but I gave up on it and put it in a box. It now turned out I need a regular phone for answering incoming phone calls and I had kept my Nokia N8 in a box last years. Also good, I had flashed it with Belle Delight 6.4 before putting it in the box, so without any effort I had a clean and (well) up-to-date mobile.

After a few hours of charging I inserted a mini-SIM and turned my old friend on.

I replaced my Nokia N8 with a Sony mobile, but last years I have used a regular iPhone. This is what I now find:

  • The N8 is small (small display, narrow, short, light, but a little fat). The size is great in the hand, but the screen is small (especially for browsing and typing).
  • There is a sluggishness in the UI. I remember this was unfortunately true when i bought N8 and did not go away with the much needed, but too-little-too-late upgrades, upgrades that came with it (Anna, Belle).
  • The “Home Screen” as a separate UI from the folder based navigation is unfortunately a bit awkward compared to iOS (and home screen was also a too-little-too-late-feature of Symbian upgrades).
  • The web browser has outdated certificates and is basically useless. I suggest go to m.opera.com immediately, download and install Opera and use it exclusively. Opera is fine, but everything really feels tiny on the screen. Unfortunately I have some certificate problems with Opera as well.
  • Multitasking? Well, kind of, I managed to crash Opera, without being able to kill it. Had to restart mobile.

This is still the way I remember Symbian. It feels a bit like Win95 or MacOS 9 when you are used to Windows 2000 or MacOS X. It is not fast/snappy, not entirely stable and a bit awkward.

Still, the N8 could have been an amazing mobile even in 2019, if it had a good enough operating system and applications. That is never going to happen. I could dream or speculate, but whatever… life goes on.

Nevertheless, my Nokia N8 is back to real duty in my home and it may very well be for another 3-4 years. It feels a bit like a time machine and it brings me good memories. I will perhaps write more about it, and I would perhaps sell it to a genuine enthusiast, but I guess a perfectly fine N8 is easy to find.

Vue components in Angular

I have an application written in AngularJS (v1) that I keep adding things to. Nowadays I prefer to write new code for Vue.js rather than AngularJS but rewriting the entire AngularJS application is out of the question.

However, when the need shows up for a new Page (controller in AngularJS) it is quite simple to write a Vue-component instead.

The AngularJS-html looks like this:

<div ng-if="page.showVue" id="{{ page.getVueId() }}"></div>

You may not have exactly “page” but if you have an AngularJS-application you know how to do this.

Your parent Angular controller needs to initiate Vue.

page.showVue = true;
var vue      = null;
var vueid    = null;

page.getVueId = function() {
    if ( !vueid ) {
        vueid = 'my_vue_component_id';
        var vueload = {
            el: '#' + vueid,
            template : '<my_vue_component />',
            data : {}
        };
        $timeout(function() {
            vue = new Vue(vueload);
        });
    }
    return vueid;
};

At some point you may navigate away from this vue page and then you can run the code:

vue.$destroy();
page.showVue = false;
vue          = null;
vueid        = null;

The way everything works is that when Angular wants to “show Vue” it sets page.showVue=true. This in turn activates the div, which needs an ID. The call to page.getVueId() will generate a Vue component (once), but initiate it only after Angular has shown the parent div with the correct id (thanks to $timeout).

You may use a router or have several different Vue-pages in your Angular-application and you obviously need to adjust my code above for your purposes (so every id is unique, and every component is initatied once).

I suppose (but I have not tried) that it is perfectly fine to have several different Vue-components mounted on different places in your Angular application. But I think you are looking for trouble if you want Vue to use (be a parent for) Angular controllers or directives (as children).

Vue.js is small enough that this will come at a quite acceptable cost for your current Angular application and it allows you to write new pages or parts in Vue in an existing AngularJS application.

Webpack: the shortest tutorial

So, you have some JavaScript that requires other JavaScript using require, and you want to pack all the files into one. Install webpack:

$ npm install webpack webpack-cli

These are my files (a main file with two dependencies):

$ cat main.js 

var libAdd = require('./libAdd.js');
var libMult = require('./libMult.js');

console.log('1+2x2=' + libAdd.calc(1, libMult.calc(2,2)));


$ cat libAdd.js 

exports.calc = (a,b) => { return a + b; };


$ cat libMult.js 

exports.calc = (a,b) => { return a * b; };

To pack this

$ ./node_modules/webpack-cli/bin/cli.js --mode=none main.js
Hash: 639616969f77db2f336a
Version: webpack 4.26.0
Time: 180ms
Built at: 11/21/2018 7:22:44 PM
  Asset      Size  Chunks             Chunk Names
main.js  3.93 KiB       0  [emitted]  main
Entrypoint main = main.js
[0] ./main.js 141 bytes {0} [built]
[1] ./libAdd.js 45 bytes {0} [built]
[2] ./libMult.js 45 bytes {0} [built]

and I have my bundle in dist/main.js. This bundle works just like original main:

$ node main.js 
1+2x2=5
$ node dist/main.js 
1+2x2=5

That is all I need to know about Webpack!

Background
I like the old way of building web application: including every script with a src-tag. However, occationally I want to use code I dont write myself, and more and more often it comes in a format that I can not easily just include it with a src-tag. Webpack is a/the way to make it “just” a JavaScript file that I can do what I want with.

Linux Apps on Chromebook R13! Finally!

For a while I have owned an Acer R13 Chromebook that I occationally have used as a development computer. I have been using Crouton, which is quite ok, but it is like something is missing.

Lately there has been talks and writings about Crostini, Container technology on Chrome OS, which enables Linux applications to run in Chrome OS. This would be different from Crouton in different ways, like:

  1. The Chromebook does not need to start/run in unsafe developer mode.
  2. There is a Terminal App, instead of running Crosh in the browser

This is perhaps not huge, but it is a step closer to making Chrome OS more universally usable.

New features are added to Chrome OS on different times for different devices. Just now (according to this thread) “Linux” was added to the Development Channel for Acer R13. I can confirm it. I changed channels to Beta (R71) and got nothing. I then switched to Dev channel (R72) and now I finally have Linux (Beta).

I guess in a few weeks R72 will have made it to Stable. If everything seems fine I will probably switch back to Stable, disable Developer mode and never touch Crouton again.

The terminal gives me a standard Debian Stretch system. The terminal itself is very minimal. I am aware of these shortcuts:

  • Ctrl + : make text larger
  • Ctrl – : make text smaller
  • Ctrl Shift P : open preferences
  • Ctrl Shift N : open new terminal windows

Compared to the terminal application I am used to in Debian or macOS this is pretty basic (and the limitation of Chrome OS is that you cant just install another terminal application easily).

Unfortunately I tried to install something (the screen command) using apt-get, and something went wrong. apt-get does not finish and when I open another terminal it crashes. A restart of the computer fixid this though. However, when during more real work things crashed on me. So there is clearly a reason for this to be in Development rather than Beta or Stable today, but it is very promising and fun nevertheless.

A new MacMini! Finally!

After well over four years Apple upgraded the MacMini!

I have like most other people only read about it, and I may never own one. But I can have opinions (as I have had before) about it anyway!

First, it is clearly a fine machine. If you buy it, put it on your desk and make use of it, it will probably serve you well for many years.

I think it is a shame that the SSD is (as it seems when I write this) not a standard replacable M.2/PCI unit. It would be so easy, trivial, and cost nothing, to make it a user replacable part (just like the memory appears to be). To me, this is a reason not to buy it. A non-replacable SSD is worse than non replacable RAM.

Previously – especially the earlier version – MacMini has been quite limited. It has seemed Apple has not wanted it to compete with the MacPro or the iMac in any way. Now it is possible to equip a MacMini with i7 CPU, 64GB of RAM and a lot of SSD storage. I think Apple has accepted that professionals will get it for doing real work (I think Adobe-stuff and perhaps programming). That is somewhat an interesting shift.

However, the entry level MacMini costs twice as much as the entry level MacMini cost when it was the cheapest. Apple seems to have abandoned the idea of selling it to regular consumers on a limited budget or as a dedicated media machine. I think it is a pity. Also if it was $449 it would be less of a problem that the storage is not replacable.

The GPU is not really for gaming and I kind of keep wondering why Apple does not release a computer suitable for Steam and market it with “pro gamer approves it runs top 10 games at 1920×1080”. However, external GPUs are becoming a real thing and perhaps a quite standard MacMini, with external storage and an external GPU could be a reasonable machine for gaming. But I don’t regret buying my Hades Canyon for gaming.

A “cheap” Apple laptop still seems like the best option to stay in the Apple ecosystem but also the new MacBook Air is quite pricey (and how can they get rid of the mag-safe?). I owned my first Mac in 1993 and I am typing this on a MacBook Air 11, but it may be the last Apple computer I ever own.