The best kittens, technology, and video games blog in the world.

Saturday, February 24, 2018

Opal - Ruby on Javascript VM - What's still missing

Freya by CarlosDemarte from flickr (CC-NC-ND)

Javascript VMs are everywhere, and environments running them such as browsers and phones look likely to remain the dominant way for users to interact with software for very long time. This led to explosion of popularity of Javascript - the native language of that environment.

But Javascript is a dreadful language. It started a dirty hack, which just so happened to be positioned right and benefited from browsers becoming universal user interface. It can't even ever get properly fixed like let's say Python 1, due to unique backwards compatibility cost.

Fortunately just as you don't need to write Java to run on JVM, or write x86 assembly to run on x86 hardware, it should in principle be possible to run on Javascript VM without writing any Javascript.

So far it's been mostly "Javascript++" style languages like CoffeeScript, JSX, TypeScript, transpiling to older versions of JS and so on. It's not nothing, but all of them are trying to make Javascript at best barely tolerable.

So why not just write in a real language, and compile it to whatever Javascript VM wants?

Opal attempts to do just such a thing, letting you run Ruby in a browser. It's a somewhat different dialect of Ruby, most notably with immutable Strings, Symbol/String unifications, single numeric floating-point type, and a few other compromises to make it run better on Javascript VM, but it's mostly good enough.

Unfortunately I don't think it's ready for serious use just yet. Here's the top 10 things it's missing, in roughly the order of importance.

Out of the box sourcemaps

When an exception happens, the most important information is where it's coming from, and the second most important is the entire stack trace. Exception type and message are usually not terribly informative anyway. With Opal, you get none of that, just some pointer to compiled code which looks nothing like what you wrote.

It's sort of true that it's also a problem with CoffeeScript, or JSX, but with such languages you can usually figure out what's up from compiled Javascript with some practice. Opal to JS mapping is too big of a change, and lack of source maps makes debugging extremely tedious.

Opal absolutely needs sourcemaps, out of the box, in every environment. That's the single barrier to productive use.

Decent test framework

Opal has opal-rspec and it's just not good enough. It doesn't work with latest version, doesn't give any meaningful information why a test failed, doesn't have any mode other than "run all tests", and is weirdly slow on top of it all.

This isn't even all that surprising, as Javascript testing is decade behind Ruby, and sourcemap issue on top of that makes it even worse. It's a huge productivity killer.

binding.pry

One of best features of ruby is binding.pry. For that matter one of the best features of Javascript is debugger, which is basically less powerful version of binding.pry.

With Opal, you get none of that. You can use `debugger` and try to figure out things from compiled Javascript code, but that's not exactly a pleasant experience.

Support for Ruby regular expressions

Opal doesn't support Ruby regular expressions, just throws whatever you write onto JS regexp engine, and it's not even close to good enough. Even something is simple as /\A\d+\z/ will completely fail - and even worse it will fail quietly without raising an exception.

Of course you can write JS regexps, but then you lose any hope of sharing same codebase between regular Ruby and Opal Ruby.

As an absolute minimum it should raise a damn exception when it sees something it can't deal with.

Support for Time.parse

Another thing which turned out to be far more annoying than expected is dealing with timestamps. Ruby has Time.parse, which is pretty decent at handling most commonly used timestamp formats. Opal will instead happily use raw Javascript constructor, and quietly give you NaN timestamp object.

Like with previous point, the absolute minimum is to raise a damn exception here, but something resembling Ruby's Time.parse would go a long way towards making Opal useful.

pry-rescue

As followup to some previous points, something that lets you jump straight into pry on unhandled exception would be pretty damn good. Especially if it also worked in the test suite.

Precompilation of libraries for better start time

Ruby doesn't have separate compile phase - it just executes code on a fresh VM, and that code setups various methods and classes via metaprogramming. Then it runs the application itself.

That works fine on Ruby VM, but most environments perform really poorly in this mode. Startup time of Ruby on JVM with JRuby or Javascript VM with Opal is thus fairly bad.

This is probably the most difficult thing to do, but right now any Opal code using a medium-sized wrapper like opal-d3 will have a lot worse startup time than native javascript version.
Once it starts, overhead isn't too bad, but this really needs to be solved for production use.

Better interoperability with plain Javascript objects

This is another point about debugging, but let's say I get a Javascript object somewhere, and I want to figure out what the hell it is, or just dump it to the console. Currently it's going to crash with a helpful message telling me that Javascript objects don't implement inspect method. Well, true, but it's awful debugging experience, as realistically we'll be mixing Opal Ruby code with native Javascript libraries in most use cases.

A site like codepen.io

