TMWServ/Client Asynch Problem

Content and general development discussion, including quest scripts and server code. TMW Classic is a project comprising the Legacy tmwAthena server & the designated improved engine server based on evolHercules.


Forum rules

This forum houses many years of development, tracing back to some of the earliest posts that exist on the board.

Its current use is for the continued development of the server and game it has always served: TMW Classic.

Post Reply
User avatar
leeor_net
Novice
Novice
Posts: 180
Joined: 03 Feb 2008, 09:17
Location: Ohio, USA
Contact:

TMWServ/Client Asynch Problem

Post by leeor_net »

This is outlined in the Mantis bugtracker but I haven't seen any movement in terms of getting the problem fixed.

Is somebody working on this? If not, I can try my hand at working toward a solution.
- Leeor

"Oh, no thanks. I ate a boulder on the way in." - Shrek
peavey
Novice
Novice
Posts: 101
Joined: 12 Feb 2008, 04:15

Re: TMWServ/Client Asynch Problem

Post by peavey »

.
User avatar
Crush
TMW Adviser
TMW Adviser
Posts: 8046
Joined: 25 Aug 2005, 16:08
Location: Germany

Re: TMWServ/Client Asynch Problem

Post by Crush »

I looked at the issues a lot and it left me in despair. Maybe you have more luck than me.

I *think* that the root of a lot (maybe all) of the current synchronisation problems is that the client always finishes the movement of a sprite (or at least the current step of the current path) before accepting any new move commands while the server changes the movement immediately. This behavior is also affecting my knockback patch negatively (that's why I suspended the development of it).

Unfortunately the client-sided movement code became very complicated in the past. It was first developed by inexperienced programmers for tile-based movement and then hacked by advanced but busy programmers for pixel-based movement. It seems to me like a lot of unnecessary artefacts were introduced in the code during this unfortunate development path (for example a horrible mixup of tile-based coordinate systems, pixel-based coordinate systems and tile+offset based coordinate systems which are stored in different, obscurely named variables and not always the same). But I have a lot of problems understanding what exactly *is* necessary for some reason and what isn't.

The recent client-sided limitation of move messages (revision #4122 and #4131) also seems to have broken something because "setbacks" (the character is moved to an old location while moving) are now much more frequent and are happening in situations where they should definitely not happen (walking straight through open terrain on a local server).


Sometimes I think that it would be easier to trash the whole movement code (client- netcode- and serversided) and redevelope it from scratch. This time without even thinking about tiles and focusing on pixel-accurate movement from the beginnig with collisions based on bounding boxes and bounding circles. But maybe I am just too pessimistic here because I fail to see the solutions for rescuing the current code.
  • former Manasource Programmer
  • former TMW Pixel artist
  • NOT a game master

Please do not send me any inquiries regarding player accounts on TMW.


You might have heard a certain rumor about me. This rumor is completely false. You might also have heard the other rumor about me. This rumor is 100% accurate.
User avatar
leeor_net
Novice
Novice
Posts: 180
Joined: 03 Feb 2008, 09:17
Location: Ohio, USA
Contact:

Re: TMWServ/Client Asynch Problem

Post by leeor_net »

I assume that the problem I'm mentioning is the same as the mantis issue: Playing the client on a localhost server has major jumps, skips and downright ignoring of collision tiles that are so major it's actually irritating at best to play test the new content we're developing.

Exactly why one would try to adapt tile-based movement code to pixel-based movement code is beyond me but from an outside perspective, I think the best course of action would be to gut all of the movement code and rewrite it from scratch. I havn't thouroughly looked at it yet but I'm sure that the functions themselves could be left intact... it would be a matter of rewriting the function code.

Granted that makes it sound far more simple than it is but I'd be very willing to aid in this task.
- Leeor

"Oh, no thanks. I ate a boulder on the way in." - Shrek
User avatar
Rotonen
TMW Adviser
TMW Adviser
Posts: 3154
Joined: 08 Sep 2004, 19:48
Location: Bern, Switzerland

Re: TMWServ/Client Asynch Problem

Post by Rotonen »

For the sake of codebase sanity, I vote for first thoroughly designing and specifying what we want. Only after that writing it from scratch. We do not want to become Microsoftian here with our design choices. We do not have deadlines, we can take our time. Especially nothing is forcing us to use old bad code which was meant to support something which has become obsolete.

This is probably the most major element which is going to make the gameplay feel. Since we are trying to be realtime, we really do not have any space for mistakes here.

Also AFAIK it has been our policy from the beginning to only produce quality code.
This message used to be meaningful.
User avatar
leeor_net
Novice
Novice
Posts: 180
Joined: 03 Feb 2008, 09:17
Location: Ohio, USA
Contact:

Re: TMWServ/Client Asynch Problem

Post by leeor_net »

Rotonen wrote:For the sake of codebase sanity, I vote for first thoroughly designing and specifying what we want. Only after that writing it from scratch. We do not want to become Microsoftian here with our design choices. We do not have deadlines, we can take our time. Especially nothing is forcing us to use old bad code which was meant to support something which has become obsolete.
Yes, absolutely -- that is the way I usually start on any non-trivial task. The way I've gone about doing it so far is to understand exactly how the gameserver sees beings/MovingObjects. My best guess right now is that the gameserver is seeing the data one way, the client is seeing it another way, and instead of rewriting the client-side code to work with the server, it was just modified/adapted/whatever to kind of sort of work with the server. Clearly, it's not working anymore.

Second, after understanding exactly what it is that the gameserver is doing, it may be better to take a different approach. Instead of comparing the position of a being on the server and the client and synching it (as it's virtually impossible to do that realtime unless we're running the gameserver and client on the same computer and even then there's some lag), we could instead approach it by having the gameserver determine if a move from a client was within a reasonable range (e.g., if there was a 10 second gap between the last known position of the client and a client can take say, 2 steps per second, then it should not be any farther than 20 steps in any direction). If the move was within a reasonable range, leave it be, take a note of the current position and assume that there are no problems. If it's not within a reasonable range, attempt to synchronize. If it is regularly unreasonable, flag the behavior as possible cheating.
Rotonen wrote:Also AFAIK it has been our policy from the beginning to only produce quality code.
Please don't take this the wrong way because I do not claim to be an expert nor the most l337 programmer in the world nor do I look down upon anybody and their work, but, there are a number of cases in the throughout the code where policy does not dictate reality.

The global variables are a screaming example of what I (and thousands of others) would consider to be a classic case of bad/amature programming practices and poor design. In a well designed system, global variables are non existant. Especially since TMW's code is in C++, everything should be encapsulated within classes and data should be passed from module to module rather than defining global variables. This, of course, is my own humble opinion and it is a standard that I use in any project that I've ever worked on.

Additionally, there is a serious lack of proper commenting througout the code so trying to figure out what some of the more complex blocks of code does/means is no trivial task for an outsider trying to understand it. This also makes it very difficult to maintain code and has the side-effect of making it difficult to track down bugs -- if a programmer makes an assumption about the data they are expecting in a line of code, that needs to be documented. Large blocks of code really should be properlly commented so that it can be understood by others.

---

I really don't want it to sound like I'm coming in with a big head not having a clue what I'm talking about and throwing crap in everybody's face. That is not what I'm trying to do. I'm just trying to point why problems like the desynching may be occuring. I'm not an official TMW developer and so I don't know what discussions you all have so I have no idea what page you guys are on or if anybody even agrees with a single word I'm saying. I'm not a pompous ass and I don't want to cause controversy -- ultimately, I want to help and I want to contribute as much as I can. Perhaps I should just shut up and sit down, shut up and silently continue with my own life -- if this is the case, please tell me. I don't know... Am I even making any sense?
- Leeor

"Oh, no thanks. I ate a boulder on the way in." - Shrek
Tametomo
Peon
Peon
Posts: 19
Joined: 29 May 2008, 19:07

Re: TMWServ/Client Asynch Problem

Post by Tametomo »

leeor_net wrote: ...

The global variables are a screaming example of what I (and thousands of others) would consider to be a classic case of bad/amature programming practices and poor design. In a well designed system, global variables are non existant. Especially since TMW's code is in C++, everything should be encapsulated within classes and data should be passed from module to module rather than defining global variables. This, of course, is my own humble opinion and it is a standard that I use in any project that I've ever worked on.

Additionally, there is a serious lack of proper commenting througout the code so trying to figure out what some of the more complex blocks of code does/means is no trivial task for an outsider trying to understand it. This also makes it very difficult to maintain code and has the side-effect of making it difficult to track down bugs -- if a programmer makes an assumption about the data they are expecting in a line of code, that needs to be documented. Large blocks of code really should be properlly commented so that it can be understood by others.
Keep in mind that I haven't looked at too much of the code, so I can't vouch for it too much, but there are reasons to use globals. It just so happens to be that there are more reasons not to use them. Globals should never be used by anyone who doesn't know the repercussions of what they're doing, and I would go as far as to say someone who hasn't at least got a degree in CS and worked for a little while. As a general rule, there's not much reason to use them unless you're programming on the OS level, where you need that level of control.

Basically, globals were made to be evil by the people who invented the object oriented techniques. There's some stuff that their camp gets right, but they aren't perfect, and object oriented programming isn't always the ideal solution that people would have you believe it is. For instance, I believe that the singleton method is a waste of time, as anytime that you really need to use it, a global variable works just as well. A singleton just makes things messier in order to accomplish the same thing.

Anyways, enough of that little rant and on to another one. As for the number of comments, I wholeheartedly agree with you on that, with one minor exception. If a function is so large that it can't be understood easily, then it's doing way too much and should be split up. I'm of the opinion that if you can't choose a name with one verb and one noun only which can't describe everything that a function does to a tee, then you've got a serious problem and should reconsider making it just one function. One thing that I hate more than anything else is when I pick up some code written by someone else in the open source community and they insist that they don't need any functions other than main, which in itself is 250+ lines by itself. 15-20 lines should be about max, but like I said before, I trust the naming rule that I stated much more than counting lines.

Just thought that I'd let you know what I thought, as I currently hold a degree and have just started coding with a goal to eventually be doing software engineering work. Also, just to let you know, I wholeheartedly agree with Rotonen in this situation. The last thing that anyone needs is a rogue programmer going around and fixing something without knowing what the repercussions are. No matter how simple it may seem to be, if you skip designing, then you're more likely than not going to spend more time trying to fix any problems that you do cause than if you get a better understanding of what's going on and how it might affect everything as a whole. This is the sort of mistake that rookie programmers will usually make, as they haven't learned that a little patience can save them a lot of heartache yet.
Post Reply