NOTE: So this right here turned out to be way more than I thought I’d be writing, sorry for it not being a 100% Ludum Dare topic. I will be using this language and my game library for future Ludum Dare events, though, so it applies well enough I guess.
This past Ludum Dare I got to use some very fun tools to create my game: A game library I wrote, Artifakt, with bindings to a scripting language that I also wrote, Score. Actually building something like a game using tools I’ve created, especially a whole language, is something I never thought I’d be doing. The event was fun, but not without struggle, so I’m glad I already had upgrades planned for the future.
I’ve been working most on the language, rewritten completely from scratch it’s a lot more efficient when it comes to maintaining proper control of the program and has more flexibility when it comes to the more complicated features I’ve wanted. While the new Score lacks it’s own proper class system like the old one had, the current functionality is actually far greater. Functions, for example, are much more useful and manageable than before.
Here’s a quick example of some of the fun things Score can do, because why not.

This might be a little confusing at first glance, so I’ll go ahead and walk through it.
- Lines 1 and 2 import classes from Java for this script to use.
- Line 4 starts defining a table value. A table in Score is similar to a table in Lua, it stores data in key/value pairs. By default a table doesn’t care about the type of an object.
- Line 5 sets the key
in to a new Java Scanner object in the table.
- Line 6 sets the key
Input to a lambda function, more on that in a second.
- Line 12 defines two values as the return values of the Input function.
- Line 13 prints stuff. The string concatenation is pretty standard, and the comma separation concatenates the values with a space between them.
So more on that lambda, there. For reference that could just as easily be written as a standard function, putting Input right before the parameter list. Anyway, there’s a lot going on there.
First of it’s defined with the keyword “func” and followed by a list of variables in brackets. This first list is optional and defines specific return values for this function. If no return list is given any number of any type of object may be returned. If a list is given with no names for the values then only values of those types can be returned. here we have types and names, so the state of those variables is what gets returned whenever the function terminates. In this case the function terminates at the end with no early break. These return types, if given names, can have default values. Those work how you’d think they do, they’re initialized to that value rather than null or a type-specific default value (i.e.zero for an int.)
After the return type list comes the parameters, which functions just about how any other parameter list would. You define values separated by commas and have the option of giving them defaults. What’s good to note is that Score will automatically default parameter values if no argument is passed for them, so default assignments have no restrictions on where they can be used.
After the parameters we have the function body. A neat thing that Score allows is that for single line functions the curly braces are optional: func PrintValue(var value) println value; is valid syntax. Functions can also use a fat-arrow to bypass the return statement: func Add(int a, int b) => a + b; will return the sum of a and b. Moving on from things not in the example, this function will first print the given message (or “Input: ” if no message is specified) and then request input through Java’s Scanner class and assign that input to the res return value. When the function returns after that, the value of res and code are returned.
Notice how in is a part of the table but Input can access it without having to reference the same table. In Score, when a function is assigned to an object (or a part of a class, but we don’t have classes yet…) that function has access to it’s container through a this parameter. Access to this is also delegated automatically as if its contents were local variables. Because of this the Input function has direct access to in.