Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Work in Progress / [C++/DGDK] Zen - Scripting language inspired by Lua and UnrealScript

Author
Message
Zotoaster
19
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 15th Jul 2011 23:57 Edited at: 16th Jul 2011 00:05
Hello, first WIP I've made in a while. I had some free time so I decided to revisit the subject again and give it another shot.

I'm inspired by Lua's simplicity and flexibility, but I also like UnrealScript's object-oriented approach to scripting, which I think allows for better expansion. So I took both and mushed them together and this is what I got.

Zen - Scripting language with bindings to C++ and Dark GDK


Scripts are written in external .zen files, and are linked against the application using C++. I guess the best way to show you is by example:

MyPackage.zen


Linking in main.cpp


Output




The scripting language features many features, most of which are optional. If you can use DBPro, you can use this. However, if you can use C++ or Lua, there are many features you can exploit. I'll explain the main ones.


Classes:
Classes are essentially the same as classes in C++. They are always allocated on the heap and the garbage collector takes care of managing the memory.



What makes classes powerful is their ability to subclass existing classes. This means that from the minute you begin to write your class, you already have a load of built-in functionalities. Classes support the ability to call base classes' methods, and support polymorphism.



Tables:
Tables are essentially the same as the tables in Lua, though they don't have all the same features such as metatables etc. Generally however, they are exactly the same.




Tables can also be used for configurations. Say you had these settings in a .zen file:


You could then read values as such from C++:



As 'x' is a string, you could even call methods on it, i.e. x.Call("length") (Results 2)


Bindings:

Scripts can be written from inside C++ and added to a global API. The advantage here is that methods aren't run by the virtual machine, but rather they are pointed to methods written natively in C++, which makes them very quick. Core libraries should be written this way. Any APIs written in C++ will automatically be exposed so scripts, so you can use them as if they were right there in the scripts.


Here's an example of how to add a class from C++:


We can then use it from all our scripts:




So that's a brief summary of what's currently working so far. I plan on squeezing out as many bugs as I can find and doing some optimisations here and there, and then work on better GDK bindings. Then I'll be releasing it for free to whoever wants it. I would like to see what people can come up with playing around with it, and help on getting a standard library up would be awesome!

Lemme know whut you think.

"everyone forgets a semi-colon sometimes." - Phaelax
Dar13
15
Years of Service
User Offline
Joined: 12th May 2008
Location: Microsoft VisualStudio 2010 Professional
Posted: 17th Jul 2011 03:20
Sounds like a great alternative to Lua for C++.

I'd certainly try it out next time I do a project in C++(if finished that is).


Zotoaster
19
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 17th Jul 2011 20:08
Thanks Dar13, I will get the source code uploaded once I get some better bindings.

Here's another feature I've implemented which also took inspiration from Unreal, which you guys might find quite useful.

States

With states, you can easily change the behaviour of your objects by explicitly defining their states and letting the code take care of the rest for you. The idea is that you can create functions in states (which must be in classes), and then by setting the state, the appropriate function is called. Most languages don't support this natively and I think they should.

Let me give you an example. This is a player class that defines two states: Wandering and Attacking. Inside both of those states is an update() function, both of which have the same signature.


You will notice that the constructor puts the player in the Wandering state to begin with. Now, when I run this code:


The player will wander around, as they are in the Wandering state. If I then do:


The same call to update() will in fact call a different function altogether, causing the player to attack.


Some extra handy things:
State stacking
If you want to remember the previous state, you can use pushState() and popState(). Here's a trivial example:


This means that after the player is finished attacking, the state will go back to whatever it was before, so you don't have to keep track of it.


State inheritance
State inheritance allows you to borrow functionalities from other states in the class while adding new ones or changing existing ones.

Here's a simple example:



Comments would be good, I'd like to know which direction you guys would like to see this going.

"everyone forgets a semi-colon sometimes." - Phaelax
Rampage
16
Years of Service
User Offline
Joined: 4th Feb 2008
Location: New Zealand
Posted: 19th Jul 2011 14:31
I for one, am extremely interested in this.
Its is most definitely something I will play around with for a project.

Regards,

Max
Zotoaster
19
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 19th Jul 2011 18:48
Thanks Rampage. I just finished implementing a generational garbage collector which seems to be working quite efficiently so far.

Next I'm going to make inline caching (which is a method of forming static links at runtime), which should improve the speed greatly. Then a little more on the GDK API, and I will give out a demo!

"everyone forgets a semi-colon sometimes." - Phaelax
Rampage
16
Years of Service
User Offline
Joined: 4th Feb 2008
Location: New Zealand
Posted: 20th Jul 2011 04:41
Great news! Looking forward to it!

Regards,

Max
Mireben
15
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 20th Jul 2011 11:19
This sounds very interesting and useful, although I don't quite understand yet how exactly you bind the scripts to the C++ code. I'm looking forward to the demo.
Zotoaster
19
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 21st Jul 2011 17:34 Edited at: 21st Jul 2011 17:38
Mireben, conceptually the bindings are quite simple. When you load a script in C++, it's almost as if you're including it, just like any header file. You can then use anything defined in that script. E.g., if I make a class in a script, I can use it like this:




That's one way bindings work. The other way is to write scripts in C++, and wherever you'd have a method, you don't write a script, but you put a function pointer, which does whatever the method would do, but in C++. Every one of those scripts is automatically loaded in your scripts when you write them.

Example: I wish to write a 3D vector in C++ that is exposed to all hand-written scripts:


Then, when I write a script, I can do this:


I've also been considering making bindings to instance variables.

"everyone forgets a semi-colon sometimes." - Phaelax
Mr Bigglesworth
16
Years of Service
User Offline
Joined: 4th Mar 2008
Location:
Posted: 23rd Jul 2011 07:59
This is awesome

States is something that I would very much like to use.
Zotoaster
19
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 3rd Aug 2011 17:51
Just an update for everyone, I've been busy moving house this last week or so and I won't have any internet till tuesday, so I'll be posting more stuff up then.

"everyone forgets a semi-colon sometimes." - Phaelax

Login to post a reply

Server time is: 2024-04-19 20:09:59
Your offset time is: 2024-04-19 20:09:59