Tab Completion

I'm Tab Atkins Jr, and I wear many hats. I work for Google on the Chrome browser as a Web Standards Hacker. I'm also a member of the CSS Working Group, and am either a member or contributor to several other working groups in the W3C. You can contact me here.
Listing of All Posts

Magical Metaphysics

Last updated:

I've been working on a homebrew fantasy world in my spare time for years. It'll probably never go anywhere, but it's fun to think about! One of the things I've wanted to nail down for a long time was the magic physics of the world, what elements made up reality in this extremely magical world.

I had a few requirements to keep in mind when developing this.

First and foremost, it had to be "complex". By this I mean--well, it's easiest to explain by contrast. In the real world, physics is "simple". The fundamental units of reality (quarks, photons, etc) have basically nothing to them. They're just a few numbers that combine together in trivial ways. The complexity of our world comes not from any fundamental complexity, but rather from enormous numbers of these super-simple things combining together. Even tho each individual thing has no complexity at all, and neither does the way they interact, the aggregate is capable of displaying tons of complexity.

Magic, on the other hand, is always "complex" at its root. It generally assumes the existence of minds as a fundamental unit of reality (whereas in the real world minds are just one of the patterns that vast quantities of unthinking particles can arrange themselves into). Sometimes it has "morality" baked in as a physical force; often it has complex things like "fire" or "earth" as core concepts. This makes magic easier to comprehend at a surface level, because it's made out of "big" things we can wrap our minds around, which combine in ways that are complex and ideosyncratic, but don't involve the dizzying amounts of data that the real world's fundamentals do. The elements of magic thus have to reflect this.

Secondly, it has to involve fives. Five is a good number of things, mentally and spiritually significant. So early on, long before I knew what anything would be, I knew I'd have five spheres of five atoms each.

So let's dive in!

The Sphere of Elements

Fire, Water, Earth, Wind, Wood

