Hacker News new | past | comments | ask | show | jobs | submit login
A Programming Language for Games: Demo [video] (youtube.com)
141 points by GuiA on Oct 31, 2014 | hide | past | favorite | 72 comments



A bit of context without even watching the video:

This dude nearly single-handedly made Braid, and is now working on a really cool 3D title that's well into its development.


It's fair to say Braid is his game but it wasn't done single-handedly. David Hellman did the great artwork and Blow licensed the music. Edmund McMillen (Super Meat Boy, The Binding of Isaac) did some of the original character designs which David Hellman remade to fit the the art style that developed.


Fair. He did all of the programming involved, as well as all of the story and gameplay design.


For anyone interested in a bit of background about him and some other indie gaming greats, I highly recommend checking out "Indie Game the Movie" - it's a documentary about the development process of Braid (Jonathan Blow), Fez (Phil Fish), and Super Meat Boy (Edmund McMillen and Tommy Refenes).

At about 10 USD it's a bit steeply priced, but I found it well worthwhile: http://buy.indiegamethemovie.com/


I'll also join in recommending this.


This talk is way too long and not very information dense. I jumped through it a little and liked what I saw, but I was wondering if anyone had a link to a white paper or an overview that could summarize the language features.


The story behind this is that Jon Blow is tired of making games in C and C++. He wants something better, but not necessarily something that is higher level. This demo goes over an initial prototype of the language. Shown are that he was able to relatively quickly get something up and working. The language operates well, but still has a lot of unknown things about it.

In the demo he shows the basic running of the language. Then he shows it's realistic to write games in the language by running a space invaders like game. He then also shows the power of using the language as the pre-processor (very lisp like) in that he is able to run arbitrary code during the compilation process, such as checking that your printf statements have the proper number of arguments, or having it so you need kill so many space invaders or your compile fails. He also showed that it runs on linux as well as windows.


Sounds like C++ with better syntax sugar. Is it really compiling already? That's impressive.


Yep! It compiles to C, and then the Windows C compiler takes over.


Why not use LLVM ?


The language simultaneously compiles to bytecode and C. LLVM is potentially planned for the future.


Maybe because Windows reigns as development platform for game developers and LLVM still doesn't support it properly.


OK, so not a real compilation. Still great though.


This is dealt with in the talk about 40 minutes in - it is described as a proper compiler, targeting either C or its own bytecode (which it uses for the compile-time execution).


The talk is just over an hour. The second hour is Q&A.


Just some thoughts:

#run can run anything, if you don't trust the codebase you have to check everything for malicious calls. ( #run format c: as a joke :-/ when you compile )

check functions seem to have limited use. They can't check for input that isn't hardcoded( or can they? ). A runtime check might be more valuable.

I don't remember if it was mentioned; I think having C like implicit conversions is a bad idea. If types don't match exactly, cast or give an error.

defer is interesting, do you get an error if you try to return an object which is also defered getting deleted?


Maybe the word check is a bit confusing, but the purpose of the feature is compile-time checking. Runtime checks would be implemented differently.

To clarify the probable mindset of the language designer: For games, runtime checks are pretty much useless - at runtime, the game is released and it's too late to do anything (ideally, discounting patches). So you want to catch everything you can at compile time. At the same time, performance is crucial. You need to be able to do everything the game needs to do within a 16ms time window. This means hardcoding / compiling in as many calculations as possible. Hence the focus on being able to do a lot at compile time.


> #run can run anything, if you don't trust the codebase you have to check everything for malicious calls.

That weakness already exists today in any project that relies on a build system (GNU Make, Autoconf, Ant/Maven, whatever), which is pretty much most of them.


About the trust thing - you probably don't often compile code without running it afterwards even now. A format call might be hidden in any library you use.


You are right. I usually wouldn't check the code if it is from a credible source anyway.

That was just the first reaction I got, wow this can run anything.


At 1:45:00:

> Do you really want a white paper?


