Scripting System Basics

Started by
12 comments, last by Biggles 20 years, 3 months ago
Apologies if this has been covered before, but I can''t seem to find any tutorials or threads that cover what I can''t figure out. Noone seems to cover the initial stuff. I''m trying to work out how to integrate a scripting system into my engine. At the moment the actual language used isn''t important (although FYI I''m considering python or lua). What I want to know is how the actual integration works. Here''s an example: I have a GUI system in the engine. I want to be able to create windows and menus using a config file (like xml or something, it doesn''t really matter what). I need to have the event functions for things like buttons execute user-defined (where user = game designer, not engine developer) code, and for that code to be executed when said button is clicked. The code would need to play with things in the engine (eg pop up a new (already defined in another config file) window, or change a graphics setting, or something like that) which means it needs to be able to change engine settings and interact with other objects in the system. Let''s say I have a window for configuring the video options. I would need the scripting code to be capable of populating certain parts of the window like list boxes (for resolution changes) and sliders and so forth. I would also need the code for the OnClick event of the OK button to be able to get the values of the list boxes, sliders, etc from them and update game settings with them. Another example would be when the user does something in the game world, like "use" an object. I would need to be able to run a block of code that would alter the game world in the way desired for when said object is used, which means the scripting system needs to be able to affect these objects in some way. So my question is (after that rather long winded paragraph) how does all this work? How exactly do I expose the required functionality in my (C++) engine? How do I run a block of code taken from a config file that says "when the object defined by this config file does this or is interacted with do this"? Links to tutorials/threads that I missed explaining this are welcome. Thanks in advance for any help. -------------------- Never eat anything bigger than your own head.
--------------------Never eat anything bigger than your own head.
Advertisement
Hi,

I don't understand (probably because of my coursed english) if you have already implemented a scripting engine or not.

You could save in the object rappresenting your window a reference to compiled or source code. When the OnClick event is encoutered iside the events queque, you have only to call a simple function that executes the user defined code. Probably you have to start the scripting engine at the application initialization, and then you have only to add refernce to already generated objects inside your simble table and run the script.

For example:

Your window is defined in this way:
<App><scripts>   <script id="ID1234">   <![CDATA[   #here you can store the bytecode if you want.   #this is only an example   print this.label+" pressed"   PARENT.destroy()   ]]>   </script></scripts><Window size="100,200" title="Hi! :)">    <Button pos="10,20" label="press me" onclick="ID1234" /></Window></App> 

this should show a simple window with a button. When clicked, it should print to stdout "press me pressed" and then the main window should close.

Now your code should looks like this (pseudo-like code ):
if button.pressed:
script := button.code
symtab := scripting_engine.symble_table
symtab.store("PARENT", button.parent)
scripting_engine.run(script)

Now your scripting engine simply takes the code and runs it following your script definition.

Implementing a scripting engine is not so simple, but there are some tutorials on the net you can follow to start.

I hope this words will help you. bye

[edited by - darkbard on January 7, 2004 10:51:18 AM]

[edited by - darkbard on January 7, 2004 10:51:54 AM]

[edited by - darkbard on January 7, 2004 10:52:42 AM]
Jan Neistadt''s series on Flipcode

There''s also info on YACC and LEX (Lexical analysis and syntax validation) here

Look also at my thread about GameMonkey and integration on their forums

And of course there''s some tutorials on VMs and basic parsing on Gamedev

Take it from me, creating a scripting language is a bitch. Don''t expect people to use it either - there seems to be hundreds floating around now.

I''m trying as hard as I can to avoid writing my own and integrate an existing language - but I KNOW that building it into my engine and have it behaving the way I want is going to be hard. Perhaps not as hard or complex as making my own language, but it''s a chore none the less.
Also check this site:

http://www.peroxide.dk/tuts_scr.shtml
So... Muira Yoshimoto sliced off his head, walked 8 miles, and defeated a Mongolian horde... by beating them with his head?

Documentation? "We are writing games, we don't have to document anything".
I''m not interested in writing my own scripting language. I''ve written compilers before, and I know that it''s far too much work to be worth doing when there are existing solutions around. What I want to know is how to integrate an existing language into my system such that I can call user defined code when necessary and have it work with existing objects in the engine like windows and entities in the game world.

--------------------
Never eat anything bigger than your own head.
--------------------Never eat anything bigger than your own head.
Biggles,

On the same search as you''re on about half an hour ago, I came across the following, and it looks like just the ticket

Download the "lua scripting" link on http://www.gametutorials.com/CodeDump/CodeDump_Pg1.htm.

Cheers,
I.

www.coldcity.com
code, pics, life
[size="2"]www.coldcity.com code, art, life
Boost.Python + Python or Lua + Luabind

I prefer the former
So... Muira Yoshimoto sliced off his head, walked 8 miles, and defeated a Mongolian horde... by beating them with his head?

Documentation? "We are writing games, we don't have to document anything".
quote:Original post by Biggles
What I want to know is how to integrate an existing language into my system such that I can call user defined code when necessary and have it work with existing objects in the engine like windows and entities in the game world.


Many existing scripting languages can do that for you. In
particular, Tcl is very suitable for GUI controls, especially
when used with Tk. But you can use Tcl with your own GUI stuff.


Kami no Itte ga ore ni zettai naru!
神はサイコロを振らない!
I''m currently looking at the GameMonkey source. The implementation is nice, it''s not as annoying as LUA to pass parameters and has a more C-style syntax.

One thing I''m *not* sure on however is the annoying ''feature'' that makes you pass C-style function pointers - this is present in every scripting language I''ve seen. I''m looking to modify the GM code base to encapsulate the calling of C++ functions from the script and vice-versa.
That link was quite helpful, IainC. Thanks.

Now, let me see if I''ve got this right. Working from the example of the GUI component:

I would create some functions in C++ that could be called from the script to retrieve a pointer to a GUI object (like a label or a button). Then, in the script, I would call the function necessary to get the object I want. Once I have a pointer to it in the script, I can do things like set and retrieve values on it as long as I also provide functions to do that in the class for that object.
For handling something like user defined code when a button is clicked, I would store the code with the button and then the OnClick function for the button (in C++) would feed that code into the script VM where it is run.

I''m still a little confused about how object scoping would work in the script, and the functions that are accessed by the script. It looks like these functions will have to be C functions, but they also need to be able to access the instances of classes in my engine (for example, a C function used by the script to draw a rectangle on the screen would need to be able to access the display object, eg Display::DrawRect), which have been encapsulated inside the main engine class. How do I get around this problem without breaking encapsulation? Is it even possible?
--------------------Never eat anything bigger than your own head.

This topic is closed to new replies.

Advertisement