Code and Script architecture
by David Coen · in Torque Game Engine Advanced · 02/11/2009 (4:35 am) · 5 replies
i'm new, sorry if this was rasied before, but i would like to share some thoughts on code and script architecture and could not find an exsisting thread for the topic.
my concern is primarially that TGEA_18 codebase looks to be using inheretance to acumulate functionality (rather than inheriting interfaces and reusing components). 'Inheriting functionality' is difficult to maintain and reduces encapsulation (as members shift from protected to public, example guiControl, (if this classes public: members are for console access then better would be to friend the static console methods) not to mention the information sharing up and down the heirarchy. (will cont. this in another post)
do like the binding of methods and members to classes in scripts (can overload objects created with names, would like to also overload un-named objects, do objects in script expose function assignment) howvever this took a while for me to work out a safe way to use this, which is to consider it as an extention of the virtual table of the class.
simSet's (?) adding of 'new' objects in it's scripted constructor to it's list of children is really cute. likewise the ease to call 'cpp' and 'cs' code from each environment.
not cute is the loss of encasulation that seems to have been caused by the lack of script heirachy and misuse of globally named objects. example. not happy that 'playGui' is referenced several times in the code (get camera for refelction) though this may just be a figment of the scripts provided.
also the scripts daisy-chaining functionality puts up BIG warning lights, a rather fragile way of building a system. (just lost two days tracing though all the client-server code, not happy)(improvement cont. in another post)
my concern is primarially that TGEA_18 codebase looks to be using inheretance to acumulate functionality (rather than inheriting interfaces and reusing components). 'Inheriting functionality' is difficult to maintain and reduces encapsulation (as members shift from protected to public, example guiControl, (if this classes public: members are for console access then better would be to friend the static console methods) not to mention the information sharing up and down the heirarchy. (will cont. this in another post)
do like the binding of methods and members to classes in scripts (can overload objects created with names, would like to also overload un-named objects, do objects in script expose function assignment) howvever this took a while for me to work out a safe way to use this, which is to consider it as an extention of the virtual table of the class.
simSet's (?) adding of 'new' objects in it's scripted constructor to it's list of children is really cute. likewise the ease to call 'cpp' and 'cs' code from each environment.
not cute is the loss of encasulation that seems to have been caused by the lack of script heirachy and misuse of globally named objects. example. not happy that 'playGui' is referenced several times in the code (get camera for refelction) though this may just be a figment of the scripts provided.
also the scripts daisy-chaining functionality puts up BIG warning lights, a rather fragile way of building a system. (just lost two days tracing though all the client-server code, not happy)(improvement cont. in another post)
#2
hub design patern rather than daisy chain for program flow (standard disclaimers of personal opinion)
looking through the network and program control flow (splash, menu, game) implemention from the script and code, there seems to be a lot of 'hand task to A', 'A does task and hands it to B', 'B does task and hands it to C'. this is fine, but any break in the chain destroys the system, and i don't think it is inherent on torque's network architecture. painful to debug for the networking as it is skipping between client and server, cpp and cs code.
an alternative is to have a more centralised control point, a manager, which could 'tell A what to do', 'nag A if it has finished yet', then when finished 'tell B what to do'. disadvantage is higher payload, though no reason why 'A' could not tell the manager that it had finished, but the point is that 'A' doesn't tell 'B', 'B' doesn't tell 'C' what to do. There is a manager that hands out tasks, and makes decisions on what to do next, including if a task fails, what to do.
this also saves 'A' from needing to know what 'B' is.
disadvantage, for game flow, if A doesn't know about B, then a loading screen is a bit more difficult, though rather than polute the interface with( does the next stage want to preload while we are active, what progress), 'B' could just contain a 'loading screen' component and a resource manager may be given hints about what resource may want to be preloaded.
yes this is more typing than 'bang it out there quick' scripting, but might be needed to get projects to competion rather than death by maintance compexity.
02/11/2009 (5:08 am)
expanded post. scripts daisy-chaining functionality. hub design patern rather than daisy chain for program flow (standard disclaimers of personal opinion)
looking through the network and program control flow (splash, menu, game) implemention from the script and code, there seems to be a lot of 'hand task to A', 'A does task and hands it to B', 'B does task and hands it to C'. this is fine, but any break in the chain destroys the system, and i don't think it is inherent on torque's network architecture. painful to debug for the networking as it is skipping between client and server, cpp and cs code.
an alternative is to have a more centralised control point, a manager, which could 'tell A what to do', 'nag A if it has finished yet', then when finished 'tell B what to do'. disadvantage is higher payload, though no reason why 'A' could not tell the manager that it had finished, but the point is that 'A' doesn't tell 'B', 'B' doesn't tell 'C' what to do. There is a manager that hands out tasks, and makes decisions on what to do next, including if a task fails, what to do.
this also saves 'A' from needing to know what 'B' is.
disadvantage, for game flow, if A doesn't know about B, then a loading screen is a bit more difficult, though rather than polute the interface with( does the next stage want to preload while we are active, what progress), 'B' could just contain a 'loading screen' component and a resource manager may be given hints about what resource may want to be preloaded.
yes this is more typing than 'bang it out there quick' scripting, but might be needed to get projects to competion rather than death by maintance compexity.
#3
Later, another company put together a promotional game for which 130,000 copies have been delivered to date in a few programmer months of almost entirely Torque-scripting, with just a few engine changes here and there to adjust UI widgets, meet Vista UAC requirements, and implement the complex custom player animations. They owe me even more money than the first story's company, but at least the project was finished on time.
Having hinted at where I would put re-architecting vs. completion of a games minimum feature set on the spectrum of goodness, I really wouldn't mind seeing any part of the Torque systems polished. Of course, if I had to spend time learning GG's new upcoming "Component" based architecture I've heard about I might mind more if it caused some feature slips and resulting stress and unpaid overtime.
02/11/2009 (6:44 pm)
I worked for a company once that re-architected everything. The code was very pretty, and very up-to-date, and chock full of complicated design patterns by the time I stopped receiving a paycheck. I doubt the creditor who took over the intellectual property ever takes it out and gazes on its beauty though. Later, another company put together a promotional game for which 130,000 copies have been delivered to date in a few programmer months of almost entirely Torque-scripting, with just a few engine changes here and there to adjust UI widgets, meet Vista UAC requirements, and implement the complex custom player animations. They owe me even more money than the first story's company, but at least the project was finished on time.
Having hinted at where I would put re-architecting vs. completion of a games minimum feature set on the spectrum of goodness, I really wouldn't mind seeing any part of the Torque systems polished. Of course, if I had to spend time learning GG's new upcoming "Component" based architecture I've heard about I might mind more if it caused some feature slips and resulting stress and unpaid overtime.
#4
Snarkiness aside, a lot of the TGE design evolved from actual game programming. I've made major modifications to GUI classes, animations, player classes, and the networking layer. I've yet to run into any true problems with the design.
02/11/2009 (9:37 pm)
Did somebody just read the Design Patterns book?Snarkiness aside, a lot of the TGE design evolved from actual game programming. I've made major modifications to GUI classes, animations, player classes, and the networking layer. I've yet to run into any true problems with the design.
#5
02/12/2009 (6:18 am)
@Matthew: We've just spent 3 (wasted) months undoing these very things. We handed off some tasks to a developer to produce a framework and a sample driver implementation upon which we could base further implementations. 3 months later we got back the most over-architected, hard to implement and support piece of "elegant framework" that I have ever seen. Not one single person could create a working driver implementation off it, it was so convoluted and "elegant". It's taken another 3 months to undo it all, and there is still plenty of the "elegant framework" that we are stuck with due to dependencies. Simplicity beats out Elegance every time.
Torque Owner David Coen
this solution is more typing, but more maintainable (standard disclaimers of personal opinion)
an alternative is to inherit interfaces, so your guiControl may inherit several interfaces( pure classes without implementation, virtual inheritance to avoid function duplication though than should be avoidable) interfaces could still inherit other interfaces.
components could exsist to implement the common functionality. manager may need to be created to deal with objects that satify an interface (rather than the common operation being expected to be contained in an object) again the guiControl example of why does it have methods for a derived class (dialog) a base class should not need to know of what has derived off it.
this can also lead to the base objects (that inhereted the interfaces) implementing the interface as first non virtual methods, that call the scripted implementation, and if that doesn't exsist, the virtual methods, which have a default implementation in the base. any inheritance of the base class is then attempted to only be one level (so can still replace the virtuals)
so this is an attempt to treat objects the same at the base level, though they may be derived to do something different. rather than keeping on derriving higher into a hierarchy to get different functionality and trusting none of the parent functionalty to change.
not an expert on 'com' architecture unfortunalty, but think that is what this stle of solution leads towards, return on interface objects.