personal plug: I've also been working on a programming language in my spare time, called "OWL"; My language is, coincidentally, also meant to be a cleaned up C++ for game development. It is an object-oriented systems language, without a garbage collector where it's most notable features are:

* classes are reference types to avoid slicing (but may still be stack allocated)

* classes are reference counted

* arrays are sized

* semicolons are optional

* tuples are first class types. (essentially acting as anonymous structs)

* basic one-way compatibility for importing C headers

The compiler can be found here: https://github.com/bsurmanski/wlc

currently it compiles for both Linux and Windows, requiring LLVM as a dependency.

a game written in OWL for Ludum Dare 30 can be found here: https://github.com/bsurmanski/ld30


The way he feels about C++, highlighted in his first video[0], "this ship has taken us pretty far, but now it's done sailing", is pretty much the opposite of how I feel C++ is going to play out in the next few years. C++17 will no doubt be a make-or-break specification with regard to being surpassed by other languages, but with its critical mass of incumbency, and the rate at which tools and compilers are moving now (thanks Clang), I just don't see anything topping it in the near future. C++11/14 does feel like a different language to '03, and I've personally got no doubt that C++17 will feel better again. Promisingly, almost all of the work going in to the language atm is about making major strides in improving developer experience and reducing complexity.

The work Jonathon has put in to his language in such a short time is super-impressive, and the ideas and their implementation seems solid, but I think he's really underestimating the time frames required to get something like this up from the pioneering stage to production ... remember that C++ was compiling to C in 1983. There are other interesting languages taking this approach even today. Vala and Nimrod both spring to mind. At the end of this third video he talks about modern pioneering spririt versus those from the heyday of the space race... well here we are 50 years later, and it turns out that space travel is still hard. I don't think programming is any different.

[0] https://www.youtube.com/watch?v=TH9VCN6UkyQ&list=UUCuoqzrsHl...


Note that I haven't watched the whole video, just skipped through it. That said, not to be negative, but what does this language offer over Rust? If the goal is to create a new language with an emphasis on safety and fine-grained memory control, along with a nice module system and high-level constructs like easy first-class functions, it seems like Rust already covers that. What does the language offer that's new?


Blow wants to optimize for (developer) speed and simplicity over memory safety - roughly, "Go's simplicity, minus garbage collection" instead of what he calls "big idea" languages. Which I would never go for myself, but he's very adamant on this point; he dismisses most new ideas in PL theory entirely in favor of focusing on the engineering problem of smoothing out basic issues seen in his existing C++ development environment, where, to paraphrase him, "everything is junk and it demoralizes me". In that respect there's plenty we could learn from this project and its whole-process agenda, even if it isn't introducing sexy new methods. There are very few PL projects that aim only to work on boring everyday problems.


I don't think Blow is against big ideas as such -- his language has some big ideas on its own -- but he certainly seems to prefer familiarity and simplicity over mind-altering language-theoretical weirdness.

One aspect of familiarity, incidentally, is being able to hire junior devs. I see that as being a problem with Go -- and, in the future, Rust -- not to mention rocket-scientist languages like Haskell, Ocaml or even Scala, or indeed C++. Go is "simple", but not really that simple, not compared to Ruby or Python. (Of course, this might not be an issue for Blow, whose company is already using C++.)

While Blow was originally talking about safety not being a paramount issue, I believe he has mentioned ownership-lifecycle management, possibly something like Rust's borrowing, as being on his mind.


This thread on the Rust subreddit compares Blow's language ideas to Rust:

http://www.reddit.com/r/rust/comments/2gwi11/jonathan_blow_i...

He specifically says that Rust "cares too much about safety" and that satisfying its safety guarantees adds too much friction to development. Some of the Rust programmers in the thread acknowledge that the safety/friction trade-off for games may be different from, say, OS kernels or web browsers.

He also notes that Rust is new and still needs to prove itself, which I don't think anyone will disagree with.


> He also notes that Rust is new and still needs to prove itself

That's true, but I don't think making a new language avoids that problem.


