Sign in to follow this  

Help integrating Entity Editor in my 2D Level editor.

This topic is 2538 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

Hi,

I have written a little 2D editor for my upcoming game. The editor is external to the game and written with Qt. It has things like Tile loading with any size and tranformation, paths, etc... But there's a missing part that is one of the big problems in any editor: the entity editor.

I can load entities and position them in the world in a static way (no animation, I don't need it). But I would like to add triggers that run actions on the entities or run a cutscene, etc... For example I would like to set a lever in the world and a wall and bind the lever on event to the wall open action. I have been thinking all day about how to do this and haven't come to any good solution.

At the moment the editor loads a set of entities templates in xml, where things like what events can throw and what actions can execute. are set And can produce an xml like this for the event association:


<Entity type="Lever">
<Signal Name="On">
<Listener Name="Door1" Action="Open" />
</Signal>
<Signal Name="Off>
<Listener Name="Door1" Action="Close" />
</Signal>
</Entity>





The problem is to use this in a clean way in C++, and as I have said couldn't be able to find a good solution. I'm using boost signals if it is of any help. In the other hand don't know if using a scripting language could help on this beause its more flexible nature.

Sorry for the long post, if you need any other help let me know.

Thanks in advance,
HexDump.

Share this post


Link to post
Share on other sites
This is really where scripting languages come into their own. Instead of writing a lot of fragile and redundant code to go from your editor's definitions to a runtime format wherein you can actually process triggers etc., you simply write a set of scripts that react to a very basic set of events: on_enter, on_exit, on_use, and so on. These scripts then invoke arbitrarily complex logic to accomplish the gameplay mechanics you wish to implement, such as opening a door, or even triggering a trap if the player isn't carrying some lucky object:

on_enter(zone(thezone), entity(theentity)) -> ()
{
if(thezone.name == "trap_one")
{
if(!has_in_inventory(theentity, "talisman"))
{
animate(thezone, lightning_effect)
damage(theentity, random(1, 42))
}
}
// etc.
}



Of course if your gameplay requirements are fairly simple you can just do this with some data-driven logic instead, whereby you iterate over a list of "responses" to a given "event" (perhaps applying some "filters" along the way to limit reactions to certain circumstances, such as the carrying the talisman in the above script).


Some more details on what all your game/engine will involve and what you specifically want to implement would be useful in making more concrete suggestions.

Share this post


Link to post
Share on other sites
Hi,

Thanks for your answer ApochPiQ.

I'm really interested in what you propose. Could you please develop a little more your response?. I mean, I have my 2D editor, and my game runtime. Where does scripting fit? Ummm... should this code be generater by the editor instead of xml? I'm a bit thick today, too much thinking, if you could develop a bit more I would be really greatefull.

Thanks in advance,
HexDump.

Share this post


Link to post
Share on other sites
Typically for smaller games you wouldn't need to use the editor tool at all to create the scripts; you'd just write them in your text editor of choice and bundle them along with the level data etc. The script engine would load the script code when the level is loaded (either from a separate file, or the same packaged file, or whatever is easiest for you) and then the game engine would invoke the scripts when certain events occur, e.g. when a player/NPC/whatnot enters a region of the map, and so on.

Share this post


Link to post
Share on other sites
Hi!,

Ok, I think I understando you now. You mean to have a global level event handle per event type. And write the bindings there. When an event of this type occurs then the game engine calls the function and it does what it should.

It is a good point, don't like the "global" thing, but I understand it the less intrusive way, and it is really practical. I think I will go this way. I just need from scripting register "EventType" -> lua function and keep it in a map or something like this and inoke it.

Thanks a lot for the tip,
HexDump.

Share this post


Link to post
Share on other sites
The approach to this I've taken on my current project and found quite flexible is to have relevant entities be able to send and receive numeric signals, most normally in the form of a 0 or a 1, and be connected to a client entity graphically in the editor (in my case by clicking the entity, then clicking its client with SHIFT held down, causing an arrow to be drawn between them, but whatever...).

For example, my button sends a 1 to its client when it is depressed and a 0 when it is released. My doors open when they receive a 1 and close when they receive a 0.

I can also graphically place gate objects which exist in the game to translate signals - a NOT gate that inverts the signal, a splitter gate which takes its signal and passes it onto multiple clients etc.

I do also have a scripting system but this integrates well as you can also add a script gate that, on receipt of a 1 signal, runs a particular procedure then passes the result onto its client, although as development has progressed, I've found I need actually typed scripting less and less and can build quite complex behaviour just by interconnecting entities and gates.

The only support within the game itself required is for relevant entities to store a reference to the ID of their client(s) and implement a ReceiveSignal() virtual method, and for the engine to provide a method for identifying the relevant entity from its ID and sending it the passed signal.

New types of entity also drop nicely into this system as the nice thing is that nothing needs to know a) what it is receiving signals from or b) what it is sending signals to, keeping everything very decoupled and distinct.

I guess I can't describe it in detail in a post but it's an approach I will continue to use religiously until something better comes up.

Share this post


Link to post
Share on other sites
Hi!,

Thanks for the explanation Aardvajk.

Could you post a screenshot of the editor using this connections?.

In the other hand, from what I understand related to you editor, you have actors (the visible entities in the game) and some kind of "boxes" that do different things and allways come in the middle of two entities: The server, the one sending the signal and the client the one receiving it?. is it enough to just send 0 and 1 for the signal? Could you show an example of a more or less complicated behaviour with your system?. Thanks a lot for sharing all this information.

Edit:
Quote:
Original post by Aardvajk
The only support within the game itself required is for relevant entities to store a reference to the ID of their client(s) and implement a ReceiveSignal() virtual method, and for the engine to provide a method for identifying the relevant entity from its ID and sending it the passed signal.


I quite don't understand this. Wouldn't serve entities to know about this "boxes", and then the boxes know about the client entities?.

Thanks in advance.
HexDump.

Share this post


Link to post
Share on other sites


Example above, the red box is a sensor area which sends a 1 to its client when Squishy enters and a 0 when he exits.

Client in this case is a splitter gate which just passes on signal to multiple clients. In this case, clients are a dialog (which says "Land on the button to activate it") and a breaker gate which will disable its client when it gets a signal.

So, when Squishy enters the sensor, the dialog opens then the sensor is disabled for future.

The button is connected to another splitter which connects to a) the door causing it to open, b) a breaker that deactivates the button and c) a NOT gate which is connected to the dialog.

So when the button is pushed, the door opens, the dialog gets a 0 (via the NOT gate) and closes then the button is deactivated.

Or in other words, approach the button and a dialog opens telling you to land on it. Land on the button and the dialog closes and the door opens. But nothing hard-coded and no actual scripting.

Hope this helps understand.

Ref your second question, the gate objects are defined in the game as Actors, same as everything else, they are just non-renderable. Everything has an ID so when a signal is sent, the engine just searches all the actors for the one with the correct ID then sends it the signal.

Share this post


Link to post
Share on other sites
Hi!,

Thanks for the explanation, now everything is more clear :).

One more question, why a splitter? and not just letting every entity talk to several targets? Is it because you could want a return signal to its own?.

I was thinking about something like your desing, but yours is much better, didn't come acrosss the idea of commands in the sense of entities. I have to think about it a little more, but I like your idea a lot. Let me digest it through the weeked :D.

The only problem I see with your design is that you don't really know what 0 or 1 mean for a client entity. I mean, for a door it could be clear that if you send a 0 it will mean close and 1 open, but for example think about the following:

1) we create an entity in th escene.
2) We create a path and attach the entity to the path.
3) You send a 1 when player enters a collider and the entity moves across the path and disappears (it is just like a mini cut scene). It is not clear what a 1 will do if the editor is used by a person that is not the one that put the entity there. This is why I was looking for something more semantic like a string. Anyway as I said I like your solution.

By the way how do you translate all this info into your game? Do you use xml as I firstly did, do you use some scripting? Or is it an ingame editor?


Thanks in advance,
HexDump.

[Edited by - HexDump on December 31, 2010 10:23:03 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by HexDump
Thanks for the explanation, now everything is more clear :).


You're welcome.

Quote:
Original post by HexDump
One more question, why a splitter? and not just letting every entity talk to several targets? Is it because you could want a return signal to its own?.


No real reason really, mainly just to avoid having to worry about storing and dispatching to a list in the code for each entity but it's not a major issue.

Quote:
Original post by HexDump
It is not clear what a 1 will do if the editor is used by a person that is not the one that put the entity there.


Yes, I agree. If this was for multiple use, documentation would be required. The nice thing about it is that it leads to completely decoupled entities that can be written and tested in complete isolation from each other.

Quote:
Original post by HexDump
By the way how do you translate all this info into your game? Do you use xml as I firstly did, do you use some scripting? Or is it an ingame editor?


Custom binary file format output by my editor and read in by the game. Entities are loaded into the editor via module files (similar to XML format, my own XCS format) which also specify which properties to export for each entity in which order, again allowing extension without touching code.

Share this post


Link to post
Share on other sites
Hi,

Thanks for your time, it has been a really nice conversation/sharing.

I will go your way, I hope it will fit all my needs, anyway I allways could have a "Scripting node" for this special cases :).

Thanks again,
HexDump.

Share this post


Link to post
Share on other sites
Quote:
Original post by HexDump
I will go your way, I hope it will fit all my needs


Me too - it works for me but I'm not pretending it is a silver bullet solution.

Quote:
Original post by HexDump
Anyway I allways could have a "Scripting node" for this special cases :).


I do exactly that. I have a script gate that references a procedure that it runs when it gets the 1 signal. This takes care of any cases that the gates alone can't handle.

Share this post


Link to post
Share on other sites

This topic is 2538 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this