Bad Data

Thoughts on game design

Wed Jul 7 10:18:50 2021


To be a good game, you need decisions. These need to be real decisions, not illusory decisions. An illusory decision can be of two types:

Thus, in tic-tac-toe, as any child quickly discovers, the choice of which square to mark is illusory, as each square either leads to a loss or a tie, and there's no particular reason to prefer one tie-square over another.

Wide or tall?

Quantity or quality?

Some games give a choice between going "wide", that is, a large expansion, or "tall", that is, a small expansion, but make what you have better.

In wargames, this is known as quantity or quality, lots of crappy units, or fewer better units.

It's hard to get the balance here right. Most space type 4X games don't really allow for a "tall" strategy, because there's a limit to how good a planet can get, and you eventually need to grow bigger, not just better.

Another problem with high quality is that in many games, the number of units is so few, that you can't afford to lose any of them at all.

Posted in / games

Big Sur Setup

Sat Mar 20 23:59:57 2021

I just picked up a 13 inch M1 macbook pro. Blogging what I had to do to make it sane.

Case sensitive file system for my home directory

I used disk utility to create a new apfs partition that was case sensitive.

Then vifs to add the following to /etc/fstab

UUID=7B0BF555-DE9E-406A-A3E4-A514B20D31BB /System/Volumes/Data/home apfs auto 0 2

from there, a reboot into recovery mode to move the existing home directory out of the way and rsync the new one

in /Users the home directory should be symlinked to /System/Volumes/Data/home/dir/

I did this from recovery mode, where it's then under something else.


I copied my private and public ssh key from my main server. Then ssh-add worked to install the key or password there to into the mac os keychain.

System Preferences

The clowns at mac think that the wrong direction is "natural" for scrolling, so in the trackpad I changed the scroll direction.

I like the dock on the left, so I changed that in the Dock and menu bar. I also set the dock to autohide, because then it's not in the way.

Display set to scaled/more space. Theme set to dark.


The default terminal has rounded corners. In fact everything does.

In the terminal preferences, I changed the default profile to "Pro", and set the window size to 80x35. Under the "Shell" I changed the window to close when the shell exits.

The default background color is set to 85% opacity, so change that to 100%.

The font defaults to Monaco at 10 point, which is too small for me, so I changed that to SF Mono at 18 point. That sounds huge, but with the screen scaled to more space, it's about right.

Set the shell to close the tab or window when it exits.


Ugh. So, use Safari to download and install firefox. Then, find your old profile on your old machine and tar it up. It should be in ~/Library/Application Support/Firefox/Profiles

Copy it to your new machine in the same directory path and untar it.

I kept firefox closed while doing this.

Firefox won't find the new directory, because it wants to use a .ini file instead of reading the directory. So edit Library/Application Support/Firefox/profiles.ini to make firefox aware of your new directory. You'll probably need to rename it in the ini file as well.

Then start firefox and go to about:profiles. From there you can set your old one as the default. Then quit and restart. Clicking on the 'Restart Normally' button didn't work.

In System Preferences / General, change the default web browser to Firefox


Adium hasn't been re-compiled for the M1 processor, and needs Rosetta. Adium also doesn't scroll down automatically.

XCode and MacPorts

xcode will be needed for macports

xcode-select --install

ports to install


FontBook appears to install the extra fonts in /System/Library/AssetsV2/com_apple_MobileAsset_Font6 where they can't be found. Copy them from there to ~/Library/Fonts

Turn off Emojis

Under the keyboard of system preferences, set the emoji/function key to do nothing.

Posted in / hardware

Set and bag operations in shell

Tue Nov 17 14:41:29 2020

Peter Krumins has a blog post about set operations in the unix shell which has some issues.

  1. Many of his operations are bash specific, and so I wouldn't call them for the "unix" shell, but rather the bash shell.
  2. For the most part, they aren't set operations at all, but rather bag operations.
  3. There is a join(1) command which can simplify some of these.

But the items are good for what they are. Following is my take on these.

First some definitions and specifications.

Set Membership

This is a simple grep against a fixed string.

grep -Fxq e A

Set Equality

This is more difficult, because the set files may not be sorted, and we want to avoid intermediate files. We can use join here to output non-matching lines.

expr "$(join -v1 -v2 A B | head -n1 | wc -l)" = 1 > /dev/null

Ok, that's hideous. I am not aware of any unix command that will return by exit value if it's input is empty.

Merely outputing the wc -l won't give an exit value, so by itself that's not sufficient to meet the above specs.

So, here's a better version:

join -v1 -v2 A B | head -n1 | (read x && test -n "$x")

At least a little better anyway, as it's a pure pipeline, albeit with a subshell. The subshell isn't strictly needed, but it avoids polluting the calling shells namespace.

