there is a small pokédex here

Hey, I am Eevee and this is veekun and it's a Pokédex. You probably want to type into that box in the top right, or maybe just start browsing.

Other stuff of interest:

Updates


At the 2016 Pokémon European National Championships a Shiny Machamp based on Mark McQuillan's Shiny Machamp will be distributed to anyone attending the events in Liverpool, Kassel and Assago between May 14 and June 12. There will also be separate live streams of the European National Championships for TCG, VGC and Pokkén Tournament available on Twitch.
Nintendo HK to hold Video Game National Championships in Hong Kong and Taiwan.
The starter Pokémon for Pokémon Sun and Moon, as well as its release dates, have been revealed.

May’s theme is clearing my plate. I have a lot of small-to-medium-sized stuff I’ve been intending to do for a while, and the sheer number of things is getting a little overwhelming. A lengthy todo list starts to get stressful; it feels like constant looming noise in my head. I want to spend this month getting as much of it as possible out of the way.

  • gamedev: I have vastly improved EeveeQuest™, my dink-around non-game for the PICO-8. From where it started last Saturday, it’s grown momentum, friction, gravity, collision, sound effects, background music (basically my first try at music!), scrolling, a HUD, and some evolution stones. The PICO-8 is super adorable, by the way.

    Also, Mel decided we’re making a game, so I’ve been adapting it to fit a map they’ve been designing.

  • blog: I rewrote the list of work I’ve done to be less, uh, unreadable garbage. I also set up subdomains c.ee.vee for hosting hostable work, and t.ee.vee for maybe eventually hosting cat photos and the like. I think these are pretty clever.

    I also wrote about what it’s been like trying to learn to draw.

  • pokémon: I’m still working on a Pokémon Showdown client for Patreon reasons; I got a bit sidetracked trying to make urwid and asyncio play well together, but I’m well on my way to having a usable API.

  • art: Lotta doodling. Appropriately, I think I’ve gotten a lot better in the last month or so.

  • doom: I made most of a horrible, horrible pain elemental variant that everyone will hate.

  • irl: I got Anise microchipped, so finally my cat is a cyborg. He is better, faster, stronger, and far more mischievous than any pure cat. His cybernetic enhancements have already enabled him to drive me up the fucking wall far more efficiently today than ever before.

  • Runed Awakening: In a stroke of inspiration, I figured out a way to connect a puzzle with no reward to a puzzle with no solution. I’m really happy with the shape the game is taking, even if there’s still infinity work left to do.

This week, I would like to finish the PICO-8 game with Mel, write another two posts, finish some of the art I’ve left hanging, finish this Showdown work, and make at least three significant improvements to Runed Awakening. Christ, I’d better get started.

On January 1, 2015, I started learning to draw.

I’d made a couple brief attempts before, but nothing very serious. I’d eyeballed some official Pokémon artwork on two occasions, and that was pretty much it. I’d been dating an artist for seven years and had been surrounded by artist friends for nearly half my life, but I’d never taken a real crack at it myself.

On some level, I didn’t believe I could. It seemed so far outside the range of things I was already any good at. I’m into programming and math and computers and puzzles; aesthetics are way on the opposite end of a spectrum that only exists inside my head. Is it possible to bridge that huge, imaginary gap? Is it even allowed? (Spoilers: totally.)

In the ensuing sixteen months, a lot of people have — repeatedly — expressed surprise at how fast I’ve improved. I’ve then — repeatedly — expressed surprise at this surprise, because I don’t feel like I’m doing anything particularly special. I don’t have any yardstick for measuring artistic improvement speed; the artists I’ve known have always been drawing for years by the time I first met them. Plenty of people start drawing in childhood; not so many start at 27.

On the other hand, I do have 15 years’ experience of being alright at a thing. I suspect, in that time, I’ve picked up a different kind of skill that’s undervalued, invaluable, and conspicuously lacking from any curriculum: how to learn!

I don’t claim to be great at art, or even necessarily great at learning, but here are some things I’ve noticed myself doing. I hope that writing this down will, at the very least, help me turn it into a more deliberate and efficient process — rather than the bumbling accident it’s been so far.

Crude pencil comic from Jan 1, 2015

I started out doing daily comics, just because Mel was also doing them. The first one was… not terribly great. It hadn’t even occurred to me to bump the contrast on this photo.

At this point I was vaguely aware of some extreme basics:

  • things are made of shapes
  • faces are two dots with a mouth under them
  • arms have some kinda little stubs at the end
  • you can do a squiggle to kind of make fur

I’ve had people tell me I was already drawing better than them here. I can see how I might’ve had a tiny bit of a head start: I do live with two artists, and clumsy attempts at web design have given me a slight appreciation for whitespace and composition. Still, I don’t think this is wildly beyond anyone’s ability.

The most important thing was probably the idea of daily comics, which got me to draw at least one thing a day — several, in fact, since they’re comics. I kept this up through the end of March, at which point I just plain ran out of ideas for comics. There are only so many ways to draw “I worked on computer stuff and also my cat does funny things”. But that’s still 90 days, times an average of at least two panels per comic, which is hundreds of drawings. My first insight is thus:

Do the thing. Do it a lot. No, don’t “practice”. “Practice” sounds rote and repetitive; even reading the word makes me feel pre-emptively bored. Just do it. Find an excuse to do it. Any excuse. You want to write embarrassing fanfiction? Do it. You want to make four-chords pop songs? Do it. You don’t need to do something high-brow or rigorous or chosen from a careful gradient of boring beginner exercises. You just need to something.

Even better, do something regularly and release it publicly (or at least to a moderate circle of people). It helps to have some light pressure, and posting something every day starts to feel like it’s expected of you, even if you’ve never explicitly promised anything.

If it starts to feel like too much of a drag, you can always drop it and try something else. You can take a break for a while, you can do some personal work, you can do whatever self-hack will help you keep doing something.

Digital painting of a landscape from an interesting angle from March 26, 2015

Mel’s birthday is March 26. On March 19, 2015, our roommate gave me his old drawing tablet. I spent most of the ensuing week on the above digital painting.

I’d only colored anything a couple things at this point, all of them basically flood-filled. I hadn’t tried shading, backgrounds, textures, colored lines, perspective.

Naturally, I tried all of them at once. Some of these experiments were, er, more successful than others. (Along similar lines, this year, I animated something for the first time.)

Regardless of the outcome, I’d now done my best at all of these things at least once, and learned a lot about each of them.

I’m reminded of every introductory beginner guide to anything ever, which introduces one concept at a time and carefully shields you from anything you haven’t seen yet. Or stories of programming teachers who will actually chide a student for using something they haven’t been taught yet.

Fuck that noise. Dive in; keep trying things you’ve never tried before. It’s how babies learn a language, which I think is pretty impressive, given that they didn’t already know one. Parents don’t restrict their speech to single-word sentences until the baby has caught on, and then start introducing nouns. They talk normally. The baby marinates in the language and picks it up over time by playing with it, starting with whatever’s most accessible.

And hey, this works for adults too. I’m pretty sure being dropped in a country where no one speaks your native tongue will have you picking up a second language much more quickly than taking night classes and having artificial conversations about dinner dates. The only real advantage a baby has is a complete lack of obligations, so they’re free to sit and listen to people talk all day.

Series of eight roughly increasingly better avatars

I figured another way to do the thing and dive in would be to finally draw my own avatar.

This took a few attempts.

