Wrecked Games

Please login or register.

Login with username, password and session length
Advanced search  

News:

We're just that awesome.

Pages: [1] 2 3 4

Author Topic: Squirrel troubles  (Read 19451 times)

mysterycoder

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 447
    • View Profile
Squirrel troubles
« on: July 23, 2006, 09:15:22 AM »

I'm trying to wrap CollisionActor with squirrel right now. CollisionActor has a function called collide. It takes 3 parameters,

1. The CollisionActor the test collision with.
2. A pointer to an array of Ogre::Vector3s, which the function will populate with contact points.
3. A pointer to an array of Ogre::Vector3s, which the function will populate with normals.

I've wrapped Ogre::Vector3 in the OgreManager.
The function looks like this:
Code: [Select]

void collide(CollisionActor* act, Ogre::Vector3* contactPoints, Ogre::Vector3* normals);


How I bind it:
Code: [Select]
func(&CollisionActor::collide, "collide")

This is the collision function in Actor.nut(nuts_test_scene):
Code: [Select]

function collision(player)
{
local contactPoints;
local normals;
collide(player, contactPoints, normals);
}


How I call it(In handleMove in InputConfig.nut):
Code: [Select]

::human.collision(::robo);

(robo is another Player, which inherits from CollisionActor)

As soon as I try to move, it hard crashes, with nothing in the log. Any ideas?

btw, if this isn't enough information, I can commit this to svn, I just didn't want to break the code in there.
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 2653
    • View Profile
    • http://www.wreckedgames.com
Squirrel troubles
« Reply #1 on: July 23, 2006, 09:49:12 AM »

Go ahead and commit. I'm not sure what is causing the crash.. with nothing in the log, it is probably use of a null pointer somewhere.. there is a squirrel class in one of the files already, with a Vector3 class already, maybe it is conflicting. I suggest you remove the Vecto3 from Util.nut and try again ;)
Logged

mysterycoder

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 447
    • View Profile
Squirrel troubles
« Reply #2 on: July 23, 2006, 09:54:54 AM »

I already removed that.  :wink:
I'll go ahead and commit.

edit: Its in.
Logged

mysterycoder

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 447
    • View Profile
Squirrel troubles
« Reply #3 on: July 23, 2006, 02:35:21 PM »

Actually, it was crashing for a different reason, the error I get is:
Code: [Select]

-----------------------------------
Details:
-----------------------------------
Error #: 9
Function: ScriptManager::executeScript
Description: GetInstance: Invalid argument type.
File: d:\wge\wge\trunk\src\wgescriptmanager.cpp
Line: 146
Stack unwinding: <<beginning of stack>>
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 2653
    • View Profile
    • http://www.wreckedgames.com
Squirrel troubles
« Reply #4 on: July 23, 2006, 06:58:25 PM »

I'll try and give it a go tonight.. Been really hot here today, and I havn't done much else but work a bit on Ogre Studio.
Logged

mysterycoder

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 447
    • View Profile
Squirrel troubles
« Reply #5 on: July 23, 2006, 07:54:30 PM »

Gah, I hate squirrel, I've been working on it all day.  :evil:
Make sure you get the latest svn update, I upgraded to a new version of SqPlus, which fixes some things. Also I applied this patch: http://wiki.squirrel-lang.org/default.aspx/SquirrelWiki/SqPlusInstancesWithScriptObjectHandle.html

edit: I knew we should have used python   :cry:
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 2653
    • View Profile
    • http://www.wreckedgames.com
Squirrel troubles
« Reply #6 on: July 23, 2006, 09:44:20 PM »

Actually, I will not be able to try this out until tomorrow, sorry got too busy.

Anyway, every language choice has it's advantages/dissadvantages. And, to be perfectly honest, I do not like python syntax at all. But, maybe it is just me.
Logged

mysterycoder

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 447
    • View Profile
Squirrel troubles
« Reply #7 on: July 23, 2006, 10:08:51 PM »

All I want is something that binds easily.  :D
Personally, I like the python syntax, maybe thats because I have a book on it.  :wink:
I think we need to pick something more mature, with better documentation, etc.
I'm fine with not using python, but boost::python looks really nice.  :)

I haven't, but have you ever used ruby? I've heard good things.
Logged

OvermindDL1

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 288
    • View Profile
    • http://www.overminddl1.com/forum/
Squirrel troubles
« Reply #8 on: July 24, 2006, 12:19:40 PM »

I've been giddy with what I've been able to do in Python recently, you should see what I've been setting up.  There is the networking function calls that I posted somewhere else in these forums.  There is this I posted in another forum:
Quote
Got another thing setup, beam your eyes on this:
Code: [Select]

class someUnit(Actor):
self.maxHealth = 100.0
def BeginPlay(self):
gotoState('Alive') # can start a state using the state name
def onHit(self, InstigatedBy, HitLocation, Damage, Momentum):
pass # do nothing in default state

class Alive(State):
def startState(self):
# can have state specific variables
self.health = self.outer.maxHealth # self.outer is the someUnit instance, may change the name outer...

def onHit(self, InstigatedBy, HitLocation, Damage, Momentum):
if isinstance(Damage, DamageTypeConcussive):
self.health -= Damage*2.5
else:
self.health -= Damage

if self.health <= 0.0:
gotoState(someUnit.Dying) # can also goto state using a class name of a state

def endState(self):
pass # could do something here too but couldn't think of anything as an example real quick...

class Dying(State):
def onHit(self, InstigatedBy, HitLocation, Damage, Momentum):
# do something like create gib or whatever here...
gotoState() # pass in nothing, empty string, etc., to exit all states and use just the original functions
# and yes, any method in any state can be '@replicateCallToServer'd too. :)


A full state machine.  

When not in a state the normal class functions are called.  When gotoState is called, the old state's (if exist) endState method is called, then the old state is unloaded, then the new state is loaded, and the new state's beginState method is called (if existing of course).  A state can override any method in the outer class unless if they start with an underscore or are reserved (like gotoState).  If a method is not defined in a state, then the outer class's method will be called.  It can also override variables for note.  States' can have their own variables specific to them, but are not saved on state switch (save to self.outer if you want them to persist).  Say good-bye to annoying to read "if (somestate) {dosomething} else if (someotherstate) {dosomethingelse} else etc...", this would be far easier to use.

And yes, if anyone hasn't noticed, the entire design of my python setup is based near identically, if not better then the UT2k4 script code.  It is amazing what I've been able to pull off so far.  


And something I posted here in the ogreaddons forum.

Quote
I use OgreNewt but unlike using multiple materials for everything I only have a few (read, currently three) that are set, and one is generic for near everything.  The generic one then decides what it needs to do by querying the Actors involved.  My system has the bodies being very generic objects that can interact with each other in interesting ways, and it was just far easier to let them control their own interactions.  I have not yet setup sound (really need to do that, only part of the engine lacking now...) but will have set sound effects as that as well, all based on how the bodies wish to react.

I have my callbacks working perfectly in this style:
Code: [Select]
someActor->callEvent("eventName", make_tuple(theParamsIWantToPass, anyAmountOfThings));

// going to make a templated overload soon so I could just do this instead
someActor->callEvent("eventName", theParamsIWantToPass, anyAmountOfThings); // and this would actually be faster as I would not have to pull from the tuple to plug the data in as I would with the above


But then again, as stated, my objects exist purely as python scripts which simplifies this greatly.  Any slow parts can be implimented in C/C++ of course, and I try to have as much done as possible in C++.  I have the scripts setup so I would only need to call into them *very* rarely and they instead store what they want done by making calls into their C++ base class (all Actors inherit from a base C++ Actor class, or from classes that derive from that, whether python or C++ classes that inherit from it, I really like Python).

But still, when the callEvent("EventName", params) is called, it then calls the script's "onEventName(*params)" that could be either a Python function or a C++ function.  If the function enforces a certain number of arguments (being Python, arguments can be specified as a signiture, or they can be specified by argument position, or they can be specified by name, or any/all combonation of the three, yea yea, I like Python...) it then makes a message in the Console talking about what was passed and what was wanted and the callEvent returns an indicator it failed, which the thing that called it can handle or ignore.  The callEvent also returns a py::object which can be bool compared like if(someObject), if false, then it contains either nothing, a Python None, a bool False, a zero number (int, float, double, long, etc...), or an empty string.  You can also convert it to a C++ standard type as such:
Code: [Select]

