Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Hubis
May 18, 2003

Boy, I wish we had one of those doomsday machines...

Vinlaen posted:

Thanks for all of the help with my other questions but now I have some about networking...

I'm trying to create a "simple" networked/multiplayer 2D game and so I've been trying to a read a lot about networking principles, player synchronization, etc. However, it seems like most articles (eg. gaffer.org) tell you to send keyboard/mouse inputs to the server, have the server process them, and send the results back to the client.

Why?

Is this only done for cheat protection?

What is the disadvantage to sending actual player position to the server and doing a sanity check? It seems like this way is better because then players will know their position even while moving and won't require interpolation or prediction.

Keep in mind that I'm talking about a simple 2D game with different objects moving around, etc.

I'm going to have a bunch of other networking questions I'm sure, and I thought about starting a new thread but hopefully you guys can help me out here. :)

Your second solution is what Half-Life/Half-Life 2 do. They have the advantage of having less latency -- when you press a key, you move immediatly instead of waiting 2-10 frames to have your input realized. This is good, but the downside is that (a) you now need to make sure the client has all the relevant world state needed to interact with the world properly (so, more data) and (b) if it doesn't update correctly (say some other player moved in your way for example) then you have to overwrite the local value with one from the server, and then have to deal with "bouncing" or "popping" or "lurching" movement, as the world state is changed. So, in some cases it can be more smooth, while in others (esp. those with high lag/packet loss) it can be worse.

It's also a simpler design, since all your logic is being handled in one place, and the specialized client-side physics and rollback code is something else you wouldn't have to write anymore. Unless round-trip latency between client and server are a problem, I'd stick with the "dumb client" model.

Adbot
ADBOT LOVES YOU

Jaded Samurai
Mar 29, 2004

Yarr ^^_
I'm writing a ~10-32 person, non-turn-based, tile based game. The maps will be something like 500x500 tiles max. Everything in it will be destructible/constructable on the fly. What I'm wondering is, is which of these two options would be a better idea, or if there's yet another solution that's better:

1) Send the map and items to the player at the beginning, and update every time some part of the map is changed, or an item is picked up(this shouldn't happen -too- fast)

2) Send only what a player could see with a screenfull when they log on. As a player moves, constantly update the missing tiles/items at the edge of the screen.

To give a crude estimate, every tile would consist of 1 wall, 1 floor, and 1 item

Ludicrous Gibs!
Jan 21, 2002

I'm not lost, but I don't know where I am.
Ramrod XTreme
Thanks for all the responses, everyone. Sounds like I should just use timeGetTime, but without any modifications.

Vinlaen
Feb 19, 2008

Hubis posted:

Your second solution is what Half-Life/Half-Life 2 do. They have the advantage of having less latency -- when you press a key, you move immediatly instead of waiting 2-10 frames to have your input realized.
It sounds like you have the same idea as Mithaldu...

quote:

This is good, but the downside is that (a) you now need to make sure the client has all the relevant world state needed to interact with the world properly (so, more data) and
Can you explain what you mean by this?

quote:

(b) if it doesn't update correctly (say some other player moved in your way for example) then you have to overwrite the local value with one from the server, and then have to deal with "bouncing" or "popping" or "lurching" movement, as the world state is changed. So, in some cases it can be more smooth, while in others (esp. those with high lag/packet loss) it can be worse.
That makes sense but making the player wait 2-10 frames before their character moves seems really annoying. (this seems to be the problem with the Byond engine)

However, let's say I send a "start moving forward packet" and start moving locally on my machine. The server receives this packet (100ms or whatever later) and starts moving my character locally and sends back an knowledgement packet. Does the server then send a position update every few seconds? If so, wouldn't the position be "old" by the time it reached my players machine? ...or does the server predict ahead of time where I will be based on the latency between the two computers?

Also, what happens if the player holds down the up arrow? Do I keep sending packets every XX milliseconds? I'm guessing I would need to keep track of when I sent the last packet and implement a delay.

Finally, do I need to include velocity or any such thing? If the other players aren't using prediction, then if the packet stream is too slow wouldn't it appear as though everybody is bouncing/popping all over the place?

quote:

