game design improvement - c#

I was having a discussion with my developer mate on following game design.
I have a collection of Move in the Game class. my developer mate is asking me to remove the collection and only have the current move information there.
what is your suggestions?
public class Game
{
public String Id { get; set; }
public String CreatorId { get; set; }
public List<Player> Players { get; set; }
public List<Move> Moves { get; set; }
}
public class Player
{
public String Id { get; set; }
public String Name { get; set; }
}
public class Move
{
public String Id { get; set; }
public String PlayerId { get; set; }
public String PlayerName { get; set; }
public String NextMoveId { get; set; }
public String NextPlayerId { get; set; }
public String Position { get; set; }
}
Edit:
my developer mate suggests me to only have a single Move object in the Game class.

There's no really correct approach that any of us can provide for your design. It isn't a cut-and-dry situation; there's no "right" or "wrong" answer. And it's especially difficult for us to make suggestions given that we don't know all of the details behind your game's design. For example, as I asked in a comment and several of the other answers have hinted towards, if you have an "Undo" or "Replay" feature, you will need to store a history of all the moves. If not, and you have no desire to implement such a feature, there is no need to store information about all of the moves.
This is the kind of design decision that you need to learn how to make as a programmer. Consider all of the possible benefits of one approach and the benefits of the other approach, then decide which one best suits your application. Make a "T" chart if you find it helpful. Something like:
Keeping List of All Moves | Storing Only Last Move
---------------------------------------|------------------------------------
- Allows you to implement Undo | - Simplifies your game's design
or Replay feature |
- Consumes more memory | - Saves memory by only storing the
| minimum amount of data
|
|
...etc.
In the end, you (and your colleague) are the ones in the best position to make this decision. Making sure that you've armed yourself with a careful comparison of the advantages and disadvantages is the best way to ensure that you've made the right one.

A game often consists of a set of moves performed by one or more players. Between each move, the game is in a certain state.
If you have the current state, and no need to playback or undo any moves, you would never access the previous moves. Future moves are not known yet, so with just the information you provided, I'd say Game should not have any Move, just a State and a ProcessMove(Move move) method to change the Game's State. The Move is generated by one of the Players.

public class Game
{
public String Id { get; set; }
public String CreatorId { get; set; }
public List<Player> Players { get; set; }
public String PlayerId { get; set; }
}
public class Player
{
public String Id { get; set; }
public String Name { get; set; }
public String Position { get; set; }
public Move(string NewPosition);
public event EventHandler onMoved;
}
This would be my prefered option, although without knowing what type of game it it it's hard to know. Either way, a player should encapsulate its own position, and the Game should know the current player.
As for moves, its game dependant, but move will change the players position, and this may or may not effect other players, so I'd probably implement move on the player and have a onMoved event on the players, which the game is subscribed to..

I think having the collection could be useful in implementing an 'undo move' feature in your game. The list of Move objects could be an implementation of commands, and you could save/restore the state of your game using information in the commands.

I see nothing wrong with having a collection of moves in there. You can expose the current move with another property, then both, you and your mate are statisfied.
That's all I can say with the information you provided. I do not know your game logic. The Collection of Moves can be an advantage when you need to have a history of moves (e.g. a replay function) or you want to plan several moves ahead. I see nothing wrong there besides the fact that you probably do not necessarily need it.
By the way: List<T> is meant for implementations, not for ObjectModels. I'd wrap the List in a class called MovesCollection. And Move should implement an interface (an abstract contract) in case you need many different moves implementations (e.g. AttackMove, Fortify-Move, Retreat-Move ...)

From my point of view. If you don't want that UNDO feature then placing list of MOVES is useless because you already mentioned that no we do not have Undo feature, nor we think about having it . then why having this list here ?
think this as, you have declare lots of variables in your code and not using them. It is good practice that keeping code clean and simple =)

Related

How do I go about saving multiple modified prefabs instantiated from the same scriptable object C#

Work with me now, I'm a confused lost little child at this point.
Intro
I have an inventory that allows me to place items into a gear slot, instantiating that item in my players hand/ on body. For example, I have a simple rifle, I put it in my gear slot and it is created. My player can now run around shoot, kill, and unequip it too! BUUUT I can not figure out how to save my modified variables.
Problem Lore
All my items are Scriptable Objects while in the inventory, so I can easily create different items. The Scriptable Object holds; some text data, other things, and the actual prefab of the weapon I want to instantiate. The problem is, when I unequip the item from the gear slot it deletes the prefab, as it should, I don't want to see or use it anymore while in game. I can easily create an upgrade system, but saving those changed variables is a problem. I'm deleting it when I unequip it and instantiating a new copy when I equip it. My game allows the player to pickup the same weapon until the inventory is full too.
Overall Problems
How do I go about saving multiple modified prefabs instantiated from the same scriptable object?
Should I figure out how to create a unique Id that represents the weapon and allows the scriptable object to instantiate this unique Id?
I'm not sure if the second question is possible, but I think you might get the gist of the problem, any solutions are helpful, if I should recreate my inventory, I'd cry for sure, but I really want a weapon upgrade system in my game, so I'LL HECKIN DO IT! Thank you guys.
Problem
I will have a lot of various classes, which is very similar("simple sword", "diamond sword", "giga sword"...)
Solution
Strategy pattern, instead of creation whole new object, i will change the property of this object
Example
interface IHandle
{
public int Speed { get; set; }
}
class SimpleHandle : IHandle
{
public int Speed { get; set; }
public SimpleHandle()
{
Speed = 5;
}
}
interface IBlade
{
public int Damage { get; set; }
}
class SimpleBlade : IBlade
{
public int Damage { get; set; }
public SimpleBlade()
{
Damage = 5;
}
}
class Sword
{
private IHandle _handle { get; set; }
private IBlade _blade { get; set; }
public void ChangeHandle(IHandle handle)
{
_handle = handle;
}
public void ChangeBlade(IBlade blade)
{
_blade = blade;
}
}

DDD - How to enforce invariants on collections across aggregates

Let's say we sell cars, customizable cars.
A customer chooses a CarModel and then starts configuring the CarModel. In our shop, she can only choose the color of the Steeringwheel.
Some CarModels can have more types of SteeringWheels than others.
Therefore, we have a Catalog which contains CarModels and SteeringWheels.
A customer can create a CarConfiguration. She chooses the model and then from the available steering wheels for that model she chooses the color steering wheel she likes.
class Catalog
{
public IReadonlyCollection<int> CarModels { get; }
public IReadonlyCollection<int> SteeringWheels { get; }
public void RemoveSteeringWheel(int steeringWheelId)
{
...
}
}
class SteeringWheel : AggregateRoot
{
public int Id { get; }
public string Color { get; }
public decimal Price { get; set; }
}
class CarModel : AggregateRoot
{
public int Id { get; }
public decimal Price { get; set; }
public IReadonlyCollection<int> SteeringWheels { get; }
public void AddSteeringWheel(int steeringWheelId)
{
...
}
public CarOrder CreateCarOrder(int steeringWheelId)
{
return new CarOrder(...);
}
}
class CarOrder : AggregateRoot
{
public int Id { get; set; }
public CarConfiguration CarConfiguration { get; set; }
}
class CarConfiguration : ValueObject
{
public int CarModelId { get; set; }
public int SteeringWheelId { get; set; }
}
For this to work there is an invariant that the available steering wheels for a car model must always be present in the catalog. To enforce this invariant, we must guard (at least) two methods:
AddSteeringWheel on CarModel; we can only add a SteeringWheel if it is available in the Catalog
RemoveSteeringWheel on Catalog; we can only remove a SteeringWheel if it is not configured on any CarModel.
How to enforce this invariant? CarModel does not know about the SteeringWheel collection on Catalog and Catalog doesn't know anything about CarModel's steering wheels either.
We could introduce a domain service and inject repositories into that. That service would be able to access the data from both aggregates and be able to enforce the invariants.
Other options are to create navigation properties and configure the ORM (Entity Framework Core in my case) to explicitly load those relations.
And probably many more, which I can't think of right now…
What are the most elegant/pure-ddd/best practice options to achieve this?
How to enforce invariants on collections across aggregates
Fundamentally, what you have here is an analysis conflict. When you distribute information, you give up the ability to enforce a combined invariant.
For example:
For this to work there is an invariant that the available steering wheels for a car model must always be present in the catalog
So what is supposed to happen when one person is updating a CarConfiguration concurrently with another person modifying the catalog? What is supposed to happen with all of the existing configurations after the catalog is changed?
In many cases, the answer is "those activities are both to be permitted, and we will clean up the discrepancy later"; ie we'll attempt to detect the problem later, and raise an exception report if we find anything.
(If that answer isn't satisfactory, then you need to go back into your original decision to split the information into multiple aggregates, and review that design).
Pat Helland has a lot of useful material here:
2009 Building on Quicksand
2010 Memories Guesses and Apologies
2015 Immutability Changes Everything
In effect, your local calculation include stale (and possibly outdated) information from somewhere else, and you encode into your logic your real concerns about that.
Well first of all, it might be that CarModel knows something of SteeringWheels, as I assume that if you add a SteeringWheel with a Price, the Price of CarModel changes?!
So there probably should be a Value Object or Entity as part of the CarModel aggregate that represents that.
Furthermore, I think you need a command handler, that knows of both, and decides if the provided SteeringWheel is valid, before trying to add that to the CarModel, that on its own has to decide if adding the SteeringWheel is allowed, trusting the command handler that the reference of the SteeringWheel is valid.
Invariants between aggregates can't be transitionally consistent, only eventually. So when you add a steering wheel to your carModel, you raise an event saying steeringWheelUsedbyCarModelEvent, you catch that event in Domain event handler and update the steering wheel. Steering Wheel aggregate holds an id(or collection if can be used by multiple car configurations) of the carmodel it is assigned to.

How do I keep extensibility with private properties?

I'm working on the following class. I've shortened the list of properties as an example.
public class Paycheck
{
public decimal Gross { get; private set; }
public decimal FederalWithholdingTax { get; private set; }
public decimal StateWithholdingTax { get; private set; }
// ...
}
Now my idea was to create an interface to calculate all the taxes...
public interface IPaycheckDeductionCalculator
{
void Calculate();
}
The idea after that is to create methods outside of the Paycheck class that can perform calculations/deductions. With the way laws and payroll processes work, how deductions are performed and what deductions are performed are constantly changing, so I want to keep extensibility easy.
My dilemma is that I want to keep the Paycheck property setters private so that just anyone can change those values. Keeping that data constant after a paycheck is processed is critical.
I considered the use of delegates, but I'm not so sure that's my answer either, as I still wouldn't be able to develop the desired methods outside of the Paycheck class.
Is there something I'm not thinking of or is this a "you can't have your cake and eat it too" kind of situation?
Have the interfaces that calculate these values return the values that they are calculating. Pass in instances of these interfaces to Paycheck, which can the perform the calculations (without needing to know anything about the implementation of the interface) and then have it set the values of the appropriate properties.

From anemic domain to domain driven

I was trying to find a clear and simple example of what an anemic domain really means. There is a lot of theory around, and also many well answered questions. Still, I could not get a clear picture about to what extent "anemic domain" meaning really goes. Therefore, I believe it would be simpler to see a dummy practical example of an anemic domain design and than ask you how could this be evolved to a domain driven one...
So, let's say we have a data entity of type TaskData:
public class TaskData
{
public Guid InternalId { get; set; }
public string Title { get; set; }
public string Details { get; set; }
public TaskState ExplicitState { get; set; }
public IEnumerable<TaskData> InnerTasks { get; set; }
}
And there is the need of an additional property called "ActualState", which is a computed state: if the Task has inner sub-tasks, the value strictly depends of the children, otherwise, the "ActualState" is equal to "ExplicitState"
If I write this logic in a separate service class (I call them "engines") we have:
internal class TaskStateCalculator
{
public TaskState GetState(TaskData taskData)
{
if (taskData.InnerTasks.Any())
{
if (taskData.InnerTasks.All(x => this.GetState(x) == TaskState.Done))
{
return TaskState.Done;
}
if (taskData.InnerTasks.Any(x => this.GetState(x) == TaskState.InProgress))
{
return TaskState.InProgress;
}
return TaskState.Default;
}
return taskData.ExplicitState;
}
}
The first question is:
Does the code above reflect an anemic domain design, even if the TaskStateCalculator service/engine is part of my Domain Layer?
If yes, in order to avoid it, we'll need to move the logic inside the TaskData class (and rename TaskData to Task). Am I right?
The second question is (actually a chain of them):
What if we have a more difficult situation? Let's say there is the need for a property called ComputeSomething inside Task entity, and the logic of this property needs to access the entire Task's repository. In this case, the Task class would have a dependency on TaskRepository. Would this be ok? How would EF construct an instance of such class? What is the alternative?
I was trying to find a clear and simple example of what an anemic domain really means
It's in fact really easy to go from an anemic domain model to a rich one.
Set all property setters to private and then add methods if you want to change state of a model.
Evaluate all Law of Demeter violations and add methods where suitable.
Eventually you will have a correct model.
In your case I would encapsulate that logic inside TaskData as your TaskStateCalculator violate Law of Demeter
public class TaskData
{
public Guid InternalId { get; private set; }
public string Title { get; private set; }
public string Details { get; private set; }
public TaskState ExplicitState { get; private set; }
public IEnumerable<TaskData> InnerTasks { get; private set; }
public TaskState GetState()
{
if (!InnerTasks.Any())
return ExplicitState;
if (InnerTasks.All(x => this.GetState(x) == TaskState.Done))
{
return TaskState.Done;
}
if (InnerTasks.Any(x => this.GetState(x) == TaskState.InProgress))
{
return TaskState.InProgress;
}
return TaskState.Default;
}
}
another thing is that I would probably not expose InnerTasks collection at all to the outside world (just have it as a member field). But it's hard to say as I do not know how the class is used in other scenarios.
Why private setters
Every time you have to change more than one property it's often better to describe the behavior with a method, as it's then impossible to forget to change all required properties. A method also describes better what you are trying to do than changing a set of properties.
Even if you just change a single property, that property can set the class in an invalid state as the change may not be compatible with the rest of the information in the class. Don't forget that encapsulation is one of the core principles in OOP

Physics in OO game programming

So I am in the process of trying to learn how to develop 2D games.
I am playing around with both Android and C#.
The issue that I am having is this.
It is easy enough to draw a sprite of some sort. Where I struggle is to visualize how one can code interactions of various objects on screen.
For example lets say I have the following Object.
public class MyGenericObject {
public MyGenericObject() {}
public Int32 Width { get; set; }
public Int32 Height { get; set; }
public Int32 X { get; set; }
public Int32 Y { get; set; }
public Image ObjectImage { get; set; }
}
Lets say I want to model the behavior of an interaction between N number of these Objects. What is a typical pattern one would utilize in such a scenario?
So for example would you simply call a method such as MyPhysicsSim.DoPhysics(List<MyGenericObjects>);
Assuming this is not a huge stretch. Inside of this method then, how do you calculate the interactions and resulting movements? I just can't get my head around it (Obviously I do understand that there are basic equations that can solve direction and speed and so forth but I just can't seem to work out how to apply these as an algorithm).
I have looked at numerous tutorials and all of them seem to concentrate on just drawing an object or assume a level of understanding about the internals that is way over my head. So I am hoping for a really simple, dumbed down response.
So basically what I am asking is how do you approach interactions between 2D objects in a OO paradigm for dummies?
Traditionally, most games have a loop similar to the one below somewhere at the core:
while (1) {
World.respondToInput();
World.updatePhysics();
World.renderScene();
Timer.waitUntilFrameExpires();
}
and the 'updatePhysics()' method can do something very basic, such as:
for (Object obj1 in World.trackedObjects()) {
for (Object obj2 in World.trackedObjects()) {
if (obj1.influences(obj2)) {
obj1.update(); obj2.update();
}
}
}
So you basically have a 'tick' in the world you're simulating, and your code works to reflect the delta in the scene that would have occurred.

Categories