Basics of how internals of Construct work

This forum is currently in read-only mode.
0 favourites
From the Asset Store
Casino? money? who knows? but the target is the same!
  • I've used GameMaker in the past. And I know some C++ and have used a few 3d engines with it. I have also looked at Unity, though I didn't get too much into it. So I know my way around programming etc...

    My question is, how does construct work internally? I know it allows python scripting, which itself is "technically" interpreted, though python is pretty fast as far as being interpreted goes. But what about the rest? Is the executable that gets created somehow compiled? Or is it converted fully to python(which I doubt because you don't need the python dll to run if not using python scripts)? Is it turned into some other interpreted language internally?

    Sorry about the questions, but before I delve into Construct, I'd like to know how it works inside. I'm likely going to try it out anyway, but I'd still like to know.

    Thanks in advance.

  • Events aren't converted to any other language. The runtime is a standalone compiled EXE application, which is optimised and actually very fast. Your events and game data are attached to the EXE as a block of data. The compiled EXE then builds an internal representation of the events in memory, and starts running them.

    It's basically an interpreter for events, but it performs very well - events usually complete quicker than the rendering on the screen, and rendering and events run in parallel together (since the game is rendered with DirectX on the GPU rather than CPU). In other words, your game code has no performance overhead unless the events take longer than the rendering.

    Also, although events are interpreted, all the actions, conditions, expressions, plugins and behaviors are written as compiled C++ plugins. This means code within them is very fast as well - for example, if you do pathfinding with the RTS behavior, that pathfinding code runs as quickly as it would in any other compiled C++ application. The only intepreter overhead is in deciding when to run each of these bits of code.

    That's a very brief overview, if you want any more detail I can provide!

  • Events aren't converted to any other language. The runtime is a standalone compiled EXE application, which is optimised and actually very fast. Your events and game data are attached to the EXE as a block of data. The compiled EXE then builds an internal representation of the events in memory, and starts running them.

    It's basically an interpreter for events, but it performs very well - events usually complete quicker than the rendering on the screen, and rendering and events run in parallel together (since the game is rendered with DirectX on the GPU rather than CPU). In other words, your game code has no performance overhead unless the events take longer than the rendering.

    Also, although events are interpreted, all the actions, conditions, expressions, plugins and behaviors are written as compiled C++ plugins. This means code within them is very fast as well - for example, if you do pathfinding with the RTS behavior, that pathfinding code runs as quickly as it would in any other compiled C++ application. The only intepreter overhead is in deciding when to run each of these bits of code.

    That's a very brief overview, if you want any more detail I can provide!

    That good news, about the performance. Now, how easy is it to access object's instances in your event system. For example(a pretty extreme case actually), I have an object. It collides with something, and I want to either destroy, or lower life on certain objects, but only in that area(say a bounding circle). How easy is it to access only those specific instances of said object that are within the circle, and for (example) weaker enemies, destroy them, and stronger enemies simply lower life?

    Also, say I want to create my own plugin for sounds, using maybe OpenAL, or cAudio. In your XAudio2 plugin, it has 64 channels, but the I would do it would not to have channels. The audio API manages all of that(including mixing) and simply returns pointers to sounds, which you need in order to stop or change position(3d sound) of the currently playing sound. Now if you can't easily return/send actual C pointers to/from the plugin, I could simply create a data structure to hold all the pointers, and return an index. But, can you describe a little how that would work, either pointers or simple integer indices???

  • That good news, about the performance. Now, how easy is it to access object's instances in your event system. For example(a pretty extreme case actually), I have an object. It collides with something, and I want to either destroy, or lower life on certain objects, but only in that area(say a bounding circle). How easy is it to access only those specific instances of said object that are within the circle, and for (example) weaker enemies, destroy them, and stronger enemies simply lower life?

    you could do it with a distance expression, but you said circle, so for this example, I'll use an actual sprite circle:

    let's say you put several life lowerable objects in a family called Hurtable

    Victim----on collision with Something:

    --------------------Move SplashCircleSprite to Position of Something

    -----For Each Hurtable

    -----------Hurtable is overlapping SplashCircleSprite

    --------------------------------Hurtable private variable Energy minus 10

    Hurtable private variable Energy equal to or less than 0

    -------------------Destroy Hurtable

    The 'picking' system automatically (in ways defined by the plugin) picks the objects relevant to the condition. So any actions under a condition, so for example:

    On Sprite Collides with OtherSprite

    would automatically only act on the particular Sprite(s) and OtherSprite(s) involved in the collision

    [quote:2lknlr9u]

    Also, say I want to create my own plugin for sounds, using maybe OpenAL, or cAudio. In your XAudio2 plugin, it has 64 channels, but the I would do it would not to have channels. The audio API manages all of that(including mixing) and simply returns pointers to sounds, which you need in order to stop or change position(3d sound) of the currently playing sound. Now if you can't easily return/send actual C pointers to/from the plugin, I could simply create a data structure to hold all the pointers, and return an index. But, can you describe a little how that would work, either pointers or simple integer indices???

    you can do any type of c++ you can think of in a plugin, period. plugins are able to communicate with eachother if necessary and pass any type of data through void pointers.

    you design the interface for the construct user within the confines of the ActionConditionExpression system.

    Basically, you decide a list of possible actions (things they can do, ie. Set Reverb to 10), conditions (things they can check, or have triggered, If Player is within hearing distance of Sprite), and expressions (GetCurrentReverbLevel).

    as i said before though, the plugin is just c++, you can include whatever libraries, and do whatever you'd expect to in a c++ program

    ...

    ....just reread your question, and I realize I misinterpreted it maybe, so

    you mean return these pointers to the Construct user?

    yes, indices in a vector, list, etc, would probably be the simplest way to give these to the enduser. The XAudio plugin has AutoPlay features that does something similar already. You can Autoplay sound "blahblah", and if the user still wanted to know what channel it was autoplayed to they can Set Private Variable MyPV to XAudio.LastChannelPlayed.

    The beauty of it is how flexible it is, though:

    I'm not saying this would or wouldn't be a good/bad idea, but an example of how many different ways you could approach it if you wanted to be weird/creative. for example you 2 plugins, a soundmanager plugin and a sound effect plugin. when a sound was played through Soundmanager, it would create a soundobject, which they could then move around the layout with it's xyz coordinates, even add a behavior to if they wished. It could automatically destroy itself when the sound completed playing. You actually would need SoundManager at all except for caching sounds or whatever prior to playing them if you were doing that.

    welcome to the boards, btw

  • I'm not about to quote all of that....

    So the "picking" as you put it automatically cancels out non relevant instances. So if I am within a collision condition, any sprite instance of bullet that wasn't collided will not be affected by whatever I do with "bullet" within the actions under said collision condition event??

    About the splash damage thing, it makes perfect sense. Now lets make an extreme case. For some reason, when a bullet hits an enemy, I want all bullets to be destroyed. If I simply do the destroy action, it will only destroy itself, because of the above paragraph I wrote, about excluding other non-relevant instances. How would I go about destroying all other bullets as well. I would think let's set a variable, and then for all bullets the condition for said variable could make them destroy themselves, but it creates the same problem of how to access those private variables of all bullets not relevant to the collision. The only solution I can think of is to have a global variable, with a condition event, that does it globally, but that is ugly.

    Basically, I would like for example to "target" a given instance of an object. In game maker, you can loop easily through all instances of an object, and choose one based on whatever you want(for example the value of a variable). You could then store that object id into a private variable of whatever was doing the choosing, and then you could do something later using said id, without doing the choosing again. In GM, every object instance has its own id, and you could access objects with it using the '.' operator. Or, you could use the name of the object, and it would loop through all of the instances of said object regardless of whether they were "relevant" in the current condition. Of course, I'm not looking for this exact method of doing things, or I would just continue using Game Maker, but, is something similar to this available?

    The other thing I did not see anywhere was controlling the view/s. I know how to make the view follow a certain object, but that assumes there is only one instance of that object. If I check that for example for "bullets" because I want you to control bullets when the shoot(a new weapon prototype ) I would need the view to follow that. But if the view is following the player, how would I switch? Also, how would I directly control the view my self(which would solve the bullet problem assuming I could choose which bullet to follow)?? I would like to make the "camera" pretty smooth. The generic view following is actually pretty smooth, but for example, if I use it where a ship is pretty fast, I would like the view to "scout ahead" if you will, and if I can control the view directly, it will work.

    Also, using the internal mouse/keyboard, I saw multiple sets of actions/controls, for multiple players. This is good. But, is it possible to have more than one view, each with it's own HUD. I saw the layout information, where you can specify that some parts not to scroll, and some to scroll, even for parallax effects. But, I would want it to be used for that, and for multiplayer. Is that functionality present yet??

    One more, last thing. Is it possible to use "tiles?" I saw that you can tile a single background all over a layout, which is good. But, for example with a platformer, I saw you can create objects as "solid" which will make the platformer behavior work good. But, behind all of those solid platforms(likely invisible) I would like to be able to create pretty graphics, likely using a tile set, which of course isn't the same thing as simply tiling a background.

    See, my issue is that I'm coming from Game Maker, where lots of these features exist, but the performance and eye candy is next to crap. But, for me to invest the time and make the switch, I would need these "features" or ways to achieve them. I don't think it would be worth my time coding my own plugins for these, as they are pretty complicated. I would probably code my own 3d sound plugin(and release it GPL) without any of the limits of the current XAudio2 thing, but I'd rather not have to code plugins for multiple views, etc... assuming it would even work with the current state of construct. But, I really like the performance and effects, which is the reason I'm taking a serious look.

  • ^ Is all doable, with several different ways of doing it.

    And it's relatively easy as well.

    Your only limitations are hardware, and those that DirectX 9 bring.

  • I'm not about to quote all that so:

    if you wanted to destroy all bullets there are four ways you can do it, off the top of my head.

    First there is a System - Advanced Collision condition, that allows you to choose whether either object involved gets picked. If no instances of an object are picked, it's as if all of them were picked. you could use that.

    You could use the 'family trick', where you put the bullets in a family called "blue" lets say. And on collision with bullet, blue.destroy. Families have their own separate picking lists, so you can do things like bullet, on collision with blue, and control the hitting bullet, and 'hitee' separately. in this case, since only the bullet was involved in the collision, all blues(bullets in that family) would be destroyed

    you could use a function, this is messy as you said, unless the process involves more than just a simple destroy. you could make a function that destroys all bullets. and function calls allow you to choose whether or not picking is conserved inside the function

    you could use my 's' plugin. it intimidates alot of users, and indeed it's more advanced core features have probably the largest learning curve of any construct plugin I'm aware of, but there are several handy easy to use things as well. In this case, there is a Pick Object action, and a Pick Object condition. They serve the same purpose, just allow you to use them in two different places. All this does is allow you to choose any object type, and order construct to pick a specific instance, unpick a specific instance, pick all that type, unpick all of that type. You can also choose whether it's picked as itself, or as a family, so you can say pick all bullets as blue, and even if there are other things in the blue family, it would only pick all the bullets there.

    there's also python, but that's overkill if you're not already using python, which unlike gamemaker, scripting isn't needed for even very advanced games, with very unique needs. I wouldn't recommend even touching python, until you realize how you can make everything you think you can't make without it.

    Controlling views. You can control views directly with the system object. controlling scrollx and y and zoom, globally as well as independently for each layer. A simple way to make a great camera is to make an invisible sprite object, and just tell the camera to "always" scroll to that object. Then put a bullet behavior on that invisible sprite, and make it always follow what you want at a speed based on the distance, that way it smoothly slows as it approaches objects. any type of movement you can conceive of except for 3d camera rotation is possible with these few simple system actions. also, there is a 3rd party 'magiccam' plugin which does alot of neat stuff for you, but I haven't used it myself, nor kept track of it's stability or development

    there's no handy tile editor as of yet (though there is grid snapping), other than cool examples made with construct you can probably find in the tutorials section of the forum. the platform school tutorial if I remember correctly had some ugly square tiles covered with pretty graphics, and that's a perfectly valid and common way to do it. If you mean one large tileset sprite, and you only reveal whichever part you need, this would be an involved process using uv distortion, which is entirely possible, but not the easy way to do it. the straightforward way is to load all the separate tiles into a single sprite animation. set the animation speed to 0, and then just switch frames in the editor like this :

    Subscribe to Construct videos now

    If by multiple views with multiple huds, you mean split screen, there have been a few examples of someone doing this with the canvas mostly. there's was a particularly awesome one here:

    I also came from GameMaker, which I purchased long long ago. The second I tried to create a script that did bezier curves, or split a convex polygon into multiple triangles though, it completely choked showing me that the engine wasn't capable of anything truly computationally complex. I can assure you that construct is capable of doing anything, gamedesignwise, that gamemaker can do in a much more intuitive way. seriously, try out the ghost shooter tutorial, and if you're like me, you'll be in love with construct halfway through it. then move onto 'platform school' tutorial, and dropout halfway through once you "get it". once you understand the basic workflow and logic to construct, you'll likely find that it's much more simple and enjoyable to make anything you can think of then you would have even hoped possible. pretty much any 2d gametype or feature you can think of, you can make.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • I already did try the ghost shooter tutorial. I'm not too afraid of doing things differently, which always happens when you try do make things better. It was after that tutorial for me that all of these questions popped out. The thing that hit me first that I didn't see in the tutorial besides all of these questions was how to create an object while having no instance of it at all. In the tutorial, you have the bullet and player, and then though the first bullet destroys itself, you can still create other instances. How complicated is it to not have an instance at first?

    Besides that one, it seems that the posters have pretty much answered my questions. I will have to look at that split screen example, among other things, but if it is like it appears, I will likely be using Construct for my next project, even if I have to create a couple of plugins myself to get it done. Thanks for all the help so far.

  • destroy on startup attribute happens before frame 1 of the game.. I could be wrong about that though. if so, it's existence for a moment at the beginning of the first tick of the game without being displayed won't affect performance or anything else. Destroy on Startup is the equivalent of having no instances at startup. unfortunately, because of early choices behind the scenes of construct, it's not possible to create a layout that has object types in it without also having that one instance that destroys itself at least.

  • Well, as long as I can get it to destroy itself upon startup, I'll be fine. Thanks.

  • You also can create any object existing in your game on any layout from another layout via single eventsheet. Add new eventsheet and you will have access to all objects in game, then include eventsheet to layout you want.

    E.g. you have 2 layouts. There's SpriteA on first layout and no Sprite's instances on second. Add new eventsheet, add "<some event>-> create object SpriteA at x,y", include the eventsheet to second layout - now you can create SpriteA's instance on second layout

  • You also can create any object existing in your game on any layout from another layout via single eventsheet. Add new eventsheet and you will have access to all objects in game, then include eventsheet to layout you want.

    E.g. you have 2 layouts. There's SpriteA on first layout and no Sprite's instances on second. Add new eventsheet, add "<some event>-> create object SpriteA at x,y", include the eventsheet to second layout - now you can create SpriteA's instance on second layout

    Thanks for that. So it would be possible to have a layout that simply has a bunch of objects that would be usable on any layout, and not have the game ever actually go to that layout?

    The other thing I'm curious about is this. How much overhead is there for objects? I remember with Game Maker, objects have a certain amount of overhead for each instance whether it actually did anything or was just visual. But Game Maker the alternative in the for of tiles, which had much less overhead and were purely visible. I see in the tutorials that recommend you to create pretty objects, and then simple "tileable" objects that aren't pretty, but are the real colliders for the levels. That makes since, and is exactly what Game Maker tuts did, using tiles for visuals and actual objects for collisions. Do objects only get overhead for what they actually do? Also, if they have to have overhead like Game Maker for speed, direction, all of those internal variables, then is Construct simply fast enough that you can have tons of object instances without too much slowdown.

    Since I'm posting again, I'll ask this one as well. What is usually the biggest bottleneck for Construct? With Game Maker, it was either too many object instances, or the gml scripting that was just too slow as it gets interpreted. Ashley posted above that usually events etc... process faster than the rendering. Is that pretty always the case, or are there certain things/functions in events that cause a specific slowdown outside of the norm?

  • The other thing I'm curious about is this. How much overhead is there for objects?

    There is actually very little overhead for objects - even fully animated sprites. Reducing overhead is something we spent some time specifically working on.

    If you have hundreds of individual tiles, though, the overheads do add up. If you use a Tiled Background instead of grids of sprites, that should be a lot more efficient.

    [quote:167sxy25]What is usually the biggest bottleneck for Construct?

    I'd say most often shaders, because they're really intense on graphics cards (but look very cool!). Apart from that, inappropriate uses of objects like RTS movement's pathfinding can burn CPU cycles. Usually there are workarounds and more efficient ways of doing that though.

  • So the tiling object is more efficient than the sprite object. I would assume that is due to the lack of animation of the first object. Even so, you have to have a lot for it to be noticable.

    And so the speed is most likely to be bottlenecked by the shaders/rendering. Besides the path-finding issue(which is a fault in the designer, not the tool, if you are using it wrong), are there any other things that I need to watch out for as far as being CPU intensive??

  • Not really. I've never ran into any performance problems until I got to the point where it was several thousand commands running per frame, or several thousand objects.

    Edit:oh yeah, and the tiled background is faster because there's only one of them for a large area. Where as a sprite would take many for the same space. If you're wondering, yes, you can distort the uv of a sprite to make it look like a tiled background, and use it in its place. Tiled background just simplifies the process

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)