It's also a simpler design, since all your logic is being handled in one place, and the specialized client-side physics and rollback code is something else you wouldn't have to write anymore. Unless round-trip latency between client and server are a problem, I'd stick with the "dumb client" model.
Are you saying that the server does all the logic and physics? Wouldn't I still need some type of interpolation on the clients to help when packets arrive too slowly (or get dropped) from the server?

I'm really sorry for all of the questions and I GREATLY appriciate your help.

digibawb
Dec 15, 2004
got moo?
In Quake 3 anyway (may well be still fairly similar to how they handle things in Source,CoD,etc):

The server runs a simulation using the latest input from the clients. In Quake 3, it actually ran the player logic whenever it got new input from a client, by default, but let's just just assume it didn't for now, and just ran player logic at the same time as the rest of the world, for the sake of simplicity. Every 50ms (by default), it would send snapshots of the world state out to each client, the information would be restricted by what was in the player's view (PVS).

The client would interpolate the states of entities from two snapshots, and would attempt to have its local simulation time approach the newest snapshot's time just as the next snapshot was about to come in, thus meaning that the data was as up-to-date as possible, without having to do any guesswork. In the case where the new snapshot arrived late, it would have to do some extrapolation, which isn't a huge deal for things other than players really.

One exception to the above, is the local player's entity. Obviously, having to wait for the round trip for your input to come through just isn't feasible. To get around this, the local player's input is re-simulated every frame, based on top of the data from the latest available snapshot. Error deltas are stored off for the difference in the new simulation vs. the previous simulation, and decayed off over a short amount of time. In this way, the local player is simulated ahead of server time, as opposed to the rest of the world, which runs behind server time.


This is just a brief overview, I could probably drill down into more detail on some specifics, but I don't think that's really important for what you were asking. Hopefully I haven't messed up much in that, having worked on a few systems since then, I may have mixed some things up here and there, but I'm sure people will gladly point them out :P


On the input sending front, user input would be throttled, depending on your connection type, looks like the defaults were 15/30 packets per second. Some routers don't take too kindly to blasting them out at 200+ packets a second, from what I recall.


EDIT: Just to clarify something on the re-simulation stage. The snapshot contains a timestamp of the last user input from that client which has been run on the server, so the client needs to apply all user input that has been generated locally since that time, or at least a sampling through the data. Re-simulating every single input every frame could become rather expensive, depending on the type of game.

digibawb fucked around with this message at 23:17 on Jan 15, 2009

Vinlaen
Feb 19, 2008

I'm still interested in a reply from Hubis on my questions above, but I also have a few for digibawb...

Are the snapshots you mentioned only deltas from the previous snapshot or is it an entire world state? If it's the entire world state, isn't that a LOT of data to be sending to every client every 50 ms?

Interpolating other player position seems easy enough, but I'm not sure on the re-simulation part of the local player. Is there any easier method for making the local player appear to have fluid controls without waiting for the server? Your re-simulation sounds very complicated...

As for the inputs, I noticed that you said they were sent 15/30 packets per second (from the clients?) but were they only sent if the player changed directions or are you saying that if the player held the up arrow that 15/30 packets per second would simply contain "up arrow"?

Also, my game isn't going to be twitch-based like Quake or other shooters. It's also not going to be in 3D (only 2D with little physics). I'm just hoping to design a system that works nice enough without going overboard (espicially since it's my first realtime networking project)

Thanks so much for the help!!

digibawb
Dec 15, 2004
got moo?

Vinlaen posted:

I'm still interested in a reply from Hubis on my questions above, but I also have a few for digibawb...

Are the snapshots you mentioned only deltas from the previous snapshot or is it an entire world state? If it's the entire world state, isn't that a LOT of data to be sending to every client every 50 ms?

Interpolating other player position seems easy enough, but I'm not sure on the re-simulation part of the local player. Is there any easier method for making the local player appear to have fluid controls without waiting for the server? Your re-simulation sounds very complicated...

As for the inputs, I noticed that you said they were sent 15/30 packets per second (from the clients?) but were they only sent if the player changed directions or are you saying that if the player held the up arrow that 15/30 packets per second would simply contain "up arrow"?

Also, my game isn't going to be twitch-based like Quake or other shooters. It's also not going to be in 3D (only 2D with little physics). I'm just hoping to design a system that works nice enough without going overboard (espicially since it's my first realtime networking project)

Thanks so much for the help!!