The first two were in March, and I used the first one for a while. 3 through 5 were all done in June in an attempt to replace the first one with something better, but all went unused. Number 6 was the first real success, lasting through the end of the year with a few seasonal variations. 7 was an attempt to update it earlier this year, and the last one is only a few weeks old and is my current avatar.

Some of these are really bad, but I can look at them and tell exactly what I was trying to do.

  1. I didn’t even draw this; I made it with vectors, using the mouse, because I couldn’t draw well enough to make it otherwise.

  2. Drawn by hand with a tablet.

  3. The angle worked out really poorly last time, so I tried working around that by aiming from straight ahead. The ears are no longer solid blobs. There are eyebrows! The nose is shaped more like a nose. The previous colors kinda clashed, so this is more reddish overall.

  4. Straight-on didn’t work out and is hardly identifiable as anything, so back to angled. Still trying to work out pupils. Right ear is drawn behind the bow, so it doesn’t look like the bow is holding it on. I don’t understand mouths, so I’ll cheat and do a smirk instead.

  5. More angled, moved upwards to center the face. Shaded and colored the lines this time. Still trying to work out pupils. Around this time I was trying to figure out how ears on the far side of the head work, and something catastrophic happened here. I was waffling on whether the insides of the ears should have one line or two, so I tried compromising with one line plus a shadow. Bow has a bit of ribbon sticking out, as a hint that it’s tied on and not just glued there.

  6. Made the lines much thicker, so they wouldn’t vanish when shrunk down. Kept the shapes simple for the same reason. Pupils reduced to dots, which actually works just fine. Fluff details are bigger, which helps cohesion. Background color matches the bow color, which helps tremendously. Mouth finally works by being aligned with the bottom of the nose. Shape of the muzzle protrusion is, finally, big enough.

  7. More detailed bow shape. Bow is now clearly tied to the ear. Insides of ears are rendered again. Entire mouth line is shown. Some shading is present again. Pupils have expanded, but not too much, and have a glint again. Lines are colored again.

  8. Small fluff details made bigger again. Background is greener to avoid the clash from last time. Mouth is open and has the little corner crease. Lines rethickened. Dropped the shaded lines, since they didn’t work out last time, but kept the lines as mostly a single non-black color. Thickened the white double outline, which looked goofy in #6 when it was thinner than the regular outline.

In every case I was trying to improve on something that hadn’t gone well before. In every case I was trying to make the best avatar I had ever made. Sometimes that meant trying something I hadn’t tried before; sometimes that meant dropping something that hadn’t worked before; sometimes that meant resurrecting something and fiddling with it until it worked.

Always try to do the best work you’ve ever done. The key is that “best” is entirely subjective, and you can define it however you want! I was terrible at drawing digitigrade legs (like cats’ back legs) for the longest time, so for a while my definition of “best” was “has the best legs I’ve ever drawn”. Pick whatever axes you like. Vary them regularly, too — both to avoid burnout and to avoid concentrating on one thing over all else.

I had a high school teacher who liked to say that “practice makes perfect” is wrong; rather, “perfect practice makes perfect”. I don’t think that phrasing is any more illuminating, but I get his point: repeating exactly the same thing over and over will only make you better at that one thing. Incremental improvement is how you progress. (Hmm, I guess that’s not as catchy.)

There’s a catch to doing this effectively, which might as well be its own bolded quip.

Learn how to tell what’s wrong. This is a tricky muscle to exercise deliberately, but the better you get at it, the more (and more quickly) you can learn from your mistakes. Eventually you learn not to make them in the first place.

Are you a programmer? Spot the problems in this snippet of some C-like language:

1
2
3
4
5
if (won = true)
    print("You did it!");
else
    print("You failed!");
    print("Press any key to try again.");

They probably stick out to you like a sore thumb. You’ve seen and made these basic mistakes so many times that your eye has learned to recoil from the very shape of them. You’re far less likely to make them now, because the moment you make the mistake, your brain vomits a little.

Unfortunately, this is something that only comes with experience, so you’ll just have to slog through making the baby mistakes. Asking for expert advice helps a little, but I think it mostly helps you find the mistake in the first place, so you can notice it again yourself next time. Spotting your own fuckups engraves them into your brain much more effectively than having them pointed out to you.

The one hack I can think of is to drown yourself in good work. The best you can find. If you get a sense for what good work is like, you might at least get the sense that something is off about your own, which is a first step to figuring out what the problem is.

You know how some people are “naturally” talented at a thing? It just “clicks” for them? I strongly suspect their actual natural talent is more about understanding their own mistakes in a particular kind of work, which lets them skip over a lot of the boring beginner part where you fumble around uselessly.

Several pixel art landscapes

Know what’s possible. Every skill has its own toolbox, and part of learning the skill is learning what’s in the toolbox. Being familiar with image editing software has been hugely helpful for experimenting with art; for example, changing the color of your lines is trivial if you know how to use alpha lock. If you don’t know, will you even suspect it exists?

I recall a Doom Let’s Play with a conversation that went like this:

A: Ah, these textures are misaligned. It’s so easy to fix, too; you can just press A in Doom Builder to align everything across several walls.

B: Wait, really? I always do it manually.

A: What? Are you serious? So when you have a big curve made out of a lot of pieces—

B: That’s why I don’t make big curves out of a lot of pieces!

If you think something is impossible (or at least impractical), you cut yourself off from whole areas of experimentation.

Listen to more experienced people when they talk about how they work. Poke around your tools and see what all the buttons do. Come up with your own tricks — it sure worked for Bob Ross.

What does this have to do with pixel art? Not much. Pixel art relates to a rough converse of this, which is that sometimes, it’s nice to limit what’s possible. I’d never really given pixel art a try until I made these last month, and it turned out to be a really fun medium. With the drastically lower resolution and a pre-chosen fixed palette (made by someone else), I was forced to forget about how smooth my curves are or how to pick colors that work well together. Instead, I was free to play with the effects different colors have on each other, experiment with light and shading in a very simple way, and add in small details that I’d usually not think about.

Similarly, I’m now trying out the PICO-8 “fantasy console”, a tiny virtual video game system with some fairly severe restrictions. As a result, after a couple days of effort, I’m much closer to having a (graphical!) video game written than I ever have been before. I’m capable of making my own sprites now, and there can’t be too many of them anyway. Even the music editor is simple enough that I can make a passable tune. If I’d tried to make a little platformer in some massively-powerful general-purpose game engine, I’d have drowned in all the resources and code I’d need to find or create. Which has happened before. Probably more than once.

A blank canvas can be overwhelming sometimes; infinite possibilities are a lot to sift through. Cutting down on those options is freeing in its own way.

Pi Day comic, in 2015 and 2016

Step back and acknowledge your progress.

Learning a thing is frustrating sometimes. A lot of the time, even. Progress is slow and incremental, and on any given day, you won’t feel any better than you were the previous day.

Keep your old stuff around. Look at it from time to time so you can actually see how far you’ve come.

I drew these one year apart. I’m still not great — I immediately see half a dozen things in the more recent version that make me wince. But I’m better.

Illustration of a few critters at the circus

I think this is the most recent thing I’ve finished. It’s certainly a far cry from some pencil scribbles.

I hope I can get much better at this. Expressing ideas visually feels like a superpower — I can take vague images in my head and inject them directly into other people’s eyeballs. It keeps turning out to be useful, too: I’ve drawn myself avatars and banners, I drew the header for this site, I can draw sprites and illustrations for my own little games. It even taught me a few things that turned out to be useful for level design.

