Jump to content
  • Advertisement

Waverider

Member
  • Content Count

    3060
  • Joined

  • Last visited

Everything posted by Waverider

  1. Greetings, all. I've been fiddling with Winsock 2.2 programming with some success. I've written an app that uses TCP, and it functions rather well. Recently, however, I've attempted some UDP programming. In order to get an idea what kinds of troubles I'll have to deal with over the internet, I wrote a small chat program that also sends packets to the other machine to perform an analysis on packet loss and overall data rate. It entirely uses UDP, which of course, presents its own difficulties... The one I want to ask about here is the concept of "solicited UDP". Apparently, some routers that otherwise block UDP packets will recognize an outgoing UDP packet and will temporarily allow a response through the sending packet's port. This allows the host side to send a response back and allow the sending machine to receive it. However, in my initial testing, the client's machine was failing to receive my packets at all (I was serving as the host). The client connects by first sending a UDP packet with username information. Then, when the client types in a chat message, that request is sent to the host which then sends the chat message back to the client to be echoed on their screen. The client wasn't seeing those messages, so this apparently wasn't working. I've tested it on my LAN, and my local machine, and it works fine. * My primary question is: Is there a way in Winsock to flag a sent UDP packet as "solicited", or is this entirely an automatic router function? Any links to articles or mention of Winsock functions and flags to set would be appreciated. I've been combing through MSDN and various other google attempts to no avail. Thanks for any insight! [Edited by - Waverider on September 28, 2008 9:33:32 PM]
  2. So I missed one small detail. I said it was a rookie mistake. From the NAT punch-through doc (which I did read, as I stated earlier): "The server may repond from the same port that the client sent to (such as in this situation) or it may repond from some other port. Thus, most useful, working NAT boxes must not keep a table of where the inboun packets are supposed to be coming from; it is sufficient and necessary to only keep track of the local masqueraded addreses." According to this, it SHOULD have worked. But apparently, I was dealing with fickle routers. Change text to "Thus, most useful, working NAT boxes keep a table of where the inboun packets are supposed to be coming from; it is necessary to preserve the destination port on the return message." Trusting that doc wasn't going to help me. Unless you'd like to point me towards something more specific. In the next section I do see the small blurb where the destination port is preserved (which is derived from reading it and understanding it entirely... that part isn't expressly stated) on the return message to keep the "server from being surprised", but you know, there are clearer ways to explain things when it could really have been ANYTHING I was doing wrong. This is a learning site, after all. [Edited by - Waverider on September 30, 2008 12:19:51 AM]
  3. SUCCESS! I made a rookie mistake. It wasn't my router. Actually my router was working as a client because it's older. Today's routers apparently have two-way validation, meaning they keep track not only of where local packets came from, but also where they are going. And the only packets they will allow back are the ones addressed from the same IP:port that the client sent the first UDP packet to! I was sending host responses through a separate socket that I allocated to each client that connected instead of the port-bound socket I was listening on! That means the port number didn't match the router's record, so the client's router blocked it! *Falls down* I recompiled it to send everything out through the host's bound listening packet and everything works! I discovered this by downloading some UDP Chat C# code that worked. The only difference from my code was that the host sent responses out through the listening socket! Whew, glad that's over. I'm off and running now... Thanks for the help! [Edited by - Waverider on September 29, 2008 8:29:31 AM]
  4. I tried to get port forwarding set up, but for some reason my router continues to reset to its current values. Frustrating. I'll keep fiddling with it. If I discover anything, I'll be sure to report back here. If it's solved with programming I'll definitely be writing an article.
  5. I took a look at WireShark. I'm assuming to get it to work I would have to install it on my sending machine behind my router, and have it installed on another machine just outside my router but before my cable modem? From a programmatic standpoint, the problem just doesn't make any sense. All I use for communication is recvfrom() and sendto() with address parameters. That's it. Any concept of "connection" is only how each program just holds on to the address info for each send, and how routers open that temporary tunnel for "solicited UDP". Why would it work on my router when it's closed and I'm a client, but not when it's open and I'm hosting? Wouldn't I notice other difficulties on my machine, like DNS lookups failing or something?
  6. On the plus side, I allowed my tester across the net to host (which always worked) and ran 3 instances of the app on one of my machines and 3 more on my laptop, both machines on my LAN. All 6 processes received their respective messages. So my router is NATing quite well. Looking more at the NAT articles, I'm still not seeing how they apply to me. I usually recommend that someone open up a port through their router if they want to host anything at all. NAT Punch Through seems to be only for machines that can't establish a connection either way. With my app, once one machine receives a UDP packet successfully (which always happens through the opened port), it attempts to reply to the client with the address and port in the sent packet (which works when he hosts, but not when I do).
  7. I've read up on NAT, I'm just not sure it applies to me. If the client's router is using NAT, then the UDP packets I receive from him should have an IP:port for me to reply to, which I do. The client's router, using its NAT that it filled in when that client sent his first UDP packet out, should route my response back to the correct machine. It works great when I'm a client. I even connected up with two machines from my LAN, and the host out on the internet sent the corresponding packets back to each of my machines correctly. To further investigate, we both enabled logging on our routers and looked at the IP:port's being sent and received. When I was hosting, I received and sent packets just fine to their expected destination. On the client's side, he saw that he was sending packets to me, but he had no log of the packets I sent to him. Further testing this, I blocked everything on my router and continued. His chat messages no longer showed up, but my router log still recorded his packets, even though they were blocked. This is really a mystery. This almost, ALMOST suggests that my outgoing UDP packets as a host are being blocked at my own router. But that doesn't make any sense, because as a client, I can connect to him, which shouldn't be possible if my router is blocking my outgoing packets. I'll continue reading up on NAT for more clues. At this point, I don't think the clients that have connected with me (3 so far, none can see my packets) are ALL using more than one router in their networks. It would seem to me the NAT vulnerabilities shouldn't be this prominent.
  8. Quote:Original post by Captain Griffen There is no real way around this apart from for the host to have the router configured to allow it, I think. If there was, then I suspect that commercial games would use it - as it is, pretty much every game requires a correctly set up router in order to be able to host behind it. Hosting isn't the problem. The problem is getting the client router to accept a response UDP packet via "solicited UDP". It works when I'm a client, but not when someone else is, so far.
  9. I just tried hosting with someone else... same problem. Curses.
  10. I just tried it again with my router NOT DMZ'd with him hosting, and it worked. So something about his setup prevents my host from sending a packet to him, but my router allows solicited UDP just fine. How is he browsing? (DNS requests are UDP, that's how I found out about "solicited" in the first place). Oh well, at least I learned something! Thanks!
  11. After our little troubles, he opened up the port it hosts on and we reversed roles. I DMZ'd my machine so that I would be sure to receive the responses. That part worked fine. By the way, UDP packets above 1k size fragment often enough to not bother with... :P
  12. UDP is connectionless, so I'm just replying using a reserved socket (not one directly generated from the client connecting as TCP would, just one I allocated space for) and the address info sent on the login request. It works locally and on my LAN, so I was assuming it would work on the internet as well. However, I could see where a router with its DMZ set to a different machine would route the packet incorrectly. Routers might do some things automatically, but I don't expect they would be able to predict where a UDP packet is REALLY meant to go... Frustrating. Maybe I should just try the app with someone else. Perhaps that first user's setup is just being difficult.
  13. Quote:Original post by Evil Steve The problem is that you need to be able to get through on one side before you can send a reply. Thanks for the link, I'll take a look at it. In response to this comment, I didn't make it clear that I did in fact see login information and chat messages from the client, he just wasn't getting them back from me. Will NAT punch-through still help?
  14. Waverider

    Particles how to blend them correctly

    Alpha objects are usually drawn last from back to front. That way they don't occlude each other, don't interfere with everything else, and properly blend on top of anything already rendered. To make a glowing effect, you'll probably have to go with a specialized texture that has a bright center and fades a lot at the edges. That way, when you render a lot of them layered against each other, you'l get an intense center with a glow effect around them. It's likely that the example you posted involves more than just the same texture layered with multiple particles, though. You may need special flare textures that you can render last. [Edited by - Waverider on September 5, 2007 10:16:06 AM]
  15. Waverider

    Need help with a visual basic command

    You could try integrating the win32 commands into your source, like this: Declare Function GetCursorPos Lib "user32.dll" (lpPoint As POINTAPI) As Long Declare Function SetCursorPos Lib "user32" _ (ByVal x As Long, ByVal y As Long) As Long ... and just use those as you see fit. I know this works for VB6, haven't done it with VB 2005.
  16. Waverider

    bullet hole and other decals

    In my estimation, the amount of memory it takes to keep an individual list of decals on every static surface in a map is a LOT less than modifying the textures themselves. (A few vertex locations, texture coordinates for each vertex, and a reference to a texture object takes up a lot less memory than keeping a separate copy of an entire wall texture to accommodate a bullet hole). The most complicated part of it is taking a quad decal and getting the intersection between it and the wall surface so it doesn't stretch past the edges. The rest is just performing a little Z-bias after the static surface is rendered then rendering all the decals without depth. When I first explored decals, I wondered if the wall textures were modified. When I realized I could prepare a lightmap first, then modulate the wall texture with it and modulate the decals as I render them, I realized modifying the wall texture wasn't necessary to ensure the decals are properly lit.
  17. When I render 3D scenes, this is what I do: 1. Define the viewport (glViewport) 2. Clear the back buffer (glClear) 3. Set up the projection (matrix mode GL_PROJECTION, gluProjection call) 4. Translate the viewpoint (matrix mode GL_MODELVIEW, gluLookAt if necessary) 5. Render each object by translating to each orientation and rendering it. 6. Swap buffers You code appears to perform a gluLookAt in GL_PROJECTION mode (well, it's commented out so frankly I'm not sure where you are setting up your projection for each render). So I don't think you're setting up the matrix pipeline properly. The fact that your cubes don't change size supports that theory.
  18. Waverider

    Is tetris really helpful for a beginner?

    Rather than simply write a demo showing off graphic ability, it's a good idea (if you want to be a game programmer) to write something that requires a certain amount of interaction with environment and testing for a variety of game conditions. Tetris is a good example. That way you get a fair expectation of the complexities of writing a game. It's better than going straight for that deathmatch or RTS or FPS or RPG you've got swimming around in your mind. I understand that if you're not planning to make anything like Tetris in the industry that it might not apply so much. I'd consider it an intermediate beginner challenge. But there will undoubtedly be times when you have to solve some problems that have a complexity that you're going to have to think and plan through. Tetris offers those kinds of challenges. To help you out, if I were to write Tetris (I wrote a simpler version in college), you can represent the playfield as a 2D array, and the rotating pieces as a list of 2D 4x4 arrays with various blocks set on or off. Then of course there's moving them around, rotating them, testing when they land, looking for rows filled, making those rows disappear and moving everything down, phew.
  19. Waverider

    The first thing you do when making an engine

    Usually just a test triangle to make sure GL or DX is initializing properly. Then I'll move up to a cube, or a couple spinning cubes with different orientations. Then texture mapping. Bah texture mapping is nice once it's working, but getting it working that first time is a pain.
  20. I can't say I've delved into the deeper aspects of OpenGL or DirectX (that is, heavy-hitting rendering with extreme optimization). I have worked with both, however, and in my experience, OpenGL is easier to learn. The learning path for DirectX is somewhat convoluted. However, DirectX can do most things OpenGL can (my OpenGL code can peak ahead in the texture pipeline, I haven't figured out how to get DirectX to do that, but I haven't started working with shaders yet), and once you get the hang of 3D rendering, you may find that DirectX implementations may offer some card-specific optimizations that aren't available in OpenGL for the same card, and vice versa. For my part, I would recommend OpenGL to beginners.
  21. Thank you for the insight. EDIT: I kicked up the buffer size to 256 and still got inaccuracies. I'll just follow the consensus and go the old fashioned route. I don't see it being a problem unless I'm running a windowed (non-fullscreen) application and I'm dragging a game icon off the edge and then lift up on the mouse, failing to get the up message. If I need exclusive mouse access, I'll use DirectInput and bear it. At this point, it's certainly simpler to just go with win32 access instead of the fancier stuff like threads and predictions.
  22. I was experimenting with the DirectInput Mouse sample in the DX 9.0 SDK and noticed that if I changed the sampling from 12 times per second down to 4 times per second, it sometimes missed movements of the mouse in buffered mode. I later realized that it was because the program was only creating space for 16 sample slots, so I increased it to 64. After that, the program picked up mouse movements much better. Then I switched over to immediate mode and dropped the sampling to once per second. When I moved the mouse around the screen, sometimes quickly, the immediate mode failed to detect the full range of mouse movement, sometimes only registering half the amount that the mouse actually moved. This doesn't exactly give me confidence towards how well the DirectInput mouse routines pick up everything. Is it best to just pipe Window mouse messages into my game engine? Is the DirectInput mouse implementation known to have sample dropouts during slow sample rates?
  23. As I continued searching, I found that other developers where having similar difficulties, and even games like Half-life 2 and Doom 3 were using win32 mouse messages. (EDIT: whoops, I misread, that was just a theory) I just wanted to be sure there wasn't some way of implementing DirectInput Mouse that can actually produce hardware-mouse levels of accuracy. If not, I have no problem using win32, frankly. EDIT2: After adding my own variable to track the calculated mouse coordinates, and setting the sampling rate to 100 times per second, not even that was able to keep the calculated coordinates equal with the hardware mouse location in immediate mode. Ew. I'll try in buffered. EDIT3: And after doing the same thing with buffered inputs at 100 samples a second, it still couldn't coincide the calculated coords with the hardware mouse. Not good. (I tested by just starting the mouse in a given position, noting the current values, moving the mouse around then back to the same location and seeing if the numbers are close. In some cases, the numbers were way off). I think I may just use GetCursorPos() and make use of those values every game tick and let Windows tell me when buttons are pressed or lifted. Adding that to the program, it gave me exact results, as expected. This is important because gamers can notice when they've lost movement in their mouse, and it's annoying to have to re-situate your mouse to center it again. [Edited by - Waverider on May 30, 2007 10:02:53 PM]
  24. Waverider

    Thought-provoking games

    Actually, Neverwinter Nights 2 didn't exactly end well for the party. It wasn't very thought-provoking, though. Instead the whole thing felt more like RP candy, and it still railroaded you through the story in a specific way. I was thinking about a game in the D&D universe that instead dealt with the nature of the Outer Planes themselves, those infinite realms defined only by the differences in alignment (chaos, law, good, evil, neutrality and all the combos). It seems to me even the gods themselves can't alter those borders, since alignment determines them. With so many games nowadays that focus on your abilities and powers, it would be a nice change of pace to play a game that somehow involves something that even the gods are at the mercy of, but not make that plot direction obvious in the beginning. Start the player out making the options for powers and abilities wide open, but later make it clear that their choices of alignment have very significant consequences, regardless of their powers. That might turn off some players, but I would find that kind of thing engaging. I'd be encouraged to play through multiple times trying out all the possibilities. It would also reawaken the abandoned mantra that regardless of your powers, there is always something bigger than you. To help reinforce the concept, and provide more roleplaying, it could offer you the chance to make your chosen alignment obvious to some but hidden to others, and even reinforce your alignment or change it based on your actions.
  25. Waverider

    Confusion over death

    A quickie and dirty solution I came up with is to have the following pieces of data on the object that you have a handle (pointer) to: * a deleted flag (if set, the object is gone) * a unique ID that is incremented every time a new object is formed (if this id isn't = to the id the handle expects to see, the object has been replaced and the handle is no longer valid) This solution requires that any object that has a handle be moved to a deleted list after it is removed from the live list so that you don't get an access error. New objects can yank nodes from the deleted list instead of allocating new memory for them.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!