Jump to content
  • Advertisement
Sign in to follow this  
RKillian

Some things I'm having trouble figuring out (graphics, timing, etc)

This topic is 4853 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been doing programming for several years, from console driven C++ to Windows C# more recently, but every time I try to apply it to games I find myself getting stuck on the same issues every time. If it helps as all, the game I would like to write is an MMORPG similar to Ultima Online without the isometric view. The basic structure would be a client that sends very basic input and recieves a list of things to draw while the server uses one timer to regulate game flow and another to do database I/O. I should probably mention my prior experience was with UO through scripting for the closed source POL engine and the more recent attempt at this was pushed by being completely baffled at how RunUO (the C# emulator) works. So, at any rate, the 3 problems I keep running into are timing/events, graphics, and input...all of which are pretty much related in some way. Keep in mind, I'd really like to stay within either the MFC or Forms framework if possible. How can I have some sane control over the rate of input? If I use regular events, holding down a key floods the message queue. If I keep polling, the system seems to lock up with no idle time. Sometimes I run into a problem of missing input if I don't hit at precisely the right time when it's looking. Throwing sockets into the equation complicates it further. I haven't ever been able to get callback timers to work. They either cause weird compile errors in the environment or simply don't work right. Also I'm wary about what order the message handler executes, as I haven't been able to find a source that says "it's completely orderly FIFO" or "every event starts a thread". Second, UO has a nice feature that allows their avatar to act as a dialog within the main window. How can I drag items around the screen like this? I mean, I can do it with a plain dialog but not any arbitrary graphic. This goes hand in hand with targeting, how would I even know what onscreen I'd targetted? Third, is there a simple way to just draw sprites in a window not created by Allegro or SDL? While I couldn't even get SDL to compile, I was able to get Allegro with VC++ 6 to initialize but only into a blank frame with a titlebar. It bothers me to either be stuck in DOS mode with no windowing or windowed with no control outside of OS widgets :/ Psuedocode:
class Client
{
   ActionObject lastkeypress
   Socket connection
   Object[] whatsaroundme

   OnReceivedKey
   {
      CriticalSection.lock();
      lastkeypress = whatthekeyboardsaid;
      CriticalSection.unlock();
   }

   OnWhen100msPassed
   {
      CriticalSection.lock();
      connection.send(lastkeypress);
      CriticalSection.unlock();

      foreach thing in whatsaroundme
         whatsaroundme.draw();
   }

   //somewhere in here I have to have a socket recieving
   //data periodically so whatsaroundme[] has stuff

   OnSocketGotSomething
   {
       CriticalSection.lock();
       decodethemessage(connection.receieve());
       CriticalSection.unlock();
   }
}

class Server
{
    Object[] everything;
    Socket[] people;

    OnWhen100msPassed
    {
        CriticalSection.lock();
        foreach thing in everything
           everything.update();
        Message m;
        foreach person in people
           m = GetAllObjectsNear(person);
           people[person.id].send(m);
        CriticalSection.unlock();
    }

    OnWhen20mPassed
    {
        CriticalSection.lock();
        SQLadapter s = new SQLadapter();
        foreach thing in everything
            s.Execute("update objects set hp=thing.hp where id=thing.id;");
        s.dispose()
        CriticalSection.unlock();
    }

    //somewhere in here I have to have a socket recieving
    //data periodically so playercharacters can do stuff

    OnSocketGotSomething
    {
        CriticalSection.lock();
        alter(everything[people.id], changes);
        CriticalSection.unlock();
    }
}
So, what I'm missing here (from a mathematical and datamoving standpoint)is, really, a way to force the socket on both sides to only send, say, every 100 ms and to keep the input reciever from stealing all the resources. The amount of critical section locks (and not knowing the C# equivalent) kind of worries me but I hope they're brief and penalty is not so bad on a modern 2ghz system. But I'm still a bit clueless on the graphical side though I think it's something I can bolt on later when the backend is working reliably. I know it's just got to be something small I can't make the logical leap to for some reason. If anyone can point me in the right direction, either on forcing a timer to set off events or with regards to graphics (see above, non default Windows style dialogs), it'd be really appreciated. [Edited by - RKillian on December 1, 2005 9:00:24 PM]

Share this post


Link to post
Share on other sites
Advertisement
Lots of stuff...

An MMORPG is a generally unreasonable project. As your first game, it's sheer folly. Start smaller so you can focus on one problem at a time.

- I've never seen any problem with simple Windows messages. Make sure to use while and not if for the message pump, and they shouldn't flood too much. The server will need to do rate limiting to deter bots, but that's a more complex topic which is unneeded for your first game.

- C# timers are fairly straightforward, have you gotten example code from MSDN to work nicely? I think the messages are a FIFO, and am slightly curious as to why it would even matter.

- There's no "simple" way to draw sprites. D3DXSprite is pretty simple, but still fairly challenging if you're not used to it.

*stop at code*

Share this post


Link to post
Share on other sites
That old saying comes to mind: if all you got is a hammer, every problem starts looking like a nail. In other words, there will be a LOT of new things to learn before it's making much sense to start writing games. I don't think that reducing everything to something you're familiar with is going to get you too far.

For input, well, either your main loop must be reasonably fast, so you won't have to hold keys forever to be registered or you use events. As stated before, empty that queue in a while loop, not just one event per frame/step.

I don't know how flexible and extensible you are to achieve things like a paper doll as interface. Placing an invisible GUI element (or transparent with just a frame) as drop target could work well enough, but rectangular shapes just might not be suitable. But that's where you should decide between pure old fashioned 2D like checking the pixel color/transparency to figure if you clicked the arm (or whatever) or if you want to do it the "modern" way, using 3D even for 2D because it's faster.

Another question is if the game should have the look and feel of a typical windows app. Making a GUI that fits in with the rest might be a good reason to look at some open source GUI libs for OpenGL (which would also mean that you can easily add your own elements or change existing ones wherever you like).

Been a while since looking at Allegro, but didn't that come with timers, input handling and all kinds of stuff?

Share this post


Link to post
Share on other sites
Well, I had tried smaller projects. Back when Allegro was on 2.x, I managed to get it installed and working enough to try Mega Man. I could get him to move and animate but couldn't grasp physics enough for much else. His jumps either violated gravity or he fell through the floor.

To avoid the gravity problem, I tried Legend of Zelda. Except I couldn't figure out hit detection. My best idea (which is sad) was storing a 640x480 array of 0s and 1s on every blit. But if putpixeling to the screen is so slow, that'd probably break just as bad. About this time I really got into UO, and scripting for the POL emulator, so I abandoned this project.

I was displeased with the dumping the administrator did on several occasions and went back to playing only to be bored to tears with the run of the mill default servers everyone was running. RunUO never clicked with me, and I was sick of some limitations of the client anyway, so I decided to give it another stab. Best off all, UO has no physics to speak of...it's practically turn based.


Telastyn:

I think the only real difference is that sockets sit between keyboard/engine and engine/screen, so I figure it shouldn't be_that_ much harder.

I did take your advice and try the timers in .NET 2.0. They work much better than their equivalents in the 1.0 runtime. Rate limiting is something I've thought alot about as well as the age old rule of never trusting the client.


I had originally thought of putting a timer on the client. Input would set a variable over and over. When the timer kicked in, it'd send the current value. So essentially you'd have 1 user-initated action per game cycle. The server, meanwhile, on every game cycle would lock the world object and loop through calling each object's (including the player, whose socket stored the last packet) update function.

But, yknow, it doesn't really work with an action that requires further responses...say, a spell requiring a target. Or looping scripts like NPC AI. How would you chunk up it's behavior script? Suddenly this timer bit (at least alone) wasn't working out.


Then I thought maybe I'd throw out the rate limiting and just make everything respond to events. What concerned me about events was...if I set off 2 long events at the same time, is the 2nd going to wait for the 1st to complete? I really never could find the answer so I asked.

Like, imagine this situation. I, as a player, send a packet that sets off an event that is supposed to do a bunch of things (say, randomize 150 properties) to an NPC. But at the same time, another player (or 5) sets off an event that kills the NPC and removes it from the object list. It becomes a threading issue, can I rely on any information about the NPC since 2 threads might be touching it or do I have to catch exceptions all over the place? If one occurs after the other, it's simpler, but who knows how long whatever I have to do in the 1st will stall the 2nd.

At this point I thought about locking (Threading.Monitor seems to be the C# version of MFC's CriticalSection) on pretty much every function. But then I wondered if I would have race conditions here.

What if a bunch of events set off changes that overlap the timer that locks to do a world save? And what if new events just keep grabbing the Monitor in the split second it's free and the save timer never gets it? Keep in mind the object update (in memory) timer would use a lock too and this too may never get it either.


And then I looked at the taskbar and discovered Windows and whatever startup apps HP had installed was using 500 threads (I had always been told 4 per process was overkill). I slapped my forehead and said "threads! that'll solve the NPC problem" and thought about that. I thought back to POL, where every item had defined a number of event scripts (onEnterContainer, onHitScript, onDestroy) that went off and ran, and said, maybe an event can trigger a thread for these.

How to reconcile that with a game cycle timer I have no idea. Put a timer on every NPC to suspend and unsuspend its running threads? It's something I really have to figure out a bit more. It's a million times more time critical and complex than the dozens of regular Windows apps I've done over the years. And this is before I get back to the maddening scourge that is graphics!


Maybe I'm underestimating today's computing power but, with 10,000 objects in the world, with 1000 threads, locking 100s of times per second, running 100s of times, while trying to do socket I/O and event processing on top of that, isn't the system going to grind to a halt and kill itself? If it doesn't, calling 10,000 SQL commands evey 20 minutes probably will...


Trienco:

I suppose I can put off graphics while I try to get the server backend sorted out.

My question was more an expression at being utterly baffled at how, in UO, I can drag a sword from anywhere on the screen and drop into the paperdoll. The only thing I've ever been able to moveg around in my own apps are dialogs. I have no idea whatsoever how they do it. I just can't figure out how it knows what to grab with the mouse pointer.

Also I am very aware of the limitations of the paperdoll approach (drawing tons of graphics). However I am a decent 2D artist and I really don't like 3D nor can I do the modeling. I had a class in OpenGL in college and it turned me off to computer graphics for a long time. I just don't have any idea how I can open a GLUT or Allegro or SDL bitmap window within an MDI frame either.

I made a little headway with GDI+, despite how slow everyone says it is. Still feels like a kludge invoking the UI thread to update a PictureBox over and over though. Man, if there's anything that drives me crazier than thread conccurrency it's got to be graphics...



Am I on the right track with any of this or do I just go back to regular applications?

[Edited by - RKillian on December 3, 2005 9:34:34 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!