Saturday, November 21, 2020

Avoiding negative reviews with EULA abuse

Avoiding negative reviews with EULA abuse

After seeing some fun-looking gameplay videos of Passportout, I went to Steam to buy the game which had quite good reviews. First, though, I was invited to read the end-user license agreement (EULA), which said a few things that made me quite uncomfortable, but especially the following:

FLAMEBAIT GAMES RESERVES THE RIGHT TO ADD, MODIFY, OR DELETE/CANCEL THE GAME, INCLUDING YOUR ACCESS TO THE GAME AT ANY TIME.

So, after buying the game, they can “delete” it or disable my access at any time, for any reason. Why?

In consideration of the payment of any applicable fees and subject to your registering for an account and compliance with the terms contained herein, Flamebait Games or the platform/service provider will, upon receipt of your payment if applicable, provide you with a limited, non-exclusive, revocable license to access the Game and enable you to access and play the Game for your personal use subject to the other applicable provisions, limitations and restrictions in this End User License Agreement.

Seriously? So if I pay you, I don’t actually own a copy of the game – I get a revocable license to access it? Why?

It continues:

You may not upload or republish the Game or Game Content on any Internet, Intranet or Extranet sites or incorporate the information in any other database or compilation, and any other use of the Game or Game Content not expressly allowed under this Agreement is strictly prohibited.

This is worded extremely broadly, implying that you can’t even publish a screenshot of the game.

However, you may upload recordings of yourself playing the Game on channels like Twitch.com and YouTube.com etc, provided that such use is done in good taste and does not infringe on the intellectual property rights of Flamebait Games or reflect negative on Flamebait Games or the Game.

Basically the EULA forces you to agree not to upload or stream gameplay videos, unless it’s “in good taste” (whatever that means, seems totally subjective) and doesn’t reflect negatively on the game. In effect, the EULA prohibits you from using footage of yourself playing the game if you’re going to say anything critical about it.

That really is disgusting and unethical abuse of an EULA that most people almost certainly click through without fully reading. It’s likely unenforceable since it overly restricts freedom of expression and criticism, so it leaves me to wonder why they bothered. This is the kind of thing you might expect from Nintendo, not a small European game company.

Shame on you, Flamebait Games.

Sunday, June 17, 2018

Lazy evaluation and list random access in Haskell

Lazy evaluation and list random access in Haskell

Today I learned about the :sprint command in GHCi, which prints the value bound to given identifier without forcing its evaluation. The unevaluated part, if any, is printed as an underscore.

Here, we can see that the value bound to s is entirely unevaluated at first:

λ> s = "0123456789"
λ> :sprint s
s = _

Now let’s peek at the first character in the string:

λ> head s
'0'
λ> :sprint s
s = '0' : _

We can see that only the first character in the string (i.e. the first element of a list of characters) was evaluated. Now, let’s use the !! operator to print the fourth character in s:

λ> s !! 3
'3'
λ> :sprint s
s = '0' : '1' : '2' : '3' : _

Interesting – we can see that this caused all of the intervening elements to be consumed, which demonstrates that random access of a list with the !! operator must walk along the cons cells and therefore can be expected to require linear time to complete.

If we print the whole string, then :sprint shows the entire string with no unevaluated component:

λ> s
"0123456789"
λ> :sprint s
s = "0123456789"

Sunday, February 04, 2018

Controlling test execution in ExUnit

Controlling test execution in ExUnit

The Elixir programming language comes with a nice, simple testing library called ExUnit, and you can run all of your tests with mix test.

But sometimes you don’t want to run all your tests. Maybe you added integration tests or for whatever reason have a test that gives useful information but takes a long time to execute. In these situations, you can add the “skip” tag by adding an annotation before a test which shouldn’t be executed by mix test:

@tag :skip
test "should be skipped..." do
...

This way, a normal mix test run will be fast (and won’t break your continuous integration system), and when you want to actually run that test locally, you can:
mix test --include skip