// To extract a primitive, just do as such:
int anInt = extract<int>(someObject);
unsigned short aUShort = extract<unsigned short>(someObject);

// to extract a string, just ask for some string object that it knows about:
std::string aString1 = extract<std::string>(someObject);
Ogre::String aString2 = extract<Ogre::String>(someObject); // same thing as std::string, but still an example

// Python is strongly typed, so, for example, if you want to extract a string, when the object is an int, have to tell it to convert it first, as such:
std::string aString1 = extract<std::string>(str(someObject));

// Can also convert it to an object
Ogre::Vector3 aVec3 = extract<Ogre::Vector3>(someObject); // Will extract out a copy
Ogre::Vector3 &aVec3 = extract<Ogre::Vector3&>(someObject); // Will extract a reference to the internal object
Ogre::Vector3 *aVec3 = extract<Ogre::Vector3*>(someObject); // Yea, gets a pointer to the internal object

// However, since Python is reference counted, and you do something like
//  get the reference or pointer to the internal object, and you exit scope
//  from the returned object, guess what happens to the pointed to object,
//  yea, don't need to guess, so if you want to keep a pointer to the actual
//  object, especially if it is a costly object or an object that cannot be
//  copied, like one of my Actor's, just wrap it in a shared pointer
typedef shared_ptr<Actor> ActorPtr;
ActorPtr anActor = extract<ActorPtr>(someObject);

// Thanks to the smart pointer, it keeps the reference count, when all
//  shared pointers from this object die, then the object is destroyed in
//  python, yes, this library does set the destructor for shared pointers to
//  this object.

// Now, you probably are wondering, what if you try to extract something,
//  that it is not, like this:
object o("hello");
int anInt1 = extract<int>(someObject); // *EXCEPTION*

// To not get an exception (or you could handle it, the exceptions tells
//  what type you tried to extract and what type it really was, might be
//  good for a log if it *needs* to be a certain something), check it first,
//  like this:
int anInt2=0;
extract<int> e(someObject);
if(e.check()) anInt2 = e();

// Which I will probably wrap into a macro, something like this:
#define ATTEMPTEXTRACT(type, object, setTo) \
{ \
    extract<type> e(object); \
    if(e.check()) setTo=e(); \
}
// maybe one that sets a default param if not...

// Probably no real point though as most events will be called by other
//  scripts.  There are a few definite events like when it is created,
//  destroyed, serialized, etc... that are not called by the event thing so
//  that really covers anything that may be called C++ side.  To call an
//  event on another object from python, just as normal:
if someOtherActor.onSomeEvent: someOtherActor.onSomeEvent(someParams)

// You can also define new Actors even during gameplay, can even alter
//  the code of a running Actor if you wanted.  As per usual Python, if you
//  edit the code on an instance, it only applies to an instance, if you alter
//  it on the class, it applies to the class and all instances and subclasses
//  of that class, unless already overriden on the instance/subclass.  
//  During gameplay, right now anyway, if you want to save an object
//  to disk then you have to do it in my little code/text editor in-game, but
//  when saved, only new instances will have the changes, you can
//  manually relink the existing Actors by resetting their __class__
//  attribute though, rather then from doing it from the code editor or line
//  by line in the console (I could automate the relink, but probably not,
//  may not want it to...).  You can also edit things line by line and
//  relinking functions manually (much much easier then it sounds)
//  directly from the console, which is how you can change currently
//  running instances and not the class (though you could change the
//  class too), but changes from the console will not save (can't really
//  think of a 'good' method to save from there).  Of course though, if you
//  extend any of the Actors back into C++, you can also edit during
//  gameplay that way by compiling the C++ library and just "reload
//  (libName)" in the console to refresh it, not relinking anything already
//  existing from it before, but if the C++ interface removes anything,
//  that could be catastrophic, but I really doubt people to edit things like
//  that anyway, make in Python first, move to C++ only if it is called
//  often or just plain needs a speed boost.


Things like that.  I am half sleep right now so the above may not be the best examples, but it shows how I am doing things.

Are you implementing any type of script system in it?


Could throw out a lot more I've done over time as well.  


And yea, I hated the Python syntax at first, but once I got to working with it, it really is one of the nicest I've worked with.
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 2653
    • View Profile
    • http://www.wreckedgames.com
