Input of a Rhythm Game - c#

So, Unity does not do a lot of rhythm games on android. I decided to find out why, and program one as assignment (the basics of it anyway). My most important hurdle is user input. As we know that input is based on frame rate in unity, and a music game (i assume) would prefer the smallest possible delay between button press and action.
If we look at music, at around 15 to 20ms of delay, the human ear hears something is "off beat".
I heard Android Unity games run at 30FPS (since 60FPS sucks the battery dry), simple math indicates: 1000/30 = 33ms per frame. Calculating in the 15ms we can probably not notice, we are at 18ms of possible disaster. assuming we always reach this 30FPS at any given moment.
When i get input from a user, i can play a sound on that input on the exact same frame. However, we could be 18ms off.
Now there is a way to get DIRECT controls from mouse and keyboard, which uses OnGui() instead of Update(), to get events of the keyboard or mouse clicks on the spot. The problem is, android probably doesn't work with this, (this doesn't work for gamepads either) and the methods sounds downright strange, especially when we try to play sounds from the OnGui() method.
My question:
What would you do, and why? Should we just accept the possible 18ms off, and assume we reach the 30FPS, or should we look for a reliable way to get input directly, instead of waiting for an update to come by?
Thanks for any insight you can give me, i have not found any articles on this that are useful just yet.
-Smiley
EDIT
I just did some basic testing with a metronome, running at 100FPS in the editor (which should be 10ms per frame) tapping my spacebar on a metronome inside unity. The results i got were just horrible.
Tapping rapidly: I get as close as 20ms to my metronome tick, but nothing closer.
Tapping on the beat: I got at least 200ms off my target tick. Unless i am confused with this rhythm, this is just wrong.
Currently i use Debug.Log to get my test data to the log. Can anyone please confirm for me if this may be the cause (causes some long delay? i know debug isn't that optimized), or is the timing actually that bad on it?
Thanks in advance,
-Smiley

First, I'd like to add a few things to your comments and analysis:
There is a hell of a lot more to measuring the latency between the tactile input and what your eyes perceive.
Probably the biggest one I'm seeing missing in your tests is the latency between the graphics card and the PC monitor you're testing on. Many common LCD monitors these days have a latency of between 15-30ms in processing lag. I don't know how much this relates to mobile screens and hardware, but I would suggest you take the time to perform additional tests on your target hardware before drawing further conclusions.
To more directly answer your question:
I would continue to use Unity however I would continue to research the best methods of taking the input and feeding it back to the player as fast as possible. In the above comments #rutter has pointed you to what appears to be a pretty good thread on the issue.
Of specific note I would look at using FixedUpdate() to decouple the framerate of the game from the input processing speed.
I think it is also worth putting time into researching the psychology of the perception of latency. For example, if your game is a sort of Guitar Hero game of matching the playing song, you could simply take into account the lag you know is there and in your game logic take that into account when checking input.

I think you are over-complicating this, and that the accuracy issue is no where near as bad as you think.
People usually hit the buttons a little early in order to sync what they are seeing and hearing.
It also depends alot on if you have some kind of scrolling display that they are trying to match up to... if the display is scrolling smoothly at 30fps (without big jumps) they they are still able to make their timing presses fairly accurate.
I would surmise that although people can hear when their timing is off, their actual timing of hitting the buttons at exactly the right time is not that accurate anyway.
Here is one other simple solution... which I think is what rock band and guitar hero often do...
You start playing the note/sound at the correct time anyway.... then change it to a broken sound if you detect they missed it or goofed up.

Related

FPS drop after few minutes in the Android game

I have made a very simple hypercasual game everything works fine but after some few minutes of gameplay, the fps goes from 60 to 50 even the phone gets heated up. Similar to this question. I tried profiling but just can't see anything off. Tried even removing some UI elements but still no luck. Tried various vsync settings. Also, I had used this to display the fps. Even without it, the lag can be seen. Even if I just open the game and do nothing then after 5 minutes the fps will become 50. If go back using the home button and re-enter the game then the fps becomes 60 again. Using unity 2018.2.6f1. Never experienced this behavior in my other Android games.
Basically it was a faulty custom vertex shader which was applied to a plane to change the background color which changed color over time. I had not used the mobile vertex color because I was not getting the desired output. But now I'll stick to the mobile one.
The two symptoms you observed are very much likely to be connected.
The phone might heat up, as you are using its full power, which in turn makes the throttling kick in, reducing the perform
I've had the EXACTLY same problem. I was trying to fix it for a very long time. You said something about faulty shaders you use. And this is the key to solve our problem.
I use a 2-color gradient as a BG, so I have to use a shader too. Due to the fact that I'm a total noob in the writing "shader-code", I have to find something in the Internet. And it was my biggest fail)
To fix the problem and remove this fps drop you should remove your gradient and shader attached to it from the scene. And try to find a more optimized shader for 2D-game (or you can always write your own one c:)

In a multiplayer game, why doesn't the server treat the client like a media player?

As you already know, when you open up Youtube, there is an option for 1080p videos.
My question is, why doesn't the server treat a client as a media player?
So basically, the client sends ONLY input to the server, as in what buttons are pressed, and the server does the drawing, and sends it back to the client as a video, as Youtube would.
Maybe it might be hard for the server to do all the drawing for several players in a game, but this will prevent cheating almost 100%. (Color-related hacks won't stop..)
Should I put this on gamedev?
But won't this be a good idea if the server is a super computer, and there aren't many players?
This is what companies like OnLive are offering already. http://www.onlive.com/
You just have a problem with the latency. When you are playing a shooter you want to have the lowest latency as possible. Gamers optimize this with a faster mouse, faster screen with less ghosting etc.
When your game is like a video, the latency (ping) will become very large. Only difference is that everyone is lagging.
Servers tend to focus on the game logic rather than any rendering, they are responsible for keeping control and synchronising clients to allow clients to perform more complex calculations as part of the rendering process if we change that we face an entirely different problem ...
A video stream is simply a series of images, a fully featured game by todays standards is built up of a full 3D environment in which complex interactions and physics take place.
That of course raises the question ... how does the server render all those viewpoints at once in order to produce the video stream does it need 1 GPU per player like your home pc?
You also have to consider that the internet is unreliable when it comes to bandwidth. The average users home broadband connection gets fits and spurts of bandwidth which is why video streaming is always seemingly smooth and gaming laggy.
Think about it this way ...
In a game I hit the forward key and all other players around me need to know this instantly.
So I need on demand bandwidth as soon i do something or as soon as somehting around me happens.
In a normal video stream, As long as the server can get the first 30 seconds to me in a hurry the rest can come down as bandwidth allows.
So I might be able to get a quick burst of data for 30 seconds worth of video but then for the next say 25 seconds I need no data at all from the server because I have enough to keep the video player going, something that would rarely happen in a game.
For example ...
How often does someone do something unexpected in call of duty?

How to refresh my grid? and How to calculate the amount of time?

I am trying to create a simple rigid body 2D physics engine.
I was able to create a rectangle image by using four lines and able to manipulate the image according to its angle and position; I can move and rotate it (though I made it possible to rotate I do not use the rotating function since I am unable to comprehend angular momentum theory yet).
The image will fall and bounce back based on simple formula:
v(velocity) += a(acceleration)
x += v(velocity)
But I have to click a button every time I want execute a movement.
I want it to execute itself automatically and update automatically, I tried to use loop but for some reason program seems to stop during the time it is in loop section. And because I use an infinite loop that will start over and over again, my program just freezes.
Not only this is the problem but also my good friend, who has better knowledge in physics, told me that I should be able to calculate the amount of time if I want to make this engine work properly.
I like DJ KRAZE's comment - use a System.Windows.Threading.DispatcherTimer, and set the interval to however often you want the picture to redraw. On the timer's Tick event, do your redraw.
If you want to know why the simple loop doesn't work, you have to know a little bit about the Windows message loop. For a brief and somewhat inaccurate overview, all of stuff running in your application, it sounds like, is happening on one thread. Windows uses a message WM_PAINT, which goes through the message loop, to make the control paint itself. It only processes on message at a time.
Where you have your infinite loop, that is happening in the processing of some message. So this keeps the message loop from processing any messages, including messages for the controls to paint. So you don't see anything updating in your infinite loop.
Perhaps you could look into XNA, it's a Microsoft platform that facilitates games development, you should go to the App Hub for information on how to get started.
As for your specific question on refreshing the screen, you can take a look at the Update and Draw methods. Here's a tutorial that, although may not address your specific question, should give you the know-to on how to refresh the screen.

Get music tempo or BPM?

I'm currently building a game in windows phone 7 using xna
i'm trying to get beat per minute from song that played in background song,
i also not quite sure if what i want is BPM, what i want is something like pace or tempo in music, faster the pace ,faster the sprites is moving. What i'm thinking right now, BPM is how much a frequency from music hits a range of defined constant, e.g 20 Mhz - 30 MHz,
Feel free to correct me if i'm wrong, i'm not really familiar with audio thing, i have tried using VisualizationData from MediaLibrary XNA, but after some googling they said that VisualizationData doesn't work with WP7, i also had tried it and the output is 256 length float array contains 0 value,,or if i could do some fft with it,i'll give it a try
Thank you...
Like you were saying, as for the beats you can't get it directly but you'll have to interpret this data. If you personally can preprocess this music and ship it with your title it would be your best bet
In XNA you really only have MediaPlayer.GetVisualizationData to work with. There isn't anything built in that allows you to predetermine this sort of thing. It's used like the following and gets you information about the different frequencies that are playing.
MediaPlayer.IsVisualizationEnabled = true;
VisualizationData visData = new VisualizationData();
MediaPlayer.GetVisualizationData(visData);
So how do you take this frequency stuff and make it worthwhile for your application? There's a great breakdown of how you can do this that's on the App Hub forums in this thread called "Audio Analysis" in the reply by jwatte. Essentially, you're going to look at the low frequencies and try to figure out when the beats are coming in. Nothing perfect, but hopefully you'll get something that you approve of.
Good luck!

polling joystick C#

i have an application that records a date/time when the space bar is pressed
unfortunately, the window doesn't always have focus, for various reasons. eg virus checker popup, itunes update, windows update, etc
so what i though would be a cool idea is to use a joystick button, then regardless of which window has focus, i can always detect the button press event and record the date/time it was pressed.
now i had a look at a few game tutorials, but they seem to have the joystick polling tied into the screen refresh event, because in a game i guess if the computer is slow and the screen doesn't refresh often, having the joystick button pressed is going to make no difference anyway.
That doesn't really suit my need, so i am looking at running a thread that will poll the joystick every so often
My questions are
is a background thread the best solution
how often should i poll the joystick
what kind of timer should i use to determine the polling frequency.
I would like the responses to be at least equivalent to a keyboard. also need to make sure it doesn't auto-repeat if trigger is held down.
any sample code (C#) appreciated
thanks
alex
If you want to go for polling the joystick just because you are not able to capture the keyboard event, I think you need to re-work your strategy.
Even if your form doesn't have the focus there are ways that you can make sure you know of the keyboard state.
You could set up a system wide keyboard hook which can be done in C# using the SetWindowsHookEx API call.
This is delving a little in unmanaged code and Windows API, but I think it's a better idea than polling a joystick cause you won't need to add a joystick to your computer just because you need to capture datetime at the press of a spacebar.
Do a little search on google for keyboard hooks in C#. It's easier than many people believe.
I don't think using a timer object to do this is a good idea at all. Cause I believe you said you need to do it at the press of a key.
Your best bet would be to create a Timer object on your form, and tie the joystick check to the Tick event.
I've also found that running simple stuff like this every 100ms (10 times a second) has a negligible effect on CPU usage.
Use something like AHK (Auto HotKey) it is a simple language that can be compiled to an EXE and is designed for automating the keyboard and mouse, I'm not 100% sure how well it works with a joystick, but I'm sure it's possible they managed to write some stuff for the wii remotes.
Also the IRC Channel and Forums always have people willing to help if need be.

Categories