Let’s make a language – Part 3a: Language Types (Intro)

The sounds a language contains can go a long way toward giving that language a specific “feel”. But the very structure of the words themselves creates another kind of feel. Think of German, with its immensely long words full of consonants. Compare that to Chinese words, short and to the point, but combined in numerous ways to make new phrases. Latin has tables of declensions, as any student knows, while English gets by with only a few variations in its word forms.

All of this comes under the field of morphology, which is, in essence, a parallel to phonology. Where phonology is concerned with a language’s sound inventory, morphology goes up to the next step: the building blocks of words. Not necessarily the words themselves, as we shall see. But first, we need to meet the morpheme.

The Morpheme

A phoneme, as we know, is the most basic unit of sound distinguished in a language. By analogy, then, a morpheme is the basic unit of grammar. This may surprise some people. After all, aren’t words the smallest part of grammar?

Well, sometimes. Words can be made of a single morpheme, and English has plenty of examples: dog, walk, I. These are called free morphemes, because they can stand alone as words in their own right. In contrast, the English plural ending -s and the past tense suffix -ed can’t be alone. They have to be attached to other morphemes to create a legitimate word, so we call them bound morphemes. Thus, the English sentence I walked the dogs has four words, but a total of six morphemes.

Languages can divide up their morphemes, free and bound, in numerous ways, but they can all be defined in two dimensions. First, how many morphemes are there in a word? Or, to put it another way, what’s the ratio of free to bound?

Isolating vs. Polysynthetic

This distinction is an easy one to think about. Look at English words like predestination or internationalization. They’re big words, and they have a lot of morphemes. “Internationalization”, as an example, has the free (“root”) morpheme nation surrounded by the bound morphemes inter-, -al, -ize, and -ation, for a total of five.

Not every language is like English, though. Many, instead, only really allow one or two morphemes per word, preferring to build their larger “words” as phrases constructed from multiple free roots. The Chinese languages are well-known examples of this style. They, and those like them, are called isolating languages, since their words are “isolated”, or able to stand alone.

The other extreme is exemplified by languages such as those of the Eskimo and Inuit peoples. Here, words can be constructed to mean entire sentences, and they are full of bound morphemes. Not only is the marker for tense stuck to the verb, but verbs and nouns themselves are welded together, and the whole thing becomes a single word. To demonstrate, I’ll copy Wikipedia’s example, the Yupik word tuntussuqatarniksaitengqiggtuq, meaning “He had not yet said again that he was going to hunt reindeer.” Wow. (By the way, this is one reason for the linguistic urban legend that the Eskimos have a hundred words for snow. Sure they do, if you count something that means “it’s going to snow tomorrow morning” as a word. But they certainly don’t have that many free morphemes that convey the meaning of “snow”.) Languages like these, where there are often many morphemes in a word, most of them bound, not allowed to stand by themselves, are called polysynthetic languages.

Of course, a language can be in the middle of this spectrum. Isolating versus polysynthetic isn’t a binary choice. English, after all, has plenty of cases of both isolation and (mild) polysynthesis. Indeed, most of the more common languages of the world fall near the muddy center of the continuum. Chinese, of course, is very isolating. English is kind of right in the middle. Turkish and Finnish are quite polysynthetic, though more of a type that we’ll see below. French manages to put one foot in either world, with a highly isolating written language that’s often spoken like it’s polysynthetic.

Conlangs tend to follow their authors’ leanings. Some like the exotic allure of polysynthetic languages, while others choose the stark simplicity of the isolating. Most, though, are somewhere in between, like the native tongues of their creators. Certainly, an auxiliary language shouldn’t be nearly as polysynthetic as Inuktitut. But that same style can definitely give an alien vibe to an otherwise simple language. An isolating style, on the other hand, could conjure up images of the East, or of Pacific pidgins and creoles.

Agglutinating vs. Fusional

For those languages that have them (purely isolating languages need not apply), bound morphemes are often used to indicate grammatical relationships. Again, we can look at English: plural -s, past tense -ed, etc. Most of these have a specific meaning, but not all. On verbs, -s marks the third person, but only the singular version: compare “he walks” and “they walk”. This is the second “dimension” of a language, and it asks, “How much meaning does a bound morpheme have?”

Like above, there are two paths we can choose. With a few exceptions (like verbal -s), English takes the “one morpheme, one meaning” approach. Thus, it’s fair to say that English is an agglutinating language. Turkish is a popular example of taking this to the extreme, as Turkish verbs can have a string of suffixes: one for person, one for tense, and so on. German’s interminable compounds are much the same, but with more “meaning” for each morpheme beyond mere grammatical marking.

At the other end of the spectrum, you have the fusional languages including, for instance, the Romance family. Take the Spanish word amó, which we can translate as “she loved”. We’ve got a root am- (amar in its dictionary form) and a suffix , and that’s it. But we know that it’s in the third person, past tense, and singular. (Spanish doesn’t distinguish gender in verb conjugation, though, so it could equally mean “he loved”.) Three separate meanings “fused” into a single suffix. And we know this by looking at a Spanish conjugation table. Change the person to first, and the word must become amé. Plural instead of singular? You have to say amaron. Want it to be in the future, rather than the past? It’s now amará. Alter any one part, and you need a whole new morpheme.

Like in the first case above, few languages fall on the absolute extremes of the agglutinative/fusional spectrum. English is mostly agglutinative, Spanish mostly fusional, but both have exceptions. The fusional type, though, seems a bit more popular in Europe (as you can see from the number of languages with declensions and inflections and make it stop), meaning that it’s better represented at the top of the chart. But even Europe has its agglutinative sect: English and Finnish, among others. Elsewhere, it really depends.

For conlangs, it still depends. Westerners are familiar with fusional languages, but agglutinating has a mechanical appeal, and it’s definitely a lot easier to work with. Auxiliary languages might be best served by a hybrid approach, where there are mostly agglutinative elements, but a few fusional aspects added where they can simplify things (like English’s verbal -s). (And if you’re making a purely isolating language, you can completely ignore the whole thing!)

Next Time

In the next post, we’ll look at Isian and Ardari and how they fit into the two-dimensional world of isolating and fusional and agglutinating and polysynthetic. The results may shock you! Oh, and we’ll also start making actual words in our two conlangs. Yes, finally.

A simple constexpr power function (C++)

Since C++11, programmers have been given the power of compile-time calculation without the hassles of template metaprogramming. (And they are hassles, believe me.) The canonical example is a factorial function completely evaluated by the compiler, but here’s another, different use, one that has much more utility.

The Power Function

It’s a sad fact that C++ has no power operator. Sure, we have the std::pow function inherited from C, but that works at runtime, which means we can’t use it in template arguments. Most notably, we can’t say something like array<int, pow(4,4)>. In other words, we aren’t allowed to use a power function when declaring the size of a C++11 array. Most users, of course, will never need it, but you never know when it might come in handy, so here it is:

template <typename T>
constexpr T ipow(T num, unsigned int pow)
{
    return (pow >= sizeof(unsigned int)*8) ? 0 :
        pow == 0 ? 1 : num * ipow(num, pow-1);
}

There are a few caveats. First, it’s (obviously) a template, so you can use it on integers, doubles, or anything else that has a binary operator* (i.e., the arithmetic one, not the pointer one). All it does is the classic “raise to a power” algorithm: repeatedly multiply a number by itself. Like the typical factorial function, it’s really written in a function mode. It even has a proper tail call, if you’re into that sort of thing. Incidentally, that’s why the second argument (the power to raise to) must be an unsigned int: you can’t use the elementary-school method with fractional powers, and raising an integer to a negative power gives you a fraction, which means that there could be type issues.

The second thing to notice is that it could use some better error handling. I put a check in to keep somebody from calling it with some huge power like 1,000,000, but all it does is return 0. It should probably throw an exception, instead. Maybe I’ll change it in version 2.