So, learn a lot of things. Try radically new things from time to time. Write a poem, bake a cake, make a video game. You’ll have experienced making something new, and you never know when that experience might come in handy. Doing rudimentary web design turned out to give me a head start at understanding color; who would’ve guessed?

I’m only writing this post now because I just realized that I hit a breakthrough point. I don’t really know how to explain it precisely in terms of art, so let me try language instead.

A very frustrating stage of learning a new (spoken) language is the late-beginner stage. You know the basic grammar and understand how the language is generally put together; you just don’t know many words. Learning resources are starting to dry up — everything’s always written for complete beginners — but you struggle to transition to learning from real native media, because you have to stop to look up every other word.

If you stick with it, you’ll eventually claw your way up to a kind of critical mass, where you know enough vocabulary that you can start to pick up the rest from context. You no longer need to spend ten minutes fishing through a dictionary just to understand what someone is talking about, and can instead focus on picking up nuance and idioms and more complex grammar. From there, you can accelerate.

I sense I’ve hit a similar kind of critical mass with drawing. I spent a long time fighting just to get my hand to draw the shapes I wanted, which got in the way of learning what shapes I should want in the first place. I realized only days ago that I don’t have this problem nearly so much any more.

That means I can now experiment with different kinds of shapes! It means I can play with line thickness and rely less on undo, because I don’t have to worry that I won’t be able to redraw a line. It means I can try painting more instead of always having a separate lineart layer. I can try more stuff without struggling with the basics.

It took a while to get here, but it’s paying off, and it’s been pretty cool to watch happen.

To promote its debut in the Pokémon Trading Card Game, Zygarde is current being distributed via Nintendo Network for PAL region games.

April’s theme was finish Runed Awakening, which I definitely did not do, but I am way further along than I was a month ago. Maybe by the end of May? I don’t want to set a hard deadline when I have no real way to estimate how much work is left, but I don’t want to lose this momentum, either. I’ll keep y’all posted. Hopefully by the end of this week I’ll have made a significant dent in some combination of Runed Awakening and May blogging.

  • Runed Awakening: Implemented padlocks, woohoo. Did some more high-level planning; getting pretty close to a cohesive whole here, at least in theory. Drew a couple more pixel items. Then, uh, kinda didn’t touch it again for most of the week because I had Patreon obligations to take care of, oops.

  • blog: I wrote about dozenal and using Lua for game development, which somehow turned into a dissection of how to embed Lua and Python.

  • art: I spent a couple days drawing after not really doing so much of it for the last few weeks, resulting in some cat complaints, some cat revenge, and my finishing this ancient art trade. At which point two more people asked to trade, sob.

    Also touched up my avatar for May.

  • doom: So there’s a texture pack (Community Chest 4) that was really popular among DUMP 2 mappers, but it’s some 13MB. A good chunk of it is just translations or color substitutions of vanilla textures, which is something ZDoom can already express with a human-readable text format, so I started writing a script to detect and convert as many of these as possible. It turned out to be harder than I was expecting and I kinda bailed halfway through. This is very fascinating, I’m sure.

    I did also poke at anachrony a bit; still trying to settle on a set of weapons/items/monsters so I can actually go build some maps when I have the urge.

  • tech: A friend lost some data from a web-based shop thing and I magicked it back into existence because I’m actually a witch IRL.

  • gamedev: Having admitted I’d never tried PICO-8 in the Lua post, I bought it on a whim and tinkered with it a bit last night, producing this fine non-game. (I worked on it some more today, so it’s better now, but it’s not last week any more so this doesn’t count.)

Nova Dasterin asks, with money:

How about usage of Lua for game development? Love2d etc. Also http://lexaloffle.com/pico-8.php which I recently heard about.

clarification: thoughts on Lua as a ‘good choice’, also Lua vs Python for that subject (gamedev)

There are a couple ways I can interpret this, so I’ll go with: all of them.

Writing an entire game in Lua or Python

This is entirely possible! Eve Online, for example, is allegedly mostly Python.

You can use pygame or cocos2d (built atop pyglet) or a handful of other things. They’re libraries/frameworks rather than dedicated game development studio apps like Unity, and they leave a lot to be desired at times, but they do exist and are maintained and have little communities around them.

Somewhat more well-known is Ren’Py, a visual novel engine that uses Python mixed with a sort of Pythonesque visual novel macro language. That’s not quite the same, but it’s close.

As for Lua, er, I don’t know. Finding this out is pretty hard, since the Internet is flooded with information on engines with Lua embedded. Maybe someone has written OpenGL or SDL bindings for Lua and sprinkled a skeleton of game stuff on top, but if so, I haven’t found it.

But this is probably not what you meant anyway, since you mentioned LÖVE, which does embed Lua.

Embedding Lua or Python

You have a game engine written in a host language, and you want to write a bunch of behavior in a guest language, because you secretly hate your host language but it’s fast at doing math.

What you really want to do is embed a particular language implementation, of course — embedding Jython is going to be a much different experience from embedding CPython. The host language is usually C or something related to C, what with C being our lingua franca (a phrase that refers to how Italian is the universal spoken language), so I assume this is about embedding liblua or CPython.

Embedding a language is a tricky problem. If it’s high-level enough to need “embedding” (rather than “linking to”), it probably has some kind of runtime, which you’ll also need to embed and babysit. At the very least, embedding a language means you have to:

  • start the guest runtime
  • load some guest code
  • convert host data to guest data
  • call some guest functions
  • convert guest data back to host data

In many cases, you’ll also want to expose host functions to the guest runtime, so that guest code can call back into your engine. You might also want to expose entire new types to the guest language, e.g. a fast vector type. That’s a lot of things to worry about, and the difficulty is entirely dependent on how cooperative the guest is.

I admit I’ve never had the need to embed a language in C myself, so don’t take any of this as gospel truth. I’ve been around people who have, though, and hopefully I’ve osmotically absorbed some of their knowledge.

Embedding Lua

I know much less about embedding Lua, but it also seems more straightforward, so it makes a good reference point.

The Lua book, which serves as its documentation, has a chapter that begins:

Lua is an embedded language.

That’s a pretty good start. Indeed, Lua is so embeddable that you can just paste the entire Lua source code into your project — which I know because SLADE has done exactly that. It’s a flat directory of C files totaling 640K, and nothing else is necessary.

As for actually embedding, the book provides this example of using a Lua script for configuration and reading width and height variables out of it:

1
2
height = 600
width = 800
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

void load (char *filename, int *width, int *height) {
    lua_State *L = lua_open();
    luaL_openlibs(L);

    if (luaL_loadfile(L, filename) || lua_pcall(L, 0, 0, 0))
        error(L, "cannot run configuration file: %s", lua_tostring(L, -1));

    lua_getglobal(L, "width");
    lua_getglobal(L, "height");
    if (!lua_isnumber(L, -2))
        error(L, "`width' should be a number\n");
    if (!lua_isnumber(L, -1))
        error(L, "`height' should be a number\n");
    *width = (int)lua_tonumber(L, -2);
    *height = (int)lua_tonumber(L, -1);

    lua_close(L);
}

An interesting concept in embedded Lua is the stack, a structure that straddles C-land and Lua-land. Invoking Lua operations from C will leave the results in the stack, where C code can then fetch them. In the above code, lua_getglobal is used to put two global variables in the stack, and lua_tonumber retrieves them as C doubles.