I'm still watching it but I was thinking the same thing but about D.

- Module system

- Optionally avoiding complex build systems (rdmd or dub)

- Fast build times

- Type inference

- Nested block comments

- Owned memory (Unique, Scoped, RefCounted)

- All variables initialized by default

- Anonymous or strong enums

- Specify enum type (inferred by default)

- Order independent symbols

- Scope guard statements (more powerful in D though)

- Locally defined functions

- Built-in dynamic arrays

- Parameterized types (doesn't work in his language yet but he says it's coming)

- Compile time function evaluation (only side-effect free code though so no playable space invaders at compile time)

- Complex checks using compile time function evaluation

- Generate code at compile time and mix it into the program itself

I like where his language is headed but I'm not convinced we aren't already there. I guess I should go back and listen to his other talks to see why he's unsatisfied with Rust or D.


He beats that horse to death in the other two videos, which can be found at the link below.

https://www.youtube.com/user/jblow888/videos


I appreciate the response, but it'd be nicer to get a quick summary than a link to a pair of nearly two-hour videos.


For Rust, the short of it is that Blow finds its ideas too new and untested to dive into it. There are also some issues such as closures having a different syntax than top-level functions: he wants to be able to move functions easily between scopes.


> There are also some issues such as closures having a different syntax than top-level functions: he wants to be able to move functions easily between scopes.

But closures have different semantics to functions, both in representation and in execution. The semantics of his language becomes even more confusing when he says that items at the top level are position independent, where as it seems that those in a function scope are, and yet they share the same syntax. There is a simple fix though. Just keep a uniform syntax for position independent items, but allow them to be declared at any scope. That is exactly what Rust does.


Yeah, I don't disagree, I'm just relating what he said in videos 1 and/or 2 about Rust.

Personally, I'm all for having different syntax for different semantics.


offhand, one problem the author mentioned with rust was writing unsafe code. he went into detail in either the first or second video (I don't remember).


The fact that he since the last video came out he not only built the lexer, parser and C-translator for this, but that he also made a complete bytecode runtime blew my mind. This guy is one hell of a productive programmer!


Once you’ve done it once or twice, throwing together a simple programming language is actually just a weekend project, provided you have clear goals.


The defer keyword seems pretty cool.

I assume it creates a stack of calls to execute just before exiting scope. Personally I find it a cool little syntactic sugar.


Go has the same functionality, you should check it out. It's great, but I feel it's a "halfway solution": you open your file and then immediately add a `defer f.Close()` statement afterward, so you don't forget to close it in all exit paths of the function (i.e. early returns in branches), however you still need to remember to type the defer.


In functional languages you often see functions like with_file that use a closure to denote the file lifetime:

    with_file(fun file ->
        use_file(file)
    )
I wonder if there is a way to code something similar that works with "defer". This would free you from needing to "remember" to add the defer and would have the advantage of allowing you to use `return` and `break` statements which don't work if you wrap them inside an inner function.

The only thing I can think of is Python's with statement. Since its language syntax it allows for `return` and `break` but I wonder if there is a way to play nice with defer instead of requiring you to use another "block level" syntax construct for every file you use.


We used to do this in Rust, but have found RAII much better for this. Dealing with multiple resources open at once can quickly become painful. See http://blog.skylight.io/rust-means-never-having-to-close-a-s...


Sounds like the finally-keyword in most languages?


He does actually mention Go as the inspiration.

Anyway, I still much prefer RAII for this - not only for guarding against your own forgetfulness, but also to make sure a rogue refactor or patch doesn't break anything.


I haven't watched the whole thing but does the language have a name?

lycos1: you are shadowbanned and have been for the last 3 or so years.


It seems to be: Jai


Looks like a language with no name :)


Maybe it's like Fortran: Proglanforgam.


Sounds like a pill to prolong orgasms...


Running code at compile time seems pretty powerful; mostly for tests.


Powerful, yes, for tests, I'm not so sure.

If it stops the compilation when a test breaks, that forces you to fix it, but it also would irritate the crap out of me, since I'd want to test the code changes before refactoring the tests (I'm not a fan of TDD, at least when it comes to fixing bugs in code; let me fix the bug, then figure out what, if any, test broke (if none, add a test for that bug). I can't imagine it's particularly useful in game development either, when there can be a huge disconnect between something seeming correct at the program logic level, but massively broken visually; writing a test to make sure that that animation is smooth isn't easily doable).

If it doesn't stop the compilation on breaking the tests...it's not really any different than any other continuous integration style tool (or even a make script that adds a call to test after compiling), except that the tests are being run as the code is compiled, forcing you to wait the extra time even when experimenting. And it's unclear what code is intended for tests, versus other uses of the facility (such as DSLs and language extensions).


The compiler currently bails upon encountering the first error, he said this was a feature, not a bug.


I guess that he considers this a feature for two reasons:

1) He's used to the atrociously poor error recovery of typical C++ compilers. You almost always get different errors after you've fixed the first error.

2) His language's semantics enforce sequential compilation, such that it's not reasonably possible to continue evaluating in the face of many or most errors.

#1 is a consequence of not designing for error recovery from the beginning. He's going to run in to a problem when people want squiggly red underlines in their IDE.

As projects grow in size, #2 is going to breakdown quickly without a good separate compilation unit story.


Come on guys, think about it!

It is trivial to make your test routine log the error but return true so that the compiler doesn't stop.


I'm totally fine with #2, if you do have a good separate compilation unit story. I'm fact, it's how many lisps work, and it works out quite well.

However, I wasn't talking just about your compile time asserts for #1. There's also syntax errors, undefined identifiers, missing or extra arguments, etc, etc. That stuff is hard to get right if you want to report many independent errors. It gets much easier if you can change your language, so don't wait too long to take a swing at it.


I really liked that feature. Also being able to write check functions for your function.


I would also like to mention here some other platforms like Unity that makes games developing a whole lot easier.


I am unsure of his rhetoric: "...everything we can do to move forward in games... (1:41)".

He is not a messiah, it's already happening, people are using C#, Scala, Python, Haxe, Elm, Rust, D, Haskell to move game programming forward. E.g. Minecraft was built in Java, not C++. Game programming of today are those thousands of small indie developers experimenting, not the several hundred of bigger traditional C++ projects making big bucks.

Besides, there is not much focus on parallelism and concurrency for a performance-oriented language. By the time it hits it's first stable release the 8-core smartphones will probably be quite common.


> He is not a messiah, it's already happening

That's a lot of negativity towards a guy who's said from the beginning he's just building a language that he wants to use himself. I don't think he's presented himself as "a messiah" in any way. He laid out some things that irk him in C/C++, and then he set out do make something that suits him better. These may not be the same things that are important to you (as demonstrated by your parallelism and concurrency criticism), but that's absolutely fine. People use different languages for different purposes and different tastes.

It worries me how makers are attacked here. "oh, we don't need that, X did the same thing ages ago" "why even bother if it doesn't do X" "oh dear, please not yet another X, people should just stop" "nobody needs X when we have Y1, Y2, Y3..."

That's some seriously bad attitude.


All I am saying is it's better to communicate along the lines of "let's also explore this way of building games" rather than "nobody is doing anything worth looking at, garbage collection is a no go, too much safety is bad and it's a first initiative ever just like the moon landing (which was kinda secondary to actually going to space first time anyway)".

But he is quite smart, so some arrogance could be forgiven. He is also not afraid to say some fair and true things out loud:

> "...the web is a giant pile, I don't want anything to do with it, it's all horrible; it's not an exaggeration, anything to do with web is like so broken and it's so nasty and it's so hard to do good things...".

Maybe it's a correct attitude if we ever want to get rid of legacy crud like JavaScript and HTML...


> let's also explore this way of building games

That's what he said, isn't it? He also actively encouraged people to write their own languages which address what they care about.

