Ruskul's Recent Forum Activity

  • You can also add in predicting aim for more accuracy and handle things like predicting acceleration.

    So, for example, since the turret behavior doesn't track or care about the difference over time in the delta between target positions, a constantly accelerating target will never be hit.

    Currently the behavior tracks changes in position from one frame to the last, and uses that to extrapolate where to shoot. It also accounts for its own speed I believe.

    But if you add a variable that stores one more previous position, you can find the difference in deltas between the 2 steps between the 3 positions and roughly account for any continuous acceleration.

    You can get this working with events by using a "ghost" target. Instead of tracking a target itself, you track a sprite that you then set to the position of the intended target. you then monitor the intended targets acceleration from frame to frame, and the distance to the turret. Using the same sort of math, you can place the ghostTarget ahead of the actual target and have the turret shoot at that. The turret will practically never miss except when an object is changing directions... and you can add another layer for dealing with delta differences of the differences, and so on recursively as many frames as you like. If the target takes time to accelerate and decelerate, it won't stand a chance.

  • This is the code from the behavior, if you don't know anything about code, I can try to step you through what is happening:

    let targetWi = this._currentTarget.GetWorldInfo();
     let targetAngle = C3.angleTo(wi.GetX(), wi.GetY(), targetWi.GetX(), targetWi.GetY());
     if (this._predictiveAim) {
     	const Gx = wi.GetX();
     	const Gy = wi.GetY();
     	const Px = targetWi.GetX();
     	const Py = targetWi.GetY();
     	const h = C3.angleTo(Px, Py, this._oldTargetX, this._oldTargetY);
     	if (!this._firstTickWithTarget)
     		this.AddSpeed(C3.distanceTo(Px, Py, this._oldTargetX, this._oldTargetY) / dt);
     	const s = this.GetSpeed();
     	const q = Py - Gy;
     	const r = Px - Gx;
     	const w = (s * Math.sin(h) * (Gx - Px) - s * Math.cos(h) * (Gy - Py)) / this._projectileSpeed;
     	const a = Math.asin(w / Math.hypot(q, r)) - Math.atan2(q, -r) + Math.PI;
     	if (!isNaN(a))
     		targetAngle = a
     }

    worldinfo has all the important bits about an objects size, location, etc... and you can look it up in the addon sdk manual. The important math parts here are at the bottom with const s, q, r, and w. (const just means a variable declaration is happening)

    If you ever want to take a deep dive into what is happening behind the scenes, you can launch a game and press f12 to bring up the devmode for the browser. You can browse all the runtime code to your hearts content, and it is indeed a really valuable tool to begin understanding precisely what is happening, and how things work under the hood. You can learn alot, though, I would recommend a code base with comments if you are just learning coding.

  • So, I launched the editor and selected my cloudfile. I hit load. I actually got the file loading before the editor even realized I didn't have a behavior loaded. The load was interrupted by the editor halting with the red screen to warn me a plugin was not installed (I had shutoff my addon server).

    So I closed the editor, launched my server, and attempted to open the file, but it "Failed to open project. Check it is a valid Construct 3 single-file (.c3p) project."

    The file has just been open earlier in the day no problems. Is there anything I should check for in the capx?

    I don't have a backup, this was just a little template project I was making, so no big loss, but I would hate to have this happen to a main project.

  • 1StepCloser

    Glad you liked it, I was like "jeez, I need to stop writing mini novels on this forum and get back to work", lol

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Putting the addon sdk behind the scripting interfaces doesn't do anything! How does that address the question of expanding the api? That intentially limits it, as others have said, all the while ignoring the issue at hand!

    No other engine offers infinite stability. Their api evolves, becomes depreciated, then eventually expires. And none of them face a pr fire because of it. This has allowed them to have cake and eat it too, and is a much better solution than -don't expand api, because then construct will stagnate- which is what it IS doing from a user perspective.

    > Do actually believe that behavior alone addresses all needs within the genre in a scalable, and sensible way?

    Maybe the behaviors don't do everything. They are designed to be flexible. But beyond that, you can use custom logic in event sheets, or JavaScript coding within a project, to implement things like custom movements. You don't have to jump to hacking the engine internals. There are usually several ways to get things done.

    "Usually" isn't always, and as always, you keep missing the entire point, which is that we aren't talking about the "usual" problems here.

    I've explained many times, in multiple posts over the years, including through suggestions. In the past, "intentional implementation" was a common word I heard when describing limiting bugs in official behaviors. The included behaviors are, as others have said, opinionated in their implementation, and only flexible if you share that opinion. In all other cases they are mediocre substitutes.

    I'd love to see you edit the node connections in the pathfinding behavior with events (oh snap, there aren't aces for that) or get it to work with hexagons. For that matter, you can't even make an rts with it. Either you have to recreate the whole behavior from scratch... and since many api aren't public, you have to recreate those as well, or you hack it.

    If behaviors were so flexible, they would be designed from the ground up to be component based, in and of themselves, regardless of the engines api, but they aren't. Instead they are rigid solutions for a particular set of problems.

    And yes, you can indeed make custom character handlers through events, but they can't be abstracted and easily re-used. Which pushes any complex project towards purgatory, which is what I'll call it since you clearly think you get to gate-keep dev-hell.

    It is not feasibly performant to recreate a collider engine/solver, or component architecture, or pathfinding in events. All the official behaviors CHEAT in that regard, in that there is hard codes solutions and dependencies in the engine for them to communicate by. That is bad architecture for a game engine when the devs do it but expect their users to get by without it - the api not being encapsulated is hardly the concern, but the actual architectural pattern.. You can't keep talking about how all the other engines have encapsulation, when all the other engines also don't require hacks to accomplish basic objectives like extending the engine.

    As an alternative, scripting editor side has a huge problems if you wish to use it with eventsheets or frequently interface through JS blocks - for performance reasons, it becomes better to not cross scripts and modules with events. Which leaves the addon sdk, which is performant through eventsheets.

    I'm not going to rescript/duplicate the entire sprite/collision backend (nevermind not being able to create an editor tool for it) in each behavior that I need, just so I can do something the engine is already doing!

    That would be insane.

  • Thanks, that's a good direction. Looks like I might have to add this to my, "nice to have" list and tackle it if I have time. I don't actually need palette swapping in my current project, but it always bothered my that my luts were sprites overlaying the entire viewport.

  • Yeah, scripting is nice. There are just a handful of things that I find simply more convenient/simple to do in eventsheets, but I'd like to eventually move even more into scripting, at least when we're talking complex projects. I really like the eventsheet for simple projects though.

    The speed for simple things is where construct really shines. I think I used c2 for a good year before I ever realized or ran into any sort of issue. But I also was naive about good programing patterns. Although, it seems across the gamedev world, I see countless example of poor code that works and met the deadline and who cares lol.

    It was when I got into the need to have modular, scalable functionality that construct became to difficult to use at the time (c2), which is why I switched to unity. But I always kept prototyping in construct. You can slam a concept out in an hour easy.

  • 1StepCloser

    I have a biased outlook on the matter, so I'll share that at the end if you care.

    For me, this is what I have found, given my projects. I lean very heavy into abstraction every where I can and prefer modularity, rather than hardcoded solutions.

    1. Using JS only has the limitations that you aren't utilizing one of constructs biggest strength amongst it's competitors; The eventsheet and the sol paradigm. I doubt anyone can match speed for speed if they only use JS, which then leads to the hybrid approach being favorable. Consider how many lines of JS it takes to emulate a simple "Is A overlapping B" condition.

    The api is very verbose imo, and could be streamlined with a number of apis to emulate picking conditions. Without those, you have to recode a lot of stuff. The ghost shooter template is a good example, because it requires a lot of typing to simply do what a few events did. Not only that, it is making lazy overlap tests that would kill performance in a full scale game. At the time it was made, there wasn't a way to GetCollisionCandidates and make use of the internal collision cells.

    2. Given the above, a hybrid approach is definitely a better workflow, taking advantage of ACES where can, and doing specialized stuff in JS. You can solve alot of construct's biggest weaknesses by utilizing oop through js modules and extending classes... But... But one issue here: The performance overhead of a single JS block is bad*

    Every event block in an event sheet has some overhead behind the scenes. It really isn't bad, but a single blank event still has a cost. Looping a blank event duplicates its cost. A "custom Action" has a cost around 3x that of a blank event and a "function" can be around 4-7x slower than the base. A loop in construct duplicates the overhead of events, which is why they take so much longer than no loop, even if they are acomplishing the same things. A js block in an event sheet takes around 300x longer to run than a blank event, which means if you are doing something simple like computing a dot product from a math module, it's going to be slower by a lot than simply doing it in events.

    So... if performance is an issue, now you CANNOT put js blocks into any sort of event sheet loop and you also have to make sure that what you are accomplishing with that Js block more than justifies its incredible overhead.

    Now, js blocks can eliminate the need for loops by looping themselves, which is WAY faster than an event sheet loop, but now you are losing any potential to do things through events. Basically, you can create JS systems, and so long as you minimise the number of js blocks that are needed to interact with those systems, you are golden.

    ---

    At the end, this is why I prefer authoring behaviors for some types of problems. they take longer to make, but if I need to constantly interact with them through the event sheet, they make sense from a performance perspective.

    As an example, I do alot of vector math in my game, so I created a behavior that has alot of vector utilities, along side an arbitrary number of vectors a user can add to an object. Another example would be a property whose state I need to monitor and control how it is accessed and modified. This is painful to create with events every time you need it, so I made a behavior to handle the boilerplate.

    In both cases, using a JS module and calling it from a JS block would make my game unplayable, while using behaviors I can still have 100s of entities/characters.

    ---

    For my bias: I believe if you are doing too much scripting, then you may as well pick a different engine. I make behaviors because the initial investment pays dividends in the event sheet and in scalability, but authoring them is incredibly slow compared to the equivalent in unity. If you are straight up coding the game purely through js, I would ask why bother with construct at that point at all.

    Almost every other game engine I have used has a much better workflow where coding is concerned. They have better, bigger, more elegant APIs, and offer more power and flexibility. Its also fair to note, I started with construct, so I should be biased towards it - and it was PAINFUL moving to unity, but once I learned it, it was better in a number of departments. I am choosing to make my current game in construct because I believe that given the my current projects lower complexity, construct will offer a shorter dev cycle than unity will, and I like the fast editor iteration times. I used c2 until about 2016, when I made the switch fully to unity. This is the first year back with c3, but I have always used construct as a prototyping tool.

    Fingers crossed, because I am using the internal, private api, but I think I can get a game out faster here than in unity.

  • I see someone likes scripting :D

    I routinely pack events out into behaviors wherever I can. I still like the flexibility of interacting with event sheets, and jsblocks are always sooo verbose.

  • Hey all,

    I think I know there is not a property for effects that can be used to load an image, but I was curious if there would be a way to load a texture in an effect from a file at runtime?

    Put simply, I'm authoring a color LUT effect.

    I also have other effects that I need to be able to reference images from, but they need not to be hardcoded, and must be user set. (think about lens dirt on a bloom effect).

    For the color LookUpTable, I used to simply set the effect to a sprite, and the sprite WAS the lookuptable. The issue with that is it will only work on a per "layer" basis, and not a per object basis for things like palette swapping.

  • Ashley

    Question 1:

    In light of what you have clarified,

    Can we find a solution? Do you want to support 3rd party development?

    Would it be possible to set up a way for folks to more easily get access to an expanded api? It's very difficult to be actively developing a game if you have to stop to go drum up popular support, pitch a suggestion that may or may not be responded to, then still have no idea if it will be made, as there is no road map!

    That is exactly a recipe for dev-hell.

    Question 2:

    If an official behavior uses an api call, why is it so hard to make those public and document them? Again, you needn't promise eternal stability, just a way to get the job done, and a promise for an alternative if the api changes. Which is why I mentioned perhaps a "experimental /dev" api in a previous post.

    Issue:

    You keep saying that you are pretty sure most things are possible without engine hacks, but you neither address the specific problems or describe the alternatives. You also have no projects or templates showcasing these scalable and well designed alternatives. As you say, using a private api is bad for a number of reasons, but If the alternative involves poor programing patterns, it isn't an alternative.

    In the specific case of creating a platformer like behavior...

    You told me you don't want anyone "duplicating" the platformer behavior (or any others for that matter). That statement alone indicates a certain level of arrogance... which leads to question 3.

    Question 3:

    Do actually believe that behavior alone addresses all needs within the genre in a scalable, and sensible way? Not only that behavior, but any of them?

    It's an objective fact that you can't possibly anticipate every need any game would ever have, which is why you need a robust way for users to extend construct's features. That is what this whole discussion is about.

    We want to be able to make OUR games, not yours!

    . C3 is supposed to be a gameenegine, not a prebuilt car package where all we do is change paint color.

    I don't want to duplicate your platform code. I want to make my own, because mine is better (for me)! The official one is fine, for those who can use it, and I use it all the time for prototypes, but never finished products. That isn't feature duplication, it is a wholly different behavior that is functionally different at all levels.

  • Also, sometimes using the internal api is as simple as:

    C3.MakeFilledArray

    Because why would I redefine that functionality when every official behavior is also using it.

    Option B in that case, is do more work and I'd prefer to do no extra work, unless I have to, ergo internal api call it is until it breaks.

Ruskul's avatar

Ruskul

Member since 23 Nov, 2013

Twitter
Ruskul has 2 followers

Trophy Case

  • 11-Year Club
  • Forum Contributor Made 100 posts in the forums
  • Forum Patron Made 500 posts in the forums
  • x6
    Coach One of your tutorials has over 1,000 readers
  • Educator One of your tutorials has over 10,000 readers
  • Regular Visitor Visited Construct.net 7 days in a row
  • RTFM Read the fabulous manual
  • Email Verified

Progress

18/44
How to earn trophies