However, this will run all tests marked skip. A more flexible approach is to add your own tag and use it to name your slow tests.

First, modify test/test_helper.exs to look like this, to prevent those tests from running by default:

ExUnit.start(exclude: :slow_test)

Next, annotate your slow tests with names:

  @tag slow_test: "backtest"
  test "Backtest should take ages" do
    ...
  end

  @tag slow_test: "optimiser"
  test "Optimiser should waste a lot of time" do
  ...
  end

Now mix test will still run your normal unit tests, and you can run one of the slow tests with mix test --trace --only slow_test:optimiser (the addition of the --trace option means ExUnit will let the test run as long as is necessary rather than killing it after 60 seconds).

Wednesday, August 30, 2017

Should we fine cyclists for breaking red lights?

(This was a comment I made in a discussion on Facebook that seemed worth saving. You be the judge.)

I don’t think cyclists should be fined for breaking red lights unless they clearly and avoidably place other people at risk, because it discourages casual cyclists and drives them back to… driving, which is of course much more likely to cause death and injury to others.

But if we insist upon it, then the fine should be proportional to the amount of damage you’re likely to do if you hit someone – this is based on many factors, so probably the most reasonable approach is a fine proportional to kinetic energy, which is the mass of vehicle and rider times the square of their speed.

Let’s do a worked example:

  • 80kg rider + 15kg bike + 5kg gear, travelling at 25km/h (just under 7 m/s)

    • = 0.5 * 100 * (6.944…)^2 = 2,411 joules
  • 80kg driver + 1180kg car (2017 Volkswagen Golf, 1.4L manual), travelling at 30km/h (city centre speed limits, just over 8 m/s)

    • = 0.5 * 1260 * (8.3…)^2 = 43,750 joules
  • 80kg driver + 3365kg van (2012 Ford Transit, 2.0L diesel), travelling at 50km/h

    • = 0.5 * 3445 * (13.8…)^2 = 332,272 joules.

So if we charged people 1 cent per joule of kinetic energy involved in these infractions, it would cost a cyclist €24.11 to break a red light, or €437.50 for a driver of a Golf doing 30, or €3322.72 for a driver of a Transit doing 50.

Or maybe we could acknowledge the fact that cyclists pose so little threat to life compared to cars and vans that we should stop discouraging them from cycling and stop focusing so much effort on blaming them for being “a menace” given that cars travelling at even low speeds carry 20 times as much kinetic energy, take more space, cause more pollution, cause more health problems, damage more bridges and lampposts, and of course cause almost all road deaths.

With this in mind, why are we even having articles in newspapers or radio discussions about the dangers posed by cyclists? Why aren’t our papers and radio discussions filled with appeals to the public to get on their bikes?

Thursday, March 19, 2015

(Linux/Ubuntu) Frequent 802.11g/WPA2 connection drops with brcmsmac/BCM4313 driver

My Samsung laptop running Ubuntu 14.10 has been dropping its WiFi connection a lot. A cursory examination of the system log reveals that it usually happens once every 20-40 minutes, with a few suspicious cases where it dropped and re-established the connection after exactly 25 minutes:
$ grep "wlan0: associated" /var/log/syslog.1
Mar 17 20:45:48 gravitycat kernel: [101379.946156] wlan0: associated
Mar 17 21:10:48 gravitycat kernel: [102880.685412] wlan0: associated
Mar 17 21:33:32 gravitycat kernel: [104244.524634] wlan0: associated
Mar 17 21:43:03 gravitycat kernel: [104815.501396] wlan0: associated
Mar 17 22:08:03 gravitycat kernel: [106316.384463] wlan0: associated
Mar 17 22:11:23 gravitycat kernel: [   35.255877] wlan0: associated
Mar 17 22:46:55 gravitycat kernel: [ 2167.317562] wlan0: associated
[...]
Mar 17 23:29:08 gravitycat kernel: [ 4701.239455] wlan0: associated
Mar 17 23:54:08 gravitycat kernel: [ 6201.802957] wlan0: associated
[...]
Mar 18 00:00:26 gravitycat kernel: [ 6579.424244] wlan0: associated
Mar 18 00:25:26 gravitycat kernel: [ 8080.034656] wlan0: associated