One of the nicest things about frontend coding is that it's possible to quickly code something in the browser, without going through all the hassle of setting up local environment, and share that with others. There's a lot of sites like codepen.io which help with this low-overhead quick coding.

Opal will definitely need a site like that, or be supported by one of them.

A Killer App

And finally we get to the usual "Killer App" point. I put it last intentionally - because unless most of the previous points are addressed, there's no killer app which could possibly work.

Saturday, February 17, 2018

Review of Star Trek: The Orville


It's usually not worth writing reviews of works with a lot of existing reviews. Either you agree with the consensus, and so provide very little information beyond what's already there, or you disagree, and the review probably says more about your taste than about the subject.

Lack of consensus

Not this time. There's no consensus at all. Critics absolutely hate The Orville:
While the audience loves it:
This is extremely unusual. Audiences and critics usually agree very closely.

Meanwhile, Star Trek: Discovery has far higher critics score:
and very mediocre audience score:

So what's the deal here?

It's simple, the critics are total idiots, and the audience is completely right. Star Trek: The Orville is awesome.

The review

The Orville is 90% classic Star Trek and 10% Family Guy. This combination is just too sophisticated for the stupid critics, but it works really well.

Star Trek was always a very optimistic and lighthearted world. Even its "dark" parts like DS9 would look like a comedy by standard of today's grimdark TV. Dark moments like In the Pale Moonlight were only so effective because they were used to sparingly against the backdrop of endless Ferengi get rich schemes, Odo and Quark's cat and mouse games, shenanigans by the station's kids, Kai Winn's pettiness, and so many other ways which made the future look so much brighter than world of today.

And it couldn't have worked any other way. Star Trek has to be bright for moral dilemmas to be engaging. If the whole world is a grimdark shithole, moral issues become irrelevant, and only survival matters.

The Orville continues doing what Star Trek was great at. Its universe, while technically not in Star Trek canon, is just like it - full of imperfect people still trying to be their best. They explore the universe, run into interesting aliens of the week, and seriously deal with new moral dilemmas just like in previous Star Trek series. It feels like it's actually doing a better job, with choices characters make having far more serious consequences, instead of being promptly forgotten by the next episode.

Sure, previous Star Trek series didn't employ Family Guy style humor, but 80s'/90s' sensibilities wouldn't work on today's TV, and this change is far less drastic than turning Star Trek into another grimdark series like everything else.

It's a must-watch for every Star Trek lover. It's still trying to perfect its formula, but it might very well end up as the best Star Trek series ever.

The bonus review of Star Trek: Discovery

To be fair, I only watched the first episode, but that should be quite telling as I watched every other Star Trek series and movies, many multiple times.

Discovery is simply not Star Trek. Maybe I'd have liked it if it didn't pretend to be one, but it's too late now.

It's just ridiculously grimdark. The characters, the antagonists, the plot, everything on the screen is just ridiculously dark. It hurts to even look at the screen. There's not one scene in the whole episode where the lights are properly on - it's all dark greys and blacks everywhere.

It's so ridiculously Not Star Trek that there's a damn mutiny in the first episode, by the first officer who wants to start a war with the "Klingons"!

As if that's not enough, for some reason it ditches Star Trek races - Discovery "Klingons" look and act nothing like Star Trek Klingons, there's a few Vulcans in the background, but they decided to ignore whole Star Trek Vulcan canon anyway, and there's some humans and some weird new types nobody cares for.

As far as I can tell - and maybe that changes later - it's doesn't even follow the crew ensemble formula, instead focusing hard on single character, who's a woman most annoyingly named Michael.

So why does it even call itself Star Trek? That sets up expectations it's completely unwilling to meet. Perhaps it could be a decent space show in its unique universe, instead it decided to steal the name and then do something completely unrelated with it.

There was nothing redeeming about the whole episode, and I doubt very much it gets any better later.

Just don't bother watching it.

Saturday, February 10, 2018

Let's Play XCOM: Enemy Unknown

It's time for another classic game - XCOM: Enemy Unknown!

The Long War mod would make it last about 200-300 episodes instead of more reasonable number like 40 or so, and let's be honest - there's no way in hell I'd be able to finish it. Even people with a lot more time than me left a lot of Long War let's plays incomplete.

I got a bunch of minor mods, two most interesting are:

  • Tweaking perk tree, and perk pool for training roulette. This mostly fixes Snipers by making Squadsight the first perk, and delaying Headshot until major-tier perk. It also makes Supports into reliable medics by removing medic skills from the pool.
  • Making alien line of sight a bit shorter to occasionally enable ambushes. This could probably be cheesed by the kind of people who like counting tiles, but I never felt like doing so.