Last, this clearly won’t be useful for a class where “raise to a power” isn’t the same thing as “multiply by itself over and over”. But if I had to guess, I’d say that there aren’t too many places where you’d want to raise that kind of object to a power at compile-time. I’d love to see a counterexample, though.

Anyway, that’s all for this time. I intend to expand on this idea (complex arithmetic at compile-time) later, so I’ll see you then.

On magic and technology

“Any sufficiently advanced technology is indistinguishable from magic,” says Clarke’s third law. But the reverse is true, too, especially in fantasy. It’s a staple of the genre that magic exists (at some level), but there are few authors who take the time to truly illustrate that fact. If magic exists in any predictable form (not just, for example, as the powers of capricious gods), then it can and will be predicted, if human evolution is any indication. In a few thousand years, we’ve gone from hunters and gatherers to spacefarers, and we’ve used everything at our disposal to get there. Why wouldn’t we use magic, too, if we could?

Fantasy, particularly high fantasy, apparently doesn’t work that way. Magic is often seen as a natural force that can’t truly be harnessed, even by those mages who wield it. Very rarely are its effects on society shown, and then usually as something like an evil wizard overlord terrorizing his subjects or a land made inhospitable by a magical explosion.

But we can do better. Indeed, some authors do go to the trouble of working out the consequences of their world-building. (Whatever your opinions on his writing and stories, Brandon Sanderson is certainly one of these, and he’s only one of the most popular.) Fantasy doesn’t have to be restricted to the generic European Middle Ages setting, nor should it be. In science fiction, it’s common to take a single development (the invention of faster-than-light travel, say) and write a story around the fallout of that development. My argument, then, is that fantasy authors should do the same kind of world-building, even if it’s only for background, because it creates a deeper, more immersive world.

So, we’ll assume that we all agree that fantasy needs world-building, too. And fantasy’s replacement for advanced technology is magic. Thus, it stands to reason that magic is the focal point for our world. Now, we can ask a few questions about that magic, and we can follow a logical path to a magical world.

How many mages?

First, just how common is magic? Are there only a few mages in the world? Or even a single one? Lord of the Rings, for instance, only has a handful of magic users in all of Middle-Earth. Although they’re pivotal to the plot, they don’t really affect the world all that much. By contrast, a series like Jim Butcher’s Codex Alera has a world where essentially everybody uses magic, and it’s a whole different place.

If magic is all-powerful (or even just plain powerful), and there aren’t that many mages, then those lucky few are probably going to be in positions of power. There’s no real reason they won’t be. Think of Watchmen, but imagine that they’re wizards instead of superheroes. For that matter, think of Sauron. If there are only, say, a dozen wizards in the world, but they can call down the wrath of the gods, they won’t be advisors to kings. They’ll be the kings. You’ll need some serious contrivances to make a realistic case that a handful of powerful mages won’t be the leaders of the known world. Gandalf, for example, is truly good, but even he admits he can be tempted by the power of the One Ring. The same for Galadriel, with her “in place of the dark lord, you would have a queen” speech.

Give the world more magic users, and things begin to change, as long as their power is “diluted” by numbers. One mage in every city, easily killed if you can get the jump on him, might still lust for power, but he won’t be able to get as much of it. Put a low-level mage in every village and town, and it becomes just another craft like smithing. This is the default assumption of the sword and sorcery genre, especially that based on tabletop RPGs.

With magic slightly uncommon (somewhere on the order of one wizard for every thousand people), users will be respected, but not deified. And that’s a lot of mages: that same ratio would give us seven million magic users today. In other words, everybody in Hong Kong is a wizard. Somewhere around this point, the medieval/D&D assumptions go out the window. Sure, you’d probably have magical schools and guilds, but the world would change drastically.

Go to the extreme, let everybody tap the power of the arcane, and the world is a totally different place. At this point, you’re not really writing about the human race anymore. You’re writing about a race of mages that look human. If magic is that common, it won’t live alongside technology at all. Instead, it might entirely take technology’s place. Why invent a lighter when a fire spell works even better? If you can concentrate energy into a tiny ball of lightning, then who needs electricity? Working out the specifics of a “ubiquitous magic” setting is a topic for a later post, but you should try to imagine the repercussions of giving magic to the whole world.

What kind of magic?

What does magic do? Can it be used to create, or only destroy? In Scott Bakker’s Prince of Nothing series (and its sequels), it’s an overriding theme that sorcerers can only mar the world’s perfection, like a child’s scribbles across a painting. They can’t make things truly beautiful. They can’t remake things. Magic is, to a first approximation, only destructive. (There’s a lot more to it than that, but that’s the general idea.) D&D’s Dark Sun setting is another take on this “creation and destruction” dichotomy.

In a world like this, where magic can only be used to harm, not help, it will certainly be weaponized. That’s just human nature. We’re always looking for better ways to kill (and to protect ourselves). But destructive magic will also have use outside of warfare, just like guns today. Destructive magic could still be used for the benefit of society. Think building demolition, clearing weeds from a field, mining, and even simple hunting.

If you allow for creative magics, then a whole new world opens up. Magic can become an art form, a craftsman’s tool, in addition to being a weapon of conquest or defense. In a “binary” world of creative and destructive magic, users of either side might actually work together, each using their own specialties. After all, building a house takes more than a construction crew. Sometimes, you need bulldozers.

With a magic system that divides the arcane into smaller pieces (elements, colleges, or whatever you want to call them), you start to get a rich background ripe for factional conflict. But there will also be knock-on effects in society at large. Fire mages would be awfully popular in the frozen wastelands of the north, while water or weather wizards could take the place of irrigation systems in arid regions. Magic then becomes a trade, and therefore subject to economic forces like supply and demand. (Again, the full ramifications can wait until a future post, but feel free to speculate.)

Other ideas

There are so many “what if?” questions one could ask about magic that a single post can never answer them. I couldn’t even begin to try. But here are a few that I feel are worthy of note. What if…:

  • …magic is technology? Namely, it’s the machinery of a long-lost civilization. This neatly ties back into Clarke’s law by making magic and advanced tech equal, instead of merely equivalent.

  • …magic is new to the world? If we discovered magic next year (i.e., 2016), then the world in, say, 2066 would be far different than if magic was first found in 1066.

  • …magic is religious? Honestly, I don’t see that changing much. Clerics and wizards aren’t that different. As long as it’s predictable and testable, it doesn’t matter whether magic comes from God, the earth, ley lines, or solar radiation.

  • …our enemies obtain magic? It’s no different from any other weapon of mass destruction, really. Sure, the idea of ISIS with guns and fireballs might be terrifying, but, unless magic makes them invincible, there’s only so much they can do.

  • …magic changes you? Plenty of authors have tried this one. (Hopefully, I’ll be guilty of it by this time next year.) The use of sorcery–since it’s usually called such in those settings–taints your soul, destroys your mind, or wrecks your body. In that case, yeah, mages might limit the use of their power, but that would actually serve to make magic seem more…magical. Fireworks would lose their luster if they weren’t limited to the Fourth of July and New Year’s. Plus, magic that can only be used so many times would be saved for the times when it’s really needed, and that sounds like an interesting story to me.

The end…?

I’ll write more on this subject later. An idea I have (that I may not actually do) is a whole constructed culture, similar to the “Let’s make a language” series, but exploring the ways a culture is shaped by its environment, its history, and itself. That’s for later, though. For the next post, I want to take our idea above–magic as technology–and run it to its logical conclusion: “magitech”.

Let’s make a language – Part 2b: Syllables and Stress (Conlangs)

Okay, last time we ran a bit long. This one should be fairly short. Today, we’ll look at the syllable structure and stress patterns of our two conlangs, Isian and Ardari. There’s no sense wasting time; let’s get right to it!

Isian

Isian, remember, is going to be the simpler of the two, so we’ll start with it. Isian syllables, for the sake of simplicity, will be of the form CVC. In other words, we can have a consonant on either side of a vowel. We don’t have to, of course. Syllables like an or de are just fine. CVC is the “maximum” complexity we can have.