Lua’s own value types don’t seem to be exposed to C at all, and there is no “any Lua value” type. Instead, there are a handful of primitive types (nil, boolean, number, string, table, function, userdata, thread) and separate C functions for getting or putting a value of the equivalent C type from or onto the stack.

This means that the Lua-land garbage collector knows exactly what types are examinable by C — they’re the ones on the stack — and it never has to worry about arbitrary C code holding direct references to Lua values.


I haven’t actually used LÖVE! I probably should sometime. I definitely want to give PICO-8 a spin, now that I’m experimenting with pixel art.

For now, my only real experience with embedded Lua comes from tinkering with modding Starbound, where actor behavior is all defined in Lua and new actors can be dropped in alongside the stock ones.

The API isn’t particularly well-documented, and it changes arbitrarily between releases. Starbound still technically hasn’t been released, so this is a little forgivable, but it sure is inconvenient having to reverse-engineer the API surface to get anything done.

Starbound is closed-source, so I don’t know how exactly they embed Lua. From the point of view of a modder, every object has a list of zero or more Lua scripts attached to it, and those scripts are mashed into a single namespace. The namespace can implement various hooks by defining global functions with specific names. There are self and storage tables made available, but there’s no use of Lua’s OO-ish facilities; they’re globals injected into your scripts, corresponding to the entity whose hooks are being executed right now. The hooks back into the engine are, similarly, exposed via a few global tables of functions.

The result is rather goofy, and not what I imagine “native” Lua would look like. If you want to, say, store the ID of your entity when it’s created:

1
2
3
4
5
function init(virtual)
    if virtual then return end

    self.id = entity.id()
end

self is a plain global table. entity is, likewise, a plain global table, but containing some API functions you can use that are specific to the entity you happen to be working with right now.

If a regular library API were implemented like this, it would seem ludicrous. Why should it be any different just because it’s part of a game engine?

This might be the hardest part of embedding any language: making it actually feel native to people who only see the guest side. If you’re going to embed a language, try writing a dummy plugin/script/whatever — before you design the API — the same way you would expect to write it if the entire engine were written in the guest language. Then embed the guest in such a way that it actually works.

To Lua’s credit, it doesn’t look like this ought to be particularly difficult; there’s a whole chapter on exposing custom C types to Lua, and the salient bits are pretty straightforward.

Hm. I just don’t have that much to say about embedding Lua; its own documentation lays out pretty much everything you might want to know. It’s designed for this very purpose, and it shows.

Python

Python is a pretty nice and featureful language, and it is embeddable, yet embedding it seems relatively uncommon.

I’ve asked around about this before, but it was many months ago and I don’t remember who it was or what they said, which is super helpful. I’ll do my best!

I’ve used the CPython C API before (to embed C in Python), and it contrasts very sharply with the Lua API. Where Lua’s API is clearly designed for embedding, CPython’s API is clearly designed for writing CPython. The exposed constructs are the ones used for implementing the standard library and the C parts of third-party libraries; if you want to embed CPython, you’re using the same wide array of fairly fiddly tools.

Python’s embedding documentation doesn’t have an exact analogue for the Lua config example, but I’ve crafted one myself:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <Python.h>

int load(char* modname, int* width, int* height) {
    Py_Initialize();
    PyObject* py_modname = PyUnicode_DecodeFSDefault(modname);
    if (! py_modname) {
        if (PyErr_Occurred())
            PyErr_Print();
        fprintf(stderr, "Couldn't decode module name \"%s\"\n", modname);
        return 1;
    }

    PyObject* py_module = PyImport_Import(py_modname);
    // This function wraps the commonly-used Py_DECREF macro, ensuring that you
    // get the right behavior even if running on a Python that was configured
    // differently, or something?  I dunno I read that somewhere
    Py_DecRef(py_modname);

    if (! py_module) {
        PyErr_Print();
        fprintf(stderr, "Failed to load \"%s\"\n", modname);
        return 1;
    }

    // TODO PyLong_AsLong can actually raise a (Python-land) exception, if the
    // number is too big to fit in a C long...  and of course a long might be
    // bigger than an int!
    PyObject* py_width = PyObject_GetAttrString(py_module, "width");
    *width = (int) PyLong_AsLong(py_width);
    Py_DecRef(py_width);
    PyObject* py_height = PyObject_GetAttrString(py_module, "height");
    *height = (int) PyLong_AsLong(py_height);
    Py_DecRef(py_height);

    Py_DecRef(py_module);

    Py_Finalize();

    return 0;
}

This is definitely, ah, wordier. (In fairness, I suspect the error() function in the Lua example is assumed to be supplied by you.) Most notably, you have to call Py_DecRef all over the place, and you have to understand what’s going on well enough to do it at the right times, or you’ll get a memory leak that’ll suck to track down. And this was just for reading two globals; calling a function is a bit worse.

On the other hand… from what I know of the CPython API, I can’t think of any reason why you couldn’t emulate something like the Lua stack. Define the stack as a structure that only exists in C; wrap the useful parts of the API in versions that interact with the stack instead; write some accessors for the stack that only expose C types instead of PyObject*s everywhere. Then the stack access functions could worry about refcounting, and C code would never have to think about it.

The result would be a bit more complex than Lua’s API, perhaps; Python has a lot of built-in types and a lot of “shapes” of types and overall just a really big API surface. Still, if you’re going to embed Python, I would definitely recommend wrapping up all the C API stuff in a simpler layer like this. I’m actually kind of surprised such a wrapper API doesn’t already exist.

That aside, there’s a much bigger problem with the above code, which is that it doesn’t actually work. I compiled it in a directory alongside this config.py file, then ran ./a.out config.

1
2
height = 600
width = 800

Result: ImportError: No module named 'config'.

Ah. sys.path is wrong. Regular ol’ Python will automatically add the current directory to sys.path if you do something like python -m config, but it seems the C API will not. And I… can’t figure out how to fix it. I can set the path manually to ., but then Python can’t find any of its own built-in modules any more, and nothing works at all — even decoding a bytestring requires the standard library. I could manually add . to the path after starting the interpreter, but surely that’s not the right way to fix this, right? A workaround is to run it as PYTHONPATH=. ./a.out config, but boy howdy is that ugly.

The problem isn’t so much this particular gotcha, but the wider issue that Python is designed as if it controlled the entire process. Its state is mostly global variables; it reads environment variables; it assumes it can look for modules as real files in standard locations. (Lua’s standard library is baked into its C, for better or worse.)

If you want to embed Python, you’ll need to think about how to map features like module importing — which has a bunch of implicit behavior perfectly suited for a standalone interpreter — to something more appropriate for your application. Where is Python’s standard library? Python can import from a zip file, and my compiled program’s sys.path even begins with /usr/lib/python35.zip (which doesn’t exist?), so this isn’t a terribly difficult problem to solve, but it’s something you have to think about from the get-go that you can pretty much ignore with Lua.

Also, do you want the entire standard library? I wouldn’t recommend eliminating all of it (though that does seem to be possible), as it’s a large part of the appeal of Python, but does embedded code need to be able to fork or start threads or spawn a GUI? Probably not, but now you have the tricky problem of sifting through some 200 modules to figure out what’s necessary and what’s not. If you don’t want embedded code to be able to read or write arbitrary files, you also need to strip out some builtins. Good luck.

