department of hack
1627 stories

The library of Alexandria and its reputation

1 Share

Many people are aware that the library of Alexandria is hugely overblown. Sure, there’ll always be people insisting that it was a magical place that held the secrets of Göbekli Tepe, Doggerland, and blond blue-eyed Europeans building pyramids in Mexico and Bolivia: there’s no point engaging with people like that. The thing is, pretty much everyone has heard of it.

Last week the History subreddit paid some attention to a piece I wrote in 2015 dispelling some myths about the Alexandrian library. Which is nice. Some people misread it and thought I was claiming it was true that ‘the burning of the library of Alexandria was “the most destructive fire in the history of human culture”’. That’s a pity, but understandable. (One reader was angry at my claiming to be a Kiwi and a hellenist: that was entertaining.)

On a more serious note, several readers pointed out that there were other library losses in history that were far more destructive. And that’s absolutely correct. Any time books are destroyed that don’t exist in other copies in other libraries, that’s a catastrophic and irreversible loss.

You can argue about whether specific incidents belong in this category. The destruction of the House of Wisdom in Baghdad in 1258 didn’t exactly put an end to the Abbasid knowledge economy and book culture, any more than the Alexandrian fire did in hellenised Egypt.

A genuine candidate for ‘most destructive fire in the history of human culture’: the Museu Nacional, Rio de Janeiro, 2 September 2018. (Photo: CBS News)

But some tragedies really are catastrophically destructive. The fire at the National Museum of Brazil in 2018 destroyed mountains of unique recordings of indigenous languages, irreplaceable archives of extinct languages, and physical artefacts. When a copy of a book gets burned, it can always be replaced if people care. But much of what was lost that day was lost for good. The fire of Rio de Janeiro was far more destructive than the incidents at Baghdad or Alexandria.

So why does the fire in Alexandria have such a vastly overinflated reputation? Why is it such a well known symbol?

Phase 1. Ancient book culture

Let’s revisit a papyrus I mentioned in the 2015 piece: one of Aristotle’s books, the Constitution of the Athenians. This text wasn’t transmitted via the mediaeval manuscript tradition. It survives only in a single papyrus copy, found in Egypt, and now held at the British Library (P. Lond. 131). Here are two interesting facts about the papyrus:

  1. It comes from Hermopolis.
  2. It was made on recycled papyrus (the papyrus was previously used for farming records).

The first fact is interesting because Hermopolis is about 400 km from Alexandria. The second fact is interesting because the fact that it’s recycled papyrus shows that it was made on the cheap.

In other words, no one was making an 800 km round trip to Alexandria, on foot, to make this copy. It was made locally.

Hellenised Egypt had a thriving book trade. There were libraries all over the place. And the loss of one big library didn’t suddenly change that.

P. Lond. 131 f. 2r, one of four scrolls that comprise the Aristotle papyrus. The papyrus was originally used for accounts for a farm near Hermopolis in the 70s CE; the blank side was later used to make a copy of the Aristotle, around 80–100 CE.

Similarly, when scholars in Rome wanted to do research, they didn’t travel all the way to Egypt. After all there were libraries in Rome: the Palatine library, the Atrium Libertatis, the Portico of Octavia, the Ulpian library, the library by the temple of Peace, the libraries at the baths of Trajan, the baths of Caracalla, the baths of Diocletian, and more. Outside Rome, there were major libraries in cities like Athens, Pergamon, Ephesos. And we know about plenty of large privately built libraries in lower-profile centres too, like Como in northern Italy, Timgad in Algeria, Prusa in Turkey.

The books that survive today via the mediaeval tradition aren’t ones that were whisked out of a burning library in Alexandria. They’re ones that got copied and so survived the format shifts over the millennia: the shift from manuscript to print in the 15th century, from uncial script to minuscule script in the 9th–10th centuries, from scroll to codex in the 2nd–4th centuries. All of these, especially the transition from scroll to codex, had a far greater impact than any one library could. A library fire affects one copy of a book: a format shift affects all copies everywhere.

Phase 2. ‘The vanity of learning’

Even in antiquity the fire of 48/47 BCE was a potent symbol. But it didn’t symbolise what it does today. Here’s how Seneca the Younger talks about it, writing in the mid-1st century CE (On tranquility of mind 9.5):

Forty thousand books burned at Alexandria. Let someone else praise that as a beautiful monument of royal elegance [elegantia]; like Livy, who says it was a tribute to the elegance of kings and the nobility of curation [cura]. It wasn’t elegance and it wasn’t curation. It was scholarly extravagance. Or rather, no, not even scholarly: since they didn't collect books for scholarship, but for show.

(The number of books varies a great deal in different sources: Seneca’s figure of ‘forty thousand’ is by far the lowest.)

The harbour fire of 48/47 BCE as depicted in Assassin’s creed origins (2017), with the Pharos lighthouse in the background. In the game, the library remains undamaged and can still be visited after the fire. Even more inaccurately, the library makes a cameo appearance in the follow-up Assassin’s creed odyssey (2018) — set a full century before either Alexandria or the library existed.

The subsequent history of the library’s reputation was mixed. The most famous fable about the library, about Caliph Omar burning the library during the Rashidun conquest around 640 CE, is in a similar vein:

And [‘Amr] received a letter from ‘Umar telling him: ‘As for the books you mention, if there is in it what complies with the Book of God, then it is already there and is not needed and if what is in these books contradict the Book of God there is no need for it. And you can then proceed in destroying them.’
Note. Al-Qifṭī, Ta‘rikh al-Ḥukama, trans. Emily Cottrell; published on Roger Pearse’s website, Sep. 2010.

This is pure morality fable, without an iota of credibility to it. Demetrios of Phaleron’s library went up in flames centuries earlier: the libraries that existed in Alexandria in the 600s CE were entirely new institutions. Still, in the Enlightenment period this fable became the single most influential story about the library of Alexandria.

It’d be easy to make the fable of Caliph Omar the basis for an islamophobic screed, slamming him for anti-intellectualism. That would be ignoring the fact that the Caliph has had plenty of western sympathisers. If Seneca could have lived to the 13th century — when the fable was invented — he would certainly have been among them.

Some later western writers did actively take the Caliph’s side, most notably Jean-Jacques Rousseau and Edward Gibbon. Here’s Rousseau’s Discourse on the sciences and arts (1750):

It is related that the Caliph Omar, being asked what should be done with the library at Alexandria, answered in these words. ‘If the books in the library contain anything contrary to the Alcoran, they are evil and ought to be burnt; if they contain only what the Alcoran teaches, they are superfluous.’ This reasoning has been cited by our men of letters as the height of absurdity; but if Gregory the Great had been in the place of Omar, and the Gospel in the place of the Alcoran, the library would still have been burnt, and it would have been perhaps the finest action of his life.

And here’s Gibbon’s Decline and fall of the Roman empire, volume 9 (1788):