From here on out the snippets will assume that you have the read and test in a shell function or program named 'nonempty', which returns true if its stdin consists of at least one line.

Similarly the snippets will assume that you have an 'empty' program which is the opposite.

And both of those will only need to read at most one line, so a preceeding head -n1 isn't needed.

Set Cardinality

The cardinality of a (finite) set is just the number of elements. Unlike the above, this produces a result, so we don't have to do stupid tricks with expr to get an exit status.

wc -l A | cut -d ' ' -f1

Ok, that's still dumb, because there isn't any way to tell wc to not say the name of the file, if it reads from a file rather than stdin. So you can do

wc -l < A

But the redirect has a certain goofiness of it's own.

We can let awk do the work.

awk 'END { print NR }' A

I think that's posix. It's going to be generally true that "let awk handle it" will solve these issues. I'm not sure that's a shell solution though, and I'd have to retitle this post as set operations in awk, which isn't nearly as cool.


Here we're testing if A is a subset of B

join -v1 A B | empty

Here the join will output the elements in A that didn't have a match. If that's empty, then it's a subset. Note that this is not necessarily a proper subset, as the sets could be equal.


Since sets can't have any duplicate elements, we just sort -u

sort -u A B


The join command makes this trivial.

join A B


The elements of A that are not in B

join -v1 A B

Symmetric Difference

Elements that are in A or B but not both

join -v1 -v2 A B

Power Set

A power set is a 'set of sets', specifically the set of all subsets of a set. We don't really have any way to represent arbitrarily nested sets. Since we don't need to parse them, just generate them, I'll put them as the elements separated by spaces on a single line.

If we assign a bit to each element of the starting set, then the power set is the set of all N bit numbers, with the subset elements corresponding to the set bits.

a b c = three elements.

so it has subsets:

000 = {}
001 = {c}
010 = {b}
011 = {b,c}


and then the power set is just the set of all of those sets.

{ {}, {a}. {b}. {c}, {a, b} ... }

So, I can output the power set by getting the count, computing 2^count, then doing some ridiculous bit bashing.

And for even as little as 32 elements, the powerset will have 4 billion elements.

The obvious conclusion is "don't do this in shell".

Posted in / software

Thoughts on 1862

Mon Dec 30 21:45:28 2019

We've played a lot of 1830, and some 1846. While those games have some differences, they basically play the same.

We recently picked up 1862 and it plays a lot differently.

Specifically, the way companies count their revenue from train runs is completely different. In 1830 trains each count their runs separately, and you can't reuse track at all. In 1862, you can reuse track with different trains, but you can only score each station, port, or off-board area once for your whole company, and each of your runs has to link up into a connected network.

This means that with multiple trains, you will necessarily be hitting a large station more than once, but you can only count it once. Rather than thinking of it as scoring trains, it makes more sense to think of it as building a network with your trains, and then counting where you hit with your network.

To evaluate a train then, don't think about how the train can run, but rather how it can extend your network. Long runs of track are rewarded if you have multiple trains, and maximizing the advantages of each type of train in a multiple permit company will lead to higher runs.

Merger Cost

Other than a few edge cases, you will always lose value on a merger. For "normal" mergers, the loss in value will be about one-third.

Take a merger of two companies, where you own 5 shares of one valued at 82 and 7 shares of another valued at 110. In this case you lose 342 in share value, a 31% loss. It may be that 60% of the combined revenue is worth more, and it will be easier to multiple jump to regain the share value, but you still have a 342 loss to overcome. It may have been better to sell a higher valued share and buy two lower valued shares.

If you did that, and then immediately merged at the beginning of the next stock round, you'd pay a net of 54, and then merge 7 shares at 82 with 6 shares at 105, which would entail a loss of 308. Plus the 54 paid out, is a loss of 362, or $20 more than the previous case. You'd also have to shell out $64 to redeem an option share, for a final loss in value of $426.

Posted in / games

Scripted Opponent for 18xx games

Wed Jul 18 12:24:42 2018

Basic thoughts:

Stock Purchases

  1. Attempt to obtain five shares in companies where the player is the president.
  2. Maximize dividend payout
  3. Start a company, par price sufficient to buy five shares. Otherwise don't start.

First stock round: start a company if it can buy five shares. If not, buy the most number of shares? Diversify? One of each?

What company to start? Preference defined by game? Minors?

Minors: buy cheapest offered minor. take random card?

What company to start?

Running companies

Company money target: two tile lays, plus one token, plus second cheapest available train. plus cost of minors?

Issue shares: always issue if possible? Issue if would hit company money target?

Purchase minors: always purchase if possible? Purchase if run increases? Purchase if will still hit money target? Money target minus train?

Lay track and tokens: always play to maximize revenue.