This was the simplest of all. I knew I needed to involve the classical "elements" of fire/water/earth/air, and I had a few common choices for what to make the fifth. I chose to go for "wood" for a few reasons. One, it's very physical, and helps tie together "elemental" magic with a druid-ish theme. Two, I already knew from my fantasy races that I wanted elves to have wooden skeletons, and for this to be properly mystically significant, I'd need wood to be a fundamental force. Three, wood is usually mystically significant in stories, which means its likely to be pretty core to the magic system, so I had to include it somewhere. Some other common choices I rejected are "metal" (already served by "earth"), "void" (too abstract/encompassing for what's supposed to be only one sphere of the world, also this feels a little sci-fi-y and I ended up letting Energies have that), and "heart" (very non-physical, so it doesn't fit well, and it's more over in the mental sphere that I knew I wanted to do).

A wrinkle: atoms can be "hard" or "soft"; the "hard" ones are suitable for making magical staffs with that aid in channeling related atoms. The hard/soft dichotomy is pretty literal, so Wood and Earth are both hard. This explains why staffs are commonly wood or metal, and/or contain gems (which are Earth) - they help channel elemental magic!

The Sphere of Energies

Heat/Light, Electricity/Magnetism, Kinetic, Entropy, Void

Lacking any hard atoms to make staves from, the energies are somewhat difficult to channel directly, particularly in the heat of combat. Instead they're usually admixed with an appropriate element, to aid in using an elemental staff to channel them. This produces the so-called "Wizard's Elements": Fire (Heat+Fire, or something Heat+Earth or Heat+Air), Lightning (Electricity+Air/Earth), Thunder (Kinetic+Air), Acid (Entropy+Water, or sometimes Entropy+Earth for Corrosion), and Cold (Void+Water/Air).

This one started out easy. I knew I wanted the D&D damage types, because I intended this world to be D&D-based, and what do you know, there are five common damage types. I also wanted to somehow include some slightly science-y things, but it seemed too on-the-nose to make them a sphere of their own, and I couldn't come up with a decent pentad for them anyway. I was pretty happy when I realized I could combine those two and get a more flexible sphere out of the deal.

The Sphere of Biology

Flesh, Blood, Bone, Elan, Soul

Flesh, Blood, and Bone are fairly self-explanatory. They cover all the things bodies are made of: cartilage and bone are both Bone; skin, muscle, and organs are mostly Flesh; mucus, blood, tears, and other liquids are variations on Blood.

Soul is the thinking substance, that our identities and selves are made of. Brains are a Flesh/Soul melange, for example.

Elan is "life energy", the animating force that distinguishes living things from dead. Without Elan infusing it, flesh is inert, and decomposes. With Elan, it's vital, active, and growing. Many simple healing spells are nothing more than increasing Elan in the body and letting natural healing take place, albeit at an accelerated pace.

Biology has more complex atomic interactions than the previous spheres. Bone is another "hard" atom, and thus suitable for making staffs with that aid in channeling, particularly other Biology atoms. But curiously, Bone is almost impervious to Elan; healing bone breaks is very difficult unless you have skill in Bone, and a Bone staff is absolutely worthless for channeling Elan. This has curious consequences! For one, healers are stuck using elemental staffs, at lower efficiency, which partially explains why it's always easier to harm than to heal. For two, it means that Biology specialists carrying Bone wands are definitely not healers, and the second most common use of Biology is... necromancy. (Note: Bone instruments are useful to actual surgeons, who have real training in Flesh/Blood/Bone beyond just "throw Elan at it until it's better".)

Necromancy uses all the non-Elan parts of Biology to do its work, warping bodies and souls in unnatural ways. (They can't use Elan, actually - it encourages natural growth and forms, which would unravel the work they're doing.) Bone is great for necromancers, then, as it enhances all of their spells.

This split in Biology carries over to its interactions with the Energies. Bone has a strong affinity to Void and Entropy; necromancers are well-known for an Entropy/Flesh blend known as "Necrotic energy", and some specialize in a powerful Void/Entropy blend known as "Uttercold". Flesh and Electricity have a unique affinity as well, such that some necromancers use it as an alternative animating energy. On the other hand, Elan has a strong affinity with Light, blending to produce the popular "Radiant energy" that is particularly damaging to undead.

The Sphere of Psionics

???

I haven't fully nailed these down yet, and the concepts I'm mulling over aren't really named yet. My initial throwaway idea is to lean on the M:tG colors to make it about the mental states that each color can produce, but that seems like a huge cop-out, particularly since I know I'm using the same conceit for the Divine sphere. I just need to do more work here.

The Sphere of the Divine

White, Blue, Black, Red, Green

Divine magic flows directly from the gods, and comes bundled with each god's own idiosyncratic preferences and restrictions. Within that chaos, tho, arcanists have discovered five consistent aspects. Not only do gods themselves tend to organize around these aspects, but entire pantheons tend to stabilize around filling the five aspects equally. As such, most arcanists consider the five divine aspects to be the fifth atomic sphere, thus completing the pentad.

[snip explanation, they're the Magic: the Gathering color-wheel philosophies]

These can manifest in dramatically different ways. For example, one of the more popular pantheons is the Unconquered Sun, a triune deity preaching Right Thoughts (Blue), Right Body (Green), and Right Heart (White), opposed by the twin evils of the quick death (murder, Red) and the slow death (decay, Black). On a very different spectrum, the Garlandite pantheon is led by Garland, god of blood and pain (cast as the good god of this pantheon, believe it or not), opposed by the Four Distractions, each associated with one of the other four aspects.

"Arc" pantheons that center in one aspect but embrace the two neighboring ones are common. Druidic religions, for example, are almost always centered in Green with a reverence for nature, but embrace both organization (White) and savagery (Red), while typically fighting against death/corruption (Black) and technology/artifice (Blue). The Unconquered Sun's White-centered arc structure is common in many folk pantheons.

Destiny scholars suggest that the Divine sphere, more than any other, is strongly self-balancing. If a particular aspect becomes strong in an area, it automatically draws strong opposition from its enemy aspects to counter it. There is no known instance of a stable, long-lived religion that did not incorporate the five aspects in major positions, whether good or evil, balanced in some significant way.

This requirement for balance can manifest in fairly simple dualities, like the Unconquered Sun's pantheon, or in vastly more intricate pantheons, like the ten carefully intertwined cults of Ravnican society, each embracing a different pair of aspects and all serving a vital role in the maintenance of the Infinite City, or the five unbalanced "wedges" (two neighboring aspects and their mutual enemy) exemplified by the Dragonlords.

More Efficient Encoding of Primes

Last updated:

Earlier I talked about efficiently encoding lists of primes via encoding the gaps between them, in a UTF-8 inspired encoding. That's great, but there's a much simpler, even more efficient way to encode a list of all primes - use bitfields!

In its simplest, least efficient form, you just associate each successive bit with each successive integer - the first bit is for 1, the second is for 2, etc. The bit is 1 if the associated number is prime, and 0 if it's composite.

This trivial, stupid encoding has an efficiency of 8 numbers per byte, which means it's equivalent to the previous gap-encoding as long as the average gap is less than 8 (which covers quite a lot of numbers!). But we can, of course, make it much better.

The first and most obvious improvement is to throw out all the even numbers. Past 2, every prime is odd, so all the even bits are guaranteed to be 0 in the naive scheme. That's wasted space; we can just assume they're composite and spend our actual data budget on the odd numbers. So now the Nth bit corresponds to the (2N + 1)th number. This *doubles our efficiency, encoding 16 numbers per byte, and roughly doubling the number of digits for which this is more efficient than the gap-encoding (covering the primes up to e^16, or ~9 million).

At this point we should pause and recognize the additional benefits we get from this encoding. Not only is it more efficient for quite a lot of primes (the primes up to 9M fill about 500kB of memory, and allow efficient prime testing/factorizing of numbers up to nearly 100 trillion), but it also gives us constant-time random access to the primality information. If you want to find out whether a random N is prime or not, you just look up the (N/16)th byte, and then check the (N/2 + 1)%8th bit. For some algorithms this is really important!

Okay, back to efficiency. Excluding all the even numbers is great, but it's of course also true that, once you get past 3, all the numbers divisible by 3 are composite. Combining that with the previous "no evens" insight, we can chop down the relevant set to just two out of every six numbers - only the values that are equal to 1mod6 or 5mod6. With this, we can encode 50% more numbers in a given number of bits! To be specific, it gives us 24 numbers per byte, exceeding the efficiency of gap-encoding up to e^24, or about 20 billion.

And we can go further! We can additionally exclude the numbers divisible by 5, leaving us with only 8 possibilities out of every 30 numbers (1, 7, 11, 13, 17, 19, 23, 29; mod 30), for an extra 25% density, winning the efficiency race up to ~10 trillion. This has some additional benefits, too - each "set" of possibles is 8 large, same as the number of bits in a byte, which simplifies the math considerably - you look in the N/30th byte, then grab the corresponding bit from the group. This limit also exceeds what we can reasonably use - storing the numbers up to 10 trillion would take about a third of a terabyte, greatly exceeding the RAM of desktop machines. So even in extreme cases, you'll get to store/use more primes with this method than the gap-encoding, and you get the random-access benefit to boot.

We could go further and exclude the multiples of 7, but the benefits are fairly small (encode about 16% more in a given space) and the math becomes a lot more annoying (49 possible primes spread across 210 numbers) and loses the nice symmetries of the previous values, so it's best to probably just stop there.

If I Had A Time Machine

Last updated:

An incomplete and growing list of mistakes that I'd fix if I had a time machine:

Languages

Make all languages be written vertically, and stack their lines left-to-right. Everyone being on one writing direction is A+, and vertical writing gives more time for the ink to dry before your hand has to touch it when you're left-handed.

Figure out a universal script that everyone can use. Doesn't have to be too complicated; tons of languages with different sounds use the Latin alphabet fine. I'm kinda in love with the Korean script, tho - it's alphabetic, but is written like it's ideographic, with the letters arranged into syllable-blocks in a standard way. Something like that would be good.

Putting everyone on a single language would be good too, but probably really hard to maintain. Just making sure everyone's writing in a mutually intelligible way is a good start.

Numbers

Switch everyone to base 6 counting. It's got some great reasons behind it!

  1. Each of your hands is a single base-6 digit (can represent the values 0-5), so you could count to 35 instead of just 10.
  2. It's got good divisibility - /2 and /3 (and /6 of course) are just "check the last digit", /4 and /9 are "check the last two digits", /5 is "sum the digits and check if they're /5" (same as /9 in base 10), /7 is "alternately add/subtract the digits and check if they're /7" (same as /11 in base 10).
  3. The multiplication table is really trivial, almost insultingly so. Similar to the divisibility, multiplying by 2 and 3 are now super easy (like multiplying by 2 and 5 are in base 10).
* | 1| 2| 3| 4| 5| 10|
----------------------
 1| 1| 2| 3| 4| 5| 10|
 2| 2| 4|10|12|14| 20|
 3| 3|10|13|20|23| 30|
 4| 4|12|20|24|32| 40|
 5| 5|14|23|32|41| 50|
10|10|20|30|40|50|100|

Numbers in base 6 are about 50% longer than in base 10, which isn't a huge loss. We can compensate for it by making sure the names for the digits are single-syllable, as that boosts your ability to remember strings of digits. Grouping digits into sets of 3 would also feel more "natural" - we might even be able to go up to sets of 6 instead.

I guess when talking about computers, we'd generally use octal (like we use hexadecimal in base 10) - 012345TE. Octal is a lot easier to learn than hex, too.

Dates

The Gregorian calendar is stupid. We can't control the length of a day or year, so we can't do anything perfect, but we can at least improve the situation by switching to a consistent 30-day month, with 6 5-day weeks. 12 of these months leaves us with a single 5-day week left over at the end, which should be treated as intercalary and placed at the end. Leap days also go at the end. This makes days consistent across months and years (the 2nd of every month is always the same day of the week, etc), and gives us much easier math in general, in both base 10 and base 6. In base 6, we have 20 months, each containing 10 5-day weeks, or 50 days total. 👌

Time

Keeping time is... fine. It's not great; our time system is clearly based on the dozenal roots in some of our old numbering systems (a day is two dozen hours, an hour is 5 dozen minutes, a minute is 5 dozen seconds), but we can still do better.

We're lucky in that, unlike calendars stuck with the unchangeable physical constants of "day" and "year" (and their terrible ratios), time-keeping is only beholden to the day - the rest of the units are human-made, and can be adjusted as we see fit. So we can switch to proper metric time! In base 10, I prefer dividing the day into 100 "hours", each equivalent to about about 15 of our old minutes, and then further subdividing into 100 "seconds", each very close to our old seconds. 15-minute chunks are very tractable, I feel - we often informally divide the hour into quarter-hours already, because it's a convenient length of time, neither too short to get anything done nor too long to keep track of.

In base 6 I'd do similar, but you can fit in three divisions - 100 hours (each about 40 of our old minutes), split into 100 minutes (each about equal to our old minute), split into 100 seconds (each about 2 of our old seconds).

Time Zones

Time zones, on the other hand, can get fucked. We don't have "season zones" for dates - when it's March 1st, it's March 1st everywhere in the world, regardless of whether that means it's snowy or cool or starting to warm up. Instead we have much fuzzier "seasons" to correspond to the weather, and those do fluctuate based on where you are.

Time should work the same. We should have a single consistent global time, and then pair it with a set of fuzzier "moments" that describe roughly what the light-level/meal time is. Then it's easy to describe when a meeting will happen (at hour 34, or something), but also tell people it's too early (it's still dawn over here at that time), same as we can tell people when we'll vacation (January) and what it'll be like (middle of summer, because we're doing a beach vacation in New Zealand).

I Understand Platonic Solids A Little Better Now

Last updated:

So I was watching this experimental gameplay video for Miegakure, a 4d indie video game. It's like Fez, which was a 2d platformer in a 3d world that involved "rotating" things in 3d to solve puzzles, except lifted one level, so it's a 3d game in a 4d world.

Anyway, it mentioned the 24-cell, a weird 4d shape that I've always wanted to understand better, so I started on a Wikipedia binge. This immediately led me back to the platonic solids, when I realized something.

It always struck me as weird that there are an infinite number of regular 2d polygons, one for every number of sides - equilateral triangle, square, regular pentagon, regular hexagon, etc - but there were only five regular 3d polyhedrons - with dice names, the d4, d6, d8, d12, and d20. Going from infinite to finite is always interesting, and I didn't get it before, but I got to thinking about the patterns in the shapes, and suddenly it clicked - there just isn't enough space for any more regular polyhedrons!

See, the dice shapes can be split into two lines. The d4, d6, and d12 form the "increasing polygon side-count" line, while the d4, d8, and d20 form the "increasing number of triangles" line. (Yes, the d4 is the base of both.)

The "increasing polygon side-count" line goes from triangle (3) sides, to square (4) sides, to pentagon (5) sides. As you increase the number of sides, the angles get larger, so you have lay the shapes out "flatter" to get them to fit together snugly, reducing the curvature and increasing the size of the die. But what happens when you fit hexagons together? They tile the plane. Put hexagons together snugly, and they perfectly fill up a flat 2d plane - 120° × 3 = 360°. You can't curve them at all, there's not enough space. So there's no way to make a polyhedron with a regular hexagon - it can't curve around to form a ball!

The same argument happens with "increasing numbers of triangles". It's easy to fit together three triangles - you get the d4. Spread them out a little and you make space for a fourth, getting the d8. A little more flattening makes room for a fifth, making the d20. You can still squeeze in one more triangle, putting six together snugly, but only by flattening them into a plane again. It's the same problem as the hexagon tiling - 60° × 6 = 360° again. The triangles don't curve around at all, so you once again can't form a ball!

7 (whether 7-sided shapes, or 7 triangles) is of course right out. You can't fit those together no matter how you try.

I presume this is why there are only three regular solids in 5+ dimension: the simplex (analogue of the d4), the measure complex (analogue of the d6), and the cross complex (analogue of the d8). In higher dimensions the volumes take up more "room", so you just can't fit as many together, and aren't able to go up to the "5" shapes (analogues of the five-sided or 5-triangled shapes).

This still doesn't answer what the fuck is up with four dimensions, tho. 4d has six regular solids - 5 analogues of the 3d solids, and 1 special. There's the three made out of increasing-size dice: the 5-cell, made out of d4s; the 8-cell, made out of d6s; and the 120-cell, made out of d12s. There's the three made out of tetrahedrons: the 5-cell, where 4 meet at each vertex; the 16-cell, where 5 meet at each vertex; and the 600-cell, where 6 meet at each vertex.

Then there's the 24-cell, made out of d8s. What the fuck. Geometry is weird.

My Password Strategy, and So Can You!

Last updated:

Everyone knows they're supposed to use strong, random passwords, and use different passwords on every single site. For most of us, tho, that's impossible - we just can't remember that many. Some of us give up and just remember one strong password (there goes your security when something is breached) or use a password locker like 1Password (hope you're backing up appropriately, and have access to the vault from every single place you'll need a password).

None of these are good strategies. A few years ago I thought about this a bit, and put together a tool to help me handle all this properly and safely. I've evangelized it a bit informally, but more people really need to know about this. So, here goes:

  1. Memorize one good, strong password. Make it long and random, as secure as you can possibly make it and still be sure to remember it. This is the only random password you'll be required to remember ever again.
  2. Whenever you need a password for something, visit https://tabatkins.github.io/password/. Put your master password from Step 1 into the master password slot, and enter a memorable "site tag" for that slot. This does not need to be secure in any way, so focus on making it as easy to remember as possible, like the domain name of the site.
  3. Hit the "Long" button and copy the generated password out. DONE.
  4. If you're using a terrible website like a bank that applies password limits, the "Short" button usually works - it gives you a 12-char password. If you need more control, the "More Options" section lets you customize the password thoroughly, which should satisfy whatever idiotic demands they call for. Try to avoid using this if possible, just because it means more memorization.
  5. Store the site tag (and the custom options, if necessary) somewhere accessible. I just use a Google Doc, which I can access from anywhere on multiple devices. This is not secure information, so don't worry about it being exposed - as long as your Master Password is good, you're safe.

And that's it! This method has several benefits over a traditional password locker:

  • Same amount of memorization - one master password.
  • No need to "back up" anything - you can probably remember the site tag anyway, and if you do record them somewhere it doesn't have to be securely stored.
  • Accessible from anywhere - as long as you can touch the internet, you can reach this - no need for a browser extension or a separate program that won't be installed on public computers.
  • Works offline - the site is totally self-contained in a single file, so you can save it to your device and use it locally without any internet connection at all.
  • Totally independent - nothing can stop working because some company was acquired or went out of business. If you save a local version of the file or host it on your own site, even me removing my site won't stop you.
  • No chance of losing passwords - no chance that your password file can be "corrupted" and impossible to decrypt, because there is no password file - it's just a hash function run on your two inputs.

If you're paranoid, feel free to audit the code on your own - it's unobfuscated HTML and JS that makes zero network calls and saves no information. The entire operation is done locally, my version of the file is served over HTTPS, and you can run a local version if you're really paranoid about code changes.

I've been using this for years, and it changed my life around passwords.