The rest is largely UI. Playing on Classic difficulty, so there should be some challenge, especially since I probably forgot everything about the game by now.

The let's play is almost exclusively battles, with base management in between cut out, as you probably don't want to see me alt-tab to spreadsheet and wiki and counting how much power I need to build when and how many corpses I need to sell on grey market to get necessary space bucks for foundry upgrades.

Here's the first episode:



As usual, episodes coming out once a day, same time of the day, until we win or aliens do.

Monday, January 29, 2018

London cycle hire adventures

Lilith on bike seat by catmom42 from flickr (CC-NC-ND)
Today I felt like coming home with a cycle hire (commonly known as "Boris Bikes", officially now "Santanders Cycles" after a rebrand).

I went to a nearest dock, which the app claimed to be in perfectly fine order, and tried to get a bike. Error. Tried a few more times just in case, still error. I thought that's just app error, so I tried to use the terminal instead - which is really painful as it involves clicking same stupid confirmation dialogs about 25 times before it lets you rent the damn bike - but it was just as broken as the app.

Could the app somehow mark the dock as not working? Right...

So I walked to the next dock, that somehow wasn't broken, so I got a bike, cycled to Aldgate, and from there to the end of pompously named "Cycle Superhighway 2" at Stratford.

Stratford is a traffic hell, with no docks near the "Cycle Superhighway 2" or the station. The app claimed the nearest two docks had zero spaces left.

There was one about 10 minutes away from the station which claimed to have 4 free spaces. I went there - wasting tons of time going in circles because direct route is not possible anywhere near Stratford - and there was only one space, which didn't take the bike in spite of repeated attempts, for whichever reason. First it flashed red, then it just gave up.

After a lot of loud cursing, I had to cycle to the next dock, which fortunately somehow had free spaces, probably because it was really damn far from the station.

The cycling itself was fine, just everything else about the experience was totally miserable, and of course they charged me extra for wasting my time due to broken docking stations.

Which is pretty much what I learned to expect from the TfL. Unionized 💩💩💩.

I really hope some competition with dockless bikes comes to London. Right now none of these new schemes allow realistic commuting between Central London and zones 2/3, but there's some hope for the future.

Tuesday, January 23, 2018

Let's Play Civilization 5 as Rome

It's been a long while since I last recorded any Let's Plays, so here's a new one!

It turns out not everybody switched to Civilization 6, and in fact new mods for Civilization 5 keep coming out. This campaign features one of them - 5th Unique Component. Other mods just as before.

As Rome, our unique abilities are:

  • 25% faster production in other cities of every building which is already built in our capital
  • Ballista - unique Catapult replacement - slightly stronger
  • Legion - unique Swordsman replacement - slightly stronger, can build roads and forts
  • Forum - unique Market replacement - +10% Great Person
  • Thermae - unique Garden replacement - +1 Science, +1 Culture, +1 Food.
  • Aedes - unique Temple replacement - +1 Global Happiness, cheaper to build, costs no maintenance, and doesn't require a Shrine.
Overall these feel like mid-tier or a bit below abilities. Faster production scales with number of cities, and Aedes gives us a bit of happiness breathing room, so together they support a bit of expansion. Unique units come too early and are of wrong kind to have much impact, early wars are dominated by Composite Bowmen supported by Horsemen.

I'd definitely love to hear feedback, especially technical feedback - I'm recording at higher resolution, and I'm not totally sure if I set OBS correctly for it.


One video a day, full playlist going to be here.




Saturday, January 20, 2018

New Hash methods in Ruby 2.5 and hash-polyfill

The Cat by marcinlachowicz.com from flickr (CC-NC-ND)

Ruby 2.5 includes a bunch of new Hash methods:
  • Hash#slice
  • Hash#transform_keys
  • Hash#transform_keys!
The first two do exactly what you'd expect them - and the same ActiveSupport's methods with the same names do. In case of key conflict Hash#transform_keys will quietly overwrite keys, which is somewhat questionable behaviour, but it's not like there's obvious better way.

Unfortunately Hash#transform_keys! took some shortcuts, resulting in rather questionable behaviour. I submitted it as a bug report, and hope they fix it soon, but to be honest track record of my Open Source bug submissions is rather poor.

I'm really surprised Hash#compact wasn't included.

If you want to use these new methods in older Ruby versions, or if you want to use methods from future rubies like Hash#compact, Hash#select_values, Hash#select_keys etc., I updated hash-polyfill gem too.

I did not include Hash#transform_keys! in the gem as its unclear if it will have corrected or current questionable behaviour long term.