The connection drops usually looked like this:
Mar 17 22:08:03 gravitycat NetworkManager[785]:  Connection disconnected (reason -4)

But were sometimes preceded by this:
Mar 18 01:09:43 gravitycat kernel: [10736.798220] wlan0: cannot understand ECSA IE operating class 33, disconnecting

It alternates between "class 33" and "class 12". After a tiny bit of digging, I found a suggestion here to try switching from Gnome's NetworkManager to WICD. At first, that seemed to make things better, but it started happening again after about an hour, with the same really frustrating behaviour (having to repeatedly queue the same videos on my Chromecast when it sees me "leave" due to the laptop dropping and reconnecting to the router).

Next port of call is to check the driver. Here's what lspci says is installed in my laptop:
$ lspci -vvnn | grep -A 9 Network 
03:00.0 Network controller [0280]: Broadcom Corporation BCM4313 802.11bgn Wireless Network Adapter [14e4:4727] (rev 01)
 Subsystem: Askey Computer Corp. Device [144f:7179]

For this device, Ubuntu defaults to the "brcmsmac" open source driver, which is always preferable to a closed-source proprietary driver, all other things being equal. This issue is so frustrating, however, that I'll take the closed-source "bcmwl" driver if it works, following these steps:
$ sudo apt-get install bcmwl-kernel-source
$ sudo modprobe -r brcmsmac bcma
$ sudo modprobe wl

After manually reconnecting with WICD, things seem stable and the ChromeCast hasn't bailed over the past day or so. It's a shame the open source driver isn't working well with the BCM4313 chipset. It'd be nice if there was a simple way to get started debugging/testing the driver – i.e. not having to download a massive tarball of the latest kernel source and spend hours tweaking with build scripts and the like. Unless things have changed in the last few years and now this is easy...?

Monday, February 09, 2015

OpenCV 2.4.10 and Macports

Every time I've needed to build OpenCV on my work Mac, it's been a bit of a struggle. I have Macports installed which helps make some things easier, but throws up problems of its own:
(using "mp-gcc49")
/Users/oisin/Documents/code/vision/opencv-2.4.10/modules/highgui/src/window_cocoa.mm: In function 'void cvDestroyAllWindows()':
/Users/oisin/Documents/code/vision/opencv-2.4.10/modules/highgui/src/window_cocoa.mm:202:23: error: expected ';' before 'in'
     for(NSString *key in list) {

(using "apple-gcc42")
/System/Library/Frameworks/QTKit.framework/Headers/QTMovieModernizer.h:123:46: error: expected ')' before '(' token
- (void)modernizeWithCompletionHandler:(void (^)(void))handler AVAILABLE_QTKIT_VERSION_7_7_3_AND_LATER;
                                          ^
/System/Library/Frameworks/QTKit.framework/Headers/QTMovieModernizer.h:123:46: error: expected identifier before '(' token

The problem appears to be Objective-C stuff in QTKit and in OpenCV's HighGUI code. This time, the solution was to revert to the system-default C/C++ compiler, Clang:
$ sudo port select gcc none
Warning: port definitions are more than two weeks old, consider updating them by running 'port selfupdate'.
Selecting 'none' for 'gcc' succeeded. 'none' is now active.

It's slightly counterintuitive that "port select gcc none" is how you go back to the system compiler with Macports, and it doesn't appear to be stated in the docs, so... well here it is!

Sunday, July 27, 2014

A tiny line-editing trick for Bash (or any REPL using Readline/emacs bindings)

A lot of shells (e.g. Bash) and interactive console programs (e.g. mysql, sqlite, ghci, irb) provide a line-editing interface based on Emacs bindings, either via the Readline library or similar.

These key bindings mostly take the form of ESC-<key> which is either an uncomfortable stretch or (on a full-size keyboard) takes your left hand away from the home row and slows you down. Here's a handy tip though: pressing Ctrl+[ is equivalent to hitting escape, but allows you to keep your hands on the keyboard's home row. And if you're lucky, you can hold the Alt key instead (so you can jump backwards with Alt-b and delete the next word with Alt-d — this works on Gnome Terminal for me at least, except where the key is one of the menu accelerator characters (f, e, v, s, t or h). Seriously though, until today I was hitting ESC then the desired key...

Thursday, September 26, 2013

Ralink RF3070 USB wireless support finally added to Linux

For a long time, these cheap Chinese USB wifi adapters didn't work in Linux. Believe it or not, I wiped my old laptop's Linux partition and tried FreeBSD and OpenBSD just to see if they supported it - but they didn't either.
So I reinstalled Linux and eventually produced a patch back in June to add support for the device, but for whatever reason it was ignored.

Now, though, one of the maintainers has implemented a proper patch and it looks like the RF3070 will soon work out-of-box in Linux.

Yay!

Monday, May 13, 2013

OpenCV build: "Could NOT find JNI" (Ubuntu)

While trying to build OpenCV so I could use the new Java bindings, I kept getting this somewhat confusing message:
Could NOT find JNI (missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY)

What does it mean - did I need to set environment variables for the AWT and JVM libraries? Surely they're both already installed. What does it even mean to say "Could NOT find JNI", since JNI is a part of Java which is installed?

Turns out I needed to manually set the JAVA_HOME environment variable:
export JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-amd64
Why Ubuntu doesn't automatically set this when you install the openjdk7 package, I have no idea.

Sunday, February 24, 2013

Eye queue

This comment by "Cabochon1360" on one of David Mitchell's Youtube videos struck me today (far more than the video), and sums up my own feelings better than I could have.
In my teens, I was proud of my allegedly high IQ. But decades of failures and other humbling experiences have shown me it's just one personal characteristic, and not the most important one.
Another thing to bear in mind is that telling your kids they did well on a test because they're smart hinders their future performance. Perhaps counter-intuitive but it's been demonstrated in a number of studies (even when performed on adults, AFAIK).

Friday, July 20, 2012

What did I miss about modern Linux?

After running Windows alone for a couple of years, I had to install a Linux distro yesterday since the CUDA API in Windows is pretty ridiculous, flat out refusing to work with MinGW (the Windows port of gcc/g++ and pals).

Although I wasted a lot of time trying to get my dumb Medion PC (MS-7358 mainboard) to boot from two different USB keys, eventually a blank CD turned up and Ubuntu 12.04 landed on it. The install was quick, and this time (unlike on the old Acer laptop my kid uses) the Nvidia card was supported better, giving a usable display.

I needed to install some tools first before getting the CUDA API/SDK/drivers on Ubuntu:
The following NEW packages will be installed:
  build-essential dpkg-dev freeglut3-dev g++ g++-4.6 libalgorithm-diff-perl
  libalgorithm-diff-xs-perl libalgorithm-merge-perl libdpkg-perl libdrm-dev
  libgl1-mesa-dev libglu1-mesa-dev libice-dev libkms1 libpthread-stubs0
  libpthread-stubs0-dev libsm-dev libstdc++6-4.6-dev libtimedate-perl
  libx11-dev libx11-doc libxau-dev libxcb1-dev libxdmcp-dev libxext-dev
  libxi-dev libxmu-dev libxmu-headers libxt-dev mesa-common-dev
  x11proto-core-dev x11proto-input-dev x11proto-kb-dev x11proto-xext-dev
  xorg-sgml-doctools xtrans-dev
0 upgraded, 36 newly installed, 0 to remove and 0 not upgraded.
Need to get 15.3 MB of archives.
...
Fetched 15.3 MB in 3s (3,835 kB/s)
...
Setting up build-essential (11.5ubuntu2) ...
Processing triggers for libc-bin ...
ldconfig deferred processing now taking place
$
Now I really wish I'd prefixed this with the "time" command, because it took far less than a minute - maybe 15 to 30 seconds to install all of this... the C++ compiler, X11 libraries and a bunch of other stuff.

In contrast, it took a good 5 minutes just to install Visual Studio 2010 on my Windows 7 laptop (a 64-bit box with a better CPU than this desktop) and the library problems cost me a couple of hours of headbanging which was never resolved.

There are still serious driver problems in Linux, but the whole experience has improved so much since I started with a Red Hat install back in 1998.
Being able to install any number of programs and libraries rapidly, with a single command, is so much more relaxing than trying to hack things together in Windows. Try it!

Sunday, June 17, 2012

Terrorist postcards

(from BBC news)
It has been dubbed a "snooper's charter" by civil liberties groups but the Home Office says new powers are needed to keep pace with how criminals and terrorists are using new technology.
Postcards are new technology now? It hardly seems like the most secure and timely way to communicate, though, does it?

Do they really think they can catch terrorists and other criminals by reading people's postcards - or are they just a pack of nosy bastards?

Wednesday, May 30, 2012

Simple Heuristics that Make Windows Dumb

C:\U\O\Documents\c\...\src> .\patch.exe --help
Access is denied.

C:\U\O\Documents\c\...\src> ren patch.exe piss.exe

C:\U\O\Documents\c\...\src> .\piss.exe --help
Usage: .\piss.exe [OPTION]... [ORIGFILE [PATCHFILE]]

...Fuck you very much, Windows.

Tuesday, April 17, 2012

Gluap: not-really-useful-yet PushGP in Lua

After abandoning this for a while, I decided to update my pet project Gluap, a PushGP-based genetic programming library for Lua. While I was at it, I opened a Github account and uploaded the project to a new repo. If you like, try it out, figure out why it's not performing well and improve it! :)

Friday, March 09, 2012

(Recursive) Confirmation bias

Ever heard of confirmation bias?

The worst thing? Being aware of the effect actually increases your susceptibility to it, rather than decreasing it. No need to thank me.

But does awareness of that fact reduce susceptibility? And if so, and you know it, does that itself---
--- ERROR: STACK OVERFLOW

Friday, February 24, 2012

Ever wanted to use the Unix "which" command on Windows?

The which Unix command takes a program name as an argument, and gives you the first matching directory on your path which contains that program. This is useful if, for example, you're trying to uninstall or upgrade software and are trying to figure out why you can still call the program after you thought it'd been deleted.

Unfortunately, there doesn't seem to be any kind of related command for DOS. Happily, a user named Mechanix2Go posted a hackish version which you can save as a batch file. I've made a couple of minor tweaks, to suppress file not found errors and fix the frankly idiotic treatment by DOS of the PATH variable as a set of tokens delimited by spaces. Some horrible hackery was taken from here to partially work around the problem. It will still fall over on weird paths with a ';' in them, and it'll echo double quotes.
Trying to express yourself in DOS batch language is like trying to compose a symphony using only two piano strings.

@echo off & setLocal EnableDelayedExpansion

if %1'==' goto :eof

for %%a in ("%path:;=";"%") do (
  dir /b %%a 2>&1 | findstr /i /b /c:"%1.exe" /c:"%1.bat" /c:"%1.com" > nul
  if not errorlevel 1 echo %1 is in %%~a && goto :eof
)

Tuesday, February 21, 2012

Reporting on reports about bad reports: SMS vs Web messaging

(source: BBC News)
Social messaging applications cost mobile network operators $13.9bn (£8.8bn) in lost SMS revenue last year, a report has claimed.
[...]
However, the study did not factor in the extra income networks received from mobile data costs because of increased internet usage resulting from social messaging.
...Then why are you even writing about it? Damnit BBC.

That's like saying "Clondalkin cost Dublin Bus $13.9bn in lost revenue on the 51B bus route last year, a report has claimed. The study did not factor in the extra income received from the 51C bus route which completely replaced the 51B route."
If they lost money on one service because everyone started using a different service that THEY ALSO PROVIDE, then you have to account for that before reporting that they lost money. Sure, sending one message via a phone's internet connection is probably much cheaper than sending an SMS, but without accounting for how much money they've been making from the increased internet usage - in general, not just for sending messages outside of SMS - it's meaningless for people to say things like this:
"I think it's a growing threat which is manageable through the right tariffs and the right costing," Mr Barford added.
Hardly a threat, if they're raking in money from all the data plans people are signing up to nowadays.

Tuesday, November 15, 2011

Google gets cabbage fronds both ways.

To follow up on an oldish post on the patchy quality of Google Translate, I tried the examples and found that they now translate very well.


Even doing a lengthy trip between very different languages produces quite good results, which is a good sign that the meaning behind text is being properly treated:

English "I like to eat cabbage fronds all day long." -> Japanese "私は長い一日キャベツの葉を食べるのが好き。"
Japanese  -> French "J'aime manger les feuilles de chou toute la journée."
French  -> Kannada "ನಾನು ಎಲೆಕೋಸು ಎಲ್ಲಾ ದಿನ ಎಲೆಗಳನ್ನು ತಿನ್ನಲು ಪ್ರೀತಿ."
Kannada  -> Hindi "मैं सारा दिन गोभी के पत्ते खाने से प्यार है."
Hindi  -> Irish "Is breá liom a ithe na duilleoga cabáiste an lá ar fad."
Irish  -> Korean "하루 종일 배추의 잎을 먹는 사랑 해요."
Korean  -> Polish "Uwielbiam jeść liście kapusty cały dzień."
Polish  -> Welsh "Rwyf wrth fy modd i fwyta'r dail bresych drwy'r dydd."
Welsh  -> English "I love to eat the leaves of cabbage all day."

So our 9-step purple monkey dishwasher train converted "I like to eat cabbage fronds all day long" into "I love to eat the leaves of cabbage all day".

There were a couple of languages (Arabic, Gujarati, Chinese) which mangled or lost some of the information (e.g. "cabbage fronds" into "cabbage" or "all day" into "every day"), but this is pretty impressive, and a tangible improvement in a relatively short time. Good work, lads!

Tuesday, October 18, 2011

Nonsmooth justice: the discontinuous mapping of crimes to sentences

From BBC news:
Jordan Blackshaw, 21, of Northwich, Cheshire, jailed for four years after admitting encouraging a riot on Facebook, which never happened
For comparison, if you were driving at 3 times the speed limit on the wrong side of the road, and you knocked someone down and left them in a braindead coma forever, the maximum sentence you could receive in the UK is 5 years. Until very recently it was 2 years.

This is somehow on a par with "encouraging a riot on Facebook, which never happened" which gained at least two people a 4 year sentence each.
Are you having a laugh? Because I'm not.

The situation is similar to that of a schoolteacher in the US who was sentenced to 200 years (!!) in prison without the possibility of parole, for possession of 20 images of child porn. Sure, collecting child porn is not a particularly nice thing to do, but again, there are murderers who will be sentenced and get out of jail before his sentence is finished. There are people who physically abuse, torture or actually kill children who could get out before him. Doesn't make much sense, does it?

Saturday, September 10, 2011

Google Translate's voice input: phones only?

So apparently Google Translate takes voice input now - although it seems you need Chrome if you're not doing it on an Android or iPhone. The privacy issue of Chrome being able to record from your microphone without your consent is... interesting.

If you do it on a PC*, it only allows you to give voice input in English. But if you do it via the iPhone/Android apps - even though they seem to use HTML5 anyway - you can give input in 15 different languages.

Google, hello? People use laptops and desktops as well - why are they restricted to English-only voice input? I couldn't find an answer to this, or a timeline for when the other languages will be available in the "vanilla" Google Translate.


* Is there a good and concise term for "non-smartphone computer"?