Obviously, the V can stand for any vowel. (It’d be kind of silly to have a vowel you couldn’t use, wouldn’t it?) Similarly, the first C stands for any consonant. For the second C, the coda, that’s where things get a little more complicated. Two rules come into effect here. First, h isn’t allowed as a final consonant. That makes a lot of sense for English speakers, who find it hard to pronounce a final /h/, although it might upset speakers of other languages. Again, simple is the name of the game.

The second rule concerns diphthongs. If you’ll recall from Part 1, Isian has six of them. Here, we’ll say that /w/ and /j/ (written w and y) can only be the final consonant if they follow a, e, or o. This matches our phonology, where /ij/, /iw/, /uj/, and /uw/ aren’t allowed. Thus, diphthongs can be neatly analyzed as nothing more than a combination of vowel and consonant.

Moving on, we’ll give Isian a fixed stress: always on the penultimate syllable. So a word like baro will always be pronounced /ˈbaro/, never /baˈro/. Words with three syllables follow the same pattern: lamani is /laˈmani/. Since a diphthong is just a vowel plus a consonant, they don’t affect stress at all: paylow will be /ˈpajlow/.

In longer words, we’ll extend this stress in the same way. Or, to put it another way, every other syllable will get some sort of stress. A hypothetical word like solantafayan would have a secondary stress: /soˌlantaˈfajan/.

There won’t be any vowel reduction in Isian. Like Spanish, every vowel will be sounded in full, and each syllable will take up about the same time. This, combined with the regular stress, will probably give the conlang a distinct rhythm. (The dominant form of poetic meter, for example, will definitely be trochaic, and Isian musicians would probably find Western 4/4 rhythms very appealing.)

Ardari

As usual, Ardari is a bit more complicated. For this language, syllables will have the structure CCVCC, and each of the four C’s will have a different set of possibilities:

  1. The first C can be any stop consonant, /m/, or /n/.
  2. The second C can be any fricative or liquid except /ɫ/, except a fricative can’t follow a nasal.
  3. V, of course, stands for any of the ten Ardari vowels.
  4. The third C is restricted to four liquid sounds: /w j ɫ ɾ/
  5. Finally, the fourth C can be any consonant except those four liquids.

Now, in addition to these definitions, Ardari syllables have a few rules about which clusters of consonants are available. In the onset, there are three broad categories: stop + fricative, stop + liquid, and nasal + liquid. The last is the smallest, so we’ll deal with it first. For that combination, there are eight possibilities: /mw mj ml mɾ nw nj nl nɾ/. Of these, we’ll say that Ardari doesn’t allow a nasal followed by /l/. Also, /nj/ isn’t that much different from /ɲ/, so we’ll say that those two sounds merge, allowing a syllable that starts with /ɲ/, but nothing else. The remaining five clusters can go in as they are.

For the combination of stop and fricative, things get trickier, because of Ardari’s rules about voicing and palatalization. Rather than a system, it might be best to show precisely which clusters are allowed:

  • Bilabial + fricative: /pɸ bβ pʁ bʁ/
  • Alveolar + fricative: /ts dz tɬ tʲs dʲz tʁ dʁ/
  • Velar + fricative: /kʁ gʁ kʲɕ gʲʑ/

For stops and liquids, we’ll do the same thing:

  • Bilabial + liquid: /pl pɾ pʲʎ pw bl bɾ bʲʎ bw/
  • Alveolar + liquid: /tw tɾ tʲɾ dw dr dʲr/
  • Velar + liquid: /kw kl kɾ kʲɾ kʲʎ gw gl gʲɾ gʲʎ/

At the end of a syllable, the clusters /ɫʁ ɾʁ ɫl ɫʎ wʎ ɾʎ ɫɲ ɾɲ/ aren’t allowed, but any others that fit the syllable structure are. (This is mainly because I find them too hard to pronounce.)

Ardari stress is free, but predictable. Syllables that have coda consonants other than just /w/ or /j/ are considered heavy, while all others are light. For most words, the stress will be on the last heavy syllable. (Secondary stress will fall on any heavy syllable not adjacent to another one.) Words with only light syllables are stressed on the penultimate, as are all words with exactly two syllables. For all of these rules, there is an overriding exception: /ɨ/ and /ə/ can never be stressed. If they would be, then the stress is moved to the next syllable. So, examples of all of these, using hypothetical words:

  • Basic stress pattern: sembina /ˈsembina/, karosti /kaˈɾosti/, dyëfar /dʲəˈfaɾ/.
  • Secondary stress in long words: andanyeskaro /ˌandaˈɲeskaɾo/.
  • Two syllables: meto /ˈmeto/, kyasayn /ˈkʲasajn/.
  • All light syllables: taralèko /taɾaˈlɛko/.
  • Stress moved because of vowel: lysmo /lɨsˈmo/, mönchado /mənˈɕado/.

Because of the vowel reduction, Ardari will likely be a more free-form language than Isian, poetically speaking. Indeed, it will probably sound a lot more like English.

Next Time

With this post, we now have enough information to start making words in both our conlangs. That may even be enough for some people. If all you need is a “naming” language, you don’t have to worry too much about grammar. That said, stick around, because there’s plenty more to see. Next up is a theory post where we begin to give our words meaning, and we find out just how many words the Eskimos have for snow. See you then!

Introduction to ES6 Modules for Game Programmers

As an application (be it a game or anything else) grows, so does the need for some sort of organization. Also, all but the simplest programs will require the use of some sort of additional libraries. For both of these reasons, just about every programming language meant for serious use has a way to separate code into logical, self-contained blocks. Even lowly C has its header files, but more modern languages can do more.

JavaScript, however, used to be sorely lacking in this department. Sure, you can load additional scripts in a web page, and jQuery (to name one example) managed an entire plugin architecture using DOM onload events. But everyone recognized that this wasn’t enough, and thus modules were born.

The problem is, they weren’t a part of the JavaScript “core”, so there was no standard way of making or using a module. Node made its own module system based off the CommonJS spec (later used by Browserify), while Require.js championed a slightly different style called AMD. In general, server-side and other “app”-style JS used Node’s modules, since they were already using Node itself, while purely browser-based libraries went with AMD. As with any case where there are two competing standards, developers are left having to learn both of them.

Now, with ES6, all that can change. Modules are now a core part of the language. Once browsers fully support them, you can use them anywhere. (Babel can convert ES6 modules into AMD or CommonJS, though, if you want to use modules right now.) And this is a case where you’ll definitely want to, no matter what you’re writing.

Using Modules

Most of the discussions out there focus on writing modules, rather than using them. But game developers, in particular, are going to be more likely to use somebody else’s module first, so I’m starting there.

The import keyword is your gateway to modularity. If you’ve ever used require() in Node, you’re halfway there, but you’ve still got more to learn. The idea is pretty simple, though. Let’s say that we’re using some made-up game library that’s fully modularized, so that all its classes (because it’s all ES6, see?) are in their own module files. Well, we can do this:

import Vec2d from "lib/vector2d";

Now Vec2d is available for us to use in the rest of that script, and it will be whatever the vector2d module exported. Presumably, that would be a class or a function that created a 2D vector.

That’s the most basic import. For modules that export a single value (class, function, or even a constant), it’s all you have to do. In fact, the way the standard was made, it’s actually the preferred way of doing things. But it’s not the only way. What if we have a module that gives us multiple exports?

import {normalize, dotProduct} from "lib/vector2d";

That gives us names for two functions that might be defined (and exported) in our hypothetical vector2d module. Of course, we can combine these two:

import Vec2d, {normalize, dotProduct} from "lib/vector2d";

Here, the default export (see below) is assigned to the name Vec2d, while the braces indicate exports that we’re “picking” from the module. If we don’t like the names the module gives us, no problem:

import Vec2d, {normalize, dotProduct as dotP} from "lib/vector2d";

Finally, if we have a module that has a lot of exports (maybe something like jQuery), we can use a “wildcard” import that brings in the whole module as an object:

import * as $ from "lib/jquery";

We do have to name the object we’re importing into. (I used the traditional $ for jQuery.) After we use this import, anything the module exported with a name will be available as a property on the $ object.

Note that all importing is done statically, so you can’t “conditionally” import like this. (This is one downside to ES6 modules compared to earlier attempts like Node’s.) For that, you need to use the new Module Loader API, which would look something like AMD:

System.import("lib/jquery")
    .then(function($) {
        // Use jquery module as $, just like always
    });

Creating Modules

Eventually, you’ll want to make your own modules. For a game, you might be using a classical OO approach, where all your game entities (enemies, powerups, etc.) are ES6 classes, each in their own file. Like we did above, we’ll start with the simplest case, where your module only has one value, particularly a class.

/* enemy.js */
export default class {
    // Class definition...
};

That’s all there is to it. export default is the magic phrase that tells your JS interpreter that you’re defining a module and that you want it to export a single value. That value could be anything: class, function, constant, or even another module. And, when you want to use your enemy, all you have to do is import it like we did earlier.

If you want a module with more than one export (maybe a library of independent functions), then you can use a syntax that’s almost the reverse of that for importing multiple values:

/* utils.js */
export function log(msg) {
    console.log(msg);
}

export function foo(bar) {
    // Some other function
}

export const MAX_FPS = 60;  // TODO: Lower to 30 for console builds

All of these will be exported, and they can be imported using the “braces” or “wildcard” versions of import. (Since there’s no default export, these are, in fact, the only two ways to use the module. A simple import utils from "utils"; wouldn’t help us here.)

If you don’t like writing export everywhere in a module like this, you have an alternative. Instead, you can write the module as you normally would, then add an export declaration at the end. This declaration consists of export followed by the name of each expression you’re exporting, all of them put in braces, like an object literal. In other words, like this:

/* utils2.js */
function log(msg) {
    console.log(msg);
}

function foo(bar) {
    // Some other function
}

const MAX_FPS = 60; // TODO: Lower to 30 for console builds

export {log, foo, MAX_FPS};

The main advantage of this style is that you can export a function (or whatever) under a different name, using as like we can when importing. So, for example, we could instead write the last line as export {log as debug, foo, MAX_FPS};.

In Closing

So modules are good, and ES6 modules make JavaScript even better. Combined with classes, we now have a language that makes writing programs (including games) much easier. Once support for modules becomes widespread in browsers, all JS game developers will reap the benefits that “native” devs already enjoy.

Let’s make a language – Part 2a: Syllables and Stress (Intro)

The syllable is the next logical unit of speech after the phoneme. It’s one or more sounds that follow a pattern, usually (but not always) centered around a vowel. These syllables can then be strung together into words, which we’ll cover in the next part. For now, we’ll see what we can do with these intermediate building blocks.

The Syllable

Most linguistic discussions divide a syllable into two parts: the onset and the rhyme. That’s as good a place as any to start, so that’s what we’ll do. The rhyme part is further subdivided into a nucleus and a coda, again a useful distinction for us to work with. As the rhyme is often the more important, we’ll look at it first.

The nucleus is the center of the syllable, and it’s usually a vowel sound. Some languages, however, permit consonants here, too, and these are known as syllabic consonants. In English, these are the sounds at the ends of words like better, bottle, bottom, and button. A few languages (e.g., Bella Coola, some Berber languages) go even farther, to the point where the dividing line between syllables becomes so blurred as to be useless. By and large, though, vowels and the occasional syllabic consonant are the rule for the nucleus.

The coda is everything that follows the nucleus, and it’s a part that is, strictly speaking, optional. Languages like Hawaiian don’t have syllable codas at all, while Japanese only allows its “n” sound, as in onsen. A slightly more complex scheme allows most (if not all) of the consonants in the language to appear in the coda. Beyond that are languages that allow clusters of two, three, or even four consonants, with English a primary example of the last category, as in the words texts and strengths. (We’ll come back to that one later.) An important distinction we can draw is between open syllables without a coda and closed syllables with one. That will come into play later on, when we discuss stress.

Moving to the onset, we see another opportunity for consonants. This can range from nothing at all (though languages such as Arabic do require an onset) to a single consonant to a cluster of two or three. Again, English is ridiculously complex in this regard, at the far end of the scale in allowing three: split and (once again) strengths. Of course, this complexity is tempered by the fact that the first of those three must be /s/, which brings us to the topic of phonotactics.

Loosely speaking, phonotactics is a set of constraints on which sounds can appear in a syllable. It’s a different system for each language. They all have a few things in common, though. First, there’s a distinction between consonant and vowel. The simplest systems allow only syllables of CV, where C stands for any consonant, V for any vowel. An alternative is (C)V, where the parentheses around C mean that it’s optional.

The next step up in complexity comes with a coda or an onset cluster: CVC or CCV. (We’ll assume the parentheses indicated an optional consonant are implied.) These two are the most common, according to WALS Chapter 12, but they’re also where phonotactics becomes important. Which consonants can end a syllable? Which clusters are allowed? Although the first question has no universal answer, the second does have a trend that we can (or should) use.

Most languages that allow consonant clusters follow what’s called the sonority hierarchy. For consonants, it’s kind of a ranking of how “vowel-like” a sound is. Semivowels such as /w/ or /j/ are high on the list, usually followed by approximants like /l/ or /r/, then nasals, then fricatives, then stops. The rule, then, is that the allowed syllables have sonority that falls outward from the nucleus. In other words, it’s incredibly common for a language to allow a syllable onset like /kɾ/, but rare for /ɾk/ to be permitted. In the coda, that’s reversed, as the sounds with higher sonority come first. English bears this out: trust is the sequence stop – approximant – vowel – fricative – stop. /s/ (and /z/, for that matter) is special, though. Many languages allow either sound to appear in a place where the hierarchy says it shouldn’t go, like in stop or tops. That’s also how English gets three consonants in an onset: /s/ is always the first.

And, of course, there are the combinations that aren’t allowed by a language despite the sonority hierarchy saying they’re fine. In English, these are mostly combinations of stops and nasals. We don’t pronounce the k in knight or the p in pneumonia, but other languages do. Conversely, those other languages have their own rules about what’s forbidden.

For a conlang, there’s really no best option for syllable structure. CV is simple, true, but it’s also limiting, and it creates its own problems. Generally, less complex syllables mean longer words, since there aren’t that many permutations that fit the rules. On the other hand, something too complicated can devolve into a mess of rules about which phoneme is allowed where.

Auxiliary languages, then, should probably stick with something in the middle of the spectrum, like CVC or a very restricted form of CCVC. Conlang artisans can go with something a bit more bizarre, especially if they’re never intending their languages to be spoken by mere mortals. And, of course, an alien race might have a different sonority hierarchy altogether, and the idea of “syllable” might make as little sense as it does for the Nuxalk of British Columbia.

Stress and Accent

However we chose to make syllables, whether CV or CVC or CCCVCCCC, we can now put them together to form words. Some words need just one. (Like every word in that sentence!) Many will need more, though, and some people find joy in hunting down the longest possible words in different languages.

Once we have more than one syllable in a word, there can be a battle for supremacy. Stress is a way of marking a syllable so that it stands out from those around it. Stressed syllables are typically spoken louder or with more emphasis. (An alternative is pitch accent, where the emphasized syllable is spoken with a different tone. This can happen even in languages that don’t actually have phonemic tone, including Japanese and Swedish.)

