Friday, June 22, 2012

Hardly anything happening right now in my game development right now, and I know why. The render target method of re-sizing the screen and making the game available in different resolutions requires some re-coding that I wish I didn't have to do, so I've just been sitting on it. I need to stop sitting on it, because I want to continue with the more exciting stuff, and not working backwards.

Sorry guys. First step to fixing the problem is admitting you have one. My lazy frustration is getting in my way.

Edit: I'm coding today. Going to attack dynamic lighting right after equipping items. Two birds with one stone, when you're designing a torch. Oh... and expect some particle engine work too. I want my torch to burn!

Thursday, June 14, 2012

In my research about lighting and different ways to go about dynamic lighting, I came upon something that I hadn't self taught myself about - Render Targets. They solve a huge issue with my game, and I have not built my game on them, so I'm about to start a (hopefully not so huge) overhaul of the game code.

Basically I've been writing my code to work in two forms. One that is twice as big and pixelated (the way I want it to look) and regular size, so that it may be possible to play with things small, but looking sharper. I did this by setting a 'scale' variable to work at x1 and x2 and had everything viewed in the game shift that much.

With Render Targets, I can take a snapshot of the entire screen (in my case, the screen would be small), and blow it up twice as big, or any size really for any screen, any resolution. It seems so easy. It solves all the pain-in-the-rear math of moving things twice a distance with larger sprites, and makes it easier to create multiple screen sizes.

Tuesday, June 12, 2012

I've been doing a lot of research to try to get smooth movement to work. It's not, and I want to move on. For now, I increased the updates to 20 times per second and I'm connecting them linearly. It doesn't look that bad, so I'm moving on. Sitting idle too long on one subject is killing my momentum, so it's time to look elsewhere.

I'm going to add some server commands that will allow me to temporarily rename players in the server. This will keep names straight for when we attempt to get four people on the server at once, without me having to finish the "Create a Player" page, as I'm not yet ready for that. This should be done tonight, so I'll be contacting a few people for testing either tonight or tomorrow.

Some things I'll be working on in the near future (not sure what I want to attack first):
- Background bricks
- Ladders
- Passable platforms
- Item equipping
- Dynamic lighting

Thursday, June 7, 2012

My player got to meet someone last night. Actually, he met me, testing from my laptop, but was still quite amazing (personally anyway). As you can see there are differing results based on small tweaks I made along the way. It still isn't "perfect" by any means, and making the movement smoother is actually trickier than you may think.

Check out the video. Feel free to skip the rant afterwords. Things are going to get deep, not so much technical, but should give you an idea what I'm up against. It will also help me think this through.

For the sake of trying not to lose you, in this next section, let me define some things. The player is the person on screen representing you, the player, as you move about the world. The friend (usually your friend) is the other player on the screen, controlled by someone else, as they move about (I actually named the class that holds all this information "Friend". How cute.)

In the initial part of the video, the friend is moving (woohoo!) but irratically, as if we turned a slow strobe light on. I'm not going to talk about the messages the player is sending, only those being received by the player from the friend, because it affects what we, the players, see. I'm also not going to talk about latency/lag (at least not yet) because, since I'm testing on my local area network, I receive messages within 2-4 milliseconds. Therefore, the choppiness is not due to lag.

What's happening is that the friend is sending messages to the player every 1/5 of a second, actually, the friend to the server to the player, but that's all about lag. To simplify, the message is coming directly from the friend every 1/5 of a second. The message contains the friend's position, velocity, and head angle (and soon facing direction). Every 1/5 of a second, the friend is updated to the new position. Velocity isn't coded right yet, so the friend doesn't actually move, he just "teleports" to the message's given locations. Your brain tries to link the positions together, and would have an easier time if we increased the number of messages per second. Also, the friend is updating the head angle, but is trumped by code telling the head to watch the cursor (same thing is happening to the facing direction, but it isn't receiving messages for that yet)

In the second portion of video, I added animation to the friend and made the head angle independent of the cursor. That's when I realized the friend was teleporting. Damn it Google, how do you not know that teleporting is a word. Teleport, teleporting, teleportation. All words. Welcome to the twenty-first century Google.

The third section of video works like this. Player receives message from the friend that says the friend is located at A, moving X speed. Until the next message, keep moving the friend at X speed (plus gravity and collisions) to help connect the teleporting positions. This is closer to smooth movement, however, any change in behavior that the friend makes (starting, stopping, jumping) causes a little stutter effect, as the player is incorrectly guessing where the friend's next location will be. Understand? No? Try this analogy:

Your friend is driving down the interstate. They call you to check in once an hour. They first call and tell you the mile marker they are at and their speed (they always drive the speed limit) of 65 mph. In one hour, they call you again. They are still going 65 mph, and they are 65 miles further than where they were the first time. You could, in theory, know exactly where the friend is along their route at any time, without having to talk to your friend.

However, the next time your friend calls, an hour after the last call, they are still going 65 mph, but they only drove 45 miles, due to bad traffic along the way. The traffic is now clear, so they are cruising at 65 mph, but you have to adjust your friends position on the highway because it was 20 miles off. If you were graphing your friends progress every minute, you would have a big jump in your friends distance traveled to correct when you got their call.

Even more severe, say your friend calls, and they drove 50 miles since the last call, and are currently driving 55 mph. Are they continuing to go 55mph? Are they speeding up? Slowing down?

This is what is happening in my game. The game assumes the car is going the same speed, but is updated and told it was off, so it corrects (causing a stutter-like effect), then keeps assuming based on the new speed. You can see above how this can be an issue.

In this third section of the video, to be more accurate, I cranked up the messages to 20 messages a second instead of 5. The movement is smoother, but still stutters when the player changes direction. This is treating the symptoms, not fixing the problem. It's also adding the amount of information being sent per second. If enough information per second piles on (from player info, monster info, item info) it can bottleneck and really cause issues.

I am proposing this to smooth out the friend's movement: add a buffer which waits for an amount of time after a message is received before actually updating the friend. Then, with the messages received, connect the positions, using the the below methods to avoid jarring jumps that cause stutter effects. If a message isn't received in time for the next update, continue moving the friend in the direction and speed last sent, as we are doing currently. There might be an abrupt movement when the next message arrives, but these glitches are unavoidable when latency is poor.

I've created these graph to help demonstrate. The green line is the actual position of the friend in some direction in time.

Currently the game acts like the orange line. It receives a message from your friend with a position and velocity, and continues in that direction until you get another message, then corrects. Look how choppy that becomes! I should also mention, this is extremely exaggerated, if you hadn't guessed. My messages arrive 5 or 20 to a second, and my player cant change directions that quickly. To fix this, I can use a buffer.

The game adds a delay (in this case, its as long as the period between messages). When a message tells the game where the friend is, it determines the velocity needed to move the friend to that new point in the amount of time the delay is for. The red line demonstrates how close the viewed motion of the friend is to the original, however, due to the delay, you actually witness the friend at the dotted red line. When it comes to a fraction of a second, this may not matter. Because this is exaggerated, the actually game might look pretty good like this. But if not, there's plan B.

Plan B (which I might do anyway): Instead of setting the velocity that will get the friend's location to the next message position within the delay time, you calculate the acceleration needed to get to that position and smoothly roll into it. Then the new velocity takes over until you get another message, and change the acceleration to turn you to that point.

HOLY CRAP! Long post, but it helped me figure out what to do next. Thanks guys! Now that the night is shot, I'll code tomorrow. Good night!