Closed ca3games closed 5 years ago
Keeping in mind that I've never tried to implement a input buffer before myself, and therefore wouldn't know if it entails anything else: Perhaps the engine could keep track of the last time each action in the input map was activated/deactivated, using something like OS.get_ticks_msec
? Then you could call something like Input.is_action_recently_pressed("some_action_name", time_in_seconds)
(returns true if the action has been pressed within that time) or Input.get_action_last_press("some_action_name")
(returns a float representing the amount of time since the action was last pressed). I wonder if something like this could be an acceptable solution?
Since a majority of games won't need this, this can likely be provided as an asset on the Asset Library :slightly_smiling_face:
@Calinou How can you dismiss this proposal right away with the assessment that the "majority of games" (whatever this means), won't need this feature before anyone making games had the time to express their need here?
Input buffers would be useful for a variety of already existing genres (OP named a few: cheat code, fighting games, metroidvanias, action rpgs.) but would also allow to easily test and come up with new game mechanics and concepts, would be fantastic as one line solution for rhythm games and quicktime events as well for debugging.
@golddotasksquestions because "proposal for it to be core" means that feature would have to be ALWAYS present in the engine, and because of this, maintained FOREVER by core devs, while only a handful of projects will actually use it. I say "handful" and "will" because it looks like that feature wasn't requested for years. It would have been if it was an actual common need rather than "a cool thing to have". Also that feature is easy to figure out and implement as an addon to help people less proficient at coding, so... that's why an addon makes sense. It doesn't mean it shouldnt be available in Godot, it means it should be available as an option.
Since a majority of games won't need this, this can likely be provided as an asset on the Asset Library slightly_smiling_face
I already mentioned a few cases where this may become handy, like a konami cheat code, fighting games, DMC clones, rythm games, smash clones, metroidvanias, action rpgs. Even FPS could use an input command for things like dash or cover. It's a very handy feature to add. Even GTA had some kind of cheat code.
@golddotasksquestions because "proposal for it to be core" means that feature would have to be ALWAYS present in the engine, and because of this, maintained FOREVER by core devs, while only a handful of projects will actually use it. I say "handful" and "will" because it looks like that feature wasn't requested for years. It would have been if it was an actual common need rather than "a cool thing to have". Also that feature is easy to figure out and implement as an addon to help people less proficient at coding, so... that's why an addon makes sense. It doesn't mean it shouldnt be available in Godot, it means it should be available as an option.
I don't think is that horrible complex feature to add, is mostly a circular buffer that receives input from the input class and can output an user made custom signal. Maybe as an aditional function of a class could be implemented, I kind of did it once for a game of mine in godot as a script, but I'm not the best coder, so it was kind of clumsy.
This can be done with timers and a dictionary/array to store the commands I believe? If done as an Addon, would be neat. With a nice API, etc.
I say "handful" and "will" because it looks like that feature wasn't requested for years.
What's the purpose of having a "proposal" repo if only proposals that have been made before the existence of this proposal repo are even considered for a discussion and everything else is immediately shut down as with the argument "noone has asked for this so far", "bloat", or casted to the asset libary (a jungle you only ever find something unless someone directly points you there)
If your goal is to stop people from making proposals to improve the engine, not the asset library, why have a proposal repo in the first place?
@golddotasksquestions proposals can be made with arguments which many other people can relate or have related in the past (and eventually will when seeing your post, as we answered it). It's part of what makes them solid (but not mandatory indeed). Also this is just one part of my explanation, you have to read it as a whole. I'm just trying to explain why @Calinou 's suggestion makes sense, not stopping people from proposing features.
It would have been if it was an actual common need rather than "a cool thing to have".
If you want to find out if there is common need to have it in core, you cannot dismiss it just a few hours after it has been posted. We all know Godot Github is frequented more often by contributors then is is by general users.
@golddotasksquestions
What's the purpose of having a "proposal" repo if only proposals that have been made before the existence of this proposal repo are even considered for a discussion
I think this is a bit of an over-exaggeration. They are just saying that there have been no previous Issues requesting the feature, so suggesting that something which can be implemented as a separate asset should instead go into the main repository is overkill.
everything else is immediately shut down as with the argument "noone has asked for this so far", "bloat"
And with good reason. Those are exactly the kinds of things that shouldn't go into the main engine repository.
I think the difference of opinion here is in what should be considered "bloat". While you are seeing, "this would be useful for a variety of games," the devs are seeing something that can easily be implemented with a script-based solution. The whole idea of having the proposals repo is to better filter OUT things that match that scenario (Edit: unless it is provably desired heavily by the community - more on that later).
casted to the asset libary (a jungle you only ever find something unless someone directly points you there)
This implies that we need to 1) improve the Asset Library's discoverability and/or 2) add support for other online asset vendors (#12). The solution is not to start porting things that we can easily host and develop separately all into the main engine repository.
If you want to find out if there is common need to have it in core, you cannot dismiss it just a few hours after it has been posted. We all know Godot Github is frequented more often by contributors then is is by general users.
The fact that engine change proposals are more heavily seen by contributors more so than general Godot users is a natural side effect of hosting the GIPs on GitHub. That won't be changing anytime soon (probably), so if people want more public feedback on their idea, that's what sharing the proposal on social media is for. I would invite OP to do that.
What is more practical would be implementing this as a separate plugin first (since that can be done easily enough) and then, if enough people are interested in and using that plugin, then it's a safe bet that people would appreciate having it merged into the engine. It's the same kind of thing that I'm going to have to do for #13.
Make a proof of concept. Prove the people want it. Get a preliminary implementation up and running. When it's clear that it would be useful as an integrated thing, then submit a PR. Converting script code to engine code isn't all that hard, so no biggie.
Prove the people want it.
I won't rally for a race of "who clicks that thumbs button first before the proposal is dismissed". If people want this feature in core, eventually more people will thumb it up. If not, then it simply won't happen. The only thing sure is that you won't get a meaningful result within a few hours of submitting a proposal because you don't have regular users eyeballing the proposal list every day. Immediately dismissing it counters the fundamental idea of a repo called "proposals". If we also had an official "ideas" repo, then this discussion could be moved there, but we don't.
When it's clear that it would be useful as an integrated thing, then submit a PR. Converting script code to engine code isn't all that hard, so no biggie.
You know very well that I'm not capable of doing that (yet). OP is in the same boat.
I won't rally for a race of "who clicks that thumbs button first before the proposal is dismissed". If people want this feature in core, eventually more people will thumb it up. If not, then it simply won't happen. The only thing sure is that you won't get a meaningful result within a few hours of submitting a proposal because you don't have regular users eyeballing the proposal list every day.
And having a many proposals in exactly this style is something they want to avoid here (which you also acknowledge with the "ideas" suggestion). Too many "maybe someday people will want this" Issues sitting around clutters the space reprehensibly, so yeah, they shut them down if they aren't clearly defined, imminently useful things with a demonstrable use case.
If we also had an official "ideas" repo, then this discussion could be moved there, but we don't.
I agree that we need a place for things like this. My suggestion in #47 for things that involve clearly useful assets/addons/plugins/modules/templates/projects would cover this case. Rather than re-iterating the same old arguments here as we do there though, we should simply refer to this case in that Issue and move along; simply close this as a "should be a separate addon" is good for now. It can be re-opened and migrated later on. Maybe @Xrayez can convert it into a tracker that starts cataloging all of the Proposal Issues to which it could reasonably apply.
Regardless of whether an open Issue exists somewhere for it, the status in practical terms for "when should this be merged into the engine" doesn't change. If someone builds it separately and it becomes popular, i.e. people star / download the addon a lot, then that will be evidence we can point to when suggesting that it be integrated into the engine in a formal Proposal. Until then, there is no proof of its public viability that warrants full-time maintenance by the core team, ergo, the Proposal should be closed.
You know very well that I'm not capable of doing that (yet). OP is in the same boat.
I was just saying that, once a formal implementation is done (which anyone who can write script code can do), migrating the code is quite easy. Any developer would be able to assist with that. I wasn't implying that you guys would have to necessarily.
Anyway, the godot-extended-libraries/godot-ideas
repo is still hanging around. @ca3games is free to transfer the Issue there if they want. There's nothing stopping us from using it and promoting the Issues on social media. Once Juan/Remi make a decision on #47, then we can see if those issues get moved to a different place in the godotengine organization or if they stay where they are. Either way, this is not the place to argue the case.
This is not a case of "if the idea is popular enough it will be merged". The reason this proposal will not be accepted is because there is no benefit to having this in core rather than providing it as a downloadable script.
The last question in the template is:
Is there a reason why this should be core and not an add-on in the asset library?:
Saying that it is too complicated for artists is not a reason to include it in core. That is just asking the core developers to code your game for you. Simple, reusable scripts like this belong on the asset library and/or in the community based godot-extended-libraries
(as willnationsdev, kindly pointed to).
Community interest is only a valid metric for proposals that meet the base criteria set out in the template.
This kinda illustrates my previous thoughts, there's a difference between a use case and a general-purpose proposal. One person is unlikely to provide many use cases (different game genres for instance), so he has to document it at least. Seeing this proposal being opened, I created another similar one #104 which I felt like is really related to this (otherwise I wouldn't create it in the first place tbh).
My point is that if enough use cases pile up for a particular problem, it can prove to be useful to be part of the core, not necessarily what the use case describe but to satisfy all those use cases to simplify implementing them via script/plugin/module etc.
@Xrayez
Well, #104 does things "correctly" where you have a valid use case, i.e. the separate system you describe when explaining the context, but the actual suggested change is scripting API updates and a new method in the Input class, i.e. things that can only be done with source code changes.
This proposal, on the other hand, has all of its necessary changes bundled into the "separate system". No part of it actually requires changes to the engine. Without any necessary engine changes, it has no purpose in being a "Proposal to Improve Godot"/"Godot Improvement Proposal." It fits better in godot-ideas
.
@willnationsdev Reading that is really confusing me as to what is allowed in this repo. If a proposal has to require changes to existing systems, then what's the point of ever suggesting new features or systems now? Don't new features or systems, by their very nature, bundle most/all of their changes into the separate system?
Or am I somehow misunderstanding this?
@LikeLakers2
Let's say I want to write some kind of script to do something. This is my "task".
If I can fully implement the task's features with script code, but I want the engine to come with my task pre-implemented and available, then I should NOT create a Proposal for adding that task's solution to the engine. It should go in a different repository that can be maintained independently and downloaded as a separate asset in the Asset Library.
If it is impossible to write the code purely with scripts, i.e. if you need to make engine/editor changes to write that script code the way you want to, then you can submit a proposal to make the necessary engine/editor changes while stating your task as the "use case"/problem you are attempting to solve.
So, for example, this Issue proposes that we introduce an input buffer into the engine. However, the code for this can be fully written in script code. It does not require any engine or editor changes to function. Having it in the engine would simply be a matter of convenience. New features as a matter of convenience, however, when they can be easily done with scripts instead of engine changes, are things the core devs want isolated to separate repositories and so should not clutter the proposal repository.
This results in less of a maintenance burden on the core team and improves the usability and power of Godot's scripting API for solving future problems.
Edit:
But then what's the point of ever suggesting new features now, if it has to require changes to other systems?
It's not that it requires changes to other systems. It's that you must have a problem that you could not already do yourself and then with the changes, you are then able to solve your problem. If you can already solve the problem on your own, then it belongs in an addon/plugin/module, not the engine repository.
Another good example is #103. I have a change to the engine/editor that I would like to make (an Instantiation Palette toolbar). However, I know that it may or may not be desired as an integrated part of the engine. It can be entirely written via script code already, so what I should do is write a plugin that adds the features to the editor.
However, as I'm thinking about how I might implement it, I realize that it has all these different performance limitations that will inhibit its responsiveness as the project's size grows. To avoid this, I came up with a list of engine/editor changes that would be required to improve its performance.
I didn't submit a proposal to add the toolbar to the editor (because even if Godot could really use it, it belongs in a separate plugin). I submitted a proposal to change things impossible for scripts that would enable my plugin to behave efficiently.
I've heard mixed things about whether "a highly successful, generic plugin that assists with game development on a large scale" can be considered for editor integration though. @clayjohn earlier said no. I've heard Remi say yes in the past. So on that point, I'm not 100% sure what the word is today.
I'm still confused, possibly even more so than before I read your comments.
If I can fully implement the task's features with script code, but I want the engine to come with my task pre-implemented and available, then I should NOT create a Proposal for adding that task's solution to the engine. It should go in a different repository that can be maintained independently and downloaded as a separate asset in the Asset Library.
If it is impossible to write the code purely with scripts, i.e. if you need to make engine/editor changes to write that script code the way you want to, then you can submit a proposal to make the necessary engine/editor changes while stating your task as the "use case"/problem you are attempting to solve.
[...]
It's not that it requires changes to other systems. It's that you must have a problem that you could not already do yourself and then with the changes, you are then able to solve your problem. If you can already solve the problem on your own, then it belongs in an addon/plugin/module, not the engine repository.
I don't understand the sense in this line of logic. Many (if not all) of the nodes (or perhaps even the SceneTree concept itself) already within the engine could be ripped out and put into GDScript with next to no penalty (besides a performance hit). Given the line of logic I'm seeing, that means they don't belong in the engine, as they could be made into assets, therefore they should.
For example, I want to draw text to the screen. You could tell me to use the Label control. Or I can use CanvasItem.draw_text
. Let's make a theoretical from this, and let's say the Label control doesn't already exist. I make a suggestion for such a Label node on this repo. From what I'm reading here, I would expect "You can draw text already using CanvasItem.draw_text
" or "This would be better suited as an asset on the asset library" as the response I'd get, as everything about the Label control can already be replicated in GDScript code without changes to the engine. Yet, because the Label node already exists in the core and is much easier to use than CanvasItem.draw_text
, it is widely used and is how we recommend people draw text to the screen. I don't understand how this line of logic holds up.
The same could be said about the Sprite node, being replicable with CanvasItem.draw_texture
. Or the MultiplayerAPI, using the PacketPeer class. We can implement a JSON parser ourselves in GDScript, with little more than a few String functions to back it up. Even the InputMap concept could be replicated using scripts. The only reason we still need them in the engine is because they're already widely used nodes... but they're widely used because they're in the engine... this feels like a big, convoluted Catch-22 to me. (not sure if there's any better term to describe this)
I've heard mixed things about whether "a highly successful, generic plugin that assists with game development on a large scale" can be considered for editor integration though. @clayjohn earlier said no. I've heard Remi say yes in the past. So on that point, I'm not 100% sure what the word is today.
This is one of the other issues I have with the whole "make it an asset" argument that I keep seeing on this repo: If I make an asset for something suggested here/elsewhere, I don't know if it'll be allowed in the engine later down the line (regardless of the asset being useful to people), specifically because it's already a publicly-available asset (despite that having been the original suggestion because it wasn't thought to be useful to the engine).
So I'd be very interested in hearing a concrete answer on this.
@LikeLakers2 it does sound like a Catch-22 (that's the right term). I think it is supposed to be somehow about balancing usability against the technical debt of core devs maintaining it. My guess is something along the lines of, "we like the current state of the core engine. Keep it where it is unless absolutely necessary." There are even plans to strip out things like InterpolatedCamera and VehicleBody, afaik, so that they will exist as assets (probably GDNative).
I too would love to hear more about how far down that particular rabbit hole goes.
@ca3games If you don't mind and since you have the code already, you can submit it to https://github.com/godot-extended-libraries/godot-next I think. Would be a very nice addition. Or, it could just be released as an addon perhaps.
No, yeah, that sounds like a good addition. If @ca3games submits a PR, I'll review it to see if I'd like any changes made before merging.
@LikeLakers2 The reason there's Label and Sprite node in the engine is that they provide much more functionality than simply using draw_string
or draw_texture
. The label.cpp code has over 700 lines of code and it's not something you can replicate easily. Also lots of Control nodes are used internally by the editor, so they need to be in core anyways. Also², I used Sprite in literally every of my (2D) projects, whereas what's proposed here I needed, like, twice and it took me just few lines to implement it.
So most of things in the core are integral parts of the engine or something used so extremely often that it makes it obvious that they should be there. There are some nodes that could qualify as add-on material, and they might be eventually moved there if the plan for official plugin library is realized (https://github.com/godotengine/godot/issues/19486).
@ca3games If you don't mind and since you have the code already, you can submit it to https://github.com/godot-extended-libraries/godot-next I think. Would be a very nice addition. Or, it could just be released as an addon perhaps.
No, yeah, that sounds like a good addition. If @ca3games submits a PR, I'll review it to see if I'd like any changes made before merging.
I have made a basic demo with my own implementation, but needs maybe a refactoring or better design. https://github.com/ca3games/Godot-fighter-demo Here's my implementation of said issue.
If anyone is willing to take a look at this issue, here's an example of an input buffer on the XNA old educational demoes. https://github.com/SimonDarksideJ/XNAGameStudio/wiki/Input-Sequence
So far my code has similar ideas, but is lacking a timer to clean the input after there's not input, and they also seem to use another trick, which is to merge inputs if they're too close.
@KoBeWi
The reason there's Label and Sprite node in the engine is that they provide much more functionality than simply using
draw_string
ordraw_texture
. The label.cpp code has over 700 lines of code and it's not something you can replicate easily.
I think you misunderstood the point. I understand it's not something you can replicate easily, and I understand those two nodes do much more than CanvasItem.draw_string
and CanvasItem.draw_texture
(Label does a good bit of math with the position, for example). The problem is that you can replicate them as assets for the Asset Library, even if it takes a lot of work. From the line of logic I was seeing from Will, the fact that they could be made as assets means that they should be made as assets, rather than be included in the engine.
We can both agree that removing the Sprite node, or Label node, or any of the Control nodes would be a bad idea, considering their widespread usage. But the problem I was seeing is that this line of logic never takes that into account, that it's a bad idea. It never considers whether it's a good idea or a bad idea for something to be made as an asset, compared to being in the engine. And if the logic can't hold up against the nodes already in the engine, then there's no reason we should be using it to determine which proposals get approved, since basically anything can be made with Godot's asset system... and since basically anything can be made as an asset, next to nothing will ever get approved under this line of logic.
(edit: removed the second part of this comment; I felt it might come off as rude, which wasn't my intention, and I couldn't really find a better way to word it)
I think what makes more sense in what @willnationsdev says, is not really that they "can" be replicated at all (this argument alone doesnt hold), but more that they require a lot of work for a frequent use. Some things really can't be replicated (like access to an OpenGL feature) but you can't say that of all features. But the way to measure these things is relative: less proficient coders find it hard, other coders find it easy. It's an ever-going battle, finding the right balance can't content everyone :p
is not really that they "can" be replicated at all (this argument alone doesnt hold), but more that they require a lot of work for a frequent use.
This argument is also very hard to follow since the core code is filled to the brim with methods that are just shorthand for a few lines of code or less: Take myarray.pop_back()
, myarray.push_back()
, myarray.front()
, myvector.angle()
, myvector.length()
just to name a few.
Correct me if I'm wrong, myvector.length()
is the same as sqrt(pow(abs(myvector.y),2) + pow(abs(myvector.x),2))
, is it not?
Even worse, myarray.front()
is to my understanding even exactly the same as myarray[0]
, no?
Don't get me wrong, I love choice and I love readable code. I like to have and use those examples.
But in the light of the above, how can a request to add an actually valuable method to the Input class (like: Array set_input_buffer ( int buffer_length, bool include_time_between_inputs=false, bool include_mousemotion=false )
, Array get_input_buffer ( )
)
be considered immediate bloat to the core without even giving folks adequate time to express their need. Was myvector.length()
not included to the core for exactly the same reasons OP has requested an input buffer? To make life easier, to get projects done faster and more readable and Godot more accessible for people who are less proficient in the technicalities of coding.
This sucks.
cc-ing @reduz and @akien-mga so that they are aware that more #10 -like discussion is happening in this Issue too. Slightly different arguments being put forth though, by @LikeLakers2.
One thing that should be brought up is the importance and widespread usage of input buffers in video games. Input buffers exist in a majority of all video games that exist; they reduce the frustration of inputting repetitive actions and allow for combination actions that don't necessitate frame perfect inputs. Given time I could produce a list of every video game that isn't a fighting game that has an input buffer, and the list would be so massive that it would eclipse the total text of the entire rest of this thread. Not having an input buffer of some kind nearly guarantees a game that isn't enjoyable to control, unless that game is immensely simplistic.
I bring this up to this topic because at the current moment, people are arguing that this wouldn't be used enough to necessitate its existence. I don't think that's a fair statement, as most people who wouldn't implement an input buffer into their game are making that decision because of a lack of understanding of how important having one is.
One thing that should be brought up is the importance and widespread usage of input buffers in video games. Input buffers exist in a majority of all video games that exist; they reduce the frustration of inputting repetitive actions and allow for combination actions that don't necessitate frame perfect inputs. Given time I could produce a list of every video game that isn't a fighting game that has an input buffer, and the list would be so massive that it would eclipse the total text of the entire rest of this thread. Not having an input buffer of some kind nearly guarantees a game that isn't enjoyable to control, unless that game is immensely simplistic.
I bring this up to this topic because at the current moment, people are arguing that this wouldn't be used enough to necessitate its existence. I don't think that's a fair statement, as most people who wouldn't implement an input buffer into their game are making that decision because of a lack of understanding of how important having one is.
It's already possible to do in Godot.. I don't know what you mean by "to necessitate its existence"
I think it's whether this is added to the core, or used as an addon. I think the lead devs will lean towards the latter
@AmericanTrailMix Can you give a few concrete exmaples?
To tack onto Calinou's request, I would be interested to know what other game engines provide in the way of an input buffer, or if they just provide the tools for a user to make one of their own the way we do.
Does any other game engine have an input buffer built-in?
Given time I could produce a list of every video game that isn't a fighting game that has an input buffer, and the list would be so massive that it would eclipse the total text of the entire rest of this thread. Not having an input buffer of some kind nearly guarantees a game that isn't enjoyable to control, unless that game is immensely simplistic.
You don't need to list them all, but naming a few would help your point.
I think this is fine as an addon. There are many ways to do input buffering and settling in one for the engine doesn't seem helpful. There might be people who needs the feature but can't use the built-in because it will be tied to a specific way of use. We could add something that it's needed to improve implementing the buffer in scripting (akin to what #104 is asking), but not simply adding the whole feature.
Thinking it of an addon should not be seen as a bad thing. Sure, we may need to improve the asset lib, but that doesn't mean we should put everything in the engine before doing so.
Very well said @vnen 👍
Thinking it of an addon should not be seen as a bad thing. Sure, we may need to improve the asset lib, but that doesn't mean we should put everything in the engine before doing so.
@vnen I think you misunderstood why there's this big debate over addons here. We're not complaining about addons being a bad thing, and we're not complaining about someone saying "I think this would be better as an addon". We're complaining about how the "this should be an addon" response is (in our view) being abused. It seems like it's being used to stifle discussion rather than encourage it, seeing as how it's being thrown out into the comments before there's any chance of discussion. We don't like it, and we're complaining in hopes that we can get that changed.
There might be people who needs the feature but can't use the built-in because it will be tied to a specific way of use.
I'd be inclined to accept this point, if it wasn't for the fact that we really haven't even discussed how we might implement it yet (barring a couple suggestions, but those were meant as examples). If you feel that way about the implementations that have been suggested, then I understand, but please say that it's in reference to suggested implementations then. But we can't just say "it'll be tied to a specific way of use" until we know how we want to implement it. Currently? We have no idea, we haven't even gotten past the stage of determining whether we want it, so how can we tell if an implementation will be focused towards one genre or the other, or one game or the other, or what-not?
There might be people who needs the feature but can't use the built-in because it will be tied to a specific way of use.
I'd be inclined to accept this point,
I'm less inclined to accept this point. Following this logic, any built in feature ties the user to a specific way of use. To my understanding, one purpose of these GIP discussion is in fact to draw, as good as we can, a complete picture of all it's possible usecases, and if possible, implement the feature in a way that allows it's application in those usecases. If we did miss an application in our discussions, users can still submit further GIP suggestions to improve it after it has been implemented
I ask you all to understand that everyone has opinions. If someone come to a proposal and say "this can be an addon", it's just that person's opinion. It's not "dismissing every proposal", it's just a particular feedback. If the feedback that follows from other comments justifies the proposal and makes it accepted, that one particular comment will be just a data point and won't stop the feature being implemented. Nobody is taking a final decision on the first comment.
I feel that, in fact, you are taking "this should be an addon" as a bad thing, while it's just one opinion. It's not stopping the discussion, and it's not meant to. If you think that the opinion is not valid, all you need to do is provide a counter-argument. If we don't allow opinions against the proposal, will any proposal be ever rejected? We also can't just accept a proposal because of one valid use case (that's the point of this repo, so other people can chime in and increase the use cases.
The same applies to "this won't be used in many games". It's an opinion, a guess. If you disagree you can express your opinion too.
For instance, the OP's implementation description is:
Basically a circular list that reads the inputs and output a signal if a certain movement is input.
Honestly I don't think it's just that. You need to configure at least the size of the buffer and the allowed time between inputs. How do you read that buffer to compare with a game-specific combo? Will the engine provide a compare()
function that takes a list of input events and compare with the buffer? Will you have to read the buffer and match accordingly? Will it register only InputMap actions or any InputEvent (which means that moving the mouse may break a combo)? How does moving an analog joystick register the input (in every poll or only when changing a major cardinal direction)?
You might think any of this questions have obvious answers, but it really depends how you intend to use it, and different games have different needs.
But we can't just say "it'll be tied to a specific way of use" until we know how we want to implement it. Currently? We have no idea, we haven't even gotten past the stage of determining whether we want it, so how can we tell if an implementation will be focused towards one genre or the other, or one game or the other, or what-not?
The way it's implemented is also a criteria to decide whether we want it or not. If the feature meets the standard for merging but the proposed implementation is convoluted with a complex API, we may refrain to merge it until a better implementation is proposed.
The same way, if an implementation proposed is fleshed out to be simple and very useful, we might consider accepting even if it's not strong on other points.
I posted my thoughts on the complications of a general implementation in the last comment.
How do you read that buffer to compare with a game-specific combo? Will the engine provide a compare() function that takes a list of input events and compare with the buffer? Will you have to read the buffer and match accordingly? Will it register only InputMap actions or any InputEvent (which means that moving the mouse may break a combo)? How does moving an analog joystick register the input (in every poll or only when changing a major cardinal direction)?
My ideal Input buffer would have a physics_process and process mode (records every physics tick vs records every drawn frame). It would record the duration(or frame in case of _process mode) for each input as well as the duration of a lack of input. So if I keep pressing a button, key or keep holding the joyaxis vector in one vector direction, a millisecond counter goes up, same as if I press nothing at all. Since multiple inputs can happen at the same time, each input would have to have it's own "thread". (Think instruments in a DAW)
The user can add buttons to record and set a buffer_length like so:
Input_Buffer.inputs(ARROW_UP, ARROW_DOWN, KEY_ENTER, KEY_9, "right", ...)
#any string like "right" is the GlobalScope looked up from the Input map.
Input_Buffer.set_buffer_length(1500)
#in milliseconds
Input_Buffer.start()
#able to start and stop recording inputs any time.
To compare, the user queries if certain inputs happened for a period of time at specific timestaps in the input_buffer:
if Input_Buffer.has(specialmove_dic):
do my thing
For joystick movement and mouse movement, you define a timestamp, vector2 and a circular radius in which the comparing vector is still valid.
Input map actions would auto translate to GlobalScope according to my definitions in the Input map: So I write cheatcode = {20: [["up", 50]], 100: [["down", 50]], 170: [["down", 50], ["B", 50]}
Also my ideal Input_Buffer could be printed to output so I don't need to write all my cheatcode and special move timings by hand, but rather just do them while the Input Buffer is "recording" them, print them out, and copy/paste them into my code for comparison. <- resulting in lightning fast balancing with guaranteed tight game controls and extremely user friendly UX while developing.
In addition, you would also want to be able to somehow specify a sensitivity level for vector direction subdivisions on joypad axes OR explicitly register certain axis ranges as belonging to the same "input." Something of that sort.
In addition, you would also want to be able to somehow specify a sensitivity level for vector direction subdivisions on joypad axes OR explicitly register certain axis ranges as belonging to the same "input." Something of that sort.
This is exactly what this would archive, no?
For joystick movement and mouse movement, you define a timestamp, vector2 and a circular radius in which the comparing vector is still valid.
@vnen
I ask you all to understand that everyone has opinions. If someone come to a proposal and say "this can be an addon", it's just that person's opinion.
[trimming everything else in-between; see here for full comment]
The same applies to "this won't be used in many games". It's an opinion, a guess. If you disagree you can express your opinion too.
I find this hard to follow.
Most opinions are worded to ensure they come off as opinions. Sometimes, this is simple, using "I think" or "I feel" to express that it's just an opinion. Other times, it's a little more complicated, but not impossible. The examples you gave do not try to explain in any way that they are opinions (not even an "I think"), so I find it hard to understand that these could so easily come off as opinions.
But even then, even if I try to assume that they are opinions even in the face of that, I find that hard to do. What makes it hard is, if they were really opinions, I would expect more thought put into the message than a simple "I don't think this will be used in many games", more elaboration than a simple summary. Right now, it feels less like an opinion and more of a statement of decision.
But even if I took it as opinion now, I'm not sure that would matter. Right now, the current wording seems a lot like a statement of decision, and I'm concerned that people reading through the issue for the first time will see that sort of thing, and think that a decision has already been made (even though you've said otherwise in your comment). They might decide not to bother reading the rest of the discussion (which would let them find out that it was just an opinion), which in turn means that they won't know they can still insert their own opinion or desire for this feature.
But then, even if they did recognize it as an opinion, I don't really think it would help matters. I don't know if you or the other team members realize this, but comments coming from those perceived as higher-ups are going to be taken differently compared to comments coming from people who aren't higher-ups (like me), even under the exact same wording.
For example, if I were to say "I don't think this fits in the engine", chances are my comment would come off as one opinion in a million (figuratively speaking). On my end, it's clearly an opinion. However, if you or another team member were to say the same thing, people are going to take that in a different manner, sometimes in a much different manner. Coming from you or another team member, it holds a lot more value, a lot more weight on the discussion, as the general understanding of someone being on a team is that they know a heck of a lot more about what fits in that team's project, compared to someone who isn't.
Thus, those sorts of comments could end up becoming barriers to overcome (if they can even be overcome at all). Now we've got to "appease the gods", if you will -- we've got to show them why their concern is not a concern at all. (see footnote) That's easier said than done... especially with people who simply want to show their support, they may not feel capable of doing so. I fear this could easily drive away comments, discussion, etc.... rather than trying to get it to flourish like the Godot team seems to want.
I'm sorry, but I really find "they're just opinions" hard to believe; and even if I were to believe it, I find it hard to understand why it's being used as a justification given the various implications that those statements hold.
(footnote: This is hard to do when the statement in question is true in some form. For example, "This could be an addon" is technically true because nearly anything could be an addon, with how extensive the addon system is... so how do we show that this shouldn't be an addon? This is also hard when the statement in question is something like "this won't be used in many games" -- how do we show that it will be used in many games? And so on.)
(Also, I'm hoping my initial suggestion could perhaps get some feedback, since we seem to be talking about suggestions now.)
Sooo, another purpose of this repository was that you share the proposals, so they can get support from community. And if they get a lot of support, they are more likely to be in engine, even if they were "better for asset library". Meantime this proposal has 3 upvotes, while the post saying it's better as external asset has 10 upvotes.
Of course there's the concern that not everyone has GitHub account, but you could e.g. create a topic on Reddit or whatever platform and then link it here, so if the linked topic gets support, it wouldn't be less important than GitHub upvotes. At least that's how I'd see it.
Now, to not derail this topic even more, I'm really confused by @AmericanTrailMix 's comment. It sounds almost like input buffers are the most important thing ever and every game needs this. Unless I'm misunderstanding something, I needed this functionality literally twice - one was fighting game (surprising) and the other was a rogue-like with combos. Out of over 15 bigger and smaller projects. You don't need this in platformers, RTS games, FPS games, jRPG games, racing games and probably other genres. And I doubt these games are "immensely simplistic". But it might be possible I don't understand what we are talking about here. I'd really like to see that huge list of games using input buffers, along with their use cases ;)
btw, @LikeLakers2 's idea is a dozen lines of code. Having this in core wouldn't hurt even if it's not "used widely". And it makes implementing combos easier.
@LikeLakers2 Fully agree with your concerns.
As for your initial suggestion, I would find it quite problematic to work with. When designing button combinations for game mechanics, you want precise control about the timing and the duration of button presses as well as how tight the margins or error are supposed to be. I'm not sure how you imagine balancing and iteration would practically work with your approach. (maybe you want to elaborate more)
This is quite complicated, because action games and fighting games require very precise control and a lot of balancing. Those button combinations have to be iterated over a lot throughout production. For that reason iteration would also have to be as straight forward as possible without compromising the power and versatility of it's application.
How would I for instance check if "left" pressed for 2 seconds, while neither "A" or "B" has been pressed, "downleft", "down", "right" each for 100 milliseconds and then "A" for 200ms? with maximum of 50 ms in between all presses? What if I want to change the timing of those presses or the pauses in between, or try of another combination? Changes like that happen throughout production a quadrillion times. My proposed solution above would allow all that to happen easily for the user.
@golddotasksquestions My proposal is not intending to implement a full input buffer as you seem to want. Rather, it is meant to build a foundation for other concepts (such as a timer or an array) to be layered onto it to achieve exactly what you want, just as I believe many things within Godot are built to do.
My proposal alone would solve simple problems on its own -- for example, if the player presses the jump button again, but we haven't fully touched the ground yet. We might use Input.is_action_recently_pressed("jump", 0.2)
(or something similar) when we hit the ground to detect such a situation, and initiate our jump once more.
However, it cannot (and should not) solve problems like the one you propose, at least not on its own. In those cases, you'll want to layer other things on top of it to achieve something like what you want.
For example, to implement a solution to your problem, I would think to use my proposal, an array, and a timer. To explain what I mean:
I hope this makes my proposal clearer.
Also, if it's desired by a few people here, I might make a more in-depth version of my proposal, with all the implementation details and functions that I would think to expect from it. So far, I've only given the general idea, and not an actual full implementation.
In this proposal: https://github.com/godotengine/godot-proposals/issues/100#issuecomment-538105674
Is this system flexible to implement a system where each input is saved to a animation player animation keyframe for a movement recording demo?
@LikeLakers2 I don't see how this would be much of any help. You can already do all that with practically the same amount of effort by using existing API of Input class and Timers. Implementing a proper input buffer and not just a gimmick would still be a lot of work. A gimmick array input buffer is written in 2 seconds with existing Godot features. What this proposal asked for, as far as I understood, is an actually useful input buffer that could be used right away. The benefit of having an actual input buffer included in Godot would be that users can focus on making games, not reinventing the wheel. The solution I proposed would still be flexible enough to cover any simple or complex usecase (at least any I could think while thinking about this for a long time) while also just work right out of the box.
@fire the first snippet in #104 is actually part of an experimental InputPlayer
I've written, each event is bound to frame, comprising a key. The way it's illustrated in https://github.com/godotengine/godot-proposals/issues/100#issuecomment-537308119 is very reminiscent to animation player with tracks indeed, this is why I linked my proposal as well.
@fire Assuming you're talking to me:
If you're asking if my input buffer proposal alone could do such a thing... no, not unless you only plan on recording each action once.
However, I'm not sure why an input buffer would be needed to do such a thing. If you plan to make a input recorder for something like a demo, wouldn't you implement such a thing by listening for (and recording) press and release events using _input(event)
?
@golddotasksquestions
I don't see how this would be much of any help. You can already do all that with practically the same amount of effort by using existing API of Input class and Timers.
I'm not sure I understand. Indeed, mine could be implemented using the existing Input API, but I already explained that the vast majority of the engine's nodes (and even some concepts) could also be re-implemented into GDScript with little to no loss in functionality. It doesn't make it a good idea to actually do that, mind you, but the point remains that it is still possible. Thus, I don't understand why we would arbitrarily apply this sort of logic to my proposal and not the rest of the engine.
On that note, I wish to point out that this same line of logic could also be said about your own proposal. Indeed, if your proposal were made in GDScript, would it not use the Input system to detect inputs? Thus, if my proposal is invalid because it could be implemented using existing APIs, then I refuse to believe that your proposal is a valid proposal either, as yours could be implemented using existing APIs too.
Implementing a proper input buffer and not just a gimmick would still be a lot of work. A gimmick array input buffer is written in 2 seconds with existing Godot features.
If I'm to understand that my solution to your proposed problem is a gimmick, I'm not sure what to tell you. You asked me for a solution as to how my proposal could do that, and I gave you one. Maybe it doesn't cover every use case you had in mind? Or maybe I missed something and confused you? What is it that makes this inferior to your solution?
You say it's because it was written in two seconds with existing Godot features. If that's the case, then I have two contentions with that:
Much of Godot builds upon itself, using existing concepts, nodes, etc. to build new ones, then using those to build new ones on top of that. Wouldn't this qualify as "using existing Godot features", in much the same way that my proposal builds upon the existing Input API to provide new functionality?
Saying something was built in "2 seconds" is, bluntly, pretty insulting to the work put into it. It completely ignores the thought and effort put into thinking up that idea. I'll admit that it didn't take me too long to think up combining my proposal, an array and a timer (maybe half an hour at best, with the rest dedicated to figuring out how to word the solution I gave)... but it's still pretty insulting to feel that you've taken my idea and thrown it out the window like it's nothing, rather than try to work with it and see if we can't fix the idea.
What this proposal asked for, as far as I understood, is an actually useful input buffer that could be used right away. The benefit of having an actual input buffer included in Godot would be that users can focus on making games, not reinventing the wheel. The solution I proposed would still be flexible enough to cover any simple or complex usecase (at least any I could think while thinking about this for a long time) while also just work right out of the box.
Believe me, I'd love just as much as you to give people a full complete package full of everything they could ever possibly want. But it's just not possible, not without careful planning.
My proposal was meant to cover the general area of input buffers -- so that if something more complex is needed, combining my proposal with other systems would usually be enough for all but the most most complex of use-cases. I don't find it worth my time to consider whether my proposal will work with those extreme use-cases -- rather, I would like to cross those bridges when we get there, if there is no other better way about it.
I apologize if that means my proposal isn't useful to you. Maybe my idea could be improved upon? You could tell me what's missing, or maybe you could explain what you'd change, or you could give me problems to solve that you think aren't covered by my current proposal. I appreciate that sort of feedback, and that's why I asked for it.
@LikeLakers2 This is a misunderstanding, I completely agree with you. I'm really sorry that you feel insulted, this is really the opposite of my intentions. My point was not that it could be done with gdscript and existing API (I'm on the same page with you on that matter), but that I am under the impression it would take nearly the same effort to use your proposed solution or use existing API to get to an Input buffer that would be more than a gimmick (of real practical use for various gamedesign).
I can already write a simple input buffer to an array any time using Input class and Timer, but it would be of little use. What I would like to discuss here is a solution that would be of immediate use. Those are way more complicated as I tried to illustrate above. At the same time the API should be very intuitive and their use flexible for any possible application. I believe the UX I proposed above would archive that. But I don't know anything about implementation, so I stay out of that discussion. I only know what I would need from a UX perspective to have a practical value from this feature as a game designer and Godot user. I did not feel like your proposal would give me that because actually implementing a useable Input Buffer would be nearly as much work as using todays tools.
I'm really sorry for not being more clear earlier.
Describe the project you are working on: A 2D remake of a NES fighting game.
Describe how this feature / enhancement will help your project: It would make my life easier, implementing an input buffer for my game.
Show a mock up screenshots/video or a flow diagram explaining how your proposal will work: A 2D fighting game input buffer.
Describe implementation detail for your proposal (in code), if possible: Basically a circular list that reads the inputs and output a signal if a certain movement is input.
If this enhancement will not be used often, can it be worked around with a few lines of script?: Sure, but making a good input buffer is not a trivial solution, my code while it works, is buggy and I think having a basic Input buffer supported by the engine would be good for action games, maybe devs who want a cheat code, fighting games, metroidvanias, action rpgs, etc.
Is there a reason why this should be core and not an add-on in the asset library?: Is not such a trivial solution, specialy for guys who may be more on the art side than programming side, like me.