Then, shareholder input for additional tile lay. Need at least two shares, greatest number of shares wins, can't go below money target, ties for greatest broken by how many of the players companies shares are owned by the opponent. If still tied, no additional tile.

Once revenue can't be increased further, extend a run. Take shareholder input, if any. Where track lay costs money, don't go below a token or train.

Pay or keep: attempt to have enough money for the next train, and a token. Would withholding be the difference between buying the next train or not? If yes, withhold, if not, pay.

Buy trains: opponent will never sell trains. Buy a train if it would increase the run. Buy the train that increases the run the most, (on existing track?) Buy a permanent train.

Posted in / games

On Property Taxes

Fri Jun 1 00:00:00 2018

Real Property taxes are the only tax that doesn't require that the government be nosy. It is necessary for the government to know who owns property (and I mean real property here, rather than personal property) in order to resolve disputes.

If I claim I own your house, to resolve the dispute, the court will need to have a definitive record, or be able to get one easily, as to who owns the house. Since ownership is what determines whether an access is lawful or trespass, these sorts of disputes will depend on the court knowing who owns the property.

This is also true of personal property of course, but these don't need a central registry as much, since personal property is movable.

A tax on property just requires a central registry of property ownership, which we already have, and a collection mechanism, which we also already have. The government only needs to know what the tax parcels are, and how much each is taxed. The government does not need to know who paid the tax, where the money came from, or anything else. All the government needs to do is know what the tax parcels are and whether the tax was paid.

In principle, the government doesn't even need to know who owns a given tax parcel unless there's a dispute, but there are other advantages to a central ownership registry, and I would expect that keeping the tax authorities from accessing it would be impossible in any case.

Title on real estate is fundamentally based on force. You have title to your property because you can defend it. Defending it personally is both difficult and inefficient, so people band together to defend each others property. Why should I respect your claim on real estate? One reason is that you will respect mine, another, and stronger reason is that you will help me defend mine.

Like many things in modern life, we have replaced the personal obligation with a money obligation. Contracts aren't generally enforced by requiring specific performance, rather we merely assess a monetary penalty. In medieval times, the personal requirement of a landholder to show up and bring a particular amount of men was gradually replaced with scutage, a money payment to avoid personal service. The superior lord would then use this money to hire men as needed.

A tax on property is simply a replacement for a requirement to show up personally, and as it turns out, a much more efficient way to do things. This assumes that you have an obligation in the first place. One might reject that obligation, but then why should I, or anyone else, respect or defend your title? In other words, suppose I acceed to your notion, and agree that you have no obligations. Why then should I not, alone or in concert with others, simply take by conquest your land? Your objections that I "shouldn't do that", or "I have no right to", have no meaning. All titles eventually root in "by right of conquest", and while there is somethign to be said for sanctifying a chain of title by time, there isn't some magical period after which acquiring title by right of conquest is not legitimate. There will of course be a period wherein there are two claimants to a land title, but eventually the one not in possession will fade away.

I am not personally strong enough to defend my property against all comers, but I am willing to band with others, and defend their titles if they will defend mine. I will accept an obligation to act in that defense. So, how might I meet my obligation? It could be met personally, but, again, the modern way is to meet it with a money payment.

A money payment will have to be paid in some manner, and it will have to be apportioned somehow. Since the money payment is ultimately, for the defense of property, making the payment be proportional to the amount of property to be defended is reasonable. How then do we assess the "amount of property"? Any number of ways are possible, but we live in an age where money is available and land is alienable, so a simple measurement of what would the property sell for, in the usual imaginary arms-length transaction between a willing seller and willing buyer.

Some specific suggestions as to how to assess property. Someone will need to put an actual dollar figure on property. This can be done in several ways, which fall into three categories: the government assigns a value, the property owner assigns a value, or a third party assigns a value. A third party here is a party not connected to either the owner or the government. A professional assessor hired by the government is not a third party for this purpose.

In some sense, the value assigned is meaningless. If a government wants to raise (say) one million dollars in taxes, and the tax base is assessed at a total of one hundred million, the government simply sets the tax rate at one percent. If the government wanted two million, it can simply set the tax rate at two percent. So, by itself, an assigned value has no connection to reality, rather it serves to apportion the tax among the taxpayers. It would be the exact same result if the government assigned points to property and taxed a hundred dollars per point. This could even easily be a workable system, with a point schedule. One point per bedroom, one point per bathroom above one, one point per garage stall, one point per full quarter acre. A point system would probably be more sophisticated, but would be entirely workable, and serves to illustrate the point that the government will have a budget it wants to meet, and will collect that taxes by adjusting the rate if needed, and an "assesssed value" is really a finely tunes set of points, rather than a value as such.

