[erlang-questions] How to write a MMO game server in Erlang?

zxq9 <>
Wed Feb 3 04:45:06 CET 2016


On 2016年2月3日 水曜日 11:28:40 月忧茗 wrote:
> I try to using Erlang to implement my tiny mmo game server.
> 
> I know the skeleton of c++ version is like this:
> 
> int main()
> {
>     GameApp app;
>     int interval = 50;  //50ms, 20 ticks per second.
>     int sleep = 0;
> 
>     uint64_t tick_start, tick_end, tick_passed;
>     while(true)
>     {
>         tick_start = CurrentTick();
>         // all logic, timer will be drive in the app.tick
>         app.tick(tick);
>         tick_end = CurrentTick();
>         tick_passed = tick_end - tick_start;
> 
>         sleep = interval - tick_passed;
>         if (sleep < 0) sleep = 0;
>         SleepMilliSeconds(sleep);
> 
>     }
> }
> 
> But now, I have no idea about the Erlang version.
> 
> in the erlang world, one client is one process (maybe gen_server). the
> process has it's own loop, and timer can use erlang:send_after or
> erlang:start_timer .
> 
> I want to know how to implement a MMO server in erlang ?
> 
> consider this situation:
> 
> Player A VS Player B.
> 
> A cast a skill X to some direction, then X flying.
> 
> the server need to detect whether X is hit on B,
> 
> When hit, add X's debuff on B, debuff will remove after 3 seconds.
> 
> ......
> 
> many things , many times , many sync ...
> 
> c++ has a signal tick,
> 
> But how about erlang ?

It depends on the combat system, specifically, but generally speaking
spawning a new process to represent the combat itself is the easiest way
to handle this.

In a turn-based fight this is easy: Spawn a combat process with the involved
characters communicating with it. The characters send their combat inputs
as messages (synch and asynch), and the combat process itself moderates
interaction rules, timing and renders outcomes -- broadcasting events
to all parties. Because the combat process is broadcasting interactions
it can also determine if some actions are supposed to not be broadcast
to some parties -- for example, if one character is a thief and has "steal"
X% and steals from character A, character A may not be able to detect the
attempt but character B (who is not the thief) may have noticed it. Etc.

In a moderated-time fight things work similarly (like World of Warcraft):
Spawn a process to manage the combat, and add characters as they become
involved in that particular fight. Fights generally work as meshes in
this case, where if A is targetting B, and B is targetting C, they are
all three managed by a single combat process. If A and B are fighting
and C and D are fighting, and then A and C wind up targetting each other
then the older process takes over completely and inherits the younger
fight's history. In games where there are complex area effect and relative
experience effects (based on party grouping, etc.) then it is more common
to have the process that controls the *location* be the combat arbitration
process.

In a real-time combat game... I'm not sure, because I've never written one
that was FPS, but I think the only solution would be to have the location
manager itself do combat arbitration.

An alternative approach is to have the character processes themselves
moderate their own combat interactions -- and this is totally possible --
but it can be extremely complicated because there will be a mix of synch
and asynch messages necessary based on the type of interaction involved,
and having symmetric protocols between identical peer processes is a recipe
for creating lots of weird deadlocks. (The best way I've seen to deal with
peer combat deadlocks, by the way, is to actually use them as part of the
combat system itself -- having timeouts become a useful effect of their own.
This also means that the connection process, the character control process
and the character process itself have to each be separate, though, otherwise
a combat deadlock also becomes a network, chat, and admin deadlock, which
is usually not acceptable.)

There are many approaches -- but first you have to let go of this idea that
there is a single global tic.

One of these days I will finally get back to working on the example game
server...

-Craig


More information about the erlang-questions mailing list