... if the ponderous mass of Arian and Monophysite controversy were indeed consumed in the public baths, a philosopher may allow, with a smile, that [Caliph Omar's burning] was ultimately devoted to the benefit of mankind. I sincerely regret the more valuable libraries which have been involved in the ruin of the Roman empire ...

An important 1979 article by Jon Thiem calls this the ‘vanity of learning’ tradition. Up to the early 20th century, people’s opinions of the library’s destruction were fairly evenly divided between regret for its loss, and smug Schadenfreude that some ancient snobs got their comeuppance.

Gibbon had previously cast the library’s supposed destruction in 391 CE (how many times did he think the same books can get destroyed, exactly?) as evil Christians destroying ‘compositions of ancient genius’, in volume 5 of Decline and fall. Then when it comes to Caliph Omar, suddenly destroying libraries is a good thing. (In his case it’s perhaps more about christianophobia than anything else.)

Rousseau and Gibbon are the most famous voices for ‘vanity of learning’, but they’re not alone. Thiem also points at Louis LeRoy’s De la vicissitude ou variété des choses (1575), and Thomas Browne’s Religio medici (1643) and Vulgar errors (1646); the utopian fictions of Sebastien Mercier’s L’an 2440 (1770) and Étienne Cabet’s Voyage en Icarie (1839), where making a better world depends on burning old books; and in the late 19th and early 20th centuries, writers like Jacob Burckhardt and George Bernard Shaw, who took the view that the library’s destruction allowed space for a better future, which could not otherwise have happened.

Phase 3. ‘The loss was incalculable’

Thiem’s article came out in 1979. This was a fortuitous time for an article on the library’s reputation, because the big reversal came the very next year. In late 1980 Carl Sagan released Cosmos, and reinvented the library’s reputation almost out of thin air.

To be sure, there had been voices in the intervening millennia that regarded the fire of 48/47 BCE — or alternatively Caliph Omar’s fictional deeds — as a bad thing. John Lydgate, for one, knew his Seneca and sharply disagreed with him (Fall of princes book 6, written in the 1430s):

Alle the vesselis wer dryue up with a flood
To gret damage of seide Tholome;
Iulius brente hem euene ther thei stood,
And a gret part beside of the cite.
And ther was brent, which was previous hit ful gret pite,
The famous librarie in Egipt of the kyng,
Ful fourti thousande volumys ther liggyng.

Richard de Bury wrote of how ‘the devouring flames consumed so many thousands of innocents’ (Philobiblon, 1345). Boccaccio very sensibly regards it as one library among thousands that were lost (Genealogy of the gentile gods, preface; 1360). And in modern times, the Hollywood blockbuster Cleopatra (1963) has the queen’s advisor Sosigenes lamenting the loss of

Aristotle’s manuscripts! The Platonic commentaries, the plays, the histories! The testament of the Hebrew god! The book of books!

(It shouldn’t need pointing out, but maybe it does, that Aristotle, Plato, and the Hebrew Bible do in fact survive. The script writers evidently switched off their brains when they wrote this line.)

Cleopatra (1963): left, the city burns; right, Sosigenes of Alexandria (Hume Cronyn) laments the loss of books that survived safe and sound in hundreds of other libraries and private collections. By the way, so far as we know the real Sosigenes was neither Alexandrian nor Egyptian.

But the library’s reputation as a magical irreplaceable repository of unique items only became solidified after Carl Sagan said on a TV programme that was broadcast worldwide,

It’s as if an entire civilization had undergone a sort of self-inflicted radical brain surgery so that most of its memories, discoveries, ideas, and passions were irrevocably wiped out. The loss was incalculable. In some cases, we know only the tantalizing titles of books that had been destroyed. In most cases, we know neither the titles nor the authors.

(To be clear, where we do know titles of books that existed in the Alexandrian collection but do not survive today, it’s because they get mentioned by people who read them in many places, not just Alexandria, and usually later than the fire of 48/47 BCE. It is the sheerest folly to imagine that only one copy of any given book existed anywhere in the world. If this was the case, then the book was already doomed, because no ancient library has survived to the present.)

In eight minutes of television, Sagan invented out of thin air the myths

  • that the library was a unique institution, with no parallels;
  • that lots of knowledge was lost along with the library;
  • that Hypatia’s death had something to do with the library’s destruction;
  • for that matter, that Hypatia had anything at all to do with the library.

All of these are pure fiction, without any basis of any kind. Sagan also repeats a bunch of myths that he didn’t invent: that religion caused the onset of a ‘Dark Age’ and centuries of superstitious ignorance; even the idea that there was still a library in the temple of Serapis when it was destroyed in 391 CE, which is doubtful.

How influential is Cosmos? Insanely influential. I talked about this a little back in 2016, but it bears repeating. Many articles, books, documentaries, and videos about the history of science still have no hesitation over citing Cosmos as the only authority they need. This is insane, because at least half of what Sagan says about history is outright false, but his authority is still seemingly unimpeachable today, forty-two years after the programme first aired.

This credit screen (right) shows the entirety of the historical research for an influential 2016 video about ancient science (left). As of November 2022, the video has been viewed nearly 25 million times on Facebook and YouTube combined. At least half of it is outright false, and every one of the falsehoods comes from Cosmos.

If you look at an Ngram analysis of the frequency of ‘library of Alexandria’ and related terms in English-language books, it’s easy to see the impact of Cosmos. Previously, the most common title for the institution had been ‘Alexandrian library’. Sagan made ‘Library of Alexandria’ a formal title. ‘Library of Alexandria’, with a capital L, took over as the most common title from 1984 onwards. Sagan also caused the rise of the phrasing 'Great Library of Alexandria', capital G and capital L, which hadn’t been a thing previously.

Google Books Ngram analysis of ‘Library of Alexandria’ and related phrases for the period 1965–2019: link. The Cosmos effect is obvious in other languages too: French, German, Russian, Spanish.

I have often suspected that the library’s popularity has been had additional boosts from the Sid Meier’s Civilization games from the 1990s onwards, which have sold many millions of copies, and which feature ‘The Great Library’ as a wonder that a historical civilisation can build. But it isn’t possible to filter out the effects of Civilization among all the noise that Sagan created. Then again, the effect is far more pronounced after the year 2000 if you look at an Ngram analysis of just fiction books, so maybe there are good grounds for seeing the Civilization effect as a real thing too.


  • Thiem, J. 1979. ‘The great library of Alexandria burnt: towards the history of a symbol.’ Journal of the history of ideas 40: 507–526. [JSTOR]
Read the whole story
4 days ago
Boulder, CO
Share this story

Erol Otis, 1976

1 Share

Erol Otis, 1976

Read the whole story
10 days ago
Boulder, CO
Share this story

Review: What Makes This Book So Great

1 Share

Review: What Makes This Book So Great, by Jo Walton

Publisher: Tor
Copyright: January 2014
ISBN: 0-7653-3193-4
Format: Hardcover
Pages: 447

Jo Walton, in addition to being an excellent science fiction and fantasy writer, is a prodigious reader and frequent participant in on-line SFF book discussion going back to the Usenet days. This book is a collection of short essays previously published on between July 2008 and February 2011. The unifying theme is that Walton regularly re-reads her favorite books, and each essay (apart from some general essays on related topics) is about why this specific book is one that she re-reads, and (as the title says) what makes it so great.

Searching for the title of one of the essays turns it up on still, so this is one of those collections that you don't have to buy since you can read its contents on-line for free. That said, it looks like these essays were from before started classifying posts into series, so it's going to be challenging to track them down in the huge number of other articles Walton has written for the site. (That said, you can't go far wrong by reading any of her essays at random.)

I read these essays as they were originally published, so this was also a re-read for me, but it had been a while. I'm happy to report that they were just as much fun the second time.

In the introduction and in the final essay of this collection, Walton draws a distinction between what she's doing, criticism, and reviewing. As someone else who writes about books (in a far more amateur fashion), I liked this distinction.

The way I'd characterize it is that criticism is primarily about the work: taking it apart to see what makes it tick, looking for symbolism and hidden meanings, and comparing and contrasting other works that are tackling similar themes. I've often finished a work of criticism and still had no idea if the author enjoyed reading the work being criticized or not, since that isn't the point.

Reviewing is assistance to consumers and focuses more on the reader: would you enjoy this book? Is it enjoyable to read? Does it say something new? What genre and style is it in, so that you can match that to your tastes?

Talking about books is neither of those things, although it's a bit closer to reviewing. But the emphasis is on one's personal enjoyment instead of attempting to review a product for others. When I talk about books with friends, I talk primarily about what bits I liked, what bits I didn't like, where the emotional beats were for me, and what interesting things the book did that surprised me or caught my attention. One can find a review in there, and sometimes even criticism, but the focus and the formality is different. (And, to be honest, my reviews are more on the "talking about the book" side than fully proper reviews.)

These essays are indeed talking about books. They're all re-reads; in some cases the first re-read, but more frequently the latest of many re-reads. There are lots of spoilers, which makes for bad reviews (the target audience of a review hasn't read the book yet) but good fodder for conversations about books. (The spoilers are mostly marked, but if you're particularly averse to spoilers, you'll need to read carefully.) Most of the essays are about a single book, but there are a few on more general topics, such as Walton's bafflement that anyone would skim a novel.

Since these are re-reads, and the essays collected here are more than a decade old, the focus is on older books. Some of them are famous: Vinge's A Fire Upon the Deep and A Deepness in the Sky, early Le Guin, Samuel Delaney's SF novels, Salmon Rushdie's Midnight's Children. Some of them are more obscure. C.J. Cherryh, for example, is a writer who never seems to get much on-line attention, but who is one of Walton's favorites.

Most of the essays stand alone or come in small clusters about a writer, often sprinkled through the book instead of clumped together. (The book publishes the essays in the same order they originally appeared on The two largest groups of essays are re-readings of every book in Steven Brust's Vlad Taltos universe (including Brokedown Palace and the Paarfi books) up to Jhegaala, and every book in Lois McMaster Bujold's Miles Vorkosigan series up to Diplomatic Immunity. This is fitting: those are two of the great series of science fiction, but don't seem to be written about nearly as much as I would expect.

There are over 130 essays in a 447 page book, so there's a lot of material here and none of them outlive their welcome. Walton has a comfortable, approachable style that bubbles with delight and appreciation for books. I think it's impossible to read this collection without wanting to read more, and without adding several more books to the ever-teetering to-read pile.

This is perhaps not the best source of reading recommendations if you dislike spoilers, although it can be used for that if you read carefully. But if you love listening to conversations about the genre and talking about how books bounce off each other, and particularly if you have read most of these books already or don't mind spoilers, this collection is a delight. If you're the type of SFF reader who likes reading the reviews in Locus or is already reading, highly recommended.

Rating: 8 out of 10

Read the whole story
10 days ago
Boulder, CO
Share this story

Decision Fatigue

2 Comments and 4 Shares

Trying to keep up with the news this month is hard. Trying to derive patterns from the news in order to blog about them coherently? Even harder, leading to decision fatigue—but I'm going to have a stab at it ...

The big buried lede of the past decade is that authoritarian conservatives network internationally as pervasively as the soi-disant "international communism" they railed against from the 1920s through the 1960s. Since the Russian invasion of Ukraine it's become glaringly clear that authoritarianism is the preferred governmental mode of petrochemical resource extraction economies (money attracts sociopaths, sociopaths like authoritarian leaders because they are convenient single points of failure for corruption-prevention systems, authoritarian leaders appeal to authoritarian followers).

This century the PREEs are all panicking. The price of new photovoltaic panels is dropping in line with Moore's Law and as a result it's now cheaper to install PV panels than to keep existing coal-fired power stations running: the result is a mad dash to pump all the oil and gas they can get out of the ground before all that new renewable infrastructure is coupled to new distribution and usage tech that will reduce the demand for constant base load. (Big Carbon must be absolutely terrified of better battery technologies—not necessarily lighter or higher capacity, but cheaper to manufacture, safer to deploy and recycle, and longer life—suitable for grid-scale load averaging or backup.)

In addition to pumping out CO2, they've been pumping out propaganda. Russia got into the game by boosting the factions in the west most tightly associated with climate change denialism (the hard right): the hard right also swung behind Putin's imperialist revanchism (look at how many US Republican leaders are pro-Russia all of a sudden).

It's looking since the US midterms like the new hotness in western hard right circles is going to be the war on youth. Young people (especially women and people of colour) overwhelmingly reject white male supremacism, for fairly obvious reasons: they're also more inclined to be worried about climate change. An immediate response by authoritarians is to push back against any resistance. In the USA, Republicans propose raising the voting age to 21 or even 28; in the UK, New voter ID laws discriminate against young people (old peoples' bus passes are acceptable at polling stations, but young persons' railcards are not), and in Iran we're seeing a striking display of inter-generational violence, as the ageing male authoritarian fundamentalists of the post-1979 revolution shoot young female demonstrators in the streets.

If anything, this should be heartening news: the kids are all right. They're marching for action on climate change, they're voting against fascism. Not universally, not all of them (some are going full Nazi, or becoming incels, or murderous mediaeval cosplayers like Da'esh)—but enough that the far right are clearly a generational problem.

Some years ago, when asked, SF author Bruce Sterling summed up the 21st century as "old people, living in cities, afraid of the sky". Well, Earth's human population is over 50% urban at this point, the sky is becoming bloody dangerous (climate!), and as for the old people ... the young are trying to adapt, the gerontocracy are pushing back, but eventually the current gerontocrats will die out.

The other striking news of the week is Elon Musk's epic flaming death spiral at the helm of Twitter. (Which currently eclipses the news that Mark Zuckerberg wasted $15Bn on a virtual reality system with, like, about 60 thousand users, and Facebook is going to undergo huge spending cuts over the next year by way of adjustment.)

Reader, I am not charmed by this. Musk's big mouth got him into an untenable position, and now he's thrashing around destructively. I'm not going to recap the arguments here, but I suspect twitter is likely to crash hard within the next few days to week or two (at most) and Musk has fired most of the people who can fix it and keep it running. He's also fired everybody involved in international regulatory compliance: he seems to think that the relatively libertarian and under-regulated political regime of California is universal. In reality, twitter is subject to GDPR, the General Data Protection Regulation thanks to it handling EU citizens' data.

GDPR, for Americans, essentially defines a constitutional-level right to online privacy throughout the EU and it is applicable to any corporation processing EU citizens' data: it was designed specifically to prevent the sort of abuses that took place in the Third Reich, when the Nazis ransacked existing punched card databases to identify Jews and other undesirables for arrest and murder. The fines are draconian (up to 4% of the corporation's annual global turnover) and can be levied separately by each nation's data privacy regulator. Hint: there are 27 of them, adding up to a potential liability of fines equal to 108% of annual turnover (if all the regulators were to hammer Twitter with the maximum level of fines simultaneously).

Musk's takeover has drawn a spotlight to the big social media platforms' collective failure to deal with false news, bullying, and extremist politics. While second tier platforms (think Mastodon) are nowhere near to providing a refuge yet, I expect any big social media that survive into 2024 will be facing vastly tighter governmental regulatory controls.

Final news: Cryptocurrencies seem to be collapsing left right and centre as the main exchanges go bust and are exposed as fronts for securities fraud. I could say "I hate to say I told you so" but I'd be lying. (And yes, I told you so right here on this blog, nine years ago.) Schadenfreude is wonderfully heart-warming in a time of otherwise terrible news!

Read the whole story
9 days ago
On the flip side, 108% of Twitter’s annual turnover is way less than the amount Musk has already lost. I wonder how many Tesla/SpaceX employees are secretly hoping he’ll have to sell enough to give up control.
Washington, DC
10 days ago
This is about as optimistic as I've seen cstross in ages.
Boulder, CO
Share this story

Saturday Morning Breakfast Cereal - Shit phase

1 Comment and 3 Shares

Click here to go see the bonus panel!

Freud also discovered that sometimes people think a thing but don't say the thing.

Today's News:
Read the whole story
10 days ago
It turns out I am very much the audience for talking shit about Sigmund Freud.
Boulder, CO
Share this story

Neko - A brief history and porting to Javascript

1 Share

In the early 90’s, being a frisian kid obsessed with computers there weren’t a ton of ways to get access to new software or learn more about computers.

The two main ways were exchanging 3.5” diskettes with friends, or go to the library. One book I remember more than others was “Windows for Kinderen” (“Windows for Kids”) by Addo Stuur.

I must have been around 10 years old and was obsessed by this book. It covered Windows 3.0, and when you got the book from the library, it came with a diskette filled to the brim with shareware. Mostly games and useless toys, but it still baffles me thinking they were able to cram it all on a 1.44 megabyte disk. Using floppys from the libraries was even back then a risky business given that they’re writable! Luckily this mostly went ok.

One that I remembered particularly well was ‘Neko’, an application that renders a cat in a window that follows your mouse. This must have been a popular thing to make at the time, because the diskette somehow had space for 3(!) different ports of this same application.

I don’t know what reminded me of Neko last week, but I started doing some more research, and found out that the first version was written all the way back in the 1980’s by Naoshi Watanabe for the NEC PC 9801.

Neko for the NEC PC 9801
Neko for the NEC PC 9801 (1980's)

After that, it was ported to the Macintosh in 1989 by Kenji Gotoh, and this art style seems to be the basis of almost every future port:

Neko on Macintosh
Neko on Macintosh (1989)

In 1991, IBM included it in OS/2! Apparently they paid 300,000 YEN, which is about $3000 CAD in todays money. At this point it also became public domain.

Neko on OS/2
Neko on OS/2 (1991)

Since then there’s been countless ports for every platform. If you’re running linux you might be able to install one by just running:

apt install oneko

I also decided to make a version. Neko is now close to 40, so my Neko is no longer interested in following the mouse, and prefers to just sleep all day unless you wake it.

If you want to know more, the Eliot Akira wrote a great article with way more information about Neko and all its ports, this is also where I took the screenshots from this page.

You can also check out the source of my port ‘jneko’. It uses the assets of oneko, which are public domain. It was a fun exercise to create a little state machine.

Creating the assets

To create the assets for jneko, I had to convert them from the .xbm format from oneko.

I did this with imagemagick on the command line using a command like this to loop through all the files:

for f in ../oneko/bitmaps/neko/*.xbm
  convert "$f" `basename "${f%.xbm}.png"`

Sadly I still had to open each one of them with Gimp and add the alpha layer.

I hadn’t really heard of the .xbm format, but when I accidentally opened one with an editor I was surprised to see that they’re actually a text format:

#define awake_width 32
#define awake_height 32
static char awake_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x04,
   0x40, 0x10, 0x10, 0x02, 0x80, 0x28, 0x28, 0x01, 0x00, 0x49, 0x24, 0x00,
   0x06, 0x44, 0x44, 0x60, 0x18, 0x84, 0x42, 0x18, 0x60, 0x82, 0x83, 0x06,
   0x00, 0x02, 0x80, 0x00, 0x00, 0x22, 0x88, 0x00, 0x0f, 0x22, 0x88, 0x78,
   0x00, 0x22, 0x88, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x3a, 0xb9, 0x00,
   0x00, 0x04, 0x40, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x70, 0x1c, 0x02,
   0x00, 0x40, 0x04, 0x05, 0x00, 0x20, 0x88, 0x04, 0x00, 0x10, 0x50, 0x02,
   0x00, 0x08, 0x20, 0x01, 0x00, 0x0b, 0xa0, 0x01, 0x80, 0x0c, 0x61, 0x02,
   0x40, 0x18, 0x31, 0x04, 0x40, 0x10, 0x11, 0x04, 0xc0, 0x11, 0x11, 0x07,
   0x60, 0x90, 0x13, 0x0c, 0xe0, 0xff, 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

Turns out this is the X BitMap format, which has the interesting property that it aside from an image format, they’re also valid C source files. This has the advantage that they can easily be statically compiled into C files without requiring a parser.

This is really similar to the history of the JSON format, which was designed to be a subset of Javascript, allowing Javascript programs to read the format without a new parser (using eval). Ironically the current JSON format is no longer a subset of Javascript, and Javascript engines now have a JSON.parse() function built in.

A deep dive into the source

jneko uses a state machine. All its possible states and transitions are expressed with this configuration object:

const stateMachine = {

  // Name of the state
  sleep: {

    // Which images are used for the state
    image: ['sleep1', 'sleep2'],

    // How quickly we loop through these images
    imageInterval: 1,

    // What state does this go to when clicked
    click: 'awake'
  awake: {
    image: 'awake',

    // We automaticall transition to this state
    nextState: 'normal',

    // How long it takes to transition
    nextStateDelay: 2.5,
  normal: {
    image: 'mati2',

    // If there's multiple nextState values, a random one is picked.
    // You make make 1 state more likely by addding it multiple times
    // to the array
    nextState: ['normal', 'normal', 'normal', 'tilt', 'scratch', 'yawn'],
    nextStateDelay: 1.5,
  tilt: {
    image: 'jare2',
    nextState: 'normal',
    nextStateDelay: 1,
  yawn: {
    image: 'mati3',
    nextState: ['normal', 'normal', 'sleep'],
    nextStateDelay: 1,
  scratch: {
    image: ['kaki1', 'kaki2'],
    imageInterval: 0.1,
    nextState: 'normal',
    nextStateDelay: 3,

Before Neko starts, we need to preload the images. This ensures that the animations happen instantly and not after a delay.

 * The filenames are a bit funny because they were taken straight from
 * the oneko project.
const imageNames = [
 * Images are actually 32x32 but it's too small for modern screens.
const nekoSize = 64;
const images = Object.fromEntries( => {
  const image = new Image(nekoSize, nekoSize);
  image.src = '/assets/posts/neko/bitmaps/' + name + '.png';
  return [name, image]

Finally, this class does all the heavy lifting:

class Neko {

  constructor(elem) {

    // The HTML element that hosts neko
    this.elem = elem;
    this.stateMachine = stateMachine;

    // Creating a new <img> element
    this.imgElem =  new Image(nekoSize, nekoSize);

    this.imgElem.addEventListener('click', () => this.onClick());



   * This property is used to keep track of states with multiple frames
  #animationIndex = 0;

  renderImage() {

    let name = this.stateMachine[this.#state].image;

    if (Array.isArray(name)) {
      name = name[this.#animationIndex % name.length];
    this.imgElem.src = images[name].src;

  #state = null;
  #nextStateTimeout = null;
  #imageCycleInterval = null;

  setState(stateName) {


    if (Array.isArray(stateName)) {
      // If stateName was supplied as an array of strings, we'll randomly
      // pick a new state.
      stateName = stateName[Math.floor(Math.random()*(stateName.length))];
    if (!this.stateMachine[stateName]) {
      throw new Error('Uknown state: ' + stateName);
    this.#state = stateName;
    const stateData = this.stateMachine[this.#state];

    // If there was a nextState, we automatically transition there after
    // a delay.
    if (stateData.nextState) {
      this.nextStateTimeout = setTimeout(
        () => this.setState(stateData.nextState),
        stateData.nextStateDelay * 1000

    // This block is responsible for cycling through multiple images
    // of the current state.
    if (stateData.imageInterval) {

      this.imageCycleInterval = setInterval(
        () => this.renderImage(),

  onClick() {
    const stateData = this.stateMachine[this.#state];
    if ( {
      // If the current state had a 'click' property, we'll transition
      // to that state, otherwise it's ignored.



Now if you’d like to call Neko, make a <div id="neko"></div> somewhere. and hook up Neko with:

new Neko(document.getElementById('neko'));

To make Neko not look ugly, tell the browser to not use anti-aliasing when scaling:

#neko img {
  /* Both are needed to support all browsers currently. */
  image-rendering: pixelated;
  image-rendering: crisp-edges;

Thanks for reading! If you have any comments you can reply to this tweet or this mastadon post to make it show up below this article automatically.

Read the whole story
11 days ago
Boulder, CO
Share this story
Next Page of Stories