Monday, July 28, 2014
Yes. Absolutely yes. This month's work is finally coming together. Today was a flurry of activity, most of which centered around the paradigm shift that the LT engine is currently undergoing from being a hard-coded engine to being a beautiful marriage of hard and soft code. I'll keep it brief, but even in my brevity I hope to convey the potential that is currently oozing out of the LT engine!Scripted Object Initialization & Updates
It's finally here. Today I implemented the ability to attach initialization as well as update loop scripts to game objects. This means that, for most game objects, an initialization script will be called when the object gets created, and then additional scripts may be called from within the object's update loop. This is where functionality starts to pour out of this month's work!!
Already, this means that I can extend or modify the functionality of most game objects without modifying the hard code. All I need to do is write a script that encodes the functionality that I need, attach the script to the object from within the object's initialization script, and profit. For example, maybe I want to implement equipment degradation. All I have to do is create a script that randomly degrades the integrity of ship subsystems over a long period of time, then add a line to Ship/Init.lts: AddScript self "EqDegradation_Update"
. The script will then attach to the ship and run each frame, just like any other piece of game logic. After doing a bit of playing around with some basic functionality mods, I am just ecstatic at the possibilities. I'm not sure why I was so hesitant about this in the beginning. The truth is that scripts can be made to run very fast, especially when they interop with the engine as naturally as LTSL does (remember, LTSL is always calling directly into the real
engine functions, as well as using efficient memory techniques to handle variables, parameters, and return values). On top of that, the more important truth is: we can have the base functionality
written in the hard code, but with a mechanism for adding an arbitrary number of running scripts to any object, we also pocket the ability to extend game functionality ad infinitum (without the performance loss of having basic game logic written in script). An object with no scripts attached incurs an absolute minimal
overhead for having the ability to be scripted - like, maybe an extra 12 bytes and a few cycles per update. A drop of water in the ocean of performance. The only thing that will start to get expensive is if lots of mods are adding loads of scripts to loads of objects. But I'm sure that I will continue to optimize the LTSL execution module, especially
after release when I start to see what kinds of things people will do with it Colony Update Script
With my lovely, new-found ability to build game content and functionality in script, I've embarked on writing my colony-related code in LTSL. Furthermore, I've pretty much settled on how I will handle colony item generation: instead of rejection-sampling items or modifying their attributes post-creation to reflect the colony's culture, I will simply use the colony's cultural vector to modify how much 'value' is given to each type of item. In this way, a military colony will be much like a faction that has continued to research weaponry for a long period of time: they will have significantly more value concentrated in their weaponry than their sensors. They'll still have sensors, thrusters, etc. since those basic components are required to get life 'started' in the universe. But you'll find that colony culture will determine the base 'quality' of a given type of item at any given planetary location. You can almost look at colonies as being representative of the 'base technology level' in a region of space - where those levels vary on a per-item-type basis according to the culture vector.
Colonies are also one game object that I'm going to implement as scripted from the beginning. There are very few colonies compared to other game objects, so implementing their basic logic in script will have minimal performance impact. Additionally, since they're such foundational elements of the gameplay (especially the economy), it will be very nice to have them totally exposed. This means that the aforementioned colony item generation algorithm, for instance, is 100% changeable!LTSL Metaprogramming!?
Almost forgot to mention this because it took so little time. Ha. But it's so amazing! I had a dream last night about how easy it would be to implement real
metaprogramming in LTSL by exposing StringTrees, a compile function that takes a stringtree and outputs an expression, and an eval function that performs compile-time evaluation of an expression to create the expression that will get called at run-time. It only took about an hour to implement!!! Now LTSL has more metaprogramming capability than c++ ever dreamed of having
I could, for example, iterate over an array of strings, emitting a correspondingly-named LTSL function that does something specific for each element in the array, and then call these functions within my script. Yep, the LTSL compiler can now execute arbitrary expression evaluations at compile-time to produce the run-time code. Pretty awesome, and I'm blown away by how simple it was (mostly thanks to the functional nature of the language!)
I'll speak more about this at some point - for now it's honestly just a toy feature that resulted from a groggy-yet-enthusiastic Josh getting a little too frisky with StringTrees and Expressions in the waking hours of the morning
In the future, though, I have faith that it will be something much, much bigger than a toy...
Still so much left to do before I can tie this month into a neat little video package...but I'm wide awake and there still seem to be many hours left between now and then