Each snapshot is a delta from the last snapshot the client acknowledged. Re-simulation is pretty easy, you just end up setting the player's state to that of the most recent data, and then applying whatever logic you run for a player multiple times over the input data.

Full input is sent every time it sends data to the server, though as someone else already mentioned, player input doesn't really need to be all that big. Looking at the Quake 3 code, a single input write looks to be around 16 bytes. The client may send multiple inputs in one go, to help with packet loss cases, in which case, everything after the first will be delta compressed against the previous one. (Technically they are all delta compressed, the first command is just delta'd against a blank command)

Whether all this stuff would apply well to your case, well, that's up to you to work out, I guess. It does seem like it might be overkill, but knowledge is power, and all that.

Cedra
Jul 23, 2007
OpenGL question: How do I make a light that's fixed relative to my eye?

As per the Nehe tutorials, I've set up the light's ambience and diffuse intensities, added the LIGHT_POSITION property and enabled lighting in the init() method. And that's it. Yet whenever I rotate/translate/scale my model using a threaded Display() loop, the lights seem to rotate with it as well.

This is confusing. I think I'm following the OpenGL FAQ's answer too ("How can I make my light position stay fixed relative to my eye position? How do I make a headlight?"), yet my results do not match it. I'm not updating the position whatsoever, so should it not stay in the same position?

Alvie
May 22, 2008

I have a question about writing a platformer using C++ and allegro. I've written a few simple games before but I've never done a platformer before, and am stuck writing the code to make the character jump. Excuse the noobish question but I'm really not all that experienced in game dev.

Basically, the game is going to be based on this idea (The author doesn't implement many of his ideas so he's basically giving them out to whoever wants to use them). Essentially, a platformer where you control two characters simultaneously using wasd and the arrow keys, and player A's foreground that he can't pass through is player B's background and vice versa.

So I've got the screen set up, most of the basic engine is down, I just kinda hit a wall when it comes to jumping. I wasn't really sure how to implement gravity in the game so I just put in a basic gravity function, like so:

code:
void man::gravity()
{	
	int check1=getpixel(screen, man::x-20, man::y+32);
	int check2=getpixel(screen, man::x-10, man::y+32);
	int check3=getpixel(screen, man::x, man::y+32);
	int check4=getpixel(screen, man::x+10, man::y+32);
	int check5=getpixel(screen, man::x+20, man::y+32);
	
	if(check1!=man::color && check2!=man::color && check3!=man::color && check4!=man::color && check5!=man::color && man::y<SCREEN_H-15)
		man::y++;
	else
		man::ground=1;
	
		
	return;
}
Since this is based on negative space (one character's background color is the other's foreground color), the check variables are in place to see if there is ground underneath the character. If none of the variables return the foreground color, the character gets moved down one. Else, set ground variable to true (should now be able to jump).

man::ground is a boolean variable that is true when the character is standing on the ground and therefore can jump and false when he's in the air, to prevent being able to fly by constantly jumping repeatedly, like an infinite set of double jumps. The problem with this is that it's not working. My jump code is like so:

code:
if (key[KEY_W] && man::y>20 && man::ground==1)
        {        
        man::y--;
		man::y--;
		man::ground=0;  
        }
Frankly I'm beaten. I'm sure it's some obvious noob poo poo that I'm missing but I don't understand why it isn't working. My characters are still infinitely jumping. Also, can anybody suggest a method of regulating jump height? Like to make the guys only be able to jump so high before plummeting back to the ground?

Excuse the question from a beginner. Hopefully my code isn't too atrocious. I'm pretty much playing this by ear rather than doing some tutorial (all the better to learn how everything works).

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Alvie posted:

code:
man::

Stop this.

Alvie
May 22, 2008

Avenging Dentist posted:

Stop this.

What's the alternative? Just using y instead of man::y? I wasn't sure if that would work or not.

edit: Like I said, not that experienced so excuse the sloppy code. Will this change have an effect on the program or is it just aesthetic?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Of course it would, it's local to the class.

Also, don't use 1 and 0 for Boolean variables, you should be using true/false for readability.

Also also, you should probably just set some breakpoints or print some debug messages. There's nothing obviously wrong with your code (aside from some unusual choices regarding collision detection, gravity, and coordinate systems).

Alvie
May 22, 2008

Alright, that was gonna be my next step (The debug messages thing). And yeah, the unusual choices as to how stuff works is based on the fact that I've never done something like this before and I'm pretty much just implementing things that I randomly come up with that seem like they'll work. Right now I'm not even really using sprites since my knowledge of them is currently rather limited and it seemed an easier route just to go with primitives since the whole game is just running with low-rez black and white graphics. This is more of a learning exercise than a game that I plan to write to completion.

Thanks for the advice!

a slime
Apr 11, 2005

Alvie posted:

code:
if (key[KEY_W] && man::y>20 && man::ground==1)
        {        
        man::y--;
		man::y--;
		man::ground=0;  
        }

If you want to decrement y twice, just use "y -= 2;"

shodanjr_gr
Nov 20, 2007
Can someone give me some practical tips on collision detection for 3D games?

Any links to tutorials, info, etc?

very
Jan 25, 2005

I err on the side of handsome.

shodanjr_gr posted:

Can someone give me some practical tips on collision detection for 3D games?

Any links to tutorials, info, etc?

Find a good library. We use bullet.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

very posted:

Find a good library. We use bullet.

Collision detection and physics are completely different.

ehnus
Apr 16, 2003

Now you're thinking with portals!

Avenging Dentist posted:

Collision detection and physics are completely different.

But also closely related in practice. If you had looked you would have seen that Bullet has a collision detection component.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

ehnus posted:

But also closely related in practice. If you had looked you would have seen that Bullet has a collision detection component.

I did look. But that doesn't change the fact that, if you're not going to use physics, Bullet is overkill.

newsomnuke
Feb 25, 2007

Re collision detection libraries: OPCODE and COLDET have both been around for ages, and are mature. Haven't used either for a long time though, but I'd check them out first. There are others like RAPID and SOLID but they're a bit old.

Thug Bonnet
Sep 22, 2004

anime tits ftw

bullet is way, way overkill if you just want to know if things are bumping into each other

shodanjr_gr
Nov 20, 2007
Thanks for the suggestions guys!

I checked out COLDET and it seems stupidly easy to use. Cheers :)

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

Null Pointer posted:

timeGetTime is fine (if you only need ~15 ms precision) but timeBeginPeriod will introduce other performance issues.
Performance issues like what? It's been used for high-precision timing for ages now. Quake 3 uses it and sets it at 1ms resolution.

Vinlaen
Feb 19, 2008

Well, I'm getting a little frustrated trying to develop my own networking engine (eg. the client-side interpolation stuff and not the winsock/sockets layer).

Are there any 2D engines that take care of this stuff for you? Synchronizing movement in 2D space seems like a fairly common/general type of thing.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
http://www.jenkinssoftware.com/

Vinlaen
Feb 19, 2008

Thanks... RakNet is probably the closest thing to what I'll find, but I'm hoping to find more of an engine that already implements RakNet, etc. Ideally I'd like to find something with the features of BYOND but implements much, much better.

RakNet certainly helps things out but you still need to create an entire game engine and then hook it up to RakNet, etc.

I'm not afraid of programming. In fact, I often very much enjoy it, but I don't want to create an entire engine... I just want to program the _game_ (but all my ideas are for multiplayer/networked games) using programming langauges, etc.

Null Pointer
May 20, 2004

Oh no!

OneEightHundred posted:

Performance issues like what?

I explained this exactly 3 posts after the one you quoted. The Windows scheduler uses the Programmable Interval Timer for preemption and scheduling. The default interval is specified by the HAL and timeBeginPeriod overrides this interval. When you set a lower value for timeBeginPeriod the scheduler runs more often so your game is interrupted more often. The associated performance consequences should be obvious to anybody with even a passing knowledge of operating systems and schedulers.

This is even explained in the documentation for timeBeginPeriod, in plain English:

quote:

This function affects a global Windows setting. Windows uses the lowest value (that is, highest resolution) requested by any process. Setting a higher resolution can improve the accuracy of time-out intervals in wait functions. However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.

So don't do it. There's no reason to: QueryPerformanceCounter is better as long as you read the documentation and use it correctly. If you don't know what timeBeginPeriod does you shouldn't be loving around with it or telling other people to use it.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Null Pointer posted:

The associated performance consequences should be obvious to anybody with even a passing knowledge of operating systems and schedulers.

Why not post numbers instead of handwaving? :colbert:

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

Null Pointer posted:

The associated performance consequences should be obvious to anybody with even a passing knowledge of operating systems and schedulers.
Considering the overhead wasn't enough to cripple games that were at the bleeding edge of performance 10 years ago, I'd love to know how the performance impact is even remotely relevant today.

I get how QueryPerformanceCounter is faster. What I don't get is why the difference would ever be noticeable.

OneEightHundred fucked around with this message at 17:53 on Jan 19, 2009

Vexed Morgan
Dec 22, 2008

Is there a way to just download a Windows .exe of Python? I want to package it with my program so Windows users can just run a "start.bat" file that says something like "python.exe game.py"

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
What's wrong with the official Windows binaries?

a slime
Apr 11, 2005

What's wrong with py2exe?

Vexed Morgan
Dec 22, 2008

The official Windows release only comes as a .msi installer and py2exe only works with Windows. I guess I'll just have to use someone's Windows computer, at least then I can use py2exe and give the game a proper test on Windows, which I wasn't originally going to bother doing.

a slime
Apr 11, 2005

Try Portable Python.

Jaded Samurai
Mar 29, 2004

Yarr ^^_
e: answered in IRC

Jaded Samurai fucked around with this message at 09:59 on Jan 21, 2009

Vinlaen
Feb 19, 2008

Does anybody have any links to any really good isometric tiling tutorials? I've found a few tutorials (including on GameDev) but they all seem to be a little bit lacking or hard to understand.

I'm also trying to remember the name of a website I found (on here I think) that had a small section of free 2D (isometric?) artwork but it was VERY, VERY high quality. It had an article that contained "Most people come here for the free artwork but here is a tutorial..." or something like that. I can't find the site on Google for the life of me though!

akadajet
Sep 14, 2003

Are you having problems understanding how isometric tiling works? It's not that much different than implementing any other 2D tiling scheme.

What are you finding difficult to understand?

Vinlaen
Feb 19, 2008

I'm able to draw basic isometric tiles without any problem (that's fairly easy) but I'm having trouble with two different things:

1) Drawing tiles with different heights. Eventually I'd like to implement a Final Fantasy Tactics system where each corner of a tile has a different height and can create sloping terrain, but I'll leave this for later since it seems much more complicated. For now I just want tiles with varying heights to create bridges over terrain, etc.

2) Using the mouse to pick tiles. I'm guessing this would get even more complicated given different tile heights too.

biznatchio
Mar 31, 2001


Buglord

Vinlaen posted:

1) Drawing tiles with different heights. Eventually I'd like to implement a Final Fantasy Tactics system where each corner of a tile has a different height and can create sloping terrain, but I'll leave this for later since it seems much more complicated. For now I just want tiles with varying heights to create bridges over terrain, etc.

From the isometric systems I've seen, to compensate for height on a tile you basically just move the output Y coordinate up. As long as you draw your tiles back to front, you're fine as far as overlap goes.

To draw a sloped tile, calculate the points of each corner of the tile at zero-height, apply the appropriate Y offset for each point's height, then distort your tile's texture to fit the polygon of the resulting points.

Adbot
ADBOT LOVES YOU

hihifellow
Jun 17, 2005

seriously where the fuck did this genre come from

Vinlaen posted:

2) Using the mouse to pick tiles. I'm guessing this would get even more complicated given different tile heights too.

This is a gigantic pain in the rear end and all the examples I found for doing it with 2D art assets were huge complicated piles of code.

If they're all the same height it's actually fairly simple, just adjusting the location of the mouse with the same math that is making the tiles line up isometrically. Of course this gets completely hosed when you add in tile heights, but I found a simple way to do it a while ago.

I gave each tile a sort of black and white imagemap, where white was clickable area and black was the part that would overlap with other tiles. Whenever the mouse was clicked, it would pull the black and white counterpart for the tiles in the surrounding area and then start stepping through each tile, starting from the bottom tile. When it finally got to a tile that contained the location of the mouse, it would pull the color of the pixel located at the mouse location: if it was black, it kept going, but if it was white it would stop and it knew which tile was actually clicked on.

Even though the program I wrote this for is a colossal mess this bit of code wasn't terrible; I'll post it if you want but it's written in c# for XNA so I don't know how much help it would be.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply