2013-11-28

A little less than two months after the previous release, I'm happy to announce
that the ooc compiler rock 0.9.8, codename columbia is now out.

The impatients can readily skip to the release notes, but for those who
prefer a narrative, let me tell you why I'm excited about this release.

String interpolation

We've thrown around this idea a lot since the early versions of rock since we
have a few rubyists in our ranks, but only recently Alexandros Naskos
took matters into his own hands and just implemented the fuck out of it.

rock now offers a syntax similar to ruby for string interpolation. Whereas
previously one would have written something like:

One may now write:

Numeric types and strings are readily supported, as for complex types, as long
as they have a toString: func -> String method, they will work out just
fine.

Any expression might be contained within a #{} block, not just simple
variable accesses. The ooc.vim syntax has been updated to color
those correctly. If someone wants to submit a patch to pygments
to support the new syntax, I would be most grateful.

Incidently, we now also have 'raw string literals', which makes 0-terminated
char* instead of full-fledged ooc strings. Instead of doing this:

...where the string is an ooc String converted back to a C string, one may
now directly do:

...and save a few allocations / conversions.

The ::= operator

One of the things that have made my life easier in ooc was := operator,
also known by its friendly name declare-assign, making what we call VDFEs
(variable declaration from expression).

Instead of having to specify a type, like so:

One may do this instead:

And the type is inferred from the right-hand-side expression.

That worked fine for variables, but properties, even read-only ones, were
always a bit of a struggle to define:

Now, the ::= operator (however terrible of an idea it might be) makes it
all better:

Foreach with index

A minor feature perhaps, but I've found myself often doing something like
that to use foreach yet have the index of the current element:

Now, one may use the tuple-ish version:

That works fine with break, continue, you name it.

Tuples fixes

Tuples fall into the set of features that I originally intended for one
single purpose (like generics in their time) but that people keep
corrupting to do their own bidding, and then I have to rewrite their
implementation.

All I had in mind at first was multi-return, like this:

But as it turns out, it's also convenient for destructuring, here
done in a rather explicit form:

Or for swapping two variables:

...which requires its own logic in the compiler (to use temporary
variables where needed).

One particularly edgy case was this one:

Believe it or not, there was a bug in rock 0.9.7 that made g()
return (1, 1, 1) instead of (1, 2, 3). I won't enter into the
details here, but hasty software architecture is to blame once
again.

Which is fine by me, btw. That's why ooc is not production-quality
software, we're all just having fun. Anyway, this bug, along with
a few others related to tuple assignment, are all fixed.

Cross-compiling

I've always been strongly in favor of writing multi-platform code,
to the point where I would withstand the abuse of testing new versions
of rock or SDK changes manually on Linux, OSX, and Windows separately.

However, when working on a game, you want to be able to iterate
quickly, release new builds without having to switch computers (or even
VMs) all the time.

After experimenting a bit with mingw32 on Debian, to produce Windows
executable, and fighting my way through the 5-hour ordeal that is
putting together a Darwin toolchain, to produce executables that run
on OSX, I decided it was time to add support for cross-compiling directly
into rock.

It doesn't do everything yet, for example, you still might have to adjust the
the PATH and PKG_CONFIG_PATH environment variables in a script before
calling rock, but it will definitely:

Respect the --host command-line option, and then call i586-mingw32msvc-{gcc,ar}
as needed instead of the non-prefixed variants.

Apply .use file directives for the host platform (the one you are compiling for) rather
than for the build platform (the one you are compiling on).

For example, with my current setup, if I want to build a Linux 64-bit binary,
I can just do the usual:

If I want a Windows binary instead, I can do:

If I want an OSX binary:

Of course in real life, I have a Makefile with variables to avoid repeating myself.

Still, with this, I can build my game for all 4 host configurations (linux32, linux64,
win32, and osx32), package them, and upload them on my server with a single command,
all in a few minutes, which is a sizeable improvement over my previous workflow.

Windows and threads

I've insisted for a long time on keeping the SDK cross-platform, even using the Win32
API for stuff like threads, pipes, processes, etc. And so, it was. But there was still
a problem on Windows.

The version of the Boehm Garbage Collector that we used to ship had a quirk
in its autotools configuration, and when building for Windows, resulted in a GC without
Win32 threads support.

Consequently, running any ooc programs with threads on Windows was an experiment
in futility, running into fun bugs such as 5000+ call frames of the GC calling the
same function recursively, trying to find the upper limit of the stack...

By downgrading to the latest stable version, 7.2e, the GC can now be compiled with
Win32 threads support, which the SDK takes advantage of, and everything is right again
with the world.

Test suite

In a community, it is a miracle if more than two people can agree on much of anything,
but one thing on which people were unanimous, was that ooc lacked tests. And even
when tests were written, that it lacked facilities to run these tests.

However, since May 2012, thanks to Nick Markwell, for every push to GitHub,
rock is being built on the Travis CI servers. At this point, we considered
that rock was kind of the largest collection of tests for ooc - if rock managed to recompile
itself, we were probably fine.

That proved foolish though, as many bug reports followed and showed us wrong. Eventually,
little by little, a few test cases were added. Then I added the test command to the
sam command-line utility.



Not only can people now easily run rock's test suite on their own machines with a single
command, it's also being run on Travis on every push. I still wish to make it faster,
but that will have to wait for another release...

To learn about rock's test suite, you are encouraged to read the rock test README.
To use sam to test your own ooc software, read sam's README.

Incremental builds

Back in 2010, a huge new feature of rock was its ability to recompile only the parts
of your program that had changed. For a language like ooc, this is non-trivial, and it
was very welcome.

However, it came with its share of bugs, and often one would end up with a buggy executable
or simply a compilation error, and then would have to clean up temporary files and try
again from scratch.

Thanks to clean-ups done in rock 0.9.5 and a recent fix just before the 0.9.8 release,
I'm happy to say that things are now much better. To read about the history of this,
feel free to check out the associated GitHub issue.

Bonus: teeworlds-ai

Back in 2009, I wrote a few naive bots for teeworlds in ooc. That reminds me of the days
I was blissfully ignorant of the open-source community and its associated pitfalls, and
I was just doing things for fun!

For old time's sake, I pulled out these legacy sources and made them compile with rock 0.9.8
again, and then I made a video for your enjoyment:

This work was particularly interesting to me because even though it retrieves player
positions directly from the game, it doesn't use the game's map info. Instead, it just
moves around, trying to figure out where floors, ceilings, and ledges are. That's what
you see in the secondary window (drawn with GTK and Cairo). Black is unknown, green is
floors, yellow is ledges.

I would love to make another AI for a game like Spelunky HD - but without the source,
it might prove more challenging!

Afterword

I haven't covered all that's new in rock 0.9.8, but hopefully that's well enough to interest
you in it. You can follow the instructions from the official website, or just
install it using brew if you're on OSX - that's right, the latest version is on there.

Until next time, take care!

Show more