C++ or Script, that is the question
by Justin Mette · in Torque Game Engine · 02/13/2002 (8:32 am) · 14 replies
Something that is a constant cause for discussion/debate with our programming team is whether a feature should be implemented in C++ or in Script (or both). Since we are all hoping to work together and enhance the base Torque offering it figures that we should all be in agreement on implementation philosophies as well. Let's discuss the ups and downs of C++ vs. Script implementations in this thread and see if we can come to a common understanding.
"All game-specific logic should go in Script". We followed this rule as much as possible in the beginning when we were really newbies to the engine. However, that's not really possible in many cases (like game-specific complex HUD controls, for example) and it's just as easy to use OO coding practices for keeping your game specific C++ code separate from the base functionality. So this rule hasn't proven a good one to follow.
So why not code the entire game in C++ and eliminate the overhead and development complexities that a scripting language introduces? I guess one answer to this question is supporting MODs in your game. MODs are a huge market but do they fit for your game and are they worth the extra effort?
Another answer might be that you don't need a bunch of skilled C++ programmers to write your game if you support a scripting language. Up until this point, we have found that all the programmers on the team really need to understand C++ in order to implement/debug any feature implemented in either C++ or script.
Yet another factor to consider is code execution speed. Its obvious that math routines (or CPU intensive routines) will most likely be faster in C++/ASM than an interpreted scripting language. But most of the math functions are generic and belong in the base engine anyway. Where do we draw the line between script and C++ when it comes to execution speed?
Network speed is another concern - is it faster to ghost an instance variable to all clients or to send a clientCommand from the server scripts? I was recently hooking up the ammo count to our HUD control and found a tutorial which implemented it all in script. In other words, a clientCommand (script message) is sent from the server to the appropriate client everytime the ammo count changes. That seems inefficient at first, but then consider that a member variable in the engine that is changing so often would cause ghost packet updates to be sent constantly to every connected client.
This is a complex issue as there are alot of factors to consider. What do you all think?
"All game-specific logic should go in Script". We followed this rule as much as possible in the beginning when we were really newbies to the engine. However, that's not really possible in many cases (like game-specific complex HUD controls, for example) and it's just as easy to use OO coding practices for keeping your game specific C++ code separate from the base functionality. So this rule hasn't proven a good one to follow.
So why not code the entire game in C++ and eliminate the overhead and development complexities that a scripting language introduces? I guess one answer to this question is supporting MODs in your game. MODs are a huge market but do they fit for your game and are they worth the extra effort?
Another answer might be that you don't need a bunch of skilled C++ programmers to write your game if you support a scripting language. Up until this point, we have found that all the programmers on the team really need to understand C++ in order to implement/debug any feature implemented in either C++ or script.
Yet another factor to consider is code execution speed. Its obvious that math routines (or CPU intensive routines) will most likely be faster in C++/ASM than an interpreted scripting language. But most of the math functions are generic and belong in the base engine anyway. Where do we draw the line between script and C++ when it comes to execution speed?
Network speed is another concern - is it faster to ghost an instance variable to all clients or to send a clientCommand from the server scripts? I was recently hooking up the ammo count to our HUD control and found a tutorial which implemented it all in script. In other words, a clientCommand (script message) is sent from the server to the appropriate client everytime the ammo count changes. That seems inefficient at first, but then consider that a member variable in the engine that is changing so often would cause ghost packet updates to be sent constantly to every connected client.
This is a complex issue as there are alot of factors to consider. What do you all think?
#2
We are all going to be contributing code to the project, hopefully, and it seems logical that we should agree on these guidlines before we get too deep. It's kind of like coding standards but that's a whole other can of worms :)
02/13/2002 (9:06 am)
Sorry, maybe there was too much detail in the original post and the point was lost. I'm not proposing that the infrastructure of the engine be changed, but rather trying to spark some discussion on what our guidlines should be for implementing a feature in C++ or script.We are all going to be contributing code to the project, hopefully, and it seems logical that we should agree on these guidlines before we get too deep. It's kind of like coding standards but that's a whole other can of worms :)
#3
The question is, where to put new code, in engine, or in script.
I'm biased, but I prefer any sort of "core" code to be in C++. What do i mean by core? well, anything I'd want to reuse anywhere else in any game.
To me, script should be kept to the places where scripting naturally falls, things like dynamic data definition for missions (so for instance, placing things initially, activating objects when something is triggered).
Almost all of my code seems to involve a marriage of both, allowing the script to "see" and "use" the C++ objects in some way. Most of the real meaty functionality will be in the C++ class, with as simple an API as possible allowing Get and Set method calls on the class for use in the script.
Basically, when I look at a particular thing I want to do, i ask myself, "what am i likely to want to change and tweak quite a lot without compiling".
I dont see any point in putting significant amounts of logic or code inside scripts because its simply not portable, if I write a class (for instance, my spline node pathing class) i write it in C++ so that its portable to any of my other projects. I write a nice API interface for it if i need it in script (so it has methods like "AddNodeAtCurrentPosition()" etc ).
Basically, I see it as the C++ is the "engine" of the game, and script should simply put the foot on the gas :))
Phil.
02/13/2002 (10:07 am)
I'm following you Justin.The question is, where to put new code, in engine, or in script.
I'm biased, but I prefer any sort of "core" code to be in C++. What do i mean by core? well, anything I'd want to reuse anywhere else in any game.
To me, script should be kept to the places where scripting naturally falls, things like dynamic data definition for missions (so for instance, placing things initially, activating objects when something is triggered).
Almost all of my code seems to involve a marriage of both, allowing the script to "see" and "use" the C++ objects in some way. Most of the real meaty functionality will be in the C++ class, with as simple an API as possible allowing Get and Set method calls on the class for use in the script.
Basically, when I look at a particular thing I want to do, i ask myself, "what am i likely to want to change and tweak quite a lot without compiling".
I dont see any point in putting significant amounts of logic or code inside scripts because its simply not portable, if I write a class (for instance, my spline node pathing class) i write it in C++ so that its portable to any of my other projects. I write a nice API interface for it if i need it in script (so it has methods like "AddNodeAtCurrentPosition()" etc ).
Basically, I see it as the C++ is the "engine" of the game, and script should simply put the foot on the gas :))
Phil.
#4
Also, I think that in the early stages of a game, people might need to know C/C++ to be able to change anything meaningful in script, but as the game gets more feature complete people don't need to play with the C/C++ side anymore.
Also, for those teams with members that don't want to/can't pay the $100 to get access to the source, exposing features to script is pretty much required. Remember, those people can't even *see* this forum, so you aren't likely to hear them. Also, we seem to have nearly all C/C++ guys/gals here, so it is not exactly representative of the general GG community.
And back to the topic... I pretty much see TCP's mission as adding things that can be controlled through script. After all, script should mostly be game-specific logic. I think the ideal case would be every team out there using the same exe, and having different models and script. We should be trying to make that possible.
Josh
02/13/2002 (11:28 am)
I think the biggest script/C divide is speed of development. Doing even a small recompile takes a minimun of a minute or so (including time to get through the main menu, connect to a server or whatever), where a lot of the time you can change script on the fly and spend maybe 10 seconds fixing a small error. This is especially valuable for UI type stuff, IMHO.Also, I think that in the early stages of a game, people might need to know C/C++ to be able to change anything meaningful in script, but as the game gets more feature complete people don't need to play with the C/C++ side anymore.
Also, for those teams with members that don't want to/can't pay the $100 to get access to the source, exposing features to script is pretty much required. Remember, those people can't even *see* this forum, so you aren't likely to hear them. Also, we seem to have nearly all C/C++ guys/gals here, so it is not exactly representative of the general GG community.
And back to the topic... I pretty much see TCP's mission as adding things that can be controlled through script. After all, script should mostly be game-specific logic. I think the ideal case would be every team out there using the same exe, and having different models and script. We should be trying to make that possible.
Josh
#5
>Why learn a new language?
>Debugging is more difficult.
>Speed.
Their answers were:
Yes, it is more dificult to debug, but the trade-offs are worth it because:
>It allows your product to be easily "modd'ed".
>No compilation for faster development.
>You can test things in script, then move to C++ for more speed at a later date.
>It's very portable.
>Easy to do GUI's, levels, scenarios.
>Its not that slow for a lot of every day tasks.
>Start with the engine by modding, then move up to real coding if you are successful or want to make a change in the engine.
Phil's contention that the "engine" is in C++ and the "game" is in script is the way we look at it.
Jeff Tunnell GG
02/13/2002 (11:59 am)
I have asked T,R,and M why we use the script so heavily (I'm sure they'll get in on this conversation soon). My concerns were:>Why learn a new language?
>Debugging is more difficult.
>Speed.
Their answers were:
Yes, it is more dificult to debug, but the trade-offs are worth it because:
>It allows your product to be easily "modd'ed".
>No compilation for faster development.
>You can test things in script, then move to C++ for more speed at a later date.
>It's very portable.
>Easy to do GUI's, levels, scenarios.
>Its not that slow for a lot of every day tasks.
>Start with the engine by modding, then move up to real coding if you are successful or want to make a change in the engine.
Phil's contention that the "engine" is in C++ and the "game" is in script is the way we look at it.
Jeff Tunnell GG
#6
Anything that has to be done 20,000 times per frame should not be done Interpreted. Data-Files _may_ be used to initialize data structures that are accessed by compiled code that often, of course.
Anything that would ordinarily be done by a non-technical person (like modelling and skinning) should be done by writing an editing tool to modify data-files (3DS-Max is such a tool).
Anything it would be convenient and useful to modify from an in-game editor (like placing objects, tweaking terrain, etc.) must be done in data-files.
Remember that a texture map is really a script in a really primitive scripting language that says "put a half-transparent blue pixel here, put a red pixel next to it". You could replace all your models and texture maps with compiled code and get faster rendering, provided you could afford the terabytes of RAM to hold your executable. Development time will be slower, of course, because adding a texture involves adding a lot of code and re-compiling.
Since Data-Files speed development they are very beneficial. Once you have your game running pretty well, it's pretty easy to replace the script files with C++ files and get it running faster and less hackably.
02/13/2002 (12:08 pm)
The General answer to Compiled (i.e. C++) versus Interpreted (Data-Files, including scripts) is something like this:Anything that has to be done 20,000 times per frame should not be done Interpreted. Data-Files _may_ be used to initialize data structures that are accessed by compiled code that often, of course.
Anything that would ordinarily be done by a non-technical person (like modelling and skinning) should be done by writing an editing tool to modify data-files (3DS-Max is such a tool).
Anything it would be convenient and useful to modify from an in-game editor (like placing objects, tweaking terrain, etc.) must be done in data-files.
Remember that a texture map is really a script in a really primitive scripting language that says "put a half-transparent blue pixel here, put a red pixel next to it". You could replace all your models and texture maps with compiled code and get faster rendering, provided you could afford the terabytes of RAM to hold your executable. Development time will be slower, of course, because adding a texture involves adding a lot of code and re-compiling.
Since Data-Files speed development they are very beneficial. Once you have your game running pretty well, it's pretty easy to replace the script files with C++ files and get it running faster and less hackably.
#7
I like the way they did it in Operation Flashpoint.
The game is less or more coded. In the ingame editor, you can click on a item, and then there is a little line for the script. There you can enter e.g. wether you want to proceed to the next waypoint, stop at the waypoint or board a vehicle etc..
I think OOP is good enough, to keep major parts in the code. Script should be event based, and should be reduced to AI-controling in general.
From the designer point of view, you shouldn't have to open up notepad, because a desgner is not a coder.
The designer should begin to script, if he is in the editor to edit the behavior at a special event.
02/13/2002 (12:46 pm)
I'm also thinking about this, how a code-script-seperation would look like:I like the way they did it in Operation Flashpoint.
The game is less or more coded. In the ingame editor, you can click on a item, and then there is a little line for the script. There you can enter e.g. wether you want to proceed to the next waypoint, stop at the waypoint or board a vehicle etc..
I think OOP is good enough, to keep major parts in the code. Script should be event based, and should be reduced to AI-controling in general.
From the designer point of view, you shouldn't have to open up notepad, because a desgner is not a coder.
The designer should begin to script, if he is in the editor to edit the behavior at a special event.
#8
Tim, Rick, and/or Mark could you share some more of your experiences and personal guidelines for when to use C++ and when to use script when implementing a feature? To help set a reference for the discussion, maybe we can talk about a feature like inventory.
It is possible to completely script an RPG style inventory system with a backpack, equippable items (like armor, jewelry, weapons, etc) and a hotkey system. The late binding feature of the Torque scripts is incredibly powerful and easily allows these types of extensions. Would there be a reason to move all or parts of an inventory system such as this into the engine?
02/13/2002 (1:34 pm)
So far, it seems like most folks are proponents of using scripts as often as possible with the exception of Phil and Andreas maybe. The responses from Tim, Rick, and Mark (through Jeff) are particularly interesting because they have actually written a game using this system and they choose to use scripts over C++ where possible (if I am reading that response correctly). There are some good points in there about being able to move script to C++ as necessary, after proving a feature works well. That's good rapid application development practice actually.Tim, Rick, and/or Mark could you share some more of your experiences and personal guidelines for when to use C++ and when to use script when implementing a feature? To help set a reference for the discussion, maybe we can talk about a feature like inventory.
It is possible to completely script an RPG style inventory system with a backpack, equippable items (like armor, jewelry, weapons, etc) and a hotkey system. The late binding feature of the Torque scripts is incredibly powerful and easily allows these types of extensions. Would there be a reason to move all or parts of an inventory system such as this into the engine?
#9
02/13/2002 (2:17 pm)
Just another aspect to the script-vs-code argument. What if you don't want the players to see what's going on? That's when you use code, and that's generally my rule as far as my game goes.
#10
02/14/2002 (10:23 am)
I'd highly recommend doing the usual script stuff in scripts until you are ready to do release builds. The savings in dev time can be immense.
#12
Yes
04/18/2002 (11:40 pm)
Justin I just have one simple answer to your question 'C++ or Script?'Yes
#13
Programming problems are like that. If you look at them from the right angle, they can be trivially easy to solve. If you approach them from the wrong angle, they can be painful, time consuming, awful things.
Case in point: 3d graphics. If you approach drawing a picture of some stuff from the perspective of "Well, if I simulate the way real life does it (ie, ray tracing), then I'll get a 3d image", it becomes incredibly difficult to get real time stuff. The world does very nicely, of course - I've never noticed low FPS ;)
But a computer can't handle real time ray tracing at high res. It'll choke, rapidly.
On the other hand, if you approach drawing a 3d scene from the perspective of "Well, I can take advantage of these certain mathematical properties of 3d-2d transformations, and just connect the dots", it becomes relatively easy to render complex scenes at high res. Compare Doom with POV Ray or 3ds Max's renderers.
It's the same with script and code. Code is great at doing things fast and efficiently. But script is flexible - really, really flexible. C++ doesn't have an "eval" function - no compiled language does. You can't say, under C++ :
Object foo;
foo = new (conType ? Player : AI)Connection();
printf("The object was %1", foo);
Because C++ doesn't work that way. You have to approach your problem from an OOP standpoint.
Torque script fakes OOPness for the most part, but it's really flexible, and great for doing glue stuff. It's relatively untyped, almost unscoped, and it's not burningly fast. Why use it, you ask?
It can be changed, and it can do things that C++ can't easily do. C/C++ tend to suffer from buffer overflow errors, for instance; languages like PHP, except when there's a flaw in their runtimes, are immune to buffer overflow.
Script is great for approaching things from a hackish standpoint - you can quickly solve complex problems with it, without the effort you might have to invest for C++. You can always go from one to the other or back, too, if you want... A function hacked up in script can be readily converted into a more optimized C++ func if you want, but mean time the function is there, and it's working. RAD is good.
It's worth noting that every major operating system has a scripting language (BAT files, shell scripts, AppleScript).
Ok, I ranted. Be nice.
04/19/2002 (2:25 pm)
I'd agree with LabRat - both code and script have their roles. I'd liken it to an orchard. Have you ever noticed how when you're driving past an orchard, from time to time, all the trees will line up in neat rows, just so?Programming problems are like that. If you look at them from the right angle, they can be trivially easy to solve. If you approach them from the wrong angle, they can be painful, time consuming, awful things.
Case in point: 3d graphics. If you approach drawing a picture of some stuff from the perspective of "Well, if I simulate the way real life does it (ie, ray tracing), then I'll get a 3d image", it becomes incredibly difficult to get real time stuff. The world does very nicely, of course - I've never noticed low FPS ;)
But a computer can't handle real time ray tracing at high res. It'll choke, rapidly.
On the other hand, if you approach drawing a 3d scene from the perspective of "Well, I can take advantage of these certain mathematical properties of 3d-2d transformations, and just connect the dots", it becomes relatively easy to render complex scenes at high res. Compare Doom with POV Ray or 3ds Max's renderers.
It's the same with script and code. Code is great at doing things fast and efficiently. But script is flexible - really, really flexible. C++ doesn't have an "eval" function - no compiled language does. You can't say, under C++ :
Object foo;
foo = new (conType ? Player : AI)Connection();
printf("The object was %1", foo);
Because C++ doesn't work that way. You have to approach your problem from an OOP standpoint.
Torque script fakes OOPness for the most part, but it's really flexible, and great for doing glue stuff. It's relatively untyped, almost unscoped, and it's not burningly fast. Why use it, you ask?
It can be changed, and it can do things that C++ can't easily do. C/C++ tend to suffer from buffer overflow errors, for instance; languages like PHP, except when there's a flaw in their runtimes, are immune to buffer overflow.
Script is great for approaching things from a hackish standpoint - you can quickly solve complex problems with it, without the effort you might have to invest for C++. You can always go from one to the other or back, too, if you want... A function hacked up in script can be readily converted into a more optimized C++ func if you want, but mean time the function is there, and it's working. RAD is good.
It's worth noting that every major operating system has a scripting language (BAT files, shell scripts, AppleScript).
Ok, I ranted. Be nice.
#14
"Scripting and C++ code each has it's place"
;)
04/19/2002 (2:28 pm)
Guess now would be a bit late for me to post?"Scripting and C++ code each has it's place"
;)
Torque Owner AIDan
sorry, but I don't think this is the place for discussing such core things like that.
There is no way to change it! If you would do so, the process will take such a long time that it makes no sense to do such a basic changement.
More important should be something like optimizing the script language for performance.
just my two cents
Felix