You don't need to wait for OK before issuing the next command. Implement a pipeline. You already have the UI to tell the user he "can't do that."
So, issue commands when the player issues them. On the server, perform commands when you receive them. If the command fails, send a message back to the player, saying that command X failed. In the UI, you will need an "intermediate" state, after a command has been issued, but before it's actually in process. This could be empty, or a shadow/ghost image, or whatever.
Client giving orders problem (RTS)
It sounds to me like the real problem is that your time steps are 1 second long. If you want less lag, make the server verify commands as soon as possible, and don't wait one second.
I'm guessing the 1 second time probably comes from the original game you're cloning, but you're applying it in places where it doesn't really make sense - your server should be constantly giving out information, even if new things only happen once a second. As soon as it gets a command, it should send the response so that it gets back to the client as soon as possible.
I'm guessing the 1 second time probably comes from the original game you're cloning, but you're applying it in places where it doesn't really make sense - your server should be constantly giving out information, even if new things only happen once a second. As soon as it gets a command, it should send the response so that it gets back to the client as soon as possible.
Quote:Then, when you receive an OK, you move the unit from the build list to the real world as if it had been built earlier. When you receive a KO, you remove it from the build list and refund. If no response, you also remove it and refund.
I can't to this because the AI is iterative. The AI must know whether or not the build order has been done to iterate the next line of the AI script.
Quote:It sounds to me like the real problem is that your time steps are 1 second long. If you want less lag, make the server verify commands as soon as possible, and don't wait one second.
I've never sets the timestep to 1s. The server handles the commands as soon as it receives them. The lag comes from the high number of little "buy unit" orders.
Here's how i've done to resolve my problem (no magic solution):
To sum up, the problem comes from 2 points:
- high number of simple 'build unit' orders given by an iterative AI script
- each order has an impact on a shared variable (the money) and of course the shared money has an impact on the orders
The AI script loops around 1000 times to buy units, each loop waits for the server response to sync the shared money with other players.
According to your responses and my research, there isn't any possibility to *considerably* speed up the process without changing pre-requisites.
I've made the choice to remove the shared money. This hasn't a big impact on the game and I don't think i'll implement it in the future. Thus, i can now predict the AI script, without waiting the server:
- while money > $2 - build unit locally - send server 'build unit' order to sync other players simulation (but no rush) - don't wait response from server- end-while
I've updated my code and it works great.
Thank you all for your support,
Pascal
Why dont you request from the server, a 'cash advance'? If you need 500$ to build something, say, "I want to block 500$ to do my constructions. Can I?". Server says yes / no and tranfers fund in your personal account and the construction starts.
a basic banking system, bank holds the pot of gold, and each player has an account to transfer funds back and forth if they need / cancel a build.
a basic banking system, bank holds the pot of gold, and each player has an account to transfer funds back and forth if they need / cancel a build.
Quote:Original post by KroahQuote:Then, when you receive an OK, you move the unit from the build list to the real world as if it had been built earlier. When you receive a KO, you remove it from the build list and refund. If no response, you also remove it and refund.
I can't to this because the AI is iterative. The AI must know whether or not the build order has been done to iterate the next line of the AI script.
I think this is the essence of your problem.
(I know you said you've worked around it, but I'd like to talk about it anyway.)
1) You have many orders to run quickly and in sequence.
2) Each order must be fully acknowledged before the next one starts, due to consistency issues.
3) Your system must use networking, which places inherent significant latency on how quickly an order can fully complete.
There's absolutely no way around this without removing or relaxing one of the constraints. Reducing the number of orders (eg. by batching them) would help. Splitting the AI up so that some operations can run in parallel would help. And reducing the overhead of the networking would help.
If it was my game - and I appreciate that I say this without understanding the underlying game you're modelling - I'd look at reworking the AI so that it can make assumptions about the current state and backtrack if that assumptions later proves to be false, resuming from the last known good point. (I suppose this would work much like branch prediction in CPUs, tech fans.)
If you had "too much lag" in a server authoritative model, then what was the source of lag? StarCraft, Warcraft III, Age of Empires, and a lot of other RTS games all use that model. Note that, if you're using TCP, you must turn on the TCP_NODELAY socket option on client and server to get low latency communications, perhaps the lag came from there?
One kind of resource that is implicitly shared is land. Thus, if I want to build on square X, and you also want to build on square X, then only one of us will win, and there is NO WAY of knowing who won without a round-trip on the network. Design for that round-trip. This typically means pipelining, and being able to back-track if you get a NAK for some previously issued command -- or just "adapt and deal" if the operation is later shown to have failed.
After all, if you start building in spot X, and it succeeds, but then an enemy flies in and shoots down the project that's underway, that's not much different than the project not being started at all. Hopefully your AI already knows how to deal with a case like this?
One kind of resource that is implicitly shared is land. Thus, if I want to build on square X, and you also want to build on square X, then only one of us will win, and there is NO WAY of knowing who won without a round-trip on the network. Design for that round-trip. This typically means pipelining, and being able to back-track if you get a NAK for some previously issued command -- or just "adapt and deal" if the operation is later shown to have failed.
After all, if you start building in spot X, and it succeeds, but then an enemy flies in and shoots down the project that's underway, that's not much different than the project not being started at all. Hopefully your AI already knows how to deal with a case like this?
Something that seems possible is batching requests and validations.
An AI loop would be:
while my side has money
ask to build N units (as many as we can afford)
receive permission from the server to allow me to build X units (X<=N); the server commits the resources to make X units to me
for X times
actually build a unit paid from my own funds (with appropriate exchanges with the server)
The server can make smarter assignments of resources than enough/not enough verifications; for example, human players can get more resources and units than their allied AI players, or fairness between allies can be enforced.
The player AI knows something new, the value of X and that construction won't be slowed or delayed because of resource shortage after the server commits resources to a batch of X units: both information items can with the planning of unit formations and future attack and build orders.
An AI loop would be:
while my side has money
ask to build N units (as many as we can afford)
receive permission from the server to allow me to build X units (X<=N); the server commits the resources to make X units to me
for X times
actually build a unit paid from my own funds (with appropriate exchanges with the server)
The server can make smarter assignments of resources than enough/not enough verifications; for example, human players can get more resources and units than their allied AI players, or fairness between allies can be enforced.
The player AI knows something new, the value of X and that construction won't be slowed or delayed because of resource shortage after the server commits resources to a batch of X units: both information items can with the planning of unit formations and future attack and build orders.
Quote:Original post by Kylotan
I think this is the essence of your problem.
(I know you said you've worked around it, but I'd like to talk about it anyway.)
1) You have many orders to run quickly and in sequence.
2) Each order must be fully acknowledged before the next one starts, due to consistency issues.
3) Your system must use networking, which places inherent significant latency on how quickly an order can fully complete.
You've really well summed up the problem.
Quote:Original post by Kylotan
There's absolutely no way around this without removing or relaxing one of the constraints. Reducing the number of orders (eg. by batching them) would help. Splitting the AI up so that some operations can run in parallel would help. And reducing the overhead of the networking would help.
You're right. After many thoughts, i've finally chosen to remove constraint 2). The original game wasn't using this much anyway.
If, for any reason, i want to put this rule back, i'll use something like oliii said: a bank system, or why not an automated donation system like supreme commander (when stocks are full, give %amount, and check this each second).
Quote:Original post by Kylotan
If it was my game - and I appreciate that I say this without understanding the underlying game you're modelling - I'd look at reworking the AI so that it can make assumptions about the current state and backtrack if that assumptions later proves to be false, resuming from the last known good point. (I suppose this would work much like branch prediction in CPUs, tech fans.)
I first thought for this solution, but the AI being the core of the game, i had to do soo many changes i wasn't able to check the consistency of the AI beside the original one. So i rollbacked my work and choosed another way (another constraint) having less impacts.
Quote:Original post by hplus0603
If you had "too much lag" in a server authoritative model, then what was the source of lag? StarCraft, Warcraft III, Age of Empires, and a lot of other RTS games all use that model.
The high number of server calls (one for each build unit order) with client waiting for response was the source of the lag.
Quote:Original post by hplus0603
Note that, if you're using TCP, you must turn on the TCP_NODELAY socket option on client and server to get low latency communications, perhaps the lag came from there?
The game is programmed in C#. The .Net TCP code is not very well optimized (read here, it's slow as hell). I've tried to enable/disable some features but had no improvements. C# uses SOAP to communicate, so i thought it was full xml. I've used 'Packet Sniffer .NET' http://www.packet-sniffer.net/ to trace the communication and see if i was sending in plain SOAP text or not. But .Net serialization was already sending it in binary because the client is in C# too. The bandwidth wasn't highly used either.
Quote:Original post by hplus0603
One kind of resource that is implicitly shared is land. Thus, if I want to build on square X, and you also want to build on square X, then only one of us will win, and there is NO WAY of knowing who won without a round-trip on the network. Design for that round-trip. This typically means pipelining, and being able to back-track if you get a NAK for some previously issued command -- or just "adapt and deal" if the operation is later shown to have failed.
For some order like this, i use a sort of basic pipeline. Because this kind of orders are sparse, i haven't problem with them.
Thank you for your ideas and sharing your knowledge.
Pascal
[Edited by - Kroah on September 26, 2007 4:43:40 AM]
Quote:The high number of server calls (one for each build unit order) with client waiting for response was the source of the lag.
Unless the server was in France, and the player in Australia, you shouldn't see terrible lag with a server round-trip time. Thus, the source of lag might be something else. See below.
C# doesn't "use" SOAP, unless you use some specific part of the .NET library that uses SOAP. You could write plain sockets on C#. And C# networking isn't "slow as hell," unless you use the high-level XML/SOAP/RPC interfaces. So don't use those! SOAP likely doesn't turn off Nagle (i e, keeps TCP_NODELAY off), thus the delay likely comes from that, much more than any SOAP processing.
If you have lag, you have to analyze all parts of the pipeline to figure out where the lag is coming from.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement