<div dir="ltr">for the static stuff -- I would just use nginx as a web server and serve that separately.<div><br></div><div>for the game states -- if you don't need to query across all the game states (which you will eventually want to do, so that you have a game design feedback loop), then all you need to do is find a way to get the game state to be alive when the player is around, and to hibernate into storage when the player isn't.  If you are in pure erlangland or largely pure erlangland, then you might pick BERT (binary erlang term representation (<a href="http://bert-rpc.org/">http://bert-rpc.org/</a>)) as your serialization/deserialization standard for ease of use (all you have to do is erlang:term_to_binary/1) and then save that binary off to some binary storage facility (files, mysql or postgres blob fields, redis values, s3 buckets...).  Then, when a player comes back, all your gen_server for that player has to do is to figure out which file is theirs, erlang:binary_to_term/2 it, and hey presto, state restored seamlessly.</div>

<div><br></div><div>3M is a really big size for a single player game state by the way -- I would carefully evaluate how tight you can package your state, because every byte will be multiplied by the number of concurrent users you have per server.  At 3M, 1K concurrent users is 3 gigabytes of memory; 10K concurrent (feasibly if you have 200K total users)  is 30G and that's starting to become a serious server investment.  If you instead had 3K worth of hard state to carry around, you could fit your entire playerbase in a 4G server, which is quite inexpensive.</div>

<div><br></div><div>F.</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jul 15, 2014 at 11:42 AM,  <span dir="ltr"><<a href="mailto:lloyd@writersglen.com" target="_blank">lloyd@writersglen.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><font face="arial"><p style="margin:0;padding:0;font-family:arial;font-size:10pt">Hi Felix,</p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt"> </p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">Thanks for helping me think this through.</p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt"> </p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">- Players do not interact. Each player is playing against the "real world," e.g. results of their actions. Think of it as project planning with many many contingencies. I'd say "expert system," but that sounds rather hoity toity. I say "game" only in the sense that there are reward points for successful action.</p>


<p style="margin:0;padding:0;font-family:arial;font-size:10pt"> </p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">Loop is basically:</p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt"> </p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">- gather facts</p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">- make plan</p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">- take action</p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">- evaluate results</p>
<p style="margin:0;padding:0"> </p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">- There are universal resources accessed by player state but these, as a whole, are static text, links, and images; wild-eyed estimate: 10 megabytes</p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">- I estimate that each player will store less than three megabytes of private data.</p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt"> </p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">- We're not dealing with elaborate graphics or animations. Only latency is a logic tree or inference engine evaluating facts; e.g. (Looking at Erlang eres/seres; but I may be able get away with something more simple minded).</p>


<p style="margin:0;padding:0;font-family:arial;font-size:10pt"> </p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">Latency, in other words, is a function of how many private and shared database lookups are necessary to evaluate a set of condition -> action rules. Effective state management should help me keep rule sets fairly minimal.</p>


<p style="margin:0;padding:0;font-family:arial;font-size:10pt"> </p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">Prospects for this game are in the 200K range, but I'm successful with low hundreds of players.</p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt"> </p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">Ad hoc querying is not necessary.</p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt"> </p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">Thanks again for your help.</p><span class="HOEnZb"><font color="#888888">
<p style="margin:0;padding:0;font-family:arial;font-size:10pt"> </p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">Lloyd</p></font></span><div><div class="h5">
<p style="margin:0;padding:0;font-family:arial;font-size:10pt"> </p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt"> </p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt"> </p>
<p style="margin:0;padding:0;font-family:arial;font-size:10pt">-----Original Message-----<br>From: "Felix Gallo" <<a href="mailto:felixgallo@gmail.com" target="_blank">felixgallo@gmail.com</a>><br>Sent: Tuesday, July 15, 2014 1:50pm<br>

To: "Lloyd R. Prentice" <<a href="mailto:lloyd@writersglen.com" target="_blank">lloyd@writersglen.com</a>><br>Cc: "Erlang-Questions Questions" <<a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a>><br>

Subject: Re: [erlang-questions] What is best way to maintain state in a web-based multiplayer game?<br><br></p>
<div>
<div dir="ltr">I think you have some more marble to cut away before the shape of the problem begins to reveal itself.
<div>* do the players interact with each other directly?  If so, what state do they share and how much?  Is there a separation between 'state for everyone' (e.g. world of warcraft: the entire world geometry and all 3d models are gigabytes of static data that are stored on the local filesystem and not kept 'live' in memory) and 'player state'?  What is the size and nature of each type of state?</div>


<div>* what are the constraints around latency -- does it look more like a real time game (e.g. street fighter, counterstrike, league of legends) where, e.g., 250 ms of latency is unacceptable to the experience, or more like a turn based game (e.g. chess, poker, backgammon) where latency of 3s is tolerable?  This drives certain considerations; e.g., you may be able to use a slightly lower performance but more reliable database system for the latter case.<br>

<br></div>
<div>* what is the shape and nature of your cost envelope?  If you are running server infrastructure for a game, then you may need to take special measures to ensure that your costs remain beneath your gross profit.</div>


<div>Since, as you say, managing game state is such a giant pain in the ass, my general best practice when I do exactly this thing as part of my day job is to first write down all of the different kinds of state, their approximate quantity in bytes per player/world/universe/shard/whatever, and then do some spreadsheet math to figure out what I can get away with.</div>


<div>Example: Game is Facebook-style web game like Farmville.  State can be boiled down to a binary data structure that is 4 kilobytes in size per player.  Expected profit per user is on the order of pennies.  Tens of millions of users expected.  Solution: save state in the user's own browser via encrypted cookie, use tiny database (sqlite, mysql, etc.) for leaderboards and sending seeds between players.  </div>


<div>Example: Game is World of Warcraft style MMO but you're trying to do it in the browser so can't download gigabytes.  So you must shard each zone into, say, a 50 megabyte downloadable size.  Zone shards are static so can be files.  Private player data (e.g. inventory, raid history, message log) is maybe 1 megabyte; public player data (e.g., x/y/z coordinates, avatar skin) is maybe 30K and shared across the entire world (but usually limited to a shard), needs fast access though as the world ticks at 30 frames per second and you need to do distance calculations, etc.  Store the public player data in memory, dets (per shard) or redis depending on whether you want raw speed, resiliency, or tooling.  Store the private data in memory, dets, redis, or mysql, depending on speed, resiliency, tooling, cost and analytics requirements.</div>


<div>Generally I use ets for fast-access random-lookup state that has to get shared between processes, redis for fast-enough (still plenty fast) random-lookup state that has to be able to get large and/or survive system crashes or writeoffs (via slave replication and aof, rather than clustering), mysql for mass market mediocre state storage where the client has pre-existing infrastructure and ad hoc querying is important, postgres for green fields state storage where ad hoc querying is important, and thankfully so far I have been able to avoid having to use inconsistent data stores in production.  I wouldn't ever consider dets or mnesia because equivalently-functional tools exist that are radically more popular and have better tooling, capability, characteristics or safety guarantees.</div>


<div>F.  </div>
</div>
<div class="gmail_extra"><br><br>
<div class="gmail_quote">On Tue, Jul 15, 2014 at 10:03 AM, Lloyd R. Prentice <span dir="ltr"><<a href="mailto:lloyd@writersglen.com" target="_blank">lloyd@writersglen.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br> I'm thinking through the design of a web-based multiple-player game. Each player maintains a private database--- most likely dets. Each player moves through nested finite state machines. Each player may be logging in or out at any state of play.<br>

<br> At this point my grasp of Erlang architecture breaks down. I don't understand how best to:<br><br> - parse game structure across players, processes, and directories<br> - maintain player state between sessions<br>

<br> At this point in my Erlang education I feel like I know the words but can't play the music.<br><br> I'd much grateful for any and all ideas and suggestions.<br><br> Many thanks,<br><br> LRP<br><br> Sent from my iPad<br>

 _______________________________________________<br> erlang-questions mailing list<br><a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br><a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a></blockquote>


</div>
</div>
</div></div></div></font></blockquote></div><br></div>