<![CDATA[Justin Bowes - Informi Labs]]>http://informilabs.com/Ghost 0.5Wed, 13 Nov 2019 20:08:27 GMT60<![CDATA[Lua x86_64 with Visual Studio 2015]]>
  • Expand Lua source code.
  • Create a batch file in the root of the expanded archive:
  • pushd "%VS140COMNTOOLS%"\..\..\VC  
    call vcvarsall amd64  
    md dist\x64  
    pushd src  
    del *.obj *.dll *.lib *.exp *.o  
    cl /MD /O2 /c /DLUA_BUILD_AS_DLL *.c  
    ren lua.obj lua.o  
    ren luac.obj luac.o  
    link /DLL /IMPLIB:lua5.3.4.lib /OUT:lua5.3.4.dll *.obj  
    link /OUT:lua.exe lua.o lua5.3.4.lib  
    lib /OUT:lua5.3.4-static.lib *.obj  
    link /OUT:luac.exe luac.o lua5.3.4-static.lib  
    copy src\lua.h dist\x64  
    move src\*.dll dist\x64  
    move src\*.lib dist\x64  
    move src\*.exe dist\x64  
    • Run in Developer Command Prompt for VS2015
    http://informilabs.com/lua-x86_64-with-visual-studio-2015/2eca8ed8-2c9f-4721-93f6-a335416272d3Sun, 06 Aug 2017 16:13:29 GMT
    <![CDATA[Building Boost 32-bit and 64-bit libraries on Windows]]>After completing this procedure you will have Boost's libraries in x86 and x64 variants, at the same time.

    cd \where_i_extracted_boost\  
    b2 --build-dir=build/x86 address-model=32 threading=multi --build-type=complete --stagedir=./stage/x86 --toolset=msvc-14.0 -j 12  
    b2 --build-dir=build/x64 address-model=64 threading=multi --build-type=complete --stagedir=./stage/x64 --toolset=msvc-14.0 -j 12  

    In MSVC, include them with a linker path of where_i_extracted_boost\stage\$(PlatformTarget)\lib for all configurations and all platforms, unless you're doing ARM or something like that (in which case, you do you!).

    Et voilà.

    Oh, you want I should explain?


    Create b2.exe. If you have Symantec Endpoint Protection installed, this might trigger a quarantine. This would be a good time to add your development folders to your exclude list.


    The build tool you just built. Replacement for bjam.


    b2 caches its configuration. When you build the second library with different settings, it looks like it uses the cached settings from the first build. Specify a distinct build directory for each build, or delete bin.v2 between runs.


    Build it this wide. If you thought you saw the Boost documentation claiming that it will build 64-bit by default if you're on a 64 bit host running 64-bit windows, you were clearly mistaken like I was. When you start the 64-bit build, you will see both 32-bit: yes and x86: yes. You can optionally worry about whether these instructions are actually going to work at this point, but the Py_ssize_t to unsigned int cast warnings flying by are your guarantee you've entered 64-bit flavour country.


    It's 2017. Include threading support. Again, if you thought you saw the Boost documentation claiming that it will build multithreaded by default, what can I say?


    Build [debug,release]x[static,shared]. That is, build all the variants so we don't have to do this again later.


    By default, boost will build to stage/ both times, wiping out your first build with your second. Don't do the default thing.


    It seemed to pick up MSVC14 on my system by default, but we've been burned before, haven't we? Specify explicitly. If you want to build for multiple toolsets, you can use the same stage dir -- the lib filenames specify the toolset to which they apply, so they won't collide. You'd probably want a different build-dir though.

    -j 12

    Boost builds on a single core by default, which is a shame because you've likely got 4, 6 or 8, times two for hyper-threading if you have that.

    Et voilà.

    http://informilabs.com/building-boost-32-bit-and-64-bit-libraries-on-windows/ea8925b2-898e-4801-8c9a-f4e541d5add2Thu, 09 Feb 2017 04:15:36 GMT
    <![CDATA[Building Freetype with MinGW-64]]>A few technical notes, because this was harder than it needed to be due to development environment cruft.

    1. Remove MSYS from your PATH.
    2. Disable Windows Subsystem for Linux.
    3. Remove old versions of GCC from your PATH.
    4. Install MinGW-64 using WinBuilds.
      a. The package URL was incorrect. If needed, override it to http://win-builds.org/1.5.0/packages/windows_64/ .
    5. Copy mingw32-make.exe to make.exe in winbuilds\bin. This may not be strictly necessary, but I'm disinclined to experiment at this point.
    6. Open CMake. Point to the source code and build target.
    7. Configure. Will succeed if paths are set properly.
    8. Set installation path.
    9. Open Terminal in build target directory (reminder: Shift+RMB).
    10. make
    11. make install
    http://informilabs.com/building-freetype-with-mingw-64/985048f4-cac7-43c1-9f70-ff87510cfa6cSat, 31 Dec 2016 14:55:33 GMT
    <![CDATA[Back in the Saddle]]>2015 was the year I ran out of money and instantly learned a lot of what I didn't know about indie game development.

    I duly went out and got a Real Job. In so doing, I learned a lot, about big teams and big systems and about doing things in ways other than the hard way.

    I learned that coding a lot every day had made me a better coder. I already knew that it did not make me a better planner or organizer.

    I didn't work on my games. I just thought about them.

    Time passed. I shipped some code that wasn't perfect. I spent a lot of time caring in an environment where a lot of people only pretended to care.

    I missed a bunch of Ludum Dares in a row.

    I wondered if I would ever go back to games. I lost my ability to write music when I emerged from a difficult period in my early twenties, and I was afraid this would be similar. I define myself by my creative outlets; I need to keep at least one alive, or I might dissociate and do stupid things.

    I moved around inside the company and worked by myself for a while. The day was easier. I cared less. I went home a little less sad.

    I found my old games, my indie corpses. They get harder and harder to build. I got them to build.

    There was a first person, 6DOF space flight simulator, written in tens of thousands of lines of C. When you rotate the spaceship, you can hear each gyroscope speed up and slow down. The cascading shadow maps that I struggled with for so long, look great. The spaceship has a console that runs an interpreter, just waiting for an interface that the player would have to modify.

    A tourist in my own code, I was amazed at what I had done. I remember the story that I wanted to tell, and how I abandoned the game when I realized that I had built a world too beautiful for me to be able to populate it properly.

    I put it down and looked at the next project.

    Here was a third person game construction kit that built spacecraft, landscapes and buildings out of a template language. It reused some of the underpinnings of the previous games, and was written in even more C. It was designed at first for simple spacecraft building; maybe KSP meets Minecraft meets Simple Planes.

    I remember going off my project plan because in the back of my mind, I wanted to tell the same story as last time, and it grew into a set of dev tools for building an adventure game. Then I realized what I was doing and changed it again.

    I killed it trying to avoid doing the project that was too big, and changing direction too many times. I switched branches in this same code base and saw the bones of an adventure game; of a Space Minecraft; of a crude but entertaining FPS construction kit. Looking at the remains of the effort, I felt such loss.

    I opened my last project.

    I had committed myself to one achieveable project in the time I had left. I had thrown away my C libraries and learned Unity.

    It started as a joke -- posting to Twitter a series of Gilded Age collage portraits, with the subjects wearing enormous fishbowl astronaut helmets. I built some scenery and physics and prototyped a compelling spin on top down Newtonian combat. The setting dictated these wonderful mechanical flight instruments, that flipped and extended and spun instead of lighting up. The menus were the same mechanized goodness, with character sheets that used procedural generation to be truly funny. I had great music playing inside a fantastic playback system on intro screens. It became clear that I was avoiding the game, because I wanted to tell the same story again and this wasn't the game that told that story.

    The Unity project was the hardest of all to recover. Intricate GameObject hierarchies that I would have expressed in code on previous projects, were mispositioned and full of broken references. The gears and dials and rotating drums were reduced to nonsense images that no longer deceived; they obviously represented time spent in premature polish. There was no game here.

    I had tried three times and spent almost three years, unpaid in the prime of my career, writing games; I failed three times because I wasn't writing the game I apparently needed to write.

    I stepped away from my failures. I quit the company where it hurt to care and joined one where being emotionally invested is the norm.

    I started writing games again. New ideas -- combat in odd geometries; generated mazes. I had ideas too big for a father of young children, coding in the evenings. I had ideas too small to be motivating.

    I rediscovered the script for the story that I had been failing to tell for all these games for all these years.

    For my birthday, I stayed up until 3:30 AM building the UI I would need for the first scene of the first page of this game.

    Last night, I took a website template and changed it until it said the things about the game that I wanted to say. I was surprised at how easy it was to talk about a thing that didn't exist.

    I need to write this game. I need to write it as simply as I can, and then I need to stop writing it and write a different game, because I am tired of wasting this motivation and building beautiful things that nobody but me will ever see.

    That's a strange way of saying it's good to be back, and this is a strange way of feeling it, but at least I keep this creative outlet; at last I remember who I am.

    I am that guy who can't let go, and here we go again.

    http://informilabs.com/back-in-the-saddle/50d2ab21-0aa9-4ae6-a51e-40e2b12233f5Fri, 09 Dec 2016 21:29:53 GMT
    <![CDATA[Unity 5 and Unplanned Obsolescence]]>I have a Unity project in progress that interacts with some physics bugs present in the 4.6 series. So, incautiously, I decided to upgrade.

    It's not that I was expecting damage. Ill-considered project mangling is one of the many perils I do not fear because of source control. But I know Unity 5 ships with an automatic source code transformer to update your use of some widespread removed API for component accessors, like Camera, Rigidbody, Renderer, etc.

    What I encountered is a confluence of decisions that make life just a little bit worse for Unity developers. Unity has introduced a reason to use the "my" prefix in cross-component wiring.

    I believe that zero-information prefixes, like "my" in module or class level code, are a code smell. They point to overlapping naming conventions.

    C# already has one of these -- types and public members both use CapCamelCase by convention, a convention that Unity wisely ignores (but meanwhile ships with MonoDevelop, which fills your projects with capitalization warnings if you follow their lead). Now,

    If your Unity 4 code looks like this:

    if (target) {  
        Rigidbody2D targetBody = target.rigidbody2D;

    ...in Unity 5, this becomes:

    if (target) {  
        Rigidbody2D targetBody = target.GetComponent<Rigidbody2D>();

    Easy enough, and if Unity hadn't provided an automated transformation tool, I might have rolled my own.

    However, there's another aspect of the way the API change was done that is going to frustrate me continuously: the component accessors (.camera, .rigidbody, .renderer, etc.) were marked deprecated and not removed. Is this what you expected? Look closer. They don't return their former types; instead, each returns a generic Component, which is sure to break most existing code. Again, with the automated code conversion, this doesn't seem like a big problem...but.

    The previous example was a component manipulating a different GameObject's components. Let's consider the common case in which the component is manipulating its own components.

    Vector3 velocity = camera.velocity;  
    camera.orthographicSize = targetZoom;  

    This code is a little bit sloppy, because as we know, the convenient accessors were just a facade to GetComponent<>. We knew this, and where it seemed worthwhile, we created a member variable and populated it with a single GetComponent call. We did this often, but maybe not always.

    This becomes:

    Vector3 velocity = GetComponent<Camera>().velocity;  
    GetComponent<Camera>().orthographicSize = targetZoom;  

    Ouch. The API change has made it painfully obvious where we've fallen short of best practice. So let's fix it:

    Camera camera;  
    void Awake() {  
        camera = GetComponent<Camera>();
    void Update() {  
        camera.transform.position = new Vector3(next.x, next.y, current.z);
        camera.orthographicSize = targetZoom;

    What's this?

    CameraController.camera hides inherited member 'UnityEngine.Component.camera'. Use the new keyword if hiding was intended. (CS0108)

    Okay. It's not a HUGE deal. I can just call it myCamera. But Unity people, this is stupid.

    The API changed the signature of accessors, and also deprecated them. Changing the API reduces cross-module dependencies for your team. I get that. It also makes our code better, as I've shown above. But if my obsolete code is already broken, release those accessor names by simply removing them, because they're the obvious choice for caching variables.

    Will it kill me to use Camera myCamera? Yes. I'll die a little on the inside, which is what I was doing writing my own engine.

    Hey Unity people, kudos on the API cleanup. Obsoleting properties plus changing their signature and breaking them anyway is the worst of all worlds, and I think it was a mistake in an otherwise well-executed transition. I look forward to you removing these obsolete properties in an early Unity 5 point release. Thanks.

    http://informilabs.com/unity-5-upgrade-experience/94ecd3eb-e4bc-47e0-9759-252a2e1f1708Tue, 03 Mar 2015 21:41:00 GMT
    <![CDATA[Unity Rigidbody2D Smooth Camera]]>Following a Unity Rigidbody2D with a camera works perfectly if done right. If not done right, it's a frustrating mess.

    Unfortunately, knowing what constitutes "done right" is also a frustrating mess, and interpolation issues in the 4.5.x and 4.6.1 releases made it difficult to identify the correct technique.

    Here's what you need to know:

    Use Update or LateUpdate, not FixedUpdate

    A lot of people suggest using FixedUpdate to maintain your camera position, and it's true that only updating your camera on physics updates results in smooth following. But GameObjects not controlled by RigidBody2D components will then be seen to stutter. The only solution is to use Update, and make Unity properly update the target's position using interpolation or extrapolation.

    Use Interpolation or Extrapolation to smooth the target's position between physics frames

    This produces smooth inter-FixedUpdate positions, with caveats. Prefer interpolation, because its degradation in case of extreme velocity changes will be lag, not overshoot.

    Set interpolation at the correct time

    As of Unity 4.6.1, you need to set interpolation on a Rigidbody2D before Update runs on it. If you do it during or after the first Update(), the property changes without having any effect on the Rigidbody2D. This is probably a bug.

    http://informilabs.com/unity-rigidbody2d-smooth-camera-following/d2fda10a-3647-4db8-9eaf-e75b886cfb26Tue, 03 Feb 2015 00:25:58 GMT
    <![CDATA[From C to Unity in Five Simple Years]]>Today is my second day of my latest attempt to use Unity. I'm going to try to document a lot of what I'm learning and seeing here. I will frequently be wrong and go down blind alleys, I'm sure, but that's how it goes with new technologies.

    The decision to use Unity 3D is an about face for me, certainly.

    I've been developing in C99 (no C++) almost exclusively for two years. Honestly, I think the majority of that time was spent writing memory management code. Not in some monolithic project -- just writing functions that initialize and free nested struct fields over and over and over. An attempt in August to port my project and its underlying cross platform library to use Samba's talloc library was the right thing done far too late.

    There is a school of thought that says games should never dynamically allocate memory, and the reasoning is informed by more experience than I possess. But it's a hard requirement to meet, and nearly impossible to retrofit. For instance, the first piece of cross-platform C game code I wrote was a system to render text using texture atlases built using FreeType. If no dynamic allocations is the game, I just lost: FreeType, the texture atlas, the atlas regions, the hashmap of glyphs. It's hard to imagine doing things another way. I was so innocent then. I was just glad it worked. I didn't know.

    A more realistic approach is to allocate no memory in your own code, and to use trusted libraries wherever a problem is intractable without dynamic allocation. A less realistic approach is to allocate no memory in your own code, except for all the libraries you wrote, which are also your own code.

    I still believe C is a productive application development language, if the platform for that development is sufficiently strong. But the platform requirements for some of my prototypes (full 3D, huge amounts of dynamic geometry, custom asset pipeline, in-engine asset building tools with full GUI) were huge. Yes, I'm now referring to my last two projects, Pod and Quanta, as prototypes, after a combined 30 months of heavy development.

    Lacking the tools to write 3D prototypes in days, I wrote them in months, predictably resulting in hard-to-ignore sunk costs and bottom-up game design. I didn't want them to be prototypes. In fact, considering the costs, I needed my prototypes to be home-runs. Predictably, they weren't.

    Here's my greatest hits collection of huge unrealized prototypes:

    Solarium. I wrote it in Java, using everything I knew about enterprise software development. That's not a joke, but it should be.

    Such beautiful planets. So much data modelling. So much code.

    Pod might contain the best rendering engine I will ever write. Its level of graphical fidelity was so high I could not afford to produce the assets for gameplay. I tried to go all-procedural: the asteroids were procedural down to the pixel. But in the end, fun gameplay is about more than modified ellipsoids. In gameplay terms, this engine was mated to...nothing. Can you make a game about nothing? Maybe Jerry Seinfeld could.

    Writing your own game library in C is a stupid way to prototype complex games. There, I've said it, and now I can stop making stupid decisions forever.

    Forever alone Farewell, Quanta. We never knew what ye were.

    I love these big, stupid projects. Looking at them breaks my heart. But the fact that they were essentially huge prototypes means that most of the time I spent on them was wasted, and crucially, I could duplicate the results if I had a game development business reason to. I don't. Not yet. Their legacy is a story, a shared universe that I never even began implementing. I need to tell that story. But I need more skills, experience, and cash to tell that story. I get it now. I think.

    There are other space games in my brain, fighting to get out. I recently wrote a prototype in libgdx, which is maybe my favourite piece of code that I almost entirely didn't write. I can't say enough good things about libgdx, as a rapid game dev tool, as I've been using it for years in my saner moments. And I have a little game -- not quite a game, really, but already crazy fun. The prototype did its job. I have some big decisions to make.

    I could carry on using libgdx, but it is a Java-based platform. I have huge reservations about Java as a runtime environment. No; "reservations" is not the right word. If I am done making stupid decisions, I'm not going to make my life harder by supporting a desktop client with JVM packaging, LWJGL, and everything about JNI you never wanted to know (but were afraid to ask). The JVM as a desktop environment is dead, killed by Oracle's focus on B2B, and Minecraft was its last hurrah.

    I thought libgdx was a good idea because it supports so many other platforms: write Java, but run whatever gets you onto the platform in question. I was initially very keen on an HTML5 target via libgdx's excellent HTML5 support. I've tested my prototype on tablets and phones already, simply by connecting to my dev server over wifi. I've confirmed that a phone is a terrible platform for two-axis scrolling. I've also learned a lot about the game I am working on.

    The first thing I learned is that it is not a casual game. It's an action game. It's a physics game. It's not for candy crushers and jewel beclickers. So the HTML5 target, a huge strength of libgdx, is irrelevant, and whether to continue with libgdx comes down to the strength of its support for other targets. As I said, desktop is out. Consoles are out (except for Ouya, I suppose). Android is in, but only Android tablets, as I mentioned. iPads are in via RoboVM.

    I just don't know if that's enough. I want to reach the platforms where the players want to play my kind of game. If I want to switch toolkits, now's the time.

    Unity's not-as-useful-as-it-looks scene editor, lack of nested prefabs, and not-quite-entity-system architecture are all decisions I wouldn't make. But I've already learned enough to work around them and get down to C#, which is the Java I always wanted. I need to make more game with less work. I need to focus on desktop for now but keep my options open in terms of platforms. I need to ship a game.

    And if it doesn't work out, "Unity 3D developer" looks a hell of a lot better on my resume than "three years of development on a closed-source C library used in 0 shipped games."

    In the games business, I've learned, plan Bs are important.

    http://informilabs.com/unity-plunge/6893fd77-15b5-40a4-bdf8-717c6686e3d3Thu, 29 Jan 2015 14:58:52 GMT
    <![CDATA[Sudden Hardware Death]]>If only I had listened.

    My friends know I've had some bad experiences. I'm no stranger to heartbreak. But this time was different, and I told them so. It's been good, I told them. Really good.

    For years we worked together, played together, laughed together, sharing the good times. Everything seemed perfect.

    Then, suddenly, gone.

    Today, my APC Back-UPS ES 750 Uninterruptible Power Supply abruptly departed this world. It had been making little peeps for a few weeks -- a high pitched sound I thought might be a saw operating somewhere down the street. It never occurred to me that this might be it; that these could be our final days together.

    When it went, I was moving plugs around, trying to attach just one more DC transformer. I moved my Macbook Pro power brick to a socket next to the master power button. I moved another plug, and accidentally brushed the brick. The button went down, halfway. I heard a pop.

    My old friend, it was an accident. When the magic smoke came out of you, I knew you were gone, but I poked at your circuit breaker 20 times anyway. Maybe you'll cool down, I thought, hopelessly. Maybe everything will be okay.

    And seriously, WTF, circuit breaker? YOU HAD ONE JOB!

    So many wonderful memories. The house in darkness; you beeping reassuringly; me cackling while I carefully, without haste or worry, save my documents to disk. Your automatic switching feature automatically turning out the LED lights around my desk when I put my computer to sleep, and creepily turning them back on when the computer wakes itself up in the middle of the night. Your crazy status monitoring cable, with a USB plug on one end and RJ45 on the other. Your green status light that is always so reassuring. ...was. Was reassuring.

    I remember these things, and I mourn.

    Farewell, sweet UPS. May your battery discharge always be shallow.

    In other news, my Apple Time Capsule died for the second time today, stupid piece of crap.

    http://informilabs.com/sudden-hardware-death/13edd047-fe76-4358-8635-4457f9d0a137Sun, 14 Dec 2014 18:20:05 GMT
    <![CDATA[Lexical Conditionals]]>Here's a thing I'd love to see in C, but I never will.

    // Suppose we have a known function pointer type...
    typedef void(*callback)(int param);
    // And some compatible function pointers...
    struct callbacks {  
        callback if_foo;
        callback if_bar;
    } my_callbacks = {...};
    void invoke_callback(struct my_callbacks *cbs, bool is_foo, int param) {  
        cbs->(is_foo ? if_foo : if_bar)(param);

    This doesn't work. People who understand C As She Is Spoke will understand clearly enough: neither possible result of the conditional ternary is an expression that can be evaluated on its own. The conditional is parsed as though if_foo and if_bar are standalone identifiers, and of course they're not.

    But of course, if you look at the statement another way, it does make some sense. The presence of the dereference operator -> along with the subsequent grouped expression, seems to establish a lexical scope that needs to be resolved before parsing can continue.

    And if seems were seams, I'd be Betsy Ross. You read the C spec and that's not how it works, and that's that. Can we gain any insight by trying to make it work another way?

    callback cb;
    // 1. Fully qualified expressions obviously work
    cb = (is_foo ? cbs->if_foo : cbs->if_bar);
    // 2. Pointer math
    cb = (callback)(is_foo ? offsetof(struct my_callbacks, if_foo) : offsetof(struct my_callbacks, if_bar) + (uintptr_t)cbs)
    // 3. Macro
    #define field_select_cond(c, prefix, a, b) (c ? prefix->a : prefix->b)
    cb = field_select_cond(is_foo, cbs, if_foo, if_bar)
    // 4. Abomination
    cb = (callback)((uintptr_t)my_callbacks + (is_foo ? offsetof(typeof(*my_callbacks), if_foo) : offsetof(typeof(*my_callbacks), if_bar)));  

    The first one is how I actually do it. The second approach loses type information that you have to restore. I will admit to using the third approach or something like it, deep within macros that generate reams of boilerplate code. The fact that the fourth works at all is a tribute to how far the new C99 and C11 specifications have come compared to C89/90.

    In fact, given that the fourth approach is valid, you could imagine this being implemented as a parser trick, the same way a function pointer cb invoked using cb(args) is actually converted to (*cb)(args) by some parsers.

    But it gets ugly so fast. The inner scope can create shadowed identifiers simply by being created (e.g. what if struct my_callbacks contained a field named is_foo?) How do we handle this? We need some kind of token to indicate whether an identifier is part of the inner scope or the outer, indicating outer scope with something like C++'s ::.

    Or...maybe that's the wrong approach. What if the outer scope is still default, and we specify inner scope the way we normally do?

        cbs(is_foo ? ->if_foo : ->if_bar)(param);

    Like the proverbial regex-smith, now we have two problems. Except for the prefix dereference operators, we have a pretty clear expression, that says evaluate the conditional, call cb with the result of that, expect a function pointer as a result of that, then call the function pointer with the argument param. This is wrong on two counts, and this is where I leave well enough alone.

    A final aside, for the sake of Monday morning quarterbacks: Was it a bad idea to use parentheses for all of the type cast operator, the function invocation operator and the statement grouping operator?

    assert([[[[this] is] so] much: better]); // They tell me this is better.  
    assert(array[object[array[[object] selector]]selector]] > 0); // WHY DID THEY LIE  

    It's too late now. ¡We've used all the standard paired delimiters!

    http://informilabs.com/lexical-conditionals/08e1c931-1890-43ee-83f8-641c2787af6dFri, 12 Dec 2014 16:12:51 GMT
    <![CDATA[Leaving IMGUI Behind]]>After a solid attempt to use immediate mode GUI concepts in my programs, I'm giving up.

    A naive implementation of an IMGUI is straightforward, easy to integrate, and easy to use. Unfortunately, when this naive implementation meets the big bad world of production use, it grows up fast.

    The strength of IMGUI is that it doesn't care how you use it. You need to throw in a debug UI that adjusts a value here, pokes a string there, and it works great.

    I'll briefly summarize my use and abuse of my homegrown IMGUI library, starting with a dirt-simple example:

    void my_game_loop(double dt) {  
        if (imgui_button(400, 300, "Spawn Enemy")) {

    But if you're trying to construct a dynamic game UI with layout, what then? You define some sort of active area (which sets hidden state):

    void my_game_update(double dt) {  
        imgui_begin(600, 400, imgui_layout_flow_lr_tb);
        if (imgui_button("Spawn Enemy")) {

    And you want it to do its processing in the engine phase of your loop, and its drawing in the render phase of your loop, so you have it manage a display list (which sets hidden state):

    void my_game_engine(double dt) {  
        imgui_begin(600, 400, imgui_layout_flow_lr_tb);
        if (imgui_button("Spawn Enemy")) {
    void my_game_render(void) {  

    And you want to integrate it with other rendering, but you have to set it up in the engine phase, so you write a callback "control" (which sets hidden state) that escapes the IMGUI display list and runs your special rendering function:

    void draw_enemy_preview(rect2d draw_area, void *context) {  
        enemy_t *current_enemy = context;
    void my_game_engine(double dt) {  
        imgui_begin(600, 400, imgui_layout_flow_lr_tb);
        imgui_draw_callback(draw_enemy_preview, vec2d_set(100, 100), current_enemy);
        if (imgui_button("Spawn Enemy")) {
    void my_game_render(void) {  

    If you're following along at home, you can see that by the time you have a full featured UI, you have a lot of hidden state inside the IMGUI context.

    So IMGUI is no simpler to implement well (and nobody seems to be claiming it is). But is it simpler to use?

    It's very explicit, and many programmers like that. You can see what is drawn, and when. Data binding can be just as explicit and easy: a slider control could take a pointer to a float and modify the value directly.

    But any sane UI implementation, including IMGUI, needs to retain state. It needs to render and cache text. It needs to know where it last put a control so it can put the next in the right spot. It needs to store skin parameters like fonts and colours, if those are configurable. It needs to know, from frame to frame, what state it can keep and what it can discard, which means that the API must accept that state every frame and check it against the last state every frame.

    We are now left with an "IMGUI" wrapper around a retained-mode UI. In other words, we have a retained UI in which the layout data is encoded as function parameters, and the layout must be re-evaluated every frame.

    IMGUI is a solution to the problem of UIs that hide an unreasonable amount of complexity for what they do. If you make an IMGUI try to do too much, you get the same complexity, only it's not hidden. It's in all your code that calls the IMGUI.

    You can roll a decent UI from scratch. I will attest to this; I've done it twice now.


    • you need that UI in a hurry
    • it's strictly for debugging
    • it's about developer convenience

    go IMGUI and regret nothing.


    • you need that UI to be user-facing;
    • you need it to be reusable;
    • you need to be able to serialize it;
    • you can anticipate being frustrated at a lack of separation of concerns and having to write MVC wrappers,

    bite the bullet and acknowledge that the retained model fits your problem better.

    That's the genesis of RUI, a C99 UI library I'm currently whipping into shape, and I'll talk more about it when maturity warrants.

    http://informilabs.com/leaving-imgui-behind/483e2785-393f-40a9-812d-781b2ae38dc2Thu, 11 Dec 2014 20:13:35 GMT
    <![CDATA[Saying No]]>I am guilty.


    • you had a project you wanted me to work on
    • it was a great opportunity to get more work down the line
    • it could work out well for everybody
    • you were just looking for the right partner


    • you wanted me to do work for you, for free


    • I probably agreed that it was a great idea
    • I probably brainstormed with you on the overall approach
    • I probably discussed first steps


    • I took my first contract more than 20 years ago
    • I work for money or equity, not opportunities or promises
    • if your idea is so valuable, you should invest in it by hiring a professional
    • I don't need to take uninformed risks in your area of interest; I have my own


    • I never contacted you again.

    I am guilty of treating you with the same lack of respect with which you treated me.

    Okay, I'm done feeling guilty.

    http://informilabs.com/saying-no/76e1c126-5307-4f51-9a03-35c1ff436220Mon, 08 Dec 2014 14:21:30 GMT
    <![CDATA[A Trial Separation]]>A link to this post was published to my Tumblr account.

    I've been doing things the same way for a long time now.

    1. Write a game about space.
    2. Post about that game on Tumblr.

    After about five years, I'm pretty clear on what works for me and what doesn't.

    What Works

    Writing games works for me. It may not pay the bills, but it provides a reason to work hard and seek inspiration.

    What Doesn't Work

    Keeping a devlog on Tumblr doesn't work for me.

    I was an early adopter of Tumblr. It was a simple way to set up a multimedia blog. I had a pretty good looking theme. I wrote long posts when I wanted to and short posts when I wanted to. The longer posts were successful more often. I had analytics and a comments system.

    But then something terrible happened: everybody joined Tumblr.

    This is not a hipster "it was better before it was popular" argument. It's just that once you join Tumblr, everything happens on the dashboard.

    The Dashboard Promotes TL;DR

    Here's what the dashboard means for posters: You're locked into Tumblr's stupid comment system. Your analytics are gone, replaced with followers and notes. Your nice theme is gone: your followers never see it. It's only advertising to people who haven't joined Tumblr yet. Your posts get boxed into a too-narrow tombstone column. The only way to attract attention is to condense everything into tweet-length posts and animated GIFs. For posters, this is a disservice.

    Here's what the dashboard means for readers: Everything is delivered in a single firehose. You can't prioritize some posters or content over others. Your dashboard is dominated by whoever can post most often, which turns it into a battle of who can care less. All those things you found interesting are distilled into a too-narrow reader interface. Magazine-length articles, photo-bloggers, aspiring directors, people trying to give away their video games, all treated with the same disdain. For readers, this is a disservice.

    It's Business, Baby

    Why does Tumblr treat both its loyal readers and its loyal posters to this menu of disservice? Not ignorance. Tumblr, being stacked with smart and competitive people, not being ignorant of their product and platform, wants things to work this way. It's business, baby.

    All the effort that goes into themes and content is advertising for Tumblr, to get you to join.

    And the subsequent de-emphasis of content is to make that same content boring, to get you to make new connections, follow more, like more, please somebody anybody post something interesting.

    To make the platform stickier.

    To keep you on the dashboard.

    Where the ads are.

    Reap it Daily

    When you de-emphasize content and personality and continuity, you kill subtlety. The people who win on the Tumblr dashboard have something to say that can be expressed in a flashy animation, or in fewer than 60 words. Attractive or inflammatory.

    You can unfollow them, but then your dashboard is barren, by design.

    Considering the work that earlier Tumblr users did to attract new members, this sucks.

    Believe it or Not, This is the Nice Tumblr

    There are so many great and creative people on Tumblr. It is easy to join and easy to use (if ultimately unsatisfying). And, in a kind of rebellion against the dashboard, the Tumblr community has repurposed tags as a means of identifying the author.

    I've tried to work within this system to help other creators. I tried reblogging people and projects I thought should be amplified. I tried assembling visual teasers of projects under a common "Tumblr & Indie Game Developers" header. I've even posted tips that "work around" Tumblr, to help your posts stand out on a dashboard. But these efforts were drowned out the same way my own projects are. I give up.

    You might say it's poor form to trash a platform that has let me publish for free for almost four years and over 500 posts. And you would have a point. I struggle with graceful exits.

    Just remember that Tumblr was bought by Yahoo, and is apparently not yet profitable. The Tumblr we see now is still willing to lose money on us. This will end at some point.

    Love & Unfollow (& Make Your Own Sandwich)

    My best content is not going on Tumblr anymore.

    Out of the people and projects here that I find so fascinating, I hope I've had some kind of dialog with most of you by now. Or, if you were too awesome and I was not worthy, then just likes.

    Staying in touch is going to take more work. I have some ideas. In the short term, I'll follow via RSS, but RSS has a few of the same failures as Tumblr. I'm working on a better solution.

    And please, if you have something worth saying that you want to own -- not just the content, but the way it's presented -- own it. Try Wordpress or Ghost.

    Thanks for reading this on my blog.

    http://informilabs.com/a-trial-separation/07b204f6-a651-4809-9868-1ccb9693be71Wed, 12 Nov 2014 03:00:00 GMT
    <![CDATA[OS X Yosemite and Google App Passwords]]>The Internet pane of System Preferences does not properly sync updated passwords to all applications. Furthermore, the failed authentication prompts on Mail and Calendar do not update a password changed in this way, neither on the account present in System Preferences > Internet Accounts, nor even in the application displaying the prompt.

    I discovered this by fighting with Google's 2-factor authentication. Since most standalone applications don't support Google's verification protocol, 2-factor doesn't work with things like IMAP mail clients, making it useless without some workaround. The workaround is app passwords, non-recoverable tokens intended to be used by a single app or device. If you're trying to secure your Google account, It's pretty frustrating when those don't seem to work either.

    After turning on 2-factor authentication, you need to switch to 2-factor sign on or start using app passwords. I created an app password for the System Preferences pane on my iMac, thinking that a single app password could take care of all the integrated apps. But it didn't seem to work. After entering the app password into System Preferences > Internet Accounts, I was treated to a barrage of password prompts. Like an insane person, I pasted the password into the dialog several more times and expected a different result. Then I tried to generate a new password several more times, with the same results.

    After a few minutes of digging in Mail and overwriting any password I could find, Mail stopped complaining. Hooray! The excitement was short-lived. Calendar soon started throwing up password prompts too. I gave up and got back to work.

    Today, I generated a new app password and pasted it into Calendar. Calendar reported that it could not connect to the server. I tried my Google account's main password, and Calendar reported that the server returned an error.

    I opened System Preferences again, determined to circumvent the app password system. I entered my main password there, and received a more helpful error: I needed to generate an app password. Of course. This is 2-factor in action: I shouldn't be able to use the main password here.

    I generated a new app password, and entered it into Calendar again. Failure. I entered it into the System Preferences, which reported that Internet Preferences cannot connect to the account:.

    To hell with it. I deleted the entire account from the preference pane, added a new Gmail account, pasted in the app password. To my perpetual amazement and confusion, everything worked.

    Until Apple fixes password syncing between System Preferences > Internet Accounts, Mail, Calendar, and the failed authentication password popups, consider the preference pane a write-once interface. That is, set it, and if you want to change it, delete the account in the pane, and then create a new one.

    http://informilabs.com/os-x-yosemite-and-google-app-passwords/434c77c6-7929-43d3-84ee-34dbf1c426a5Tue, 11 Nov 2014 17:21:50 GMT
    <![CDATA[Programmer Hypotheticals]]>As a programmer, I try to always be reading questions and answers, and never writing them. The truth is that I would rather work around the lack of a good answer than deal with a particular type of conversation.

    Since programmer-speak can verge on the arcanely obscene, I've taken the liberty of translating such an interaction into a different context, so that programmers and muggles alike may groan in unison.

    Well, piano experts may find this annoying. It couldn't be helped.

    I have a problem moving my piano.

    The piano is a Funkenhauser K2 grand which was a gift from my late mother. I can't get it through our patio door without taking the legs off it and moving it at an angle, which I was warned not to do because the frame on this model is supposedly susceptible to warping. It doesn't look like I have any alternative. Is there any way to minimize the risk of damage?

    Any advice would be appreciated.

    Why would you want to move the piano outside? The humidity and temperature variation will destroy a wooden piano body, especially one that uses a more permeable lacquer like the factory finish on the Fünkenhauser K2.

    I don't want to move it outside, exactly. We're moving out of our house (which was also a gift from my mother) into a new place, and for a lot of reasons I'd like the piano to come with us.

    Well, just move it out however it got in there originally.

    I would do that if I could, but the patio door was replaced at some point after she purchased the piano and the new opening is smaller. I'm just looking for a way to get it out of there with minimal damage to the house and piano.

    You should never reduce the size of a doorway below the size required to move the item out of a room. Also, warping is a known issue with the K2 and you should avoid moving it at an angle.

    You're right, of course, but that's the position I'm in now. Does anybody have any advice? (Anybody?)

    If you intended to move it you shouldn't have reduced the size of the doorway. If there was a chance that you were going to reduce the size of the doorway and you might end up manhandling the piano, you shouldn't have purchased a model with a lightweight frame that can warp like the Fünkenhauser K2.

    Does this seem exaggerated? Ridiculous? Only slightly. This hypothetical exchange demonstrates some of some of the worst of programmer hubris and self-deceit, which I shall call:

    The Pillars of Unhelpful Assistance

    1. Conflating knowledge and intelligence. A person seeking the solution to an intractable problem is possibly in over his or her head, but that does not imply that he or she is an idiot. However, if you cannot think of a situation in which your intelligent self might ask an obvious question out of ignorance, you might be an idiot.

    2. Ignoring critical background information and constraints in your proposed solution. The solution to a lot of hypothetical programming problems is to remove some constraint. The question is often being asked in an attempt to locate the constraint of least resistance. If there is no good answer to the question, that's useful information. On the other hand, if you just can't tolerate being without an answer, go watch Jeopardy.

    3. Ignoring the requirements to reframe the problem as trivially solvable, or not a problem at all. Instead of changing the environment of the problem, you're changing the problem itself, so rather than solving the problem being asked, you're solving the problem you think should have been asked, or objecting to the fact that there is one. My observations suggest that most programmers who treat user requirements this way, get fired. On the other hand, a person receiving this response to a question in a public forum can only hope you go away. Unless user18399057 is actually your boss.

    4. Making the asker the problem. If you are such an expert that you would never find yourself in such a situation, and you have no useful answer, then the question wasn't for you. The question was intended for an expert who could get themselves out of such a situation anyway -- the kind of thing that is going to be expected of you at your next promotion.

    I have seen these characteristics demonstrated by some of the most knowledgeable specialist programmers on the Internet. A specific, highly technical question, set against a background of "that's how I would do it too," gets a thorough, detailed, correct and utterly authoritative reply, and it is a privilege to read. Then you see another reply, from a bad day or a question that was "beneath" the respondent, and not only is it combative, unhelpful and a waste the asker's time to read, but a criminal misuse of the time of the expert replying, because that time could have been spent answering a better question, or finding a cloud that looks like Snoopy.

    I think that these sort of bad answers are the response of an intelligent person to what he or she perceives as a deluge of bad questions. I understand the complaint, but in public fora like StackOverflow where such questions reign, there is no standard of service; no obligation for anyone to reply; no ticket queue to clear before Friday. If you do not like the question, there is nothing to be done. It's Darwinian -- those who can search or ask to get the information they need, survive to experience even greater ignorance in tougher challenges.

    And so:

    The Pillars of Helpful Unassistance

    1. If a question is beyond you, don't answer.
    2. If it's beneath you, don't answer.
    3. If you're having a bad day, don't answer.
    4. If it's unsolveable, answer that it's unsolveable as asked, and identify the limiting constraint for bonus marks...or just don't answer.

    Questions and answers aren't for everyone. In my own case, it is well within my capability to ask a stupid question and give a demeaning, unhelpful reply on the very same day.

    If this could be describing you, too, you can try my system: ask only Google, and channel any insufferable haughtiness into blogging.

    http://informilabs.com/programmer-hypotheticals/8dbc155d-7f7f-4e2e-b107-e6bb7c1fa19cThu, 30 Oct 2014 20:16:06 GMT
    <![CDATA[C's Curious Incapability]]>Suppose I have a service that controls lights. It's attached to a common struct interface, like this:

    typedef struct light_controller light_controller_t;  
    struct light_controller {  

    I use it like this:

    light_controller_t *lights = ...  
    lights->switch(lights, false);  

    And it's implemented like this:

    static void lights_switch_impl(light_controller_t *self, bool on) {  
        self->room->lit = on;
    void lights_controller_default_init(lights_controller_t *self) {  
        self->switch = lights_switch_impl;




    static void lights_switch_impl(light_controller_t *self, bool on) {  
        self->room->lit = on;
            child->switch(child, on);




    function service_node.get_service(service_type):  
        if (self implements service_type)
            return self as service_type
            return service_proxy(self, service_type) as service_type
    function service_proxy(parent, service_type):  
        self = new service_type()
        for (method in service_type.methods)
            method = function(args...):
                for (child in parent.children)
        return self



    class Proxy  
      def initialize(owner)
        @owner = owner
        def method_missing(method, *args, &block)
          @owner.children.each { |child|
            child.send(method, *args, &block)





    function service_proxy(parent, service_desc):  
        proxy_method = pseudo_asm(self, args):
            args = stack_pop()                      // take args
            self = stack_pop()                      // take self
            for (child in parent.children)
                stack_push(args)                    // copy args
                stack_push(child)                   // self pointer will be child instead
                call next_eip                       // magic! :)
        for (method in service_desc.methods)
            method = proxy_method
        return self




    Stone age computing hurt brain!

    Let's JFGI.



    #include <limits.h>
    #include <stdint.h>
    #include <alloca.h>
    #include <inttypes.h>
    #include <string.h>
    /* Currently we don't care about floating point arguments and
     * we assume that the standard calling conventions are used.
     * The wrapper function has to start with VA_WRAP_PROLOGUE()
     * and the original function can be called by
     * be stored in ret.  The caller has to provide ret
     * even if the original function was returning void.
    #define __VA_WRAP_CALL_FUNC __attribute__ ((noinline))
    #define VA_WRAP_CALL_COMMON()                                        \
        uintptr_t va_wrap_this_bp,va_wrap_old_bp;                        \
        va_wrap_this_bp  = va_wrap_get_bp();                             \
        va_wrap_old_bp   = *(uintptr_t *) va_wrap_this_bp;               \
        va_wrap_this_bp += 2 * sizeof(uintptr_t);                        \
        size_t volatile va_wrap_size = va_wrap_old_bp - va_wrap_this_bp; \
        uintptr_t *va_wrap_stack = alloca(va_wrap_size);                 \
        memcpy((void *) va_wrap_stack,                                   \
            (void *)(va_wrap_this_bp), va_wrap_size);
    #if ( __WORDSIZE == 64 )
    /* System V AMD64 AB calling convention */
    static inline uintptr_t __attribute__((always_inline)) va_wrap_get_bp()  
        uintptr_t ret;
        return ret;
    #define VA_WRAP_PROLOGUE()           \
        uintptr_t va_wrap_ret;           \
        uintptr_t va_wrap_saved_args[7]; \
        asm volatile  (                  \
        :                                \
        :"a"(va_wrap_saved_args)         \
    #define VA_WRAP_CALL(func, ret)            \
        VA_WRAP_CALL_COMMON();                 \
        va_wrap_saved_args[6] = (uintptr_t)va_wrap_stack;  \
        asm volatile (                         \
        "call             *%%rbx \n\t"         \
        : "=a" (va_wrap_ret)                   \
        :  "%rcx", "%rdx",                     \
          "%r15"                               \
        );                                     \
        ret = (typeof(ret)) va_wrap_ret;
    /* x86 stdcall */
    static inline uintptr_t __attribute__((always_inline)) va_wrap_get_bp()  
        uintptr_t ret;
        return ret;
    #define VA_WRAP_PROLOGUE() uintptr_t va_wrap_ret;
    #define VA_WRAP_CALL(func, ret)        \
        VA_WRAP_CALL_COMMON();             \
        asm volatile (                     \
        "call  *%1        \n\t"            \
        : "=a"(va_wrap_ret)                \
        : "r" (func),                      \
          "r"(va_wrap_stack)               \
        );                                 \
        ret = (typeof(ret))va_wrap_ret;

    Uhng. How it work?

    int __VA_WRAP_CALL_FUNC proxy_printf(char *str, ...)  
        int ret;
        VA_WRAP_CALL(printf, ret);
        return ret;

    Ladies and Gentlemen...printf.




    static void lights_switch_impl(light_controller_t *self, bool on) {  
        self->room->lit = on;
            child->switch(child, on);

    Looks pretty good right now, doesn't it?

    http://informilabs.com/cs-curious-incapability/dad613cc-bad6-45fe-81ce-8b66ad4675f4Thu, 30 Oct 2014 17:36:48 GMT