Lesson 2.1: Initial Player Class

As we start building our RPG, we need to consider how to design the layers of the game. It is a typical pattern to separate the user interface from the code that drives behavior. For a game, we would separate the game screens and UI from the the game engine. We want to put as little code logic as possible into the game screen and components. We want to have the complex logic in the game engine, so that it is easier to test and enables us to reuse the game engine for multiple games.

Create GameEngine Library

To do this, we’re going to create a separate class library that holds our data classes and game logic. As we’ve done in chapter 1, let’s add a new project to our simple-rpg-game solution. Right-click on the solution and select Add > New Project. This time create a Class Library (.NET Standard).

Fig 1 – Add new project – Class Library (.NET Standard)

Then, name the class library project: SimpleRPG.Game.Engine. And click the Create button.

Fig 2 – Configure Engine project

This will create a new library project with a single class in it. Delete that class for now, so that we can start clean.

You may be wondering: what is a .NET Standard class library? .NET Standard is a formal specification of .NET APIs that are intended to be available on all .NET implementations. The motivation behind .NET Standard is to establish greater uniformity in the .NET ecosystem. A .NET Standard class library can be run on any platform that supports .NET Standard… which includes, .NET Core, Blazor, Xamarin, Unity, and more. So this type of library gives us the broadest reach for our code.

Blazor WebAssembly requires .NET Standard 2.0 or higher class libraries, so that’s why we created this type of class library. But the fact that it also has the broadest reach on .NET is a great reason to target class libraries to .NET Standard.

Next, right click on the newly created project – SimpleRPG.Game.Engine. And select the Properties menu item.

Fig 3 – Project properties

In the Application tab, change the Target Framework from .NET Standard 2.0 to .NET Standard 2.1. This is the latest version and gives us a few additional capabilities. Since this is a new project, we want to target the latest and greatest.

Let’s save everything and build the project. We now have an empty .NET Standard 2.1 class library.

Create Player Class

We need a C# class to represent the player of the game. This class will contain all of data for a player and any interactions with that class.

To create this class, we will first create a new folder in the Game.Engine project. Let’s create that folder and name it Models. By convention Models are data classes and entities that represent your domain. For an RPG, that would be concepts like: Player, Item, Monster, Location, Quest, etc. Since we’re going to have many of these classes having a separate folder for them makes sense. And if we use a naming convention across our projects, the code will be easier to understand.

Now let’s create the new class:

  • Right-click on the “Models” folder
  • Select Add > Class
  • Then, name the class “Player.cs”
  • Finally, click the Add button to complete the operation
Fig 4 – Add new class

This will result in a new file being created and the editor open with that file. Now we’re going to add the initial code to that class.

namespace SimpleRPG.Game.Engine.Models
{
    public class Player
    {
        public string Name { get; set; } = string.Empty;

        public string CharacterClass { get; set; } = string.Empty;

        public int HitPoints { get; set; }

        public int ExperiencePoints { get; set; }

        public int Level { get; set; }
        
        public int Gold { get; set; }
    }
}

The first line defines the namespace our Player class belongs to. The namespace keyword is used to declare a scope that contains a set of related objects. You can use a namespace to organize code elements and to create globally unique types.

The Player class itself starts with a set of properties that hold data about a player in our game. Properties contain a datatype like string, int, decimal, etc; a property name; and the getter and setter operators that enable calling code to read and write data to the properties.

Reading the Player.cs file, we have a class that can hold all of the above properties. We haven’t added any operations or behavior yet, but we will add those later.

Create Another Test Project

Now that we have the SimpleRPG.Game.Engine project, we want to create a test project just for that library. We build matching test projects, so that our tests are logically broken down just like our code. Also if we decide to move the game engine out to another solution, we can also easily move its tests.

We’ll follow the same process above but this time create a new xUnit test project:

Fig 5 – Add new xUnit test project
Fig 6 – Configure Engine test project

Follow the steps to create an xUnit test project named: SimpleRPG.Game.Engine.Tests.

Then, right click on the new test project Reference node and select the Add Project Reference. Finally, check the SimpleRPG.Game.Engine item and click OK.

Fig 7 – Add project reference

We want our test projects to closely map to our source structure, so also create a Models folder within it. Then create a new PlayerTests.cs file. Let’s create a test to simply verify that our properties are working as expected.

using SimpleRPG.Game.Engine.Models;
using Xunit;

namespace SimpleRPG.Game.Engine.Tests.Models
{
    public class PlayerTests
    {
        [Fact]
        public void CreateSimplePlayer()
        {
            // arrange

            // act
            var p = new Player
            {
                Name = "Test",
                Level = 1,
                HitPoints = 10
            };

            // assert
            Assert.NotNull(p);
            Assert.Equal("Test", p.Name);
            Assert.Equal(string.Empty, p.CharacterClass);
            Assert.Equal(1, p.Level);
            Assert.Equal(10, p.HitPoints);
            Assert.Equal(0, p.ExperiencePoints);
            Assert.Equal(0, p.Gold);
        }
    }
}

We can now rebuild the whole solution and run all of the tests. We will see that a new namespace shows up in the Test Explorer with our latest test in it.

Fig 8 – Test Explorer results

Let’s commit our code before we move on to the next lessons…

2 thoughts on “Lesson 2.1: Initial Player Class

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s