It would be useful to connect the value to reality in some manner. One way is to make the assessments a binding offer to buy or sell. If the government makes the assessment, this should be a binding offer to purchase the property at that price. Similarly, if the owner makes the assessment, this should be a binding offer to sell. A third party making an assessment would also be a binding offer to buy. Taxes then would be paid based on the highest assessment on record.

Any system can be gamed and corrupted. If the government is setting an assessment, and is compelled to make an assessment a binding offer to buy, the government can, as noted above, just set the tax rate as it needs and make very low assessments. If, for example, a house would sell for $100000, the government could just assess it at $50000 and double the tax rate. Since no-one would sell for $50000, this doesn't put any limitation on the government to make reasonably assessments. I don't see any solution to this other than fixing the tax rate, which removes any flexibility, and wouldn't last in any case. Eventually the government would remove the restriction, or get around it by creating additional tax authorities.

An assessment by the owner also has an incentive to understate the value of the property, since that would reduce the owner's relative tax burden. If the government would be the only entity that could buy at the owner's stated value, then politically connected owners would be able to understate their assessment, confident that the government wouldn't actually buy out their property.

A third party assessment has less of an incentive to under or overstate the value of a property, however, the could be an incentive to harass a property owner by making a high assessment to drive up their property tax bills. This can be mitigated or eliminated by requiring that a third party assessment have the full amount of the assessment put in escrow to be effective. Interest on this amount should go to the government.

more to come...

Posted in / econ


Wed Apr 25 15:15:50 2018

Here is a script that will output commands to break up the head git commit into a separate commit for each file. Public domain.


#break up a given commit into separate commits, one for each file

#commit=$(git rev-parse "${1:-HEAD}")

#git rebase -i 

author=$(git log -n1 $commit --format='%an <%ae>')
authdate=$(git log -n1 $commit --format='%ad')
msg=$(git log -n1 $commit --format='%B')

# while read?
echo git reset HEAD^
git diff-tree --no-commit-id --name-only -r $commit -z |
xargs -0 -n1 -IFILE echo git add FILE '&&' git commit -C $commit -uno

Posted in / software

Assert for Postgres

Thu Jun 22 15:11:38 2017

Here's a small function to create an assertion, which throws an error if the first argument is not true. Public domain.

create or replace function assert(pass boolean, msg text default null)
returns void
language plpgsql
as $$
    if pass then
    end if;

    if msg is null then
        get diagnostics msg = PG_CONTEXT;
    end if;

    raise exception '%', msg;

Posted in / software / postgres

Dumping a function definition

Wed Mar 15 17:09:03 2017

I frequently need to get the definition of a function out of postgres, so here's a small shell script I wrote to do that.


cat <<EOS
select pg_get_functiondef(oid)
from pg_proc where proname = '$1'
} | psql -Aqt

Posted in / software / postgres


Sun Mar 5 15:37:01 2017

I recently bought a early 2015 macbook pro, and there's a lot of issues.

Apparently the Retina displays actually suck. Since the programmers at apple are apparently not talented enough to change the font size on the menu bar, if you use the actual resolution of the screen, it's too small to read. So their "solution" is to default to doubling each pixel. This actually give me less screen resolution than I had on my 2011 macbook pro. They also don't allow you to even set the screen to the maximum resolution, but do allow for some scaled resolutions. Which is going to make it blurry. The whole point of having more screen resolution is to use it, instead I get to pay for a screen that I don't really get to use. They could have just made the laptop cheaper, or even wrote a way to set the title font size.

Some other things to do, if in the future I should have the mis-fortune of having to set up a mac laptop again.

Posted in / hardware

Building a computer

Sun Nov 27 15:23:51 2016

In high school, some friends and I had a project to build a computer ourselves. We didn't get very far at the time. I've been playing around with an arduino the last few days and the idea has come back to mind.

So I started looking around at how I might build a computer from relatively discrete components. Not down to the transistor level, but ideally with each major subsystem being separate. We had a 16 bit computer in mind, as we'd had Commodore 64's, and thought a 16 bit computer would be cool.

I've looked around, and there don't seem to be all that many actual 16 bit processors around. Several 16 bit microcontrollers. I'd like to be able to use external ram, which means that the CPU chip will need to have external memory address pins. So for this post, I'm meaning microcontroller to mean that there is no direct support for external memory.

I'd also like everything to be available in PDIP packages to make the design and prototyping easier.

What I've found so far:


CR16: doesn't seem to be actually available

Looks like one is available: $27

C166S: possibly available, a hybrid processor, with embedded ram, but an external databus. Seems to be from $10-$25. These are available in TQFP or LQFP packages.

documentation terrible

[W65C816S]: This is a 6502 with extensions for 16 bit registers and a 24 bit memory bus. It seems heavily banked into 64K regions. I'd also like to use a cleaner 16 bit CPU.

The following have no support for external memory

Posted in / hardware