Author Topic: Jonathan Blow (Braid) talks about game programming languages  (Read 7040 times)

Offline Hearteater

  • Core Member
  • *****
  • Posts: 2,334
Jonathan Blow (Braid) talks about game programming languages
« on: September 19, 2014, 01:19:11 PM »
Just saw a fascinating talk by Jonathan Blow (creator of Braid) where he talks about designing a new language for game design. It is long but well worth it if you have any interest in programming languages.

EDIT: Youtube version
« Last Edit: September 21, 2014, 04:11:19 PM by Hearteater »

Offline x4000

  • Chris Park, Arcen Games Founder and Lead Designer
  • Administrator
  • Zenith Council Member Mark III
  • *****
  • Posts: 30,603
Re: Jonathan Blow (Braid) talks about game programming languages
« Reply #1 on: September 19, 2014, 01:31:14 PM »
I haven't watched his video, but whenever someone proposes a new language I always want to see new details.  I'm not opposed to the idea that new languages can be better than existing ones -- I sure hope that things continue to progress.

But there's a balance between clarity and quickness to type, and a lot of the newer experimental ones sacrifice one or the other.  Or make the typical case really easy, while making anything a little less common way harder.  Looking at you, Ruby!

There are other ones that try to intuit your meaning in various ways.  While to some extent that is... kind of helpful... it's much better to build that sort of thing into an IDE and leave the language as being really clear and deterministic.  That's pretty key for a lot of things.  When the language starts making assumptions about what you want, that's often a bad thing.  Of course, some people believe that about Garbage Collection, and I don't, so it's obviously subjective.

And I got pretty used to the TSQL abstraction with quary optimization, etc.  It frustrates a lot of programmers, but I wound up really liking it.  But that was having it optimize itself based off of analysis of usage, not based off of trying to intuit your meaning.  That's really only applicable to data-oriented code, that I can think of.

You do run into things like LINQ which can make data manipulation a lot more efficient to code inside existing languages, but then you inevitably take a big performance hit with that while it is trying to figure out what you were trying to say.  The way it then evaluates its data is typically not optimized the way you would if you did it by hand.

On the other side of the coin, I absolutely hate C++ because it makes you say everything multiple times.  Header files to go with regular files, declaring method signatures and methods in different places.  Callbacks and whatnot are super complicated to define, in terms of how much code you have to type for simple things, etc.

JavaScript is pretty okay, except its object model is really bonkers because they added it belatedly.  Being dynamically-typed is pretty cool in some respects, but for serious purposes it makes a lot of compile-time checking impossible, which is harmful to productivity.  And in general it lets people shoot themselves in the foot more than they should be able to.

I really believe that empirically right now C# is the top language for the mixture of productivity, power, and clarity that you get.  It's not perfect, but I just have yet to see something better.  C# is not great in terms of how it handles multithreading, although it certainly works.  But there aren't really any languages that make multithreading invisible the way that Java and C# make garbage collection invisible, and I think that's the next big jump in languages that we need to see.

Beyond that, when it comes to languages that try to simplify things in the style that Ruby does -- typing less code to do the same thing -- I feel like that is what libraries are for.  C# in general does a really good job of that, but the libraries for game programming are either overly-generalized (most game engines) and thus slow, or are completely bare-metal (and thus do-it-yourself-every-time), or really unoptimized in general.  And shaders are a mess.  The new ShaderLab visual designer stuff is really good for the unity environment, if you're going to do 3D games.

So I do agree that new tools and libraries and language features are always a good thing, and I'm glad that there are serious computer researchers exploring new languages.  But I don't think anything substantial is coming soon, at least not that I've heard.
Have ideas or bug reports for one of our games?  Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark IV
  • *****
  • Posts: 3,861
Re: Jonathan Blow (Braid) talks about game programming languages
« Reply #2 on: September 19, 2014, 01:57:11 PM »
Watching it now, but Twitch is AWESOME for jumping to a specific point in the video.  I accidentally navigated away and now it's spending 4, 5, 8 minutes just trying to get me back to where I left off.  Then I decided I wanted to be a minute prior to that so I could get a point of context.

Cue 4, 5, 8 minute additional delay. :V

Offline x4000

  • Chris Park, Arcen Games Founder and Lead Designer
  • Administrator
  • Zenith Council Member Mark III
  • *****
  • Posts: 30,603
Re: Jonathan Blow (Braid) talks about game programming languages
« Reply #3 on: September 19, 2014, 02:44:58 PM »
Yeah, I saw it was twitch and just gave up.
Have ideas or bug reports for one of our games?  Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline Hearteater

  • Core Member
  • *****
  • Posts: 2,334
Re: Jonathan Blow (Braid) talks about game programming languages
« Reply #4 on: September 19, 2014, 02:51:16 PM »
I'll post the youtube link when it comes up. Twitch is just where he gave the original talk. Just to note he isn't proposing a language, but rather laying out the case for why maybe one should be developed, and he goes into some goals such a language should have and features that would benefit games.

Offline x4000

  • Chris Park, Arcen Games Founder and Lead Designer
  • Administrator
  • Zenith Council Member Mark III
  • *****
  • Posts: 30,603
Re: Jonathan Blow (Braid) talks about game programming languages
« Reply #5 on: September 19, 2014, 03:43:17 PM »
Ah.
Have ideas or bug reports for one of our games?  Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline Shrugging Khan

  • Hero Member Mark III
  • *****
  • Posts: 1,216
  • Neinzul Y PzKpfw Tiger!
Re: Jonathan Blow (Braid) talks about game programming languages
« Reply #6 on: September 21, 2014, 02:02:47 PM »
Wall of Text

I don't know whether it's because you're just so right anyone would have to agree, or because I learned most of what I know about  programming from Keith and Draco...but I've got to give an approving nod to everything you wrote.
The beatings shall continue
until morale improves!

Offline x4000

  • Chris Park, Arcen Games Founder and Lead Designer
  • Administrator
  • Zenith Council Member Mark III
  • *****
  • Posts: 30,603
Re: Jonathan Blow (Braid) talks about game programming languages
« Reply #7 on: September 21, 2014, 02:21:46 PM »
Cheers.  ;D
Have ideas or bug reports for one of our games?  Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark IV
  • *****
  • Posts: 3,861
Re: Jonathan Blow (Braid) talks about game programming languages
« Reply #8 on: September 21, 2014, 04:06:31 PM »
I never did get around to watching the video.

Anyway, C#: yes.  I've gotten a fairly good handle on it with Unity now.  Although I pine for the way Java allows enums to not only mean one thing, but also have their own properties.

if (this.material = EnumMaterial.DIAMOND) then { this.durability = EnumMaterial.DIAMOND.durability } //obviously not real code

It's glorious.

I've had to fake it in Unity.

Offline Hearteater

  • Core Member
  • *****
  • Posts: 2,334
Re: Jonathan Blow (Braid) talks about game programming languages
« Reply #9 on: September 21, 2014, 04:10:52 PM »
Here is the youtube version. Enjoy.

Offline x4000

  • Chris Park, Arcen Games Founder and Lead Designer
  • Administrator
  • Zenith Council Member Mark III
  • *****
  • Posts: 30,603
Re: Jonathan Blow (Braid) talks about game programming languages
« Reply #10 on: September 21, 2014, 06:05:35 PM »
I never did get around to watching the video.

Anyway, C#: yes.  I've gotten a fairly good handle on it with Unity now.  Although I pine for the way Java allows enums to not only mean one thing, but also have their own properties.

if (this.material = EnumMaterial.DIAMOND) then { this.durability = EnumMaterial.DIAMOND.durability } //obviously not real code

It's glorious.

I've had to fake it in Unity.

You can actually do something along those lines; Keith has recently been adding that to our own code, it's really cool.  For instance:

Code: [Select]
public enum MapPlaneType
{
    Normal,
    Cutscene,
    Length
}

#region Helper Classes
public static class MapPlaneTypeExtensionMethods
{
    public static MapPlaneTypeData GetData( this MapPlaneType Type )
    {
        return MapPlaneTypeData.Lookup[Type];
    }

    public static void SerializeTo( this MapPlaneType Type, ArcenSerializationBuffer Buffer )
    {
        Buffer.AddItem( (int)Type );
    }

    public static MapPlaneType DeserializeFrom( ArcenDeserializationBuffer Buffer )
    {
        return (MapPlaneType)Buffer.ReadInt32();
    }
}

public class ArcenEnumIndexedArray_MapPlaneType<T>
{
    #region Instance Fields
    private readonly T[] internalArray = null;
    #endregion

    #region ctor
    public ArcenEnumIndexedArray_MapPlaneType()
    {
        this.internalArray = new T[(int)MapPlaneType.Length];
    }
    #endregion

    public T this[MapPlaneType key]
    {
        get
        {
            return this.internalArray[(int)key];
        }
        set
        {
            this.internalArray[(int)key] = value;
        }
    }
}
#endregion

public class MapPlaneTypeData
{
    public readonly MapPlaneType Type;

    public MapPlaneTypeData( MapPlaneType Type )
    {
        this.Type = Type;

        switch ( this.Type )
        {
            case MapPlaneType.Normal:
                break;
            case MapPlaneType.Cutscene:
                break;
            default:
                ArcenDebugging.ArcenDebugLogSingleLine( "Missing definitions for MapPlane " + this.Type, Verbosity.Displayed );
                return;
        }
    }

    public static ArcenEnumIndexedArray_MapPlaneType<MapPlaneTypeData> Lookup = new ArcenEnumIndexedArray_MapPlaneType<MapPlaneTypeData>();
    private static bool HasInitialized = false;

    public static void Initialize()
    {
        if ( HasInitialized )
            return;
        HasInitialized = true;

        for ( MapPlaneType i = (MapPlaneType)0; i < MapPlaneType.Length; i++ )
        {
            MapPlaneTypeData typeData = new MapPlaneTypeData( i );
            Lookup[i] = typeData;
        }
    }
}

We've done all of that for years and years, except the stuff in the Helper Classes region, which he just recently introduced.  You could do even more with that if you wanted; it's really powerful.
Have ideas or bug reports for one of our games?  Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark IV
  • *****
  • Posts: 3,861
Re: Jonathan Blow (Braid) talks about game programming languages
« Reply #11 on: September 21, 2014, 06:38:33 PM »
Oh, sure, enums exist, I just went the hacked route, because it was less wonky (i.e. don't need a helper class with a lookup function).

Offline x4000

  • Chris Park, Arcen Games Founder and Lead Designer
  • Administrator
  • Zenith Council Member Mark III
  • *****
  • Posts: 30,603
Re: Jonathan Blow (Braid) talks about game programming languages
« Reply #12 on: September 21, 2014, 06:43:05 PM »
I gotcha. :)
Have ideas or bug reports for one of our games?  Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark IV
  • *****
  • Posts: 3,861
Re: Jonathan Blow (Braid) talks about game programming languages
« Reply #13 on: September 21, 2014, 07:20:04 PM »
For the linked case, I just needed a series of primitive data types (two floats, three colors, a string name, and a vector of references to each other) that--except for the vector list--was referenced once in setting a cloned material type to have the correct values.

Old pic, but this is what it did:


All five of those use the same textures (each model having its own UV mapping to a different section of a 512x512 image) and utilizing color multipliers in the custom shader to give them different looks.

And rather have to reference stuff in odd ways and avoid duplication, an enum-with-properties was pretty much what I wanted.  Or in this case, a class with static instance references.
« Last Edit: September 21, 2014, 07:22:37 PM by Draco18s »

Offline Hearteater

  • Core Member
  • *****
  • Posts: 2,334
Re: Jonathan Blow (Braid) talks about game programming languages
« Reply #14 on: September 21, 2014, 07:22:54 PM »
Well, if we are breaking out code involving data type manipulation, here is an amusing piece I came across. First is the class SwitchOnType:

Code: [Select]
    internal sealed class SwitchOnType<T1>
    {
        private bool _break;

        public SwitchOnType()
        {

        }

        public SwitchOnType<T1> Case<T2>(Action action)
        {
            if (!_break)
            {
                if (typeof(T1) == typeof(T2))
                {
                    action();
                    _break = true;
                }
            }

            return this as SwitchOnType<T1>;
        }

        public void Default<T2>(Action action)
        {
            if (!_break)
            {
                if (typeof(T1) == typeof(T2))
                {
                    action();
                    _break = true;
                }
            }
        }
    }
}

Next is a method that is parsing an XAttribute from an XML file and converting it into the appropriate object:
Code: [Select]
        internal static T GetValue<T>(XAttribute att)
        {
            T value = default(T);

            if (att != null)
            {
                new SwitchOnType<T>()
                  .Case<int>(() =>
                  {
                      int x = 0;
                      if (int.TryParse(att.Value, out x))
                      {
                          value = (T)Convert.ChangeType(x, typeof(T));
                      }
                  })
                  .Case<decimal>(() =>
                  {
                      decimal x = 0;
                      if (decimal.TryParse(att.Value, out x))
                      {
                          value = (T)Convert.ChangeType(x, typeof(T));
                      }
                  })
                  .Case<string>(() =>
                  {
                      value = (T)Convert.ChangeType(att.Value, typeof(T));
                  })
                  .Case<double>(() =>
                  {
                      double x = 0;
                      if (double.TryParse(att.Value, out x))
                      {
                          value = (T)Convert.ChangeType(x, typeof(T));
                      }
                  })
                  .Case<float>(() =>
                  {
                      float x = 0;
                      if (float.TryParse(att.Value, out x))
                      {
                          value = (T)Convert.ChangeType(x, typeof(T));
                      }
                  })
                  .Case<long>(() =>
                  {
                      long x = 0;
                      if (long.TryParse(att.Value, out x))
                      {
                          value = (T)Convert.ChangeType(x, typeof(T));
                      }
                  })
                  .Case<bool>(() =>
                  {
                      bool x = false;
                      if (bool.TryParse(att.Value, out x))
                      {
                          value = (T)Convert.ChangeType(x, typeof(T));
                      }
                  })
                  .Default<DateTime>(() =>
                  {
                      DateTime x = DateTime.MinValue;
                      if (DateTime.TryParse(att.Value, out x))
                      {
                          value = (T)Convert.ChangeType(x, typeof(T));
                      }
                  });
            }

            return value;
        }