Squirrel troubles
« Reply #9 on: July 24, 2006, 12:29:32 PM »

Well, I was contemplating moving Script binding to a seperate (loadable) dll module. So, you could in your game.exe use different script bindings - or no script at all, and just use the c++ classes.

Though, this will involve quite a bit of code changing. Which I'm open to, if this is the consensus ;)

edit -
Something like:

WGE::ScriptManager::setScriptor("some_dll_name");
Logged

mysterycoder

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 447
    • View Profile
Squirrel troubles
« Reply #10 on: July 24, 2006, 12:34:51 PM »

Not really sure about the second example, but the 1st one is really cool.  :)
Logged

mysterycoder

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 447
    • View Profile
Squirrel troubles
« Reply #11 on: July 24, 2006, 12:37:19 PM »

@pjcast: That'd be really cool, someone could even make their own C# version if they wanted to, correct?
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 2653
    • View Profile
    • http://www.wreckedgames.com
Squirrel troubles
« Reply #12 on: July 24, 2006, 12:39:46 PM »

Quote from: "mysterycoder"
@pjcast: That'd be really cool, someone could even make their own C# version if they wanted to, correct?


I imagine someone could swig, or port WGE to CLI/C++ and use c# scripting. With the script binding in an external dll, at least WGE could be made more flexible in terms of what script lanaguages could be used :)
Logged

mysterycoder

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 447
    • View Profile
Squirrel troubles
« Reply #13 on: July 24, 2006, 12:42:55 PM »

You have one vote for the change.  :P
Logged

OvermindDL1

  • Administrator
  • Veteran
  • *****
  • Karma: +0/-0
  • Posts: 288
    • View Profile
    • http://www.overminddl1.com/forum/
Squirrel troubles
« Reply #14 on: July 24, 2006, 01:25:02 PM »

I'm not so sure, although tightly integrating things is generally looked down upon, having everything know that there is a script system and exactly how to use it is opens up so many possibilities.  If you abstract that away, the scripting suddenly becomes far less powerful.

Take this as an example.  Before *anything* is done in my app, I init the scripting system.  I then load my base configuration file, which is a simple python script, but just things like:
Code: [Select]

GameName = "MyGame"
GameVersion = "0.4"
EngineClass = "MyTestGameEngine"
# etc...


It looks like a normal configuration script, although I could define functions, import other scripts/configurations, etc...  The EngineClass is then looked for in the script system as a class name, in this case MyTestGameEngine is a C++ class derived from EngineBase, both of which are exposed to Python.  The engine could just have easily been a python script, which for a real-time game you probably would not want to do, or at least only very little of.  The engine then inits all graphics, its resource system (Ogre in this case), sets up networking, etc... and launches the beginning level.  The Engine also has a configuration script along the lines of:
Code: [Select]

class MyTestGameEngine(_MyTestGameEngine):
    PlayerClass = "MyPlayerClass"
    IntroLevel = "MainMenu"
    ModuleDirectories = ["../Modules/Base", "../Modules/Levels", "../Modules/whatever"]
    # etc...


The engine could just as well be headless for like a dedicated server, probably a subclass of the graphical version that just does not start the graphics.  If wanted, the engine could just as easily be a web server that hosts a little html game...

This engine then launches the IntroLevel, which is the MainMenu (which is still a level), and proceeds and so forth.

Just by changing the first scripts name to a different Engine, I could have a completely different program.
By changing the Engine's intro map, maybe under a new configuration class name that would be called something like MyTestGameEngineMenuMod, then I'd have a different main menu, which could setup an entirely different type of play.  By adding a listing of something like "../mods/myMod" to the ModuleDirectories variable, then I could play my own mod of a game.  I can alter that variable during gameplay from within the game, like a module manager to enable disable module directories, or individual modules, or whatnot.

My exe is also setup so it calls a configuration script of the same name, so if someone wanted their own mod off of, but not inside of this, they'd just have to make a new base configuration script, and copy the exe and rename to the same name as the configuration script, but as .exe and not .cfg...  You can also pass it as a /cfg <configurationFilename> to the exe as well...

You can see where I am going from here...
Logged
Pages: [1] 2 3 4