There doesn’t have to be any special meaning attached to stress. Many languages fix the position of the stressed syllable, so it’s always the last, the next to last (penultimate), or the third to last (antepenultimate). Others go in the opposite direction, stressing the first (initial), second, or third syllable from the beginning. In any of these languages, the stress falls in a specified place that doesn’t change, no matter what the word is. Examples (according to [WALS Chapter 14])(http://wals.info/chapter/14) include:

  • Final stress: Persian, Modern Hebrew
  • Penultimate: Swahili, Tagalog
  • Antepenultimate: Modern Greek, Georgian
  • Initial: Finnish, Czech
  • Second syllable: mostly smaller languages such as Dakota and Paiute
  • Third syllable: almost no languages (the only example in WALS is Winnebago)

Conversely, a language can also have stress that doesn’t seem to follow any rules at all. This free stress occurs in languages like English, where (as usual) it is weirder than it looks. In fact, English stress is phonemic, as it can be used to tell words apart. The canonical example is permit, which is a noun if you stress the first syllable, but a verb when you stress the second. In languages with free stress, it must often be learned, and it can be indicated in the orthography by diacritics, as in Spanish or Italian. Free stress can even vary by dialect, as in English laboratory.

It’s rare that a language has completely unpredictable stress. Usually, it’s determined by the kind of syllables in a word. This is where the distinction between open and closed syllables comes into play. Closed syllables tend to be more likely to take stress (i.e., they’re “heavy”), while open (“light”) syllables are stressed only when they are the only option. (Some languages consider long vowels and diphthongs to be heavy, too, but this isn’t universal.) It’s entirely possible, for example, for a language to normally have penultimate stress, but force the stress to move “back” to the antepenultimate if the final two syllables are light.

Stress in conlangs might be entirely unpredictable. All types are represented, in similar proportions to the real world, although pitch accent is one of those things that conlangers find fascinating. Auxiliary languages tend to have stress that’s either fixed or easily predictable; Esperanto’s fixed penultimate is a good example. Artistic languages are more likely to have free stress, though some of this might be due to laziness on the part of their creators. Fixed is easier, of course, since it’s mechanical, but free stress has its advantages. (An interesting experiment would be to create a language with free, unmarked stress, then come back to it a few years later and try to read it.)

Rhythm and Timing

Rhythm is kind of a forgotten part of conlanging. (I’m guilty of it, too.) It’s most closely tied to poetry, obviously, but the same concept creeps into spoken language, as well. For this post, the main point of rhythm is secondary stress. This kind of stress is lighter than the main, primary stress we discussed above, and it mostly occurs in long words of at least four syllables. Now, some languages don’t need (or have) a rhythmic pattern, but it can make a conlang feel more natural.

Generally, a heavy syllable is going to be more likely to get secondary stress, especially if there is a single, light syllable between it and the main stress. (In which direction? Whichever one you use to find the primary stress.) Languages without heavy syllables (such as pure CV languages) will probably have a pattern of stressing alternate syllables; in a penultimate-stress language, this would be the second to last, fourth to last, and so on.

Somewhat related to rhythm is timing, another under-appreciated aspect of a language. In languages such as Spanish or Italian, unstressed syllables are treated essentially the same as those that are stressed, and each syllable sounds like it takes the same amount of time. In others, including English, an unstressed syllable is spoken more quickly, and its vowel is reduced; here, it seems to be the amount of time between stressed syllables that stays constant.

For the most part, conlangers don’t need to worry much about rhythm and timing. However, if you’re writing poetry (or song) in your language, it will certainly come into play. Any post I do about that is a long way off.

The Mora

Some languages don’t use the syllable as the basis for stress and rhythm. Instead, these languages (including Japanese and Ancient Greek, to name but two) use the mora (plural morae). This is, in essence, another way of looking at light and heavy syllables. Basically, a short vowel in a syllable nucleus counts for one mora, while long vowels or diphthongs are two. A coda consonant then adds another mora, giving a range of one to three. Thus, a syllable that has one mora is light, and two morae make a heavy syllable. Three morae can make a “superheavy” syllable, though some languages don’t have these, and four seems to be impossible.

In a moraic system, stress (or pitch, if using pitch accent) can then be assigned to heavier syllables. Rhythm, too, would be based on the mora, not the syllable. The distinction can even be shown in writing, as in the Japanese kana. The end result, though, can be explained in the same terms either way. It’s just another option you can look into.

Conclusion

That was a lot to cover, and I only scratched the surface of syllables. But we can now make words, and that was worth a long post. Next up is a combination post for both Isian and Ardari. Since the theory’s out of the way, the implementation won’t take much explanation, so I’ve decided to cover both languages at the same time. After that, we’ll actually start diving into grammar. See you next week!

Thoughts on ES6

ES6 is out, and the world will never be the same. Or something like that. JavaScript won’t be the same, at least once the browsers finish implementing the new standard. Of course, by that time, ES7 will be completed. It’s just like every other standardized language. Almost no compilers fully support C++14, even in 2015, and there will certainly be holes in their coverage two years from now, when C++17 (hopefully) arrives. C# and Java programmers are lucky, since their releases are dictated by the languages’ owners, who don’t have to worry about compatibility. The price of a standard, huh?

Anyway, ES6 does bring a lot to the table. It’s almost a total overhaul of JavaScript, in my opinion, and most of it looks to be for the better. New idioms and patterns will arise over the coming years. Eventually, we may even start talking about “Modern JavaScript” the way we do “Modern C++” or “Modern Perl”, indicating that the “old” way of thinking is antiquated, deprecated. The new JS coder in 2020 might wonder why we ever did half the things we did, the same way kids today wonder how anyone got by with only 4 MB of memory or a 250 MB hard drive (like my first PC).

Babel has an overview of the new features of ES6, so I won’t repeat them here. I will offer my opinions on them, though.

Classes and Object Literals

I already did a post on classes, with a focus on using them in games. But they’re useful everywhere, especially as so many JavaScript programmers come in from languages with a more “traditional” approach to objects. Even for veterans, they come in handy. We no longer have to reinvent the wheel or use an external library for simple inheritance. That’s a good thing.

The enhancements to object literals are nice, too. Mostly, I like the support for prototype objects, methods, and super. Those will give a big boost to the places where we don’t use classes. The shorthand assignments are pure sugar, but that’s really par for the course in ES6: lots of syntactic conveniences to help us do the things we were already doing.

Modules

I will do a post on modules for game development, I promise. For now, I’d like to say that I like the idea of modules, though I’m not totally sold on their implementation and syntax. I get why the standards people did it the way they did, but it feels odd, especially as someone who has been using CommonJS and AMD modules for a couple of years.

No matter what you think of them, modules will be one of the defining points of ES6. Once modules become widespread, Browserify becomes almost obsolete, RequireJS entirely so. The old pattern of adding a property to the global window goes…out the window. (Sorry.) ES6 modules are a little more restrictive than those of Node, but I’d start looking into them as soon as the browsers start supporting them.

Promises

Async programming is the hot thing right now, and promises are ES6’s answer. It’s not full on threading, and it’s distinct from Web Workers, but this could be another area to watch. Having a language-supplied async system will mean that everybody can use it, just like C++11’s threads and futures. Once people can use something, they will use it.

Promises, I think, will definitely come into their own for AJAX-type uses. If JavaScript ever gets truly big for desktop apps, then event-driven programming will become even more necessary, and that’s another place I see promises becoming important. Games will probably make use of them, too, if they don’t cause to much of a hit to speed.

Generators and Iterators

Both of these really help a lot of programming styles. (Comprehensions do, too, but they were pushed back to ES7.) Iterators finally give us an easy way of looping over an array’s values, something I’ve longed for. They also work for custom objects, so we can make our own collections and other nifty things.

You might recognize generators from Python. (That’s where I know them from.) When you use them, it will most likely be for making your own iterable objects. They’ll also be handy for async programming and coroutines, if they’re anything like their Python counterparts.

Syntactic Sugar

A lot of additions to ES6 are purely for aesthetic purposes, so I’ll lump them all together here, in the same order as Babel’s “Learn ES2015” page that I linked above.

  • Arrows: Every JavaScript clone (CoffeeScript, et al.) has a shortcut for function literals, so there’s no reason not to put one in the core language. ES6 uses the “fat” arrow =>, which stands out. I like that, and I’ll be using it as soon as possible, especially for lambda-like functions. The only gotcha here? Arrow functions don’t get their own this, so watch out for that.

  • Template Strings: String interpolation using ${}. Took long enough. This will save pinkies everywhere from over-stretching. Anyway, there’s nothing much to complain about here. It’s pretty much the same thing as PHP, and everybody likes that. Oh, wait…

  • Destructuring: One of those ideas where you go, “Why didn’t they think of it sooner?”

  • Function Parameters: All these seem to be meant to get rid of any use for arguments, which is probably a good thing. Default parameters were sorely needed, and “rest” parameters will mean one more way to prevent off-by-one errors. My advice? Start using these ASAP.

  • let & const: Everybody complains about JavaScript’s scoping rules. let is the answer to those complaints. It gives you block-scoped variables, just like you know from C, C++, Java, and C#. var is still there, though, as it should be. For newer JS coders coming from other languages, I’d use let everywhere to start. const gives you, well, constants. Those are nice, but module exports remove one reason for constants, so I don’t see const getting quite as much use.

  • Binary & Octal Literals: Uh, yeah, sure. I honestly don’t know how much use these are in any higher-level language nowadays. But they don’t hurt me just by being there, so I’m not complaining.

Library Additions

This is kind of an “everything else” category. ES6 adds quite a bit to the standard library. Everything that I don’t feel is big enough to warrant its own section goes here, again in the order shown on “Learn ES2015”.

  • Unicode: It’s about time. Not just the Unicode literal strings, but the String and RegExp support for higher characters. For anyone working with Unicode, ES6 is a godsend. Especially if you’re doing anything with emoji, like, say, making a language that uses them.

  • Maps and Sets: If these turn out to be more efficient than plain objects, then they’ll be perfect; otherwise, I don’t think they are terribly important. In fact, they’re not that hard to make yourself, and it’s a good programming exercise. WeakMap and WeakSet are more specialized; if you need them, then you know you need them, and you probably won’t care about raw performance.

  • Proxies: These are going to be bigger on the server side, I think. Testing will get a big boost, too, but I don’t see proxies being a must-have feature in the browser. I’d love to be proven wrong, though.

  • Symbols: Library makers might like symbols. With the exception of the builtins, though, some of us might not even notice they’re there. Still, they could be a performance boost if they’re faster than strings as property keys.

  • Subclassing: Builtin objects like Array and Date can be subclassed in ES6. I’m not sure how I feel on that. On the plus side, it’s good for consistency and for the times when you really do need a custom array that acts like the real thing. However, I can see this being overused at first.

  • New APIs: The new builtin methods are all welcome additions. The Array stuff, particularly, is going to be helpful. Math.imul() and friends will speed up low-level tasks, too. And the new methods for String (like startsWith()) should have already been there years ago. (Of all the ES6 features, these are the most widely implemented, so you might be able to use them now.)

  • Reflection: Reflection is always a cool feature, but it almost cries out to be overused and misused. Time will tell.

Conclusions

ES6 has a lot of new, exciting features, but it’ll take a while before we can use them everywhere. Still, I think there’s enough in there to get started learning right now. But there are going to be a lot of projects that will soon become needless. Well, that’s the future for you, and what a bright future it is. One thing’s for sure: JavaScript will never be the same.

Let’s make a language – Part 1c: Ardari Phonology

Okay, the last time wasn’t so bad. But Isian is supposed to be simple. Ardari, on the other hand, will be a little bit different. Again, I’m going to try to explain some of the reasoning behind my choices as we go.

Ardari Consonants

Bilabial Alveolar Palatal Velar Uvular
Nasal m n ɲ ŋ
Stop p pʲ b bʲ t tʲ d dʲ k kʲ g gʲ q
Fricative ɸ β s z ɬ ɕ ʑ x ɣ ʁ
Approximant w l j ʎ ɫ
Tap ɾ

Instead of the relatively few 19 consonants of Isian, Ardari has a total of 33, slightly above the world average. And some of them are…well, you can see the table. The main features of Ardari’s consonant system are as follows:

  • A set of palatalized stops (all the ones with a ʲ). Note that there aren’t any actual palatal stops or affricates. Maybe they merged with the alveolar or velar stops at some point in the language’s history.

  • The uvular stop /q/ and fricative /ʁ/. These don’t quite fit in, but we can say they developed from earlier glottal stops or something. /q/ doesn’t have a voiced counterpart (nor does /ʁ/ have a voiceless one), but allophonic alteration will likely fill in the gaps. (By the way, WALS Chapter 6 has info on uvular consonants.)

  • A full set of fricatives, including bilabials (instead of the labiodentals of English), alveolars (the familiar /s/ and /z/), palatals (technically alveolo-palatals as found in e.g., Polish), and velars (voiceless and voiced).

  • More lateral consonants. We have the basic /l/, the “dark” velar /ɫ/, the palatal /ʎ/ (like ll in some Spanish dialects), and the voiceless fricative /ɬ/. The last is rare in Europe, with the exception of Welsh, where it is written ll. (WALS Chapter 8 is all about laterals.)

  • Two different kinds of “r” sound: the /ɾ/ from Spanish pero and /ʁ/, which is more like the French sound.

To add to this, some of the consonants will change at times. The most important point here is that palatalization and voicing change consonants in clusters. In pairs of consonants, the first takes on the voice quality of the second, while the second takes on the palatalization of the first. As an example, the cluster /sgʲ/ (assuming it’s possible) would be pronounced as if it were [zg], while /dʲs/ would come out as [tʲsʲ]. This only happens for stops and fricatives, though, since they’re the only ones where voicing and palatalization really matter.

As you can see, Ardari’s consonants are quite different from Isian’s. Still, even though some of them might be hard for you to pronounce, they still aren’t quite as outrageous as some of the real world’s languages. Be glad I didn’t add in implosives or clicks or something else completely weird.

Ardari Vowels

Front Central Back
High i ɨ u
Mid-High e o
Mid ə
Mid-Low ɛ ɔ
Low æ ɑ

The vowel system is more complex, but it’s still a system. Ardari has 10 vowel phonemes, and we can divide them into three groups: front (/i e ɛ æ/), middle (/ɨ ə/), and back (/u o ɔ ɑ/). The two middle vowels are most likely reduction vowels that gained full phonemic status at some point. /ɛ/ and /ɔ/, on the other hand, probably represent a lost length distinction.

The Ardari vowels, since there are so many of them, don’t show too much variation. In unstressed syllables, some vowels might be pronounced as [ɨ] or [ə]. There is one rule that will stick out, though: /i/ and /e/ are never found after a non-palatal stop. /ɨ/, conversely, can’t follow any palatal or palatalized consonant. (A similar constraint can be found in Russian, for example.)

There will still be diphthongs in Ardari, though we’ll postulate that most of them have been converted into pure vowels over time. The four that remain visible are /aj æw ej ou/ (phonetic [aɪ æʊ ɛi ɔu]), corresponding to English lie, how, say, and low. Most other combinations of vowels followed by glide consonants (/j/ and /w/) will end up being pronounced as one of these. For instance, the sequence /eu/ would become [æʊ], and /oj/ would turn into [aɪ].

Although the table looks ripe for it, Ardari doesn’t have vowel harmony. Sure it’d be easy to add it in, and I’ve done just that with a conlang that has these exact phonemes. But not this time. We’ll keep it simple for now, saving the complications for the grammar, which will come soon.

Orthography

With a total of 43 phonemes (not counting diphthongs), it’s clear that fitting Ardari into the English alphabet is going to be a challenge. We have two options. We can opt for digraphs, which are strings of multiple letters standing for one phoneme (like English and Isian sh), or we can use diacritics, those funny little squiggles above letters in foreign languages. For Ardari, a combination of both might be our best bet.

Some of the phonemes can take their letter values, just like we did with Isian. Here, we’ll let the consonant phonemes /m p b w n t d s z l k g q/ and the cardinal vowels /e i o u/ all be written as they are in the IPA (/ɑ/ is close enough to a that we can say they’re the same). But that doesn’t even get us halfway!

If you look at the chart above, you can see that the palatalized stops are a big component. Let’s write them as the regular stops followed by y. That’ll take care of six more. Then, we can do the same for the palatal nasal and lateral: ny and ly. Now we’re getting somewhere. We’ll write /j/ itself as j, though, and you’ll see why in a moment. For the palatal fricatives, we’ll use the digraphs ch and zh. (We could also use Slavic diacritics and type them as š and ž. We can call that an alternate standard.)

The bilabial fricatives are pretty close in sound to their labiodental counterparts, so we’ll use f and v for them. The velar nasal is almost everywhere written as ng, so we’ll do that, except when it comes before another velar sound, when it will be n. Since nasals will assimilate, that’s okay.

We have two “rhotic” sounds /ɾ/ and /ʁ/. Either one could lay claim to r, but I’m going with /ɾ/ for that. For /ʁ/, we’ll use rh. That helps signify its “rougher” quality, don’t you think?

That leaves two laterals, two velar fricatives, and five vowels. For the velars, we can use the digraphs kh for /x/ and gh for /ɣ/. The laterals are a little tougher to figure out, but I’ll choose lh for /ɬ/ and ll for /ɫ/. It’s an arbitrary choice, to be sure, but I’m open to suggestions.

For the vowels, the best bet is usually diacritics, because the English alphabet simply doesn’t have enough vowel letters. Sure, you can use clever digraphs and trigraphs, but that way lies madness and Irish orthography, which are pretty much the same thing. Squiggles it is, then. We’ll use familiar European standards where we can, like a German-style ä for /æ/. French gives us è for /ɛ/, and we can extend this by analogy to ò for /ɔ/. That takes care of all but the two central vowels, which turn out to be surprisingly difficult. For /ɨ/, we can use y, since we already said it can’t appear after palatal consonants. (In other words, there’s no way to get yy.) For the schwa, we’ll go with ë or ö. Which to use depends on the previous consonant: ë after palatals, ö otherwise.

Whew. There we go. Let’s look at all this in a format that’s easier to read.

Written Phoneme Description
a /ɑ/ a as in father
ä /æ/ a as in cat
b /b/ b as in bad
by /bʲ/ palatalized b
ch /ɕ/ something like sh in show; more like Polish ś
d /d/ d as in dig
dy /dʲ/ palatalized d
e /e/ e as in Spanish queso
è /ɛ/ e as in bet
ë /ə/ a as in about; only after palatals
f /ɸ/ f as in Japanese fugu
g /g/ g as in got
gh /ɣ/ g as in Spanish amigo or Swedish jag
gy /gʲ/ palatalized g
i /i/ i as in German Sie
j /j/ y as in yet
k /k/ k as in key
kh /x/ ch like in German acht
ky /kʲ/ palatalized k
l /l/ l as in let
lh /ɬ/ ll as in Welsh llan
ll /ɫ/ l as in feel
ly /ʎ/ ll as in million (American English)
m /m/ m as in may
n /n/ n as in no
ng /ŋ/ ng as in sing
ny /ɲ/ ñ as in Spanish año
o /o/ au as in French haut
ò /ɔ/ o as in hot
ö /ə/ a as in about; only after non-palatals
p /p/ p as in pack
py /pʲ/ palatalized p
q /q/ q as in Arabic Qatar
r /ɾ/ r as in Spanish toro
rh /ʁ/ r as in French rue
s /s/ s as in sit
t /t/ t as in tent
ty /tʲ/ palatalized t
u /u/ ou as in French sous
v /β/ b as in Spanish bebe
w /w/ w as in wet
y /ɨ/ like i in bit; closer to Polish or Russian y
z /z/ z as in zebra
zh /ʑ/ like z in azure; closer to Polish ź

Wow, that’s a lot of letters! Next time, it’s back to the theory, where we’ll discuss all the things that we can use to make these sounds into words.

Introduction to ES6 Classes for Game Programmers

If you’ve used JavaScript for game programming, you probably already know some of its shortcomings. One of those is its object system. Where most languages that have objects are class-based (think C++, Java, etc.), JavaScript is unusual in that it’s prototype-based. If you have experience with the language, you know this already, of course. And you know that the syntax can leave a lot to be desired, especially if you come from a background in, say, any other language. (Well, any class-based language, at least. If you’re used to something like Lisp or Haskell, then nothing will surprise you.)

With the newest standard, ES6, that’s going to change. It’s supposed to come out by the end of this month, and maybe that’s true. I’m writing this on June 15th, so it might even be released before this post goes up. If that’s the case, great! (I still remember when C++11 was codenamed C++0x, so I remain skeptical.) Anyway, some of the new features of ES6 are incredibly useful for all developers, but we’ll start with classes, because they’re simple yet powerful, and game development has always been one of the main uses of object-oriented programming. (EDIT 6/18: ES6 is now out! I’m amazed, and I’m happy to admit that I was wrong. Even though the release happened between writing this and posting it, I won’t remove what I already said.)

(By the way, most browsers don’t support much of ES6 yet, and even Node.js support is spotty. You’ll likely need to use a transformer like Babel to turn your ES6 code into something usable under the current standard, ES5.)

Basic Syntax

Let’s take a look at a little class that we can use to represent an enemy in a game. In ES6, it might look something like this:

class Enemy {
    constructor(id, name) {
        // Some properties that are passed into the constructor
        this.id = id;
        this.name = name;

        // A property we can define ourselves
        this.health = 100;
    }

    doAI() {
        /* Do some AI work here */
    }

    kill() {
        /* Play a death animation or something */
    }

    hit(damage) {
        this.health -= damage;
        if (this.health <= 0) {
            this.kill();
        }
    }
}

If you’ve ever worked with Java, C++, C#, ActionScript, or any other language like that, then the syntax will be familiar. Inside the class definition, you can define methods, both instance methods (like all of those here) and static methods. Instance methods are basically the same as the prototype methods already in JavaScript. You call them on an instance of an object, and they can use that object as this. Static methods don’t require an instance of the class; they’re called on the class itself, like the functions of the Math object.

Using this class is as easy as any object constructor. var myEnemy = new Enemy(0, 'myEnemy'); is exactly the same as what you’d use if we defined Enemy in the traditional JS way, defining methods on the prototype and so on. That’s the beauty (if you want to call it that) of ES6 classes: deep down, they’re the same thing as before, but prettier, like CoffeeScript and Typescript claim to be.

constructor is a special method. (I wonder what it does…), but you can define any other method you like. You can also use get and set before method names, just like with the object literal syntax. Static methods are prefixed with static. And that’s pretty much it.

Inheritance

If ES6 classes could just do that, they’d be a pretty good bit of syntactic sugar, but they’d definitely be missing something. Subclassing (AKA inheritance) is that something. Like their counterparts in other languages, ES6 classes can derive from another class, adding or redefining methods and properties. Taking our Enemy class from above, we can make a couple of different enemies using subclasses:

class ToughEnemy extends Enemy {
    constructor(id, name) {
        super(id, name);

        this.health = 200;
    }
}

class BossEnemy extends ToughEnemy {
    constructor(id, name) {
        super(id, name);

        this.lives = 3;
    }

    kill() {
        if (this.lives > 0) {
            this.lives--;
            this.health = 200;

            /* say something cheesy
            e.g., "Ha! You thought I would go down that easy?"
            and play a regeneration animation */
        } else {
            // All lives are gone, so he's really dead
            super.kill();
    }
}

Now we have two new classes. ToughEnemy is a generic bad guy with double health. There’s not much to change for him, but it shows the super keyword that we can use to call methods of the superclass. In the constructor, you can use it by itself to call the superclass constructor. Actually, you have to. Otherwise, you can’t use this anywhere in the derived class’ constructor. Since we want to change the this.health property, we do call super, forwarding the constructor parameters to it, which also means we don’t have to deal with them.

For BossEnemy, we further subclass ToughEnemy, but with a little added logic. First, we give him a property this.lives, set to 3. Then, we change his kill() method as you can see above. If he goes down to 0 health, he loses a life, but he goes back to full health. That continues until he’s out of lives, when we call the superclass kill() method. Since we didn’t define one for ToughEnemy, the call goes up another level, to Enemy, which does have kill().

So, to make a subclass, define a class as usual, but add extends and the name of the base class after your derived class’ name. Everything else is the same, except for the caveat about super in the constructor. You can change methods to your heart’s content, and any that you leave out will stay the same as they were in the base class. Just like any other OO language. Like it should be.

The only downside (and a lot of people wouldn’t see it as such) is that you only get single inheritance, meaning you can only derive from one base class. That’s okay for JS, since we didn’t have anything else to begin with. And Java doesn’t have multiple inheritance, nor does C#. C++ and Python do, but it takes a lot of extra work on the programmer’s part to use it well. Basically, once you truly need multiple inheritance, you’ll know how to fake it, no matter what language you’re using.

For Games

Since ES6 classes are just a fancier way of writing JS prototypes, you can use them wherever you’d use those: pretty much anywhere. And, due to the way they’re defined, you can subclass “traditional” JS objects by extending a constructor. This includes builtins like Array (but not Math, as it’s not a constructor). If you’re using a game library like Phaser, you can extend its objects with classes, too. Basically, wherever you’d already use objects and prototypes, classes fit right in.

Compatibility

ES6 is new, and not everything supports it. According to this compatibility table, nothing actually has full support for classes yet. Firefox 39 will have just about everything, and Chrome 42 allows classes, but not completely. Internet Explorer, as usual, is hopeless, but Edge has quite a bit of support if you enable “experimental” JavaScript. Safari and iOS are out of the question right now. Realistically, if you want to use ES6 classes at the moment, you’ll need a transformer. But that will change, and the next generation of programmers might wonder why we ever bothered with prototype at all.

Let’s make a language – Part 1b: Isian Phonology

This will be a much shorter post than the one last week, since we have all the theory bits out of the way. This time, we’re solely focusing on the sound system of our “simpler” conlang, Isian. Rather than just give a list of sounds, though, I’ll try to justify some of my choices as we go.

Isian Consonants

Labial Alveolar Palatal Velar Glottal
Nasal m n
Stop p b t d k g
Affricate tʃ dʒ
Fricative f s ʃ x h
Approximant w l r j

Isian has a total of 19 consonant phonemes. None of them are too exotic, though monolingual American speakers might have a little trouble with /x/, the “ch” sound in German acht or Scottish loch. Everything else should be familiar. If you don’t know the IPA symbols for the palatal consonants, that’s okay. In order, /tʃ dʒ ʃ j/ are the initial sounds of church, judge, shut, and yet. Also, the /r/ phoneme can be either a tap [ɾ] like Spanish or an approximant [ɹ] like English, though the first pronunciation will be the “official” one.

So why these particular 19 sounds? Well, Isian is supposed to be easy to pronounce, but I still want it to look and sound a little “foreign”. /x/ accomplishes this feat (for Americans, anyway).

English speakers might notice what’s been left out. There’s no /v/ (as in view), /z/ (as in zip) or /ŋ/ (as in *sing). That’s all right, because of allophones. Between vowels, /f s ʃ/ can sound like [v z ʒ] (the last as in French jour or English azure), and /x/ can disappear altogether, instead making the vowel before it sound a little longer. Or it could sound like [h], if the two vowels it’s between are the same. So we might have /taxa/ pronounced more like [taha], but /tixa/ as [tiːa]. Some of our fictitious speakers might instead substitute the voiced velar fricative [ɣ]; we’ll say that this is an older and more formal pronunciation.

In the same way, /m/ and /n/ will assimilate to a following consonant, except approximants and /h/. Before a labial, /n/ becomes [m]. Likewise, /m/ comes out as [n] before an alveolar. Both of them will subtly change to [ɲ] before palatals and [ŋ] before velars.

There are no TH sounds, since those are relatively rare, and Isian is meant to be fairly average. For the same reason, we don’t have any phonemic alterations like palatalization or aspiration going on. Voiceless stops might sound aspirated at the beginning of a word, like English, or not, but this can be explained away as a dialect feature.

Isian Vowels

Front Central Back
High i u
Central e o
Low a

Isian’s vowel system is an average one, with the five cardinal vowels. But we’ll embellish it a little with some allophonic alteration.

First, these aren’t the only vowel sounds possible. We’ll say that any of the three “lower” vowels /a e o/, when followed by a /j/ or /w/ consonant, creates a diphthong, a kind of combination of two vowels in the same syllable. It doesn’t take much math to see that this creates six diphthongs: /aj ej oj aw ew ow/.

  • /aj/ is about the same as the English long-I sound in lie,
  • /ej/ is close to the English long-A sound in lay,
  • /oj/ is pronounced like in English toy,
  • /aw/ can be the sound in English law or loud (we can write this off as dialect differences),
  • /ow/ is the English long-O in low,
  • /ew/ isn’t in English, but it’s the first vowel sound in Spanish or Italian neutro. We’ll say that some dialects pronounce it as [iʊ], like English few.

So, even though we have only five vowel phonemes, thanks to diphthongs, it seems like we have 11.

Second, we’ll say that a few vowels change a little before certain consonants. /a/ becomes [æ] (English ash) before the palatal consonants /tʃ dʒ ʃ/. And we saw above how vowels before /x/ might become lengthened. Finally, although we haven’t discussed syllables and stress, we’ll say that unstressed vowels tend to be “reduced” in fast or colloquial speech. For example, an unstressed /a/ might sound like a schwa ([ə]), like in English about.

Orthography

Orthography is, basically, how a language is written. Isian certainly isn’t going to have its own writing system; we’ll just use the alphabet. But we need a way to convert the phonemes into letters. English, of course, is notorious for being hard to spell, but Isian has far fewer phonemes, so it should be easier to fit into 26 letters.

Most of the phonemes can just be written as the appropriate letters. That works just fine for all the vowels, as well as the consonants /p b m f w n t d s l r g h/. The remaining six sounds need a little more thought. Here’s what we’ll do:

  • /k/ will usually be written as c, but k when it comes before /i/ or /e/. (This is mostly an aesthetic change. There’s nothing stopping us from writing k everywhere.)
  • /tʃ/ will be written ch, like it is in English. The same for /dʒ/ as j, /ʃ/ as sh, and /j/ as y.
  • /x/ can be written as kh. We can’t use ch, like German, since it’s already taken, and x would give English readers the wrong impression. Sometimes, you have to compromise.

So our full orthography for Isian looks like this:

Written Phoneme Description
a /a/ a in father; a in cash before ch, sh, and j
b /b/ b in boy
c /k/ c in cat; only used before a, o, or u
ch /tʃ/ ch in church
d /d/ d in dog
e /e/ e in Spanish peso
f /f/ f in fish
g /g/ g in go (always a “hard” G)
h /h/ h in hard
i /i/ i in French fini
j /j/ j in jet
k /k/ k in key; only used before i and e
kh /x/ ch in German nacht
l /l/ l in list
m /m/ m in man
n /n/ n in note
o /o/ au in French haut
p /p/ p in pit or top
r /r/ r in run or Spanish cero
s /s/ s in sat
sh /ʃ/ sh in sharp
t /t/ t in top or hot
u /u/ ou in French sous
w /w/ w in wet; creates diphthongs after a, e, or o
y /j/ y in yes; creates diphthongs after a, e, or o

The next post will switch over to Ardari. When we come back to Isian, we’ll make these sounds into syllables, then into words.