> nobody is doing anything worth looking at, garbage collection is a no go, too much safety is bad and it's a first initiative ever just like the moon landing (which was kinda secondary to actually going to space first time anyway)

Those are his views, he needs those in order to make the new language. It's similar but not equal to your judgement of JavaScript and HTML. Those things are not bad per definition, they are just something you don't happen to like. The bigger theme here is that working with things that you don't like makes you unproductive.

So yeah, it does bother me a little when he says these things so emphatically, but they're still well distinguishable from global blanket judgements because they are expressed within the context of designing the new language.


In an earlier video blow mentions that he wants to use this language to develop AAA level game engines and run on consoles. Even games which use a higher level language for some functionality usually have engines written in much lower level, non GC languages (usually C++).

Parallelism is a complicated topic and he will probably dedicate a video to that later.


(disclaimer: skimmed through the video) Would be interesting to know what specifically about certain advanced PL typesystems he found to be too bureaucratic and where that line is drawn in his language.


This is the third video in the series. Go to his youtube page to find the two videos previous to this where he talks about all that to death. Each video is between 1.5 and 2 hours. Also, keep in mind he's talking about a language specifically for game development. His requirements are highly specialized.


Way too long for a video (2 hours!), this should be an article. Disappointing, not really a new language - more like syntax sugar for C. It looks to me like he's not solving a problem here but just having a lot of fun creating his own language (which I agree is a lot of fun).

And just to make sure I deserve all the ire I might get: we already have a language for making games and I don't even need to write what it is because you already know :) (and that's why you know it's true)


I'm not sure that a "programming language for games" would be a subset of a general purpose language. I can't think of an operation that a general purpose lang can do that I would not want to use in a game. In that case, how could you specialize for games? A game is kind of an abstract concept - it could be anything. Maybe try constructing a language that lets you choose a subset of its total functionality for your specific game, possibly through extensions. Haskell does that well.


I think the idea is that the language is focused towards games. Games generally have some inherent shared qualities, mainly that they need to be real time and the language should be minimal overhead. On the otherhand, a language focused on enterprise software would sacrifice speed and low overhead to instead add some safety features like a garbage collector.

Its not a language only for games, but it is a general purpose language where the main feature set is chosen to benefit professional game development.


Yes I agree that the games he's designing the Lang for have certain shared qualities, but IMHO those concerns are best dealt with using libraries or (E)DSLs in a host language. That way you can still support games like zork, which don't have to be real time - as well as games that transcend what the "game specific Lang" was designed for. I personally don't see why there is a distinction between "a game" and "an enterprise app" - some enterprise apps need real time rendering and low overhead (unity, blender, arcgis, cad, etc). My point being - a language that is good at describing all games is good at describing all programs.


1. It will still be turing complete. In that sense its always going to be a general purpose language.

2. From what I've been taking away, all he is looking for is a way to remove some of the redundant parts of his day to day C++ code/process. Nothing more. Thats why, while I get that it is a full compiler, very intentionally (I think), a lot of the time it just seems like very nice syntax sugar (maybe "program sugar") for C++.


A language that tries to be good for describing all games, will end up not being good at describing any of them, because different types of programs require different tradeoffs


Exactly - and those trade offs will be handles at the library level.


A lot of modern game frameworks go in a similar direction. It's all about having entity-component systems where the designers (and not the programmers) can put together the objects dynamically. And those all fight with similar problems. One is about making the system cache efficient. Another is about how to add new components. I suppose the latter might be a reason he put so much power into the preprocessor that he even created a VM for that. Current complete solutions tend to have the problem that you have to repeat the class-names of your components often and that type-safety get's lost at some point when ini-files in any format are involved. Having more power in the preprocessor might help to fight this.

I don't know what he has planned for his language, but if I hear about a language that's specific for programming games, then entity-component systems would be the use-case I would have in mind.


I'd like to point out though, that I commend the effort of writing a Lang, I'm not try to discourage - just adding my thoughts! We need more language choices!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: