Skip to main content
added 473 characters in body
Source Link
Philipp
  • 121.5k
  • 28
  • 261
  • 342

Consider C# events.

This allows you to have cards in the game which subscribe to events by registering a callback method with the event. The result is that as soon as you .Invoke(arguments) the event in your game loop, all those previously subscribed event handlers will get called.

I assume that you already have some class which manages the general progression between different game phases. I will call this class GameState. This GameStateManager would expose a bunch of events like this:

public event Action<Player> OnBeginTurn;
public event Action<Card> OnCardPlayed;
public event Action<Card> OnCardDestroyed;
public event Action<Unit, int> OnUnitDamaged;

and so on.

The GameStateManager would then invoke those events at appropriate times.

public void SwitchTurn(Player newPlayer) {
    currentPlayer = newPlayer;
    // all the other stuff which needs to happen on turn changes
    OnBeginTurn?.Invoke(currentPlayer);
}

A card could then subscribe to an event like this:

public void EnterGame() {
    gameStateManager.OnCardPlayed += OnCardPlayed
}
public void LeaveGame() {
    gameStateManager.OnCardPlayed -= OnCardPlayed
}

private void OnCardPlayed(Card playedCard) {
    // Deal 3 damage to every unit in the game when another player plays a resource card
   if (playedCard.type == Card.Type.RESOURCE && playedCard.owner != owner) {
       foreach(var otherCard in gameStateManager.allCardsInPlay) {
            if(otherCard.type == Card.Type.UNIT) {
                 otherCard.Damage(3);
            }
       }
   }
}

More complex events like "playing 3 cards in the same turn" might require to keep a journal of all events which happened in the current match and then search through that journal for what happened in the past.


Yes, this will require that you have a hardcoded OnCardPlayed method for every card which you need to program (although similar cards might share the same method).

I don't think that it would be a good idea to try to get around hardcoding here. If you attempt to implement some "soft logic" which you can edit via a GUI in a custom editor window, you will likely end up investing a ton of work into a system which isn't much easier to use than just hardcoding and still won't be able to cover the more exotic use-cases you have in mind.

Consider C# events.

This allows you to have cards in the game which subscribe to events by registering a callback method with the event. The result is that as soon as you .Invoke(arguments) the event in your game loop, all those previously subscribed event handlers will get called.

I assume that you already have some class which manages the general progression between different game phases. I will call this class GameState. This GameStateManager would expose a bunch of events like this:

public event Action<Player> OnBeginTurn;
public event Action<Card> OnCardPlayed;
public event Action<Card> OnCardDestroyed;
public event Action<Unit, int> OnUnitDamaged;

and so on.

The GameStateManager would then invoke those events at appropriate times.

public void SwitchTurn(Player newPlayer) {
    currentPlayer = newPlayer;
    // all the other stuff which needs to happen on turn changes
    OnBeginTurn?.Invoke(currentPlayer);
}

A card could then subscribe to an event like this:

public void EnterGame() {
    gameStateManager.OnCardPlayed += OnCardPlayed
}
public void LeaveGame() {
    gameStateManager.OnCardPlayed -= OnCardPlayed
}

private void OnCardPlayed(Card playedCard) {
    // Deal 3 damage to every unit in the game when another player plays a resource card
   if (playedCard.type == Card.Type.RESOURCE && playedCard.owner != owner) {
       foreach(var otherCard in gameStateManager.allCardsInPlay) {
            if(otherCard.type == Card.Type.UNIT) {
                 otherCard.Damage(3);
            }
       }
   }
}

More complex events like "playing 3 cards in the same turn" might require to keep a journal of all events which happened in the current match and then search through that journal for what happened in the past.


Yes, this will require that you have a hardcoded OnCardPlayed method for every card which you need to program (although similar cards might share the same method).

I don't think that it would be a good idea to try to get around hardcoding here. If you attempt to implement some "soft logic" which you can edit via a GUI in a custom editor window, you will likely end up investing a ton of work into a system which isn't much easier to use than just hardcoding and still won't be able to cover the more exotic use-cases you have in mind.

Consider C# events.

This allows you to have cards in the game which subscribe to events by registering a callback method with the event. The result is that as soon as you .Invoke(arguments) the event in your game loop, all those previously subscribed event handlers will get called.

I assume that you already have some class which manages the general progression between different game phases. I will call this class GameState. This GameStateManager would expose a bunch of events like this:

public event Action<Player> OnBeginTurn;
public event Action<Card> OnCardPlayed;
public event Action<Card> OnCardDestroyed;
public event Action<Unit, int> OnUnitDamaged;

and so on.

The GameStateManager would then invoke those events at appropriate times.

public void SwitchTurn(Player newPlayer) {
    currentPlayer = newPlayer;
    // all the other stuff which needs to happen on turn changes
    OnBeginTurn?.Invoke(currentPlayer);
}

A card could then subscribe to an event like this:

public void EnterGame() {
    gameStateManager.OnCardPlayed += OnCardPlayed
}
public void LeaveGame() {
    gameStateManager.OnCardPlayed -= OnCardPlayed
}

private void OnCardPlayed(Card playedCard) {
    // Deal 3 damage to every unit in the game when another player plays a resource card
   if (playedCard.type == Card.Type.RESOURCE && playedCard.owner != owner) {
       foreach(var otherCard in gameStateManager.allCardsInPlay) {
            if(otherCard.type == Card.Type.UNIT) {
                 otherCard.Damage(3);
            }
       }
   }
}

More complex events like "playing 3 cards in the same turn" might require to keep a journal of all events which happened in the current match and then search through that journal for what happened in the past.


Yes, this will require that you have a hardcoded OnCardPlayed method for every card (although similar cards might share the same method).

I don't think that it would be a good idea to try to get around hardcoding here. If you attempt to implement some "soft logic" which you can edit via a GUI in a custom editor window, you will likely end up investing a ton of work into a system which isn't much easier to use than just hardcoding and still won't be able to cover the more exotic use-cases you have in mind.

added 473 characters in body
Source Link
Philipp
  • 121.5k
  • 28
  • 261
  • 342

Consider C# events.

This allows you to have cards in the game which subscribe to events by registering a callback method with the event. The result is that as soon as you .Invoke(arguments) the event in your game loop, all those previously subscribed event handlers will get called.

I assume that you already have some class which manages the general progression between different game phases. I will call this class GameState. This GameStateManager would expose a bunch of events like this:

public event Action<Player> OnBeginTurn;
public event Action<Card> OnCardPlayed;
public event Action<Card> OnCardDestroyed;
public event Action<Unit, int> OnUnitDamaged;

and so on.

The GameStateManager would then invoke those events at appropriate times.

public void SwitchTurn(Player newPlayer) {
    currentPlayer = newPlayer;
    // all the other stuff which needs to happen on turn changes
    OnBeginTurn?.Invoke(currentPlayer);
}

A card could then subscribe to an event like this:

public void EnterGame() {
    gameStateManager.OnCardPlayed += OnCardPlayed
}
public void LeaveGame() {
    gameStateManager.OnCardPlayed -= OnCardPlayed
}

private void OnCardPlayed(Card playedCard) {
    // Deal 3 damage to every unit in the game when another player plays a resource card
   if (playedCard.type == Card.Type.RESOURCE && playedCard.owner != owner) {
       foreach(var otherCard in gameStateManager.allCardsInPlay) {
            if(otherCard.type == Card.Type.UNIT) {
                 otherCard.Damage(3);
            }
       }
   }
}

More complex events like "playing 3 cards in the same turn" might require to keep a journal of all events which happened in the current match and then search through that journal for what happened in the past.


Yes, this will require that you have a hardcoded OnCardPlayed method for every card which you need to program (although similar cards might share the same method).

I don't think that it would be a good idea to try to get around hardcoding here. If you attempt to implement some "soft logic" which you can edit via a GUI in a custom editor window, you will likely end up investing a ton of work into a system which isn't much easier to use than just hardcoding and still won't be able to cover the more exotic use-cases you have in mind.

Consider C# events.

This allows you to have cards in the game which subscribe to events by registering a callback method with the event. The result is that as soon as you .Invoke(arguments) the event in your game loop, all those previously subscribed event handlers will get called.

I assume that you already have some class which manages the general progression between different game phases. I will call this class GameState. This GameStateManager would expose a bunch of events like this:

public event Action<Player> OnBeginTurn;
public event Action<Card> OnCardPlayed;
public event Action<Card> OnCardDestroyed;
public event Action<Unit, int> OnUnitDamaged;

and so on.

The GameStateManager would then invoke those events at appropriate times.

public void SwitchTurn(Player newPlayer) {
    currentPlayer = newPlayer;
    // all the other stuff which needs to happen on turn changes
    OnBeginTurn?.Invoke(currentPlayer);
}

A card could then subscribe to an event like this:

public void EnterGame() {
    gameStateManager.OnCardPlayed += OnCardPlayed
}
public void LeaveGame() {
    gameStateManager.OnCardPlayed -= OnCardPlayed
}

private void OnCardPlayed(Card playedCard) {
    // Deal 3 damage to every unit in the game when another player plays a resource card
   if (playedCard.type == Card.Type.RESOURCE && playedCard.owner != owner) {
       foreach(var otherCard in gameStateManager.allCardsInPlay) {
            if(otherCard.type == Card.Type.UNIT) {
                 otherCard.Damage(3);
            }
       }
   }
}

More complex events like "playing 3 cards in the same turn" might require to keep a journal of all events which happened in the current match and then search through that journal for what happened in the past.

Consider C# events.

This allows you to have cards in the game which subscribe to events by registering a callback method with the event. The result is that as soon as you .Invoke(arguments) the event in your game loop, all those previously subscribed event handlers will get called.

I assume that you already have some class which manages the general progression between different game phases. I will call this class GameState. This GameStateManager would expose a bunch of events like this:

public event Action<Player> OnBeginTurn;
public event Action<Card> OnCardPlayed;
public event Action<Card> OnCardDestroyed;
public event Action<Unit, int> OnUnitDamaged;

and so on.

The GameStateManager would then invoke those events at appropriate times.

public void SwitchTurn(Player newPlayer) {
    currentPlayer = newPlayer;
    // all the other stuff which needs to happen on turn changes
    OnBeginTurn?.Invoke(currentPlayer);
}

A card could then subscribe to an event like this:

public void EnterGame() {
    gameStateManager.OnCardPlayed += OnCardPlayed
}
public void LeaveGame() {
    gameStateManager.OnCardPlayed -= OnCardPlayed
}

private void OnCardPlayed(Card playedCard) {
    // Deal 3 damage to every unit in the game when another player plays a resource card
   if (playedCard.type == Card.Type.RESOURCE && playedCard.owner != owner) {
       foreach(var otherCard in gameStateManager.allCardsInPlay) {
            if(otherCard.type == Card.Type.UNIT) {
                 otherCard.Damage(3);
            }
       }
   }
}

More complex events like "playing 3 cards in the same turn" might require to keep a journal of all events which happened in the current match and then search through that journal for what happened in the past.


Yes, this will require that you have a hardcoded OnCardPlayed method for every card which you need to program (although similar cards might share the same method).

I don't think that it would be a good idea to try to get around hardcoding here. If you attempt to implement some "soft logic" which you can edit via a GUI in a custom editor window, you will likely end up investing a ton of work into a system which isn't much easier to use than just hardcoding and still won't be able to cover the more exotic use-cases you have in mind.

Source Link
Philipp
  • 121.5k
  • 28
  • 261
  • 342

Consider C# events.

This allows you to have cards in the game which subscribe to events by registering a callback method with the event. The result is that as soon as you .Invoke(arguments) the event in your game loop, all those previously subscribed event handlers will get called.

I assume that you already have some class which manages the general progression between different game phases. I will call this class GameState. This GameStateManager would expose a bunch of events like this:

public event Action<Player> OnBeginTurn;
public event Action<Card> OnCardPlayed;
public event Action<Card> OnCardDestroyed;
public event Action<Unit, int> OnUnitDamaged;

and so on.

The GameStateManager would then invoke those events at appropriate times.

public void SwitchTurn(Player newPlayer) {
    currentPlayer = newPlayer;
    // all the other stuff which needs to happen on turn changes
    OnBeginTurn?.Invoke(currentPlayer);
}

A card could then subscribe to an event like this:

public void EnterGame() {
    gameStateManager.OnCardPlayed += OnCardPlayed
}
public void LeaveGame() {
    gameStateManager.OnCardPlayed -= OnCardPlayed
}

private void OnCardPlayed(Card playedCard) {
    // Deal 3 damage to every unit in the game when another player plays a resource card
   if (playedCard.type == Card.Type.RESOURCE && playedCard.owner != owner) {
       foreach(var otherCard in gameStateManager.allCardsInPlay) {
            if(otherCard.type == Card.Type.UNIT) {
                 otherCard.Damage(3);
            }
       }
   }
}

More complex events like "playing 3 cards in the same turn" might require to keep a journal of all events which happened in the current match and then search through that journal for what happened in the past.