• Advertisement
Sign in to follow this  

Unity scripting language api - exposed class naming

This topic is 4714 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having a bit of difficulty deciding exactly how the C++ classes will be exposed in my scripting language. I'm currently designing my scripting api, so this thread is very interesting. I would quite enjoy hearing the actual details of why the current api's aren't so hot. Also if anyone has any ideas for how to nicely bind C++ and a scripting language it would be much appreciated. My current plan is to have an xml file that is hand edited to explain what you want to expose and how. This file is then read by a command line program that generates a cpp file with all the class function wrapper methods and a function with the same name as the file that, when run dynamically adds these definitions to the virtual machine runtime. I think this method isn't too bad because the xml file really contains exactly the information that you need. Comments and suggestions welcome. If everyone thinks that this way of doing things is okay, then on to my problem at the moment. Do you want to expose a C++ class into the scripting language with a different name? And if so, do you want to do the same with it's methods? Is this important functionality that I should include in my api?

Share this post


Link to post
Share on other sites
Advertisement
Might be okay, if you can get this command line utility integrated in your build process it probably wouldn't be too hard to keep the scripting language bindings up to date at all times.

However, you would still be required to update two places each time you change or add a function that is to be exposed to the scripting language. That's why I like the approaches of LuaBind and Boost.Python where the scripting language bindings are generated by template magic solely in C++ without a seperate command line utility.

-Markus-

Share this post


Link to post
Share on other sites
Yes that was the idea, a make file will be able to generate them easily.

mmm, template magic. Sounds interesting, but I distrust templates. I will have a look into them though.

Share this post


Link to post
Share on other sites
As a result of that thread, I'm playing with something new to see how it works out. I'm basically playing around with meta-classes. You declare a class definition in your application, attaching methods and properties to it. What you do then is ask the environment to make you an instance of that class; this is then usable in both the scripting environment and your native application. What's more, your 'native' classes can also be extended via the scripting langauge to add new methods, overrides or properties. The main drawback of this is that although you can access the meta-class instance in C++, it'd obviously be slower than using native code - the benefits are that there's not really a 'script' API any longer as the meta-class system and the scripting system share the same interface.

Again, not sure how this will pan out though - but it keeps me occupied at least.

Look at my journal for snippets...

Share this post


Link to post
Share on other sites
Quote:
Original post by umbrae
mmm, template magic. Sounds interesting, but I distrust templates. I will have a look into them though.


Oh, don't. Templates are wonderful things =)

I used a heavy template approach when writing gmBind, a C++ binding library for GameMonkey Script.

Share this post


Link to post
Share on other sites
Quote:
Original post by umbrae
I'm currently designing my scripting api, so this thread is very interesting. I would quite enjoy hearing the actual details of why the current api's aren't so hot.


1. Verbosity - if I have to type a lot to expose a function, it gets boring quickly. Similarly, if I have to check the number of parameters to each function, then the type of each of them, and write a 2-clause if statement for each, I'm gonna get bored and make mistakes.

2. Error-proneness - if the API is verbose or offers many different functions, it takes longer to look up what is needed for the binding and subsequently debug it.

3. Error-reporting facilities - generally you want the API to be able to detect when you misuse it (eg. you write a binding for a function that takes a double but you bind it as if it takes an integer), so ideally you want checked conversion operations and a well-defined place to report any errors.

4. Documentation quality - for example, the Lua documentation is quite comprehensive but poorly organised. A lot of the best binding functions are hidden in the extra libraries and not fully explained. Make sure your binding helper functions are clearly documented with examples.

Share this post


Link to post
Share on other sites
I think for the moment that I will stay with this xml method and see how far it goes. It might be an interesting idea if I also generate the class's .h file from the xml source as well. That way there would only be one place to make any changes.

I think it is a bit of a toss up between being able to expose already written C++ code (api's etc) or writing C++ for the scripting language directly. If you are trying to expose already written C++ code you don't want to make many changes, but C++ code for the language can be written it in a way that makes it easy to expose.

Since I'm starting with this language the latter is fine for me, but I also want other people to use it which means that it should be easy to bind. But if I want to expose any type of C++ class I need to support all the weird methods and heirarchy features of C++. My language doesn't have multiple inheritance is it okay to leave out support for this and other C++ language features? My plan was to just be able to expose one class, not a heirarchy. You will be able to setup a heirarchy in the scripting language, but it will behave like an object in my language, not a C++ object. ie every method is virtual etc.

Anyway, my original question is whether you want to expose C++ classes into the scripting language as a different name, and the same with methods. ie C++ class called "Scene" is actually exposed as "Scene3D" in the language. I think this would be good for libraries and cleaning up naming conventions.

[Edited by - umbrae on March 16, 2005 9:15:17 PM]

Share this post


Link to post
Share on other sites
Kylotan: Thanks heaps for your comments.

This is currently how I am envisioning binding classes to my language. This xml file is parsed and a .h file is generated. A C method with the same name as the file is also made and when called it registers the wrapper functions to the virtual machine.

<?xml version="1.0" standalone="no" ?>
<class name="bob" alias="bob_tyre">
<method name="print_a" type="void" />
<method name="number_id" type="int" />
<method name="distance" type="float">
<parameter name="x" type="int" />
<parameter name="y" type="int" />
</method>
</class>

<class name="dave">
<method name="print_a" type="void" />
</class>


So now in the scripting environment you can reference a class called "bob_tyre" and call methods from it. I still have to add a few more options to the xml file (to allow for a few of the cool features of my language) but it won't change much.

My code isn't commented, and it is all in the main function. But it does generate stuff.

Share this post


Link to post
Share on other sites
CPB is now working with C++, it should do what you need. Expect to see a new version that includes the new features in a few days.

http://www.thomasandamy.com/projects/CPB/

Share this post


Link to post
Share on other sites
Toes: I'm guessing that the technique that you use in CPB only works with x86? For me at least this isn't an option, my binding library needs to work on more platforms than just windows. Especially because I don't currently have a windows machine.

Interesting technique, but too low level for me.

edit: ooh, and I am not using lua, this is for my own scripting language.

Share this post


Link to post
Share on other sites
I experimented with this type of scripting once and it got limited really quickly. I found that to be of any real use, I had to implement conditional logic into the XML management code, which quickly became a nightmare. The experiement was scrapped straight after that. It is, however, possible to use XML for declaration and a scripting language for the logic. I'm still writing the next part of my article series which discusses this exact topic.

Share this post


Link to post
Share on other sites
evolutional: looking forward to that article, do post or something when you are done.

I don't plan to have the language in xml, just the binding.

I'm guessing that users will want to name the C++ classes differently in the scripting language. Actually thinking about this more it's obvious, I plan to have java-like packages so a C++ class exposed into my language should be put into a package anyway so changing the name as well seems logical.

Share this post


Link to post
Share on other sites
Personally speaking I wouldn't enjoy the XML because I don't want to go through a separate interface writing stage; I like wiring the script directly into the engine, which will only involve a small number of C++ functions being translated directly into a scripting language.

It's a different matter for accessing classes directly though, which I suppose could be more useful (However, Python and Lua have more dynamic objects than C++ does, which is another reason why I don't tend to favour direct 1-1 mapping from one language to another.) In this case, why not generate the binding directly from the source header? Most of the information you need is right there in the C++ class definition, and the rest can be added via C++ comments. See how Doxygen does it if you need inspiration.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Kylotan
Personally speaking I wouldn't enjoy the XML because I don't want to go through a separate interface writing stage; I like wiring the script directly into the engine, which will only involve a small number of C++ functions being translated directly into a scripting language.

It's a different matter for accessing classes directly though, which I suppose could be more useful (However, Python and Lua have more dynamic objects than C++ does, which is another reason why I don't tend to favour direct 1-1 mapping from one language to another.) In this case, why not generate the binding directly from the source header? Most of the information you need is right there in the C++ class definition, and the rest can be added via C++ comments. See how Doxygen does it if you need inspiration.



Or binding directives could be imbedded as C MACROS in the .h files (that reduce to nothing in C compilation) but have a structure that could alleviate some of the parsing if comments were used to impart the binding instead.


EXPOSE(method_nanme, p1_type, p1_name, p2_type, p2_name)




Share this post


Link to post
Share on other sites
Sorry about the late reply,

Most of what I am going to be doing with this language won't entail exposing whole C++ classes, I will be using C funtions that are manually bound to the vm (not using this xml system) to write the libraries. It is of course possible to do this for an entire game...

I think it comes down to what language you want dominant in your game environment; C++ or your scripting language. I want to write a lot of the game in my language. The problem is that I want to hide a lot of the underpinnings of the engine in C++ just because there is almost no point for the scripting language to know about it. The collision system for example - the scripting language doesn't need to know how it works, and more importantly doesn't want to be called for each test cycle. And if I am going to build a collision system I will want to use C++ objects.

The other important situation to think about is external libraries. If I want to have the functionality of a library in my scripting language I have a few choices. Build the library myself, extend the library directly into the environment or write wrapper classes and then expose those. If I just extend the library into the language it will be messy and probably not flow with the rest of the libraries. Using wrapper classes seems like the best idea, the problem is that I will want to be selective as to which methods are exposed. I need a way of saying what methods are going to be shown because some of the methods will be for private library usage only.

Kytolan, when you say that you like wiring the script directly into the engine, do you mean that you like doing it how GameMonkey Script does things - actually writing each wrapper yourself?

My original idea was to use macros to generate the wrapper methods - but it became hard to do certain things (like overloading methods) because the macro language wasn't powerful enough. To be honest thinking about parsing an actual .h file gives me the heebie-jeebies, C++ is just too crazy and I don't really want to put design by contract style markup in my header files (to add modifiers and other constructs that are in my language).

AP: the problem for me is time, if I have to write a parser for what ever structure is generated by those macros it's time that I could spend elsewhere. At the moment xml is good because there are plenty of good parsers (tinyxml for example). Thinking about it - I could use a jml type comment system (special comments) that are extracted and the binding information parsed from them - that actually would be quite cool. At the top of each class there could be a binding chunk of information.

mmm, interesting - I have a few things to mull over now, thanks.

[Edited by - umbrae on March 25, 2005 5:02:40 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by umbrae
Kylotan, when you say that you like wiring the script directly into the engine, do you mean that you like doing it how GameMonkey Script does things - actually writing each wrapper yourself?


Yes, GameMonkey is closer to what I like. As is the way I use Lua.

Part of the difficulty in having this discussion is the use of the word 'wrapper'. It implies that you take an existing C++ program and then attach a scripting language to it, presumably just to make automation easier. This in turn implies that all your functionality was already there in a suitable form in C++, but you want to access it using slightly different syntax in dynamically loaded text files.

That's not how I see things. Generally speaking, yes, the functionality is already coded in C++, but I do not want to simply replicate all my C++ functions in Lua, Python, Gamemonkey, or whatever. If you do that, you miss out on the benefits that these languages have to offer.

eg. A good C++ interface to a container class might expose begin() and end() functions so that you can iterate over the members like so. But that's not what you want in Python.


// Original C++

MonsterList iterator = myMonsters.begin();
while (iterator != myMonsters.end())
{
iterator->DoSomethingMonsterlike();
++iterator;
}

// How I'd need to use a naive binding of that for to Python
iterator = myMonsters.begin()
while iterator != myMonsters.end():
iterator.monster.DoSomethingMonsterlike()
iterator.next()


// How I'd really like to be able to access the container
for m in myMonsters:
m.DoSomethingMonsterlike()



A naive wrapper is not going to do that for me. A complex wrapper might do it, providing I gave it the right input. But if there's a nice and simple API then I can just code it directly. And when I do want to perform plain wrapping, that'll only be 2 or 3 lines of code each time too.

Share this post


Link to post
Share on other sites
Kylotan: Yes, that's what I was trying to get at when I was talking about libraries. Just exposing them isn't good enough, you want to wrap them with C++ that emulates the functionality of the scripting language.

The problem that I see is that there seems to be no easy way to do this other than actually spend some time writing the functionality that you need. You can't just have an automated tool to generate code.

Just as a comparison, this is how you would write the example that you gave in my planned language (at the moment):
myMonsters.each monster
monster.DoSomethingMonsterlike()



[Thread about my language]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By GytisDev
      Hello,
      without going into any details I am looking for any articles or blogs or advice about city building and RTS games in general. I tried to search for these on my own, but would like to see your input also. I want to make a very simple version of a game like Banished or Kingdoms and Castles,  where I would be able to place like two types of buildings, make farms and cut trees for resources while controlling a single worker. I have some problem understanding how these games works in the back-end: how various data can be stored about the map and objects, how grids works, implementing work system (like a little cube (human) walks to a tree and cuts it) and so on. I am also pretty confident in my programming capabilities for such a game. Sorry if I make any mistakes, English is not my native language.
      Thank you in advance.
    • By Ovicior
      Hey,
      So I'm currently working on a rogue-like top-down game that features melee combat. Getting basic weapon stats like power, weight, and range is not a problem. I am, however, having a problem with coming up with a flexible and dynamic system to allow me to quickly create unique effects for the weapons. I want to essentially create a sort of API that is called when appropriate and gives whatever information is necessary (For example, I could opt to use methods called OnPlayerHit() or IfPlayerBleeding() to implement behavior for each weapon). The issue is, I've never actually made a system as flexible as this.
      My current idea is to make a base abstract weapon class, and then have calls to all the methods when appropriate in there (OnPlayerHit() would be called whenever the player's health is subtracted from, for example). This would involve creating a sub-class for every weapon type and overriding each method to make sure the behavior works appropriately. This does not feel very efficient or clean at all. I was thinking of using interfaces to allow for the implementation of whatever "event" is needed (such as having an interface for OnPlayerAttack(), which would force the creation of a method that is called whenever the player attacks something).
       
      Here's a couple unique weapon ideas I have:
      Explosion sword: Create explosion in attack direction.
      Cold sword: Chance to freeze enemies when they are hit.
      Electric sword: On attack, electricity chains damage to nearby enemies.
       
      I'm basically trying to create a sort of API that'll allow me to easily inherit from a base weapon class and add additional behaviors somehow. One thing to know is that I'm on Unity, and swapping the weapon object's weapon component whenever the weapon changes is not at all a good idea. I need some way to contain all this varying data in one Unity component that can contain a Weapon field to hold all this data. Any ideas?
       
      I'm currently considering having a WeaponController class that can contain a Weapon class, which calls all the methods I use to create unique effects in the weapon (Such as OnPlayerAttack()) when appropriate.
    • By Vu Chi Thien
      Hi fellow game devs,
      First, I would like to apologize for the wall of text.
      As you may notice I have been digging in vehicle simulation for some times now through my clutch question posts. And thanks to the generous help of you guys, especially @CombatWombat I have finished my clutch model (Really CombatWombat you deserve much more than a post upvote, I would buy you a drink if I could ha ha). 
      Now the final piece in my vehicle physic model is the differential. For now I have an open-differential model working quite well by just outputting torque 50-50 to left and right wheel. Now I would like to implement a Limited Slip Differential. I have very limited knowledge about LSD, and what I know about LSD is through readings on racer.nl documentation, watching Youtube videos, and playing around with games like Assetto Corsa and Project Cars. So this is what I understand so far:
      - The LSD acts like an open-diff when there is no torque from engine applied to the input shaft of the diff. However, in clutch-type LSD there is still an amount of binding between the left and right wheel due to preload spring.
      - When there is torque to the input shaft (on power and off power in 2 ways LSD), in ramp LSD, the ramp will push the clutch patch together, creating binding force. The amount of binding force depends on the amount of clutch patch and ramp angle, so the diff will not completely locked up and there is still difference in wheel speed between left and right wheel, but when the locking force is enough the diff will lock.
      - There also something I'm not sure is the amount of torque ratio based on road resistance torque (rolling resistance I guess)., but since I cannot extract rolling resistance from the tire model I'm using (Unity wheelCollider), I think I would not use this approach. Instead I'm going to use the speed difference in left and right wheel, similar to torsen diff. Below is my rough model with the clutch type LSD:
      speedDiff = leftWheelSpeed - rightWheelSpeed; //torque to differential input shaft. //first treat the diff as an open diff with equal torque to both wheels inputTorque = gearBoxTorque * 0.5f; //then modify torque to each wheel based on wheel speed difference //the difference in torque depends on speed difference, throttleInput (on/off power) //amount of locking force wanted at different amount of speed difference, //and preload force //torque to left wheel leftWheelTorque = inputTorque - (speedDiff * preLoadForce + lockingForce * throttleInput); //torque to right wheel rightWheelTorque = inputTorque + (speedDiff * preLoadForce + lockingForce * throttleInput); I'm putting throttle input in because from what I've read the amount of locking also depends on the amount of throttle input (harder throttle -> higher  torque input -> stronger locking). The model is nowhere near good, so please jump in and correct me.
      Also I have a few questions:
      - In torsen/geared LSD, is it correct that the diff actually never lock but only split torque based on bias ratio, which also based on speed difference between wheels? And does the bias only happen when the speed difference reaches the ratio (say 2:1 or 3:1) and below that it will act like an open diff, which basically like an open diff with an if statement to switch state?
      - Is it correct that the amount of locking force in clutch LSD depends on amount of input torque? If so, what is the threshold of the input torque to "activate" the diff (start splitting torque)? How can I get the amount of torque bias ratio (in wheelTorque = inputTorque * biasRatio) based on the speed difference or rolling resistance at wheel?
      - Is the speed at the input shaft of the diff always equals to the average speed of 2 wheels ie (left + right) / 2?
      Please help me out with this. I haven't found any topic about this yet on gamedev, and this is my final piece of the puzzle. Thank you guys very very much.
    • By Estra
      Memory Trees is a PC game and Life+Farming simulation game. Harvest Moon and Rune Factory , the game will be quite big. I believe that this will take a long time to finish
      Looking for
      Programmer
      1 experience using Unity/C++
      2 have a portfolio of Programmer
      3 like RPG game ( Rune rune factory / zelda series / FF series )
      4 Have responsibility + Time Management
      and friendly easy working with others Programmer willing to use Skype for communication with team please E-mail me if you're interested
      Split %: Revenue share. We can discuss. Fully Funded servers and contents
      and friendly easy working with others willing to use Skype for communication with team please E-mail me if you're interested
      we can talk more detail in Estherfanworld@gmail.com Don't comment here
      Thank you so much for reading
      More about our game
      Memory Trees : forget me not

      Thank you so much for reading
      Ps.Please make sure that you have unity skill and Have responsibility + Time Management,
      because If not it will waste time not one but both of us
       

  • Advertisement