Hello Monks,

I'm toying with some proof-of-concept code for an online game with the logic written in Perl (and Moose). The game would have a typical client/server architecture, with the closed-source server determining all critical game state and logic, and open-source client handling the player UI and game view. What I'm not sure of is how to model the game state in the client without duplication of code. Say I have the bad guys modeled like so (simplified):

package TheGame::BadGuy; use Moose; has health => (is => 'rw', isa => 'Num'); # 0 == dead has max_health=> (is => 'rw', isa => 'Num'); # 100% health has inventory => (is => 'rw', isa => 'ArrayRef[TheGame::Item]'); sub health_percent { return $_[0]->health / $_[0]->max_health; } # ... many more attributes and methods

The server of course needs low-level r/w access to this information. The client, however, will run on the player's computer and must therefore have limited access but enough to display the bad guys on screen and determine how the player may interact with them.

The rub is: I'm operating under the assumption that someone will start hacking at the Perl client code. Obviously the client can't just do $badguy->health(0); and expect a meaningful result; that's not the issue. The issue is exposing only select fields to the client (possibly munged) so it's non-trivial to reverse-engineer the game mechanics (see Note), and how to design the class(es) efficiently. For example:

So, then, what's the best way to go about this? Keeping in mind the client will receive some kind of serialized copy of the relevant data (and only the relevant data), here are some options I've brainstormed so far:

  1. Subclass to TheGame::BadGuy::Client, with the "hidden" fields overridden to throw exceptions (the underlying hash elements wouldn't ever have been initialized, either). This sounds good on the surface, but it also implies I have to either release the server TheGame::BadGuy source with the client, or create an alternate TheGame::BadGuy package, which makes me more than a little queasy.
  2. Don't bother subclassing anything. Just instantiate a TheGame::BadGuy in the client, with only the desired fields populated. Allow undef for others. Override health_percentage, or maybe just normalize health and max_health to e.g. 0..1 or 0..100.
  3. Create a new non-subclassed TheGame::Client::BadGuy class that mirrors the desired fields, with no mention of any other fields.
  4. Go up one more level: TheGame::BadGuy is the superclass for TheGame::BadGuy::Server and TheGame::BadGuy::Client
  5. Something else?

There are tradeoffs to each of these. But it still feels like there's a pattern I'm missing (it's been a while since I did any serious OO design, plus this is my first non-trivial effort with Moose).

Note: I believe that determined players should be able to figure out most of the game mechanics, but doing so should involve observation, math, and intuition, not just a couple of trivial method calls. In fact I'd be honored if someone cared enough to go to the effort.


In reply to Moose class design for game by wanna_code_perl

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.