Wednesday, October 1, 2014
Ok folks, don't hate me
----- October 3rd
I've just finished the coding all-nighter. But I can't wrap it up yet -- not when things are going like this. I will
wrap it up today! Seriously! I haven't run into any challenging issues like last time. This time, I'm not really sure why, but the update process is just squeezing a lot
of productivity out of me, and I'm going to take advantage of that. Probably something to do with this update being long overdue and me wanting to make you guys happy (which you will be!! Promise!)
Today I won't skimp on the devlog, because I've got quite a few thoughts in my head after that lovely night of flying code
You know, it was only after starting to work with LTSL that I began to understand the relationship between latency-of-development-iteration and productivity. In my naivity, I initially assumed, as I think many people would, that the relationship is linear. You increase your iteration speed by 10%, you increase your net productivity by 10%. Seems right, huh? No. Only now am I coming to understand it. Development is a feedback loop
. Like most feedback loops, it exhibits exponential
behavior. Increasing iteration speed by 50% means, on the surface, yes, you get to see your ideas come into play 50% faster. But the very act of seeing those ideas spawns a web of new ideas, each of which can be brought into existence 50% faster. Those ideas often feedback
into the old ideas, since the web of ideas is not an acyclic web -- it's a richly-connected structure. Bringing a new idea into existence can and often does unlock insights that increase the power old ideas. There is nothing linear about this process. That's not even the end of the story, though, as there's also a very real psychological component at work. With a fast iteration loop, you are more inclined to explore
new ideas because it costs less to do so. That exploration can, in turn, unfold new webs of ideas, which again feedback into the old ones. The whole thing is just so much more connected than I realized. Development is not
a linear system. Right now I am riding the exponential. I am experiencing what it means to be able to unfold chains of ideas that would have never even had a chance to surface with the old methodology, and to have those chains kick back through the web.
No, I'm not saying it's all perfect yet. But today LT lives in an entirely different realm of development than it did half a year ago. Of this I am simply...grateful. It was no great insight that led me to it. Frankly, it was an accident. I was blind. But what an incredible parcel of good fortune it's been
Sorry for all this teasing and grandeur. But I think that, after seeing this update, you'll appreciate the truth of what I've been saying these past two months
One more thing -- today was all
about content, minus one tiny piece of tech that's actually really, really simple, but unlocks yet another level of power for LTSL and, in particular, the UI. I spoke a while back about how game objects can use 'messages' to communicate with each other. Today I took some time (only about 30 minutes! Seriously, this feature is dead-simple
) to implement messaging in the UI. But I'm quite proud of how I did it. The UI messaging system is significantly more powerful than the object messaging system, because I had a nice insight: instead of defining a certain number of message types and then checking the type, why not let the type of the message be the type of the data contained therein?
Woah, what? Yes, this means in code I can define something like:
Code: Select all
And then...wait for it...
Code: Select all
MessageOpenApplication myApp true
You see, the message is
simply a variadic piece of data (it can be of any type, including new, script-defined types). This particular message is sent up
through the widget hierarchy via parents, but can also be broadcasted down
to children, or across
to other components of 'widget'. If you want to respond to a certain type of message, you simply:
Code: Select all
function Bool ReceiveMessage (Widget self Data message)
case (message.IsType MessageOpenApplication)
var realMessage (MessageOpenApplication message)
var appWidget (Widgets:Window application application.GetName)
appWidget = (Components:Expand appWidget)
This simply checks to see if the message is a MessageOpenApplication, and, if so, casts the message to its real type, then creates a window to house the application. It applies an 'expand' component if the app wants to be fullscreen (this component will cause the window to expand to use the maximal size allowed by the parent -- aka, fullscreen). Any number of message types can be checked and handled in any widget.
I am already using this technique to allow the HUD widgets to communicate with the HUD itself. Very, very handy. Any
widget can now send arbitrary data through the UI to other widgets. Opens up a lot of possibilities for modders, but also opens up a lot of ways for me to save time and write less code to do things
I absolutely love this mechanism!
OK! Time to get back to the exponential
PS ~ Woohoo finally cutting that devlog deficit!!