Creating A Game Library (Best Practices?)

I've created a 'Windows Game Library' project to act as a re-usable API on which to build my games. It will contain most the basics... Sprite drawing objects, Line drawing, Bitmap Fonts, Input, etc...

The thing I'm running into is how best to give my library layer access to all the important details from the game layer. Properties in the GraphicsComponent and Graphics Device are two good examples.

Should I design all my objects to take a "Game" object as a parameter and call back using that Is there a better way What are other people doing

Thanks.




Answer this question

Creating A Game Library (Best Practices?)

  • Tony Brett

    Thanks, Jurak. That's the kind of stuff I was looking for.



  • Zulu27

    No offense to the authors, but demo code like "Space Wars" is not usually the best place to look for "Best Practice" code. Personally, I think passing dependent objects to a constructor is usually a bad idea. What if two objects are both dependent on eachother You can't pass them both to the constructor. You can pass the object it needs to it when it needs it, OR you can use a Service based approach, which XNA provides to allow a component to find another component that it is dependent upon.

    Here are some stubs that show a simple and common design.

    namespace MyGameLibrary.Graphics
    {

    public class Context
    {
    public GraphicsDevice Device { get; set; }
    public Matrix World { get; set; }
    public Matrix View { get; set; }
    public Matrix Projection { get; set; }
    // other properties here that correspond to standard Effect file Semantics...
    }

    public class Node
    {
    public IList<Node> Children { get; }
    public void Initialize(Context context); // called once initially, then with device resets.
    public void Update(float time); // called once ever frame
    public void Render(Context context); // called once per frame to allow rendering.
    }

    public class Shape : Node
    {
    BoundingBox Bounds { get; }
    }

    }

    // when an effect is about to begin, it can look at the 'Context' object to get the values that it should set it's parameters to before it starts rendering.
    // after an effect is started, any child shapes can render themselves, when that returns, the effect ends or starts a new pass.




  • Ricardo_ES

    "That said, on GBA games, I would usually have a global pointer to something like "Game" as opposed to constantly passing it in as a parameter"

    I've done this before as well, the problem is my Game Library code does not have a reference up to the assembly that contains my "Game" object.

    I'd like to see some more examples using the "Game Services" method for building an re-usable engine layer.



  • Dany V

    At the moment I am thinking it might be best to just use whatever is in SpaceWar (though I'm changing the class names) as a temporary solution until they release the Content Pipeline stuff. As far as you know it could turn out to be incompatible with whatever you write.

    That said, on GBA games, I would usually have a global pointer to something like "Game" as opposed to constantly passing it in as a parameter. I'd usually try to encapsualte any other universal management objects ("Singletons") beneath this so as to keep the number of globals to a minimum. I'm not sure how possible this is in C# since I'm just starting out with it. As I recall globals are considered bad form when you're trying to be object-oriented, but they can sometimes greatly simplify the "what is the best way to pass things in where" problem.


  • Adminanup

    Thanks for the feed back so far.

    Spacewars is a good example to explain what I'm struggling with.

    The RetroShip has an object hiearchy like so:

    RetroShip --> VectorShape --> Shape.

    Shape get's a "Game" object in it's constructor and so can then access the Device thru the IGraphicsDeviceService.

    VectorShape extends Shape but VectorShape not only makes use of the "Game" object that was passed in, but it also calls into the static properties of the "SpacewarGame" object. (

    worldViewProjectionParam.SetValue(World * SpacewarGame.View * SpacewarGame.Projection);

    RetroShip extends VectorShape and simply provides the vertex info.

    So, this is all fine when everything is in a single assembly like it is in Spacewars, but I'm interested in pushing things like VectorShape and Shape down into a Game Library. My question revolves around how to give my lower layers access to things like the View matrix and Projection matrix and any other "generic-game" info. I can see several ways to do it: add these properties to my lower level objects and pass them in as needed from the Game layer, define some sort of custom interface like IMyGame that has these properties and pass that to my lower layer objects instead of the Game object (Game would be a part of this interface), and I'm sure there are other ways. I'm just don't have a good idea what is the prefered way... if there is one.



  • Ed209

    If you are building a "Scene Graph", then usually the objects don't hold any reference to the GraphicsDevice or related components. They are just passed to them in a recursive rendering call.

    for instance:

    public class Node
    {
    public IList<Node> Children;
    public virtual void Update(float delta);
    public virtual void Render(GraphicsDevice device) // use a wrapper that contains a GraphicsDevice if you want some abstraction.
    {
    foreach(Node child in Children)
    child.Render(device);
    }
    }

  • Jkumar

    edit (after a bit more study): The SpaceWars sample passes the game object to each component's constructor if it's a graphical element. That's probably good since the component can get the graphics device if it needs to be recreated.

  • rusty_dev

    All the drawing stuff just needs to use the graphics device for initialization right Pass a reference to the device to the classes when you create them. It doesn't need access to it after that, unless you lose the device. In that case you can call each component's Initialize function with the new graphics device. The SpaceWars sample passes the game object but I don't see why it does that instead of just passing the device. Of course I haven't fully studied all the code in there yet.

  • Creating A Game Library (Best Practices?)