public static class Global
{
public static List <Faction> Factions;
public static Dictionary <Faction, FactionRelation> FactionRelationships;
}
public class Faction
{
public Faction Parent;
}
public class FactionRelation
{
public Faction ForeignFaction; //The enemy or friend of this faction
public decimal Multiplier; //Standings gain/loss with the faction get applied to ForeignFaction by this percentage. Ex: I get +100 with NativeFaction. If multiplier is -0.1M, then I'll get -10 with ForeignFaction
}
public class Player
{
public Dictionary <Faction, decimal> Standings;
public void SetStandings(decimal mod)
{
foreach (Faction f in Global.Factions)
{
}
}
}
The above code represents a rudimentary faction system for a game. The Global class initializes the game, creating the Faction objects from some data definition. It also contains a collection of Factions and decimal values which represent the relationships between factions.
Factions Let's say we have 2 main factions: DirectionFolk and ColorFolk. These have no Parent factions.
We also have UpFolk and DownFolk factions whose Parent Faction are both DirectionFolk. Finally, we have RedFolk and BlueFolk factions whose Parent Faction are both ColorFolk.
So,
- DirectionFolk
- UpFolk
- DownFolk
- ColorFolk
- RedFolk
- PinkFolk
- ScarletFolk
- BlueFolk
- RedFolk
This nesting could go much deeper; for example, RedFolk might have PinkFolk and ScarletFolk as subfactions.
Any standing gain with any faction should propagate up and down the tree until it reaches the nesting limit in either extremity. The nesting depth of the set determines that amount of standing modification that should occur at any level. To make it simpler, let's say it is divided evenly. So if I gain 100 standing directly with ColorFolk, I should get 50 standing with both RedFolk and BlueFolk, and 25 with both PinkFolk and ScarletFolk. If instead I gained 100 standing directly with RedFolk, I should get 50 with BlueFolk, and 25 with both PinkFolk and ScarletFolk. The idea is that faction modification directly with the lowest tiers would be more pronounced than that at the highest tiers. So, it's easier to become friends or enemies with PinkFolk than it is with ColorFolk.
If this algorithm has a name, I don't know what it is.
Furthermore, any faction which does not have a parent can have a relationship with another parentless faction. So, let's say that DirectionFolk and ColorFolk are enemies. Any faction standing gain with ColorFolk should result in a proportionate standing lost with DirectionFolk. Since only parentless factions can have cross-faction relationships (positive or negative multipliers), this standing loss would always occur at the top of the related faction's chain, and trickle down.
Ideally, I'd like to be able to assign more interesting values to the faction relationships, both cross-parent-faction, and among subfactions of a parent. So a standing modification to some subfaction might propagate through some other factions depending on multipliers, and standings gain with the parent faction in the tree would be more granular.
Players The Player object has a list which represents their standings with each faction. Pretty simple - a Faction and a decimal value. This is the value I will be modifying, as each player holds the data representing their standings with a faction. (The factions themselves are unaware of players in that sense).
--
My question is, should I be directly setting a collection of values in the Player object through some hoary recursive process, or is there an elegant way to simply calculate this based on very few values stored by the player?
Also, would making this a little more interesting - say, having some factions be neutral to each other, even in the same tree (like, RedFolk and BlueFolk don't care about each other) - or mixing up the distribution so that it's not strictly even - would these kinds of things seriously complicate the matter, or is it possible to design an algorithm which is more agnostic to all that?
I'm really just looking for a start on how to wrap my head around this. If anyone else has designed something similar, I'd love to hear your thoughts on it.