Jump to content

Add New C++ function callable by JS


Recommended Posts

Working on visual replay system and need to add event tracking for attacks/kills

I've only worked with the C++ code base mostly so far.<br class="Apple-interchange-newline">

Need some quick advice on how to proceed

Need to call C++ function with unit Names or IDs or attacker and damage receiver

cppTakeDamage(attackerID, victimID, damageLevel, victimHealthBefore, victimHealthAfter) // don't really need the health stuff...

Attack.js

CauseDamage() looks like the place to do it

Help on the following would be appreciated1. general task list to add a cpp funciton and how it gets exposes to JS

2. any way to debug the JS ?

Link to comment
Share on other sites

You can expose member functions of C++ components to JS fairly easily. See examples in source/simulation2/components/ICmp*.cpp - the macros BEGIN_INTERFACE_WRAPPER, DEFINE_INTERFACE_METHOD_#, and END_INTERFACE_WRAPPER are your friend.

Link to comment
Share on other sites

Just curious, why you'd want to do this? Generally, the engine shouldn't have anything to do with gameplay concepts like attack and damage. If you're just wanting it for some kind of graphical indicator, I'd suggest exposing a suitable API to scripts, if it doesn't already exist, and calling that directly (we do that in a few cases related to health bars and selection rings).

As far as debugging scripts, you currently have to do this by hand, uneval() and warn() are your friends :)

Link to comment
Share on other sites

Just curious, why you'd want to do this? Generally, the engine shouldn't have anything to do with gameplay concepts like attack and damage. If you're just wanting it for some kind of graphical indicator, I'd suggest exposing a suitable API to scripts, if it doesn't already exist, and calling that directly (we do that in a few cases related to health bars and selection rings).

As far as debugging scripts, you currently have to do this by hand, uneval() and warn() are your friends :)

The reason we want to do this is that we have hooked c++ code into the engine to track game play events and unit position updates during game play (recording)

so we can automatically generate cinematic camera coverage for visual replays (we extended the replay system to do visual replays).

System then generates a webm video with sound.

Currently, projectile units are all we have in the engine for battle events.

Melee events are entirely handled in script.

Looking for some guidance on how to do this from attack.js

ie code examples in script/engine that show exposed API being called by script. in other places

how does a particular script know about the exposed API calls ?

I need unit ids to or unique unit names for the instigator and the target.

How do I look at or find out the js object hierarchy, members ?

Link to comment
Share on other sites

The reason we want to do this is that we have hooked c++ code into the engine to track game play events and unit position updates during game play (recording)

so we can automatically generate cinematic camera coverage for visual replays (we extended the replay system to do visual replays).

System then generates a webm video with sound.

Sounds interesting. Is this an open source project by any chance?

Link to comment
Share on other sites

Sounds interesting. Is this an open source project by any chance?

The replay and video capture is not open source.

We will be submitting the visual replay changes to 0AD for inclusion into the code base.

(And also the mods to 0AD to integrate the functionality, if desired)

I would expect that the company would likely provide a run time binary add on or distribution with 0AD at no charge, if desired and provided that it didn't require a distribution of the source code.

BUT I am NOT authorized to make that decision, it's just my personal opinion.

The video system works via C++ through LUA plugins that determine what gets covered and how it looks.

Those would be open source and the user or developer community could modify or make their own director and shot plugins.

(Decoda has a nice lua debugger that works well with the 0AD and the lua director scripts.)

Link to comment
Share on other sites

I think the best approach is probably to create a new C++ component, so that it can call other C++ and can be called from scripts (or from C++). The documentation here should be relevant: create something like an ICmpCinematicCameraManager in C++, use DEFINE_INTERFACE_METHOD_* to specify which methods can be called by scripts, create a CCmpCinematicCameraManager that implements those methods by passing the data along to the other parts of the engine that need it, etc, as documented there. Then add CID_CinematicCameraManager to the list of SYSTEM_ENTITY components in simulation2/Simulation2.cpp ResetComponentState so that it automatically creates a single instance of that component. Then you can either have scripts call the component directly ("var cmp = Engine.QueryInterface(SYSTEM_ENTITY, IID_CinematicCameraManager); cmp.DoWhatever(stuff);"), or have the component subscribe to messages that the gameplay code is already sending (as here; e.g. subscribe globally to the PositionChanged message to get notified when any entity moves, without having to insert any new code into CCmpPosition).

Link to comment
Share on other sites

You can expose member functions of C++ components to JS fairly easily. See examples in source/simulation2/components/ICmp*.cpp - the macros BEGIN_INTERFACE_WRAPPER, DEFINE_INTERFACE_METHOD_#, and END_INTERFACE_WRAPPER are your friend.

Thanks for the info, that helped me get in working.

I think the best approach is probably to create a new C++ component, so that it can call other C++ and can be called from scripts (or from C++). The documentation here should be relevant: create something like an ICmpCinematicCameraManager in C++, use DEFINE_INTERFACE_METHOD_* to specify which methods can be called by scripts, create a CCmpCinematicCameraManager that implements those methods by passing the data along to the other parts of the engine that need it, etc, as documented there. Then add CID_CinematicCameraManager to the list of SYSTEM_ENTITY components in simulation2/Simulation2.cpp ResetComponentState so that it automatically creates a single instance of that component. Then you can either have scripts call the component directly ("var cmp = Engine.QueryInterface(SYSTEM_ENTITY, IID_CinematicCameraManager); cmp.DoWhatever(stuff);"), or have the component subscribe to messages that the gameplay code is already sending (as here; e.g. subscribe globally to the PositionChanged message to get notified when any entity moves, without having to insert any new code into CCmpPosition).

Thanks for the info, got it working.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...