View Single Post
Old 11-16-2012, 07:12 AM   #7
koteko
New Member
 
Join Date: Mar 2012
Posts: 20
koteko is on a distinguished road
Re: Event-based with threads instead of game loop

Wow, thank you guys. That's a awesome lot of answers. I see that I've definitely been too fast in my search of codebases, I'll have a look at CoffeeMUD but..I fear my own self-challenge won't allow me to throw my code in the rubbish.

Let's go in order, anyway:

@Ide: thank you for the suggestion, I'll surely use a framework to stress-test my little MUD or I might write a bruteforce user-faking class for the purpose. I'll just have to add a few milliseconds to each socket transaction to fake the internet delays.

@camlorn: I'm processing the tons of suggestions you've given me I'll look into akka too. But I guess some of your remarks would only stand true in a totally asynchronous system. I don't totally understand that "edit" part though. I do use reflection to get the commands, and I don't have to touch the IO: the threads dedicated to the player pre-process the strings, get the correct Command class instantiating it and than they put it in a global blocking queue.

The ActionExecutor blocks on this "pendingCommands" queue and when something comes up, it executes it. So far, with no optimisation, each command takes less than 1ms to execute (I should start looking at nanoseconds to improve things). So unless in the same exact moment (the very same millisecond) are issued 100 commands, the user would see the effect of his/her command without lag (I'm using the 100ms rule of thumb here, but you get the idea).

For the rest, there is no trace in the commands' code of threads things, since the single command is going to be executed sequentially. Also, I don't think the building layer would need in any way a mention of concurrency-related stuff, considering how mob AIs or Room events are going to be issued and built inside separate threads, but executed into the same action executor. But I haven't implemented yet a building layer, so far it's pretty much all hard-coded (MobAIs are classes, and I use reflection at bootstrap to get the corrent AI-class for a particular mob just loaded).

I don't see a problem even in combat, for example. I'm going to implement a first version of this shortly, and my first thought is about timed tasks and status variables. For example, if player A attacks player B, and the fight begins, they both will have a status "IS_FIGHTING". According to their skills and other things, a first TimedTask will be issued from the attacker, let's say in 1.5 seconds, to do the first hit, and at the same time another TimedTask will be issued from player B, the defender, let's say in 2 seconds, to do his first hit. They will run as timed, very short-lived threads, just doing this:

1. check if the player is still fighting
2a. if yes set up a hit (this is a Command that will go into the ActionExecutor)
2b. if not, terminate

The command that makes the hit will do what it has to, but in addiion it will also have to either stop the fight for some reason, by changing the status of both players to "IS_NOT_FIGHTING" or something, or to issue another TimedTask for the next hit. In this way I can control, for example, also shorter distance hits (the command Hit at time t will issue a TimedTask in 0.5 seconds instead of 1.5 seconds).

At this point of development I don't see any drawbacks, but I'm not sure.

Just to mention it, there isn't overhead in creating this little timedtask (at most, at a particular time there can be as much TimedTasks as logged players+active mobs) because I am using ExecutorServices with thread pool caching. I could even reduce further the overhead by using the Command itself as a TimedTask. Actually now that I say it, it seems more reasonable and quicker to do.

@KaVir: just searched for the thing, and I might have read it one year ago because it gave me the same willingness to NOT go for a totally asynchronous system, but using a global queue for pending commands. Thank you for reminding me of it

@Viriato: Nice to hear this from you! So you have actually been more brave than me: you went for a totally asynchronous thing and make it work. For the rest, I am following your same approach: a MobAI class (actually two of them, one for all the mobs and the other for active mobs, in this way I can have immediate reaction from aggressive mobs, for example, when a player enters the room, and I still "move" also the others that are far away from any player), and I plan to use a dedicate threads for many other things like the weather.
koteko is offline   Reply With Quote