Again, there’s nothing really stopping anyone from doing all this work for you and making it available as a wrapper. But no one has. Maybe I’m wrong, and the comments are full of links to projects that do exactly this! I sure hope so. If not, and you decide to build such a thing for your own project, please share it with the world.

Other potential roadbumps that come to mind:

  • You probably don’t want to start and stop the interpreter all the time, since Python has a lot of default state that it would have to create and destroy repeatedly.
  • Having multiple interpreters is possible, using “sub-interpreters”, but care is required — nothing prevents passing a PyObject* from one interpreter into another, for example.
  • I’ve heard that it’s difficult to use Python modules written in C from embedded Python, though I don’t know the details.
  • Python supports (OS) threads, so there are things to be aware of if you call into Python from different threads. I don’t know what those things are, exactly.

Other ways to embed Python

CPython’s API is not the only option. Perhaps one of these will be more helpful.

Boost.Python is a common suggestion, but it’s mostly intended for embedding C++ in CPython. It does have some support for embedding, but the second paragraph mentions “you’ll need to use the Python/C API to fill in the gaps”, which is not a particularly good sign. Still, this example code is much more encouraging than the equivalent using the C API:

1
2
3
4
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
object ignored = exec("result = 5 ** 2", main_namespace);
int five_squared = extract<int>(main_namespace["result"]);

In fact, I can rewrite my C example as something like this, which I have not bothered to test:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include <boost/python.hpp>

void load(string modname, int* width, int* height) {
    using namespace boost::python;

    object py_module = import(modname);

    *width = extract<int>(py_module.attr("width"));
    *height = extract<int>(py_module.attr("height"));
}

Certainly much better. No reference counting in sight; the object wrapper type takes care of it. Python exceptions are (partially) mapped to C++ exceptions, so the caller can worry about them. You’re not saved from the runtime concerns like where the stdlib lives, but your actual glue code is much less terrible.


Cython is another project originally intended for writing extension modules — it uses a modified Python syntax that compiles to C code using the Python API, and can operate on both Python and C objects interchangeably.

The good news is, it’s possible to embed the entire CPython interpreter with Cython! The bad news is, the documentation appears to consist solely of a one-page wiki article, a few mailing list threads, and a demo.

I do see a glimmer of real potential here. The part you compile is more or less just Python, which means you can write all your loading code in Python. That reduces the amount of C or C++ glue junk you have to write to nothing, an infinity-percent improvement.

Unfortunately, Cython produces a binary that just directly executes the compiled module. From what’s provided, I don’t see how you’re supposed to produce a C API you can call at will from other C code. So close! If only some project had done the same thing but actually finished and documented it.


CFFI did!

CFFI is a pretty slick library, not for writing extension modules, but for calling C library functions from Python. It’s kinda like ctypes, but with a less atrocious API and the ability to learn the C library’s API from its header files.

I found out yesterday that it now also supports embedding Python. It’s the same general idea as with Cython: you write some Python and it gets built into a shared library. But here, you can declare Python wrappers for C functions and C wrappers for Python functions, giving you an explicit list of interfaces between the environments. Particularly nice about this is that CFFI is already designed for wrapping C libraries, so you have a good shot at creating a Python API that actually feels Python-native.

As an added bonus, CFFI is built into PyPy, the JITted Python implementation, so you can use that instead of CPython if you like.

Alas, this still doesn’t save you from dealing with paring down and locating the stdlib. Someone should really figure that out once and for all, then tell the rest of us.

Conclusions

Lua is certainly the simpler option. You don’t even have to link to Lua; you can just drop the whole damn thing into your codebase and forget about it. The API is already fairly simple to use, which leaves you lots of spare dev time for making your API not be a few bags of injected globals.

On the other hand, if you really like Python, you might be willing to deal with its few extra headaches to get it embedded. It’s not as common as Lua, but it certainly can be done. The best option at the moment looks to be CFFI, which has some pretty clever people behind it who might be able to give you some pointers.

What a letdown. I really wanted to root for Python here. If only… if only there were some other way…

A third option: embedding in Python

If you ask the #python IRC channel about embedding Python in an application, you will almost always get the same response: don’t.

Instead, they’ll tell you, you should embed your application in Python.

Now, this isn’t always practical. If your application is intended to support plugins in multiple different languages, this is perhaps not the best approach. But if you only ever intend to support Python, and if you wish you could be writing Python anyway, this is entirely doable.

Remember that the biggest issue with embedding Python is that it’s designed assuming it controls the entire process. It has global state and tendrils into the system all over the place. In contrast, your application is probably less invasive, and you have complete control over it besides. So why not hand the wheel to Python?

Build your application like a library, then call its entry point from Python using one of the C embedding gizmos, like CFFI. You can pass Python callbacks into your C code with def_extern, or do the bulk of application work in Python and keep the heavy lifting in C, or whatever.

Then you can bundle and deploy the whole thing with any of the existing Python-to-executable tools: cx_Freeze, py2exe, py2app, PyInstaller, etc. (This isn’t a thing I have to do, so I don’t know which is the latest and greatest.) Or, hell, compile all your Python in Cython’s embedded mode.

This is a pretty radical departure from what people tend to mean when they say “embedding”, but it has the major benefit that there’s just far more C-in-Python tooling available than Python-in-C.

Alas! You still have to worry about paring down the standard library and builtins yourself, and that’s really tricky from pure Python. If you want arbitrary mods to be relatively safe for players to use, and you are not an expert on Python internals (I’m not!), you might have to stick with Lua.

A fourth option

Godot took the rather radical approach of creating their own vaguely Pythonesque language, GDScript.

Obviously this is a hell of a lot of work, especially if you’ve never designed a language before. On the other hand, the control over the embedding API and native types was apparently reason enough for the Godot developers. As I’ve previously mentioned, most programming languages are bad at expressing simulation, so a new language can be a chance to design some more appropriate syntax and types. (I can’t speak to whether GDScript has pulled this off.)

It’s not unheard of, either. RPG Maker had its own language before switching to Ruby a few years ago. The original Quake had QuakeC, though that was dropped in favor of native libraries in later engines. Unreal had its own language before… uh… ditching it two years ago. Hmm, maybe there’s a pattern here.

One thing GDScript does have going for it is that it kinda solves the problem of getting scripts to feel “native”, since the language itself is just designed to be native. In particular, scripts are associated with nodes, and everything in a script file is implicitly part of that node’s type (or class, if you must) in a way that plays pretty well with Godot’s concept of instancing.

I definitely wouldn’t advise designing your own language without a really good reason, especially not for just a single game. Language design is hard — most languages are still evolving to fill their gaps decades after they were first conceived.

But hey, if you do go down this road, for the love of god, please don’t base your language on Java or C. That gets you the worst of both worlds: all the introspection of a static compiled language with all the tooling of a dynamic language.

Appendix: the languages themselves

I don’t want to get into a huge language fight here. Lua is pretty good for what it is, which is an embedded dynamic language in 640KB of ultraportable C and nothing else. It has some goofy decisions, like using ~= for inequality and indexing arrays from 1, but whatever. It also has coroutines and metatypes, which is impressive. I only have a couple real beefs with Lua, and they’re mostly grievances I have with JavaScript as well:

  • There’s only one numeric type (number, double-precision floating point) and only one data structure (table). Ehh. You can return multiple values from a function or iterator, but there’s no real tuple type, and misusing a faux tuple will silently discard the unconsumed values.

  • Reading a nonexistent variable is not an error; it produces nil. Likewise (actually for the same reason), reading a nonexistent table entry silently produces nil. Writing to a variable that’s not declared local will silently create a new global.

  • If a function receives too many arguments, the extras are silently ignored. If too few, the missing ones default to nil.

  • There’s nothing like Python’s repr built in, let alone pprint. A table prints as table: 0xa6c300, without even delimiters around it. This is terrible — half the appeal of a dynamic runtime is the ability to inspect the state of your program from within itself, but the only data structure the language even has is opaque.

  • break and return have to be the last statement in a block. There’s a trivial workaround (wrap it in a dummy do ... end) but it’s still kind of annoying. Also there’s no continue.

  • You need the built-in debug library to do a lot of useful things, like print Lua tracebacks, but the Lua book advises disabling it in production builds because it allows Lua code to do naughty things. Indeed, Starbound doesn’t have debug. Trouble is, a production build of Starbound is the development environment for a mod.

These issues are compounded when Lua is embedded in a larger engine with a poorly-documented API, ahem. Mistakes like nils and typoed variable names can persist for several lines or several functions before causing any obvious errors, at which point you have to reload the entity (or as is oftne the case with Starbound, reload all the game assets) for every attempted diagnosis or fix.

Contrast with Python, which is perfect in every way.

Well, er. The biggest drawback with Python is the one I’ve already mentioned: it’s a general-purpose language which exposes a lot of general-purpose system functionality. If you don’t want your scripts to be able to start a web server, you’ll have to trim the language down into something more appropriate. (On the other hand, it looks like people are making use of sockets in Blender…) And what of the other things Python developers take for granted, like imports or the logging module? Do you support third-party modules? How? Do you respect Python’s environment variables? Where does print go? What do you do with all the goodies in the sys module — some useful, some nefarious, some a bit of both? How do you insulate scripts from each other; an entire sub-interpreter for each one? Did you know that CPython lets you construct, modify, and execute arbitrary bytecode? Do you need to protect against that? Or against using ctypes to call the CPython C API from Python code?

One other thought: Python has syntactic async support as of 3.5, which sounds like something that might be pretty useful in a game engine, but I have no idea how you would actually embed code that uses it. I’d sure be interested to hear if you got it to work, though.

Decimal sucks.

Ten is such an awkward number. Its only divisors are two and five. Two is nice, but five? Who cares about five? What about three and four?

I have a simple solution to all of these non-problems and more, which is: we should switch to base twelve.

A brief recap

For ease of writing larger numbers, we use places. The number “123” really means: three ones, two tens, one hundred. “Hundred”, of course, is just what we call ten tens.

This all assumes that ten is a magical number. It’s not. We generally have ten fingers, which makes it convenient. Mathematically, though, ten is not particularly special. We could just as well use a different number, like two (which gives us binary), or seven, or twelve. The number we pick, the number where the ones place gets full and rolls over, is called the number base.

We use decimal, base ten. This post is about duodecimal, base twelve.

It turns out that there are people who advocate for this. I haven’t read any of their writing, instead opting to do my own research. The one tidbit I’ve picked up is that they insist that base twelve be called dozenal, as the name “duodecimal” is still in terms of ten.

So, in dozenal, “123” means: three ones, two dozens, one gross. You know that number as one hundred and seventy-one.

To avoid confusion, all numbers in this post that are written with digits will be in dozenal. Words are independent of base — “thirteen” always means the same thing — so I’ll use those to translate.

Extra digits

Base ten has ten digits, so base twelve needs twelve digits. I need to pick some.

There are in fact already two dozenal digits in Unicode 8.0: ↊ U+218A TURNED DIGIT TWO and ↋ U+218B TURNED DIGIT THREE. Unfortunately, since these are very recent, font support is lacking.

There’s also the consideration of 7-segment LCD displays. An upside-down 3 would work fine and would resemble a capital E, but an upside-down 2 would look the same as a 5.

I mulled this over for a while and came up with:

  • ƌ for ten — resembles “d” for decimal, and displays in 7-segment like a mirrored 6
  • ⅃ for eleven — resembles a rotated 7, which it also rhymes with

No? Fair enough. These are all pretty awkward to type, anyway, even for me. I could use the more self-explanatory ⑩ and ⑪… but perhaps not.

For now, I’ll go with the old standby and use A to mean ten, B to mean eleven.

The numbers from one to twenty are thus written: 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, 10, 11, 12, 13, 14, 15, 16, 17, 18.

Got it? Super.

Twelve in daily life

We’re already surrounded by twelves. This year is 1200 in dozenal!

There are twelve months in a year. (Leap years are every four years, so in dozenal, a leap year would always be a year ending in 0, 4, or 8.)

There are twelve hours on the clock and sixty minutes in an hour (which is 50 — five dozen). Dozenal would let us save an entire digit on clock faces, since the hour will never be two digits; the moment before midnight is B:4B.

There are 10 (twelve) inches in a foot, 3080 feet in a mile (easily rounded to an even 3000). If metric were based on dozenal, the biggest part of the squabble between metric and imperial units would largely disappear.

Donuts come in dozens. It’s there in plain sight: a donut resembles a zero, and one dozen is written 10.

Teenagedom would begin at 10, and adulthood would be at 16, halfway to 20. No one would ever have lived to 100, though.

We have unique names for numbers from one to twelve; it’s only at thirteen that patterns start to emerge. We also already have a name for twelve twelves.

I had to learn times tables up to twelve in elementary school, which makes much more sense if twelve is written as 10.

Twelve digits would fit nicely in a 3×4 grid. Adding a fifth row for symbols (pound, star, something else?) would make the grid 3×5, which with square buttons is pleasingly close to the golden ratio.

A full circle is three hundred sixty degrees, which is a multiple of twelve. It’s also two and a half gross, i.e. 260.

Numbers would be eight percent shorter on average. (Dozenal can express everything up to one hundred forty-three with only two digits.)

Twitter might have rounded the number of available characters up from B8 to an even 100.

But wait!” I hear you cry. “Twelve might be great, but how do we count to it when we only have ten fingers?”

No problem! Check out your hands. Each of your fingers has two knuckles, which divide it into three segments. Three segments times four fingers makes… twelve! And your thumb is left over for keeping track of where you are. You can actually count higher with one hand in dozenal than with both hands in decimal! If you use your other hand for the dozens place, you can count all the way to 100 (a gross, one hundred forty-four) just on your fingers.

Arithmetic

Is exactly the same, but with two more digits. Carrying and whatnot are the same regardless of base; the only difference is that 9 + 1 is the single-digit A rather than wrapping around to two digits.

You can do long subtraction:

1
2
3
4
5
  23
  3̸4̸2
- 173
-----
  18B

Or long multiplication:

1
2
3
4
5
6
7
8
  342
× 173
-----
  A06
1B52
342
-----
54526

Or long division… which I will not attempt to Unicode-art here.

Fractions

Twelve is what’s called a highly composite number — it’s the smallest number with five divisors. (One, two, three, four, and six.) Ten, on the other hand, has three divisors (one, two, five), making it only as composite as six. What a waste.

The number of divisors is important, because it allows for many more “natural” divisions. Consider that most simple fractions in decimal repeat forever, making them ugly and cumbersome to work with. Well, check out some fractions in dozenal.

  • ½ = 0.6
  • ⅓ = 0.4
  • ⅔ = 0.8
  • ¼ = 0.3
  • ¾ = 0.9
  • ⅙ = 0.2
  • ⅚ = 0.A
  • ⅛ = 0.16
  • ⅜ = 0.46
  • ⅑ = 0.16

True, one-fifth is written as the somewhat less-pleasing 0.2̅4̅9̅7̅. But, honestly, who cares about fifths? Fifths are usually a cheap imitation of sixths, which are the beautiful 0.2 in dozenal.

You can see how nice this scheme really is when you consider it in terms of percentages. Decimal percentages are a little hard to reckon with, since so few of them divide evenly into one hundred — what does thirteen percent mean, exactly? (About one-eighth. You can’t even express a pizza slice as a whole percentage!) On the other hand, all of the above fractions can be expressed as whole dozenal percentages: one third is 40%, one half is 60%, one twelfth is of course 10%. Just look how many dozenal percentages ending in zero are really simple fractions.

Let’s say a percentage is “satisfying” if it can be converted into a fraction where at least two primes cancel out. For example, seventeen percent is just seventeen hundredths, which is unsatisfying; but thirty-two percent is eight twenty-fifths, which is at least partly simplified.

By this definition, only 28 whole decimal percentages are satisfying — that’s 3A%. But a whopping 48 whole dozenal percentages are satisfying, which is of course 48%! 48% is itself even satisfying; it’s seven eighteenths.

Divisibility rules

These are tricks like, “if the sum of the digits is divisible by three, the original number is divisible by three”. Dozenal has a different set of digits, so the same tricks won’t work.

However, the new tricks are often much easier. I went ahead and figured some out:

  • 2: If the last digit is divisible by two (0, 2, 4, 6, 8, or A), the number is divisible by two.

  • 3: If the last digit is divisible by three (0, 3, 6, or 9), the number is divisible by three.

  • 4: If the last digit is divisible by four (0, 4, or 8), the number is divisible by four.

  • 5: Multiply the last digit by two, and subtract from the rest of the number. If the result is divisible by five, the original number is divisible by five.

    Here’s an example, for the number B3 (one hundred thirty-five).

    Take off the 3 and double it to get 6. The rest of the number is B (eleven). B - 6 = 5, which is divisible by 5, so B3 is also divisible by 5.

  • 6: If the last digit is divisible by six (0 or 6), the number is divisible by six.

  • 7: Multiply the last digit by three, and add it to the rest of the number. If the result is divisible by seven, the original number is divisible by seven.

  • 8: If the last two digits are divisible by eight (0, 8, 14, 20, 28, 34, …), the number is divisible by eight.

    Alternatively, but more of a mouthful, you can see a pattern in the numbers above. If the last digit is 0 or 8 and the dozens digit is even, OR the last digit is 4 and the dozens digit is odd, the number is divisible by eight.

  • 9: If the last two digits are divisible by nine (0, 9, 16, 23, 30, …), the number is divisible by nine.

    Again, there’s a pattern in the numbers, though this one is more complicated.

  • A (ten): Must be divisible by both two and five.

  • B (eleven): Add all the digits. If the result is divisible by eleven, the original number is divisible by eleven.

  • 10 (twelve): If the last digit is 0, the number is divisible by twelve.

  • 11 (thirteen): From left to right, alternate subtracting and adding the digits. If the result is divisible by thirteen, the original number is divisible by thirteen.

    Here’s an example, for 891 (one thousand two hundred sixty-one, or thirteen times ninety-seven).

    Compute 8 - 9 + 1; it’s zero, which is divisible by thirteen, so the original number is too.

  • 12 (fourteen): Must be divisible by both two and seven.

  • 13 (fifteen): Must be divisible by both three and five.

  • 14 (sixteen): If the last two digits are divisible by sixteen (0, 14, 28, 40, 54, …), the number is divisible by sixteen.

The primes start to get trickier after that.

Dozenal and computers

A double-precision floating point number has fifty-three binary digits. That’s only (barely) sixteen decimal digits of precision. In dozenal, it’s slightly worse at almost fifteen digits, since each dozenal digit stores more information.

A byte is 8 bits and can hold a value up to 193. Two bytes is 14 bits and maxes out at 31B13 (a lovely palindrome!). Four bytes is 28 bits, max 9BA461593. Eight bytes is 54 bits, max 839365134A2A240713. Six bytes is, pleasingly, 40 bits.

A kilobyte (kibibyte, if you must) is 714 bytes… but of course, we wouldn’t define it that way if we used dozenal. We like one thousand twenty-four because it’s a power of two that’s coincidentally very close to a power of ten. This doesn’t really happen in dozenal until 2¹⁶ = 107854. But hey, that means we’d never have had this ridiculous inconsistency in advertised hard drive space; we would’ve just said a kilobyte is 1000 bytes from the beginning. If so, a two terabyte hard drive would be described as a paltry 2B6 gigabytes.

With two extra digits, ASCII would have two fewer slots available for punctuation. I wonder which two wouldn’t have made it?

Unicode would have space for 458,8A7 characters.

Some familiar numbers

The square numbers up to 20 are 1, 4, 9, 14, 21, 30, 41, 54, 69, 84, A1, 100, 121, 133, 169, 194, 201, 230, 261, 294, 309, 344, 381, 400.

The primes up to 200 are 2, 3, 5, 7, B, 11, 15, 17, 1B, 25, 27, 31, 35, 37, 3B, 45, 4B, 51, 57, 5B, 61, 67, 6B, 75, 81, 85, 87, 8B, 91, 95, A7, AB, B5, B7, 105, 107, 111, 117, 11B, 125, 12B, 131, 13B, 141, 145, 147, 157, 167, 16B, 171, 175, 17B, 181, 18B, 195, 19B, 1A5, 1A7, 1B1, 1B5, 1B7. Notably and pleasingly (to me, anyway), 101 is composite: it’s 5 × 25.

π = 3.184809493B918664573A

τ = 6.349416967B635108B279

e = 2.8752360698219BA71971

√2 = 1.4B79170A07B85737704B

φ = 1.74BB6772802A46A6A186

It’s suspected that π is a normal number — that is, it has an even distribution of all possible digits no matter what base you write it in.

Okay uh

This is less of a case for base twelve and more that I wanted to write a bunch of math stuff and play in a different base. This post isn’t really going anywhere in particular, so I’ll arbitrarily cut it off here. I hope you enjoyed this hazy thought experiment, if you read this far.

I like to remember sometimes that even many of the things we take for granted — like the way we write numbers — are still arbitrary conventions.

Decimal does suck a bit, though.

Appendix: convert to a base in Python

Curiously, Python can convert integers from any base, but can’t handle floats or convert to an arbitrary base. So here is some code that can, and that also handles negative numbers and floats. And fractions.Fraction. And decimal.Decimal. And complex numbers.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def tobase(n, b, precision=20, digits='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
    # Split off any imaginary part to be dealt with later
    imag = n.imag
    n = real = n.real

    # Handle negation separately
    neg = False
    if n < 0:
        n *= -1
        neg = True

    # Split off any fractional part
    n, frac = divmod(n, 1)
    n = int(n)

    # Convert to base b.  Yep, that's all it takes
    out = []
    while n:
        n, r = divmod(n, b)
        out.append(digits[r])

    if neg:
        out.append('-')

    # Converting to a base moves away from the decimal point, so these digits
    # are in reverse order and need flipping before dealing with a fraction
    out = out[::-1]
    if frac:
        # Leading zero if necessary
        if not out:
            out.append(digits[0])
        out.append('.')
        for _ in range(precision):
            if not frac:
                break
            d, frac = divmod(frac * b, 1)
            out.append(digits[int(d)])

    # Add any imaginary part, keeping in mind that there might not even be a real part
    if imag:
        imagres = tobase(imag, b, precision=precision, digits=digits)
        if not real:
            return imagres + 'j'
        if imag > 0:
            out.append('+')
        out.append(imagres)
        out.append('j')

        # Python's repr wraps fully complex numbers in parentheses
        if real:
            out.insert(0, '(')
            out.append(')')

    return ''.join(out)

Appendix: deriving divisibility rules

How did I figure out the rules above? I’m glad you asked because that’s actually super interesting.

The reason we have divisibility rules at all is that someone has already done a bunch of division for you, by virtue of writing the number out in digits. That’s how you convert an abstract number to something you can write out: you divide repeatedly by twelve, or ten, or whatever base you’re using. A divisibility rule is a trick for taking that work and adapting it to a different divisor.

Easy cases

The easiest cases are for divisibility by d, where the base itself is already divisible by d. You only have to look at the last digit. That’s why picking out even numbers in both decimal and dozenal is so easy — the base is divisible by 2, so the last digit gives away whether an entire number is divisible by 2.

I think this is pretty intuitive. Count up by twos: 2, 4, 6, 8, A, 10. Every sixth number will roll over the ones place into the dozens place, and reset the ones place to zero, which is where it started. Counting like this will eventually find every multiple of two… so every number ending in an even digit must be divisible by two, and no number divisible by two can ever end in an odd digit.

Symbolically, you can write any natural number as:

1
n = 10x + y = (2 · 6x) + y

where y is the ones digit and x is all the rest of the digits. This is just the definition of how we write numbers; 984 is really 98 · 10 + 4.

x must be an integer, since it’s just digits, so 2 · 6x must be even. Iff y is also even, the original number must be even.

You can easily do the same thing for any number that’s a factor of the base. For decimal, that’s two, zero, and ten; for dozenal, it’s two, three, four, six, and twelve. Consider for a moment that that means if we used an odd base, you couldn’t easily tell whether a number were even! It’s only trivial in decimal because ten is a multiple of two.

You can also extend this to work for any number that’s a factor of a power of the base. Dozenal’s divisibility rule for 9 is to look at the last two digits of the number. That’s because:

1
n = 100x + y = (9 · 14x) + y

This time, y is the last two digits, but otherwise it’s the same idea. There’s a similar rule in decimal for divisibility by four (though you only need one digit to work that out in dozenal).

Special cases

Most shenanigans that involve looking at individual digits actually work just as well in dozenal, or any base, but perhaps with different results. Of particular interest: in base b, the same divisibility rules for b - 1 and b + 1 will always work.

Adding all the digits works for b - 1. To prove this, consider a simpler case: instead of adding all the digits together, add the last digit (y) to the rest of the digits (x) to make a new number, s. Then:

1
2
3
4
n = bx + y
s = x + y

n - s = (bx + y) - (x + y) = bx - x = (b - 1) · x

n - s is always divisible by b - 1. Thus, if s is also divisible by b - 1, the original number must be — because it’s just the sum of these other two numbers.

Summing all the digits is just a matter of repeating the above process.

Incidentally, the decimal rule for 3 exists specifically because 3 is a factor of 9, one less than ten. (Eleven is prime, so this doesn’t come into play with dozenal.) You can kind of see how it works above. Hint: n and s have the same remainder when dividing by b - 1.

b + 1 has several possible rules; I used the one I like the most, which is to alternate adding and subtracting. Note that it doesn’t matter whether you start out subtracting or adding; x - y + z is just the negation of -x + y - z.

If we split off two digits separately this time, we get:

1
2
3
4
5
6
n = b²x + by + z
s = x - y + z

n - s = (b²x + by + z) - (x - y + z)
      = (b² - 1)x + (b + 1)y
      = (b + 1)(b - 1)x + (b + 1)y

Same thing happens here: n - s is always divisible by b + 1.

Hard cases

Decimal doesn’t have a “hard” case until seven; dozenal has one as early as five. I basically reverse-engineered the decimal rule for seven to figure out the rest.

Let’s play with my rule for five (multiply the last digit by two, and subtract from the rest of the number) and see what happens.

1
2
3
4
n = 10x + y
s = x - 2y

2n + s = 2(10x + y) + (x - 2y) = 21x

Aha. 21 is twenty-five, which is divisible by the number we’re interested in, five. So 2n + s is always divisible by five. If s is also divisible by five, then 2n must be… and the 2 isn’t contributing to divisibility here, so the original number must also be divisible by five.

I came up with this by looking for a number c that would work out nicely:

1
2
3
4
5
n = 10x + y
s = x + cy

cn - s = (10c - 1)x
s - cn = (-10c + 1)x

For either of those expressions to be divisible by five, I need a number ending in either 1 or B that’s a multiple of five. I listed out the multiples of five until I found one: 5, A, 13, 18, 21, aha! That gives me c = -2.

This works for any (prime…ish…) number, though the values of c start to get a little ridiculous if the number you want to test is very large. I did come up with a divisibility rule for nineteen, for example, by counting multiples: 17, 32, 49, 64, 7B. c = 7, and you just need to multiply the last digit by seven and add it to the rest of the number, then repeat until you can tell whether it’s a multiple of nineteen. Yikes.

Also, note that the expressions above don’t actually do any math with 10, which is really b, the base you’re working in. Exactly the same approach would get you the decimal divisibility rule for seven — seven times three is twenty-one, so c is -2, and the rule is… coincidentally, exactly the same as dozenal’s rule for five.

April’s theme is finish Runed Awakening.

Mel is out of town, so I’m being constantly harassed by cats.

  • irl: I cleaned the hell out of my room.

  • Runed Awakening: I finally figured out the concept for a decent chunk of the world, and built about half of it. I finally, finally, feel like the world and plot are starting to come together. I doubt I’ll have it feature-complete in only another week, but I’m miles ahead of where I was at the beginning of the month. The game is maybe 40% built, but closer to 80% planned, and that’s been the really hard part.

    I’d previously done two illustrations of items as sort of a proof of concept for embedding images in interactive fiction. A major blocker was coming up with a palette that could work for any item and keep the overall style cohesive. I couldn’t find an appropriate palette and I’m not confident enough with color to design one myself, so the whole idea was put on hold there.

    Last week, a ludum dare game led me to the DB32 palette, one of the few palettes I’ve ever seen that has as many (!) as 32 colors and is intended for general use. I grabbed Aseprite at Twitter’s suggestion (which turns out to default to DB32), and I did some pixel art, kind of on a whim! Twitter pretty well destroyed them, so I posted them in a couple batches on Tumblr: batch 1, batch 2, and a little talking eevee portrait.

    I don’t know if the game will end up with an illustration for every object and room — that would be a lot of pixels and these take me a while — but it would be pretty neat to illustrate the major landmarks and most interesting items.

  • spline/flora: I wrote a quick and dirty chronological archive for Flora. I then did a bunch of witchcraft to replace 250-odd old comic pages with the touched-up versions that appear in the printed book.

  • blog: I wrote about elegance. I also started on another post, which is not yet finished. It’s also terrible, sorry.

Sources:

Forum activity

The forums are dead quiet. No one is posting. A lone tumbleweed rolls by.

Maybe you should do something about this.