GithubHelp home page GithubHelp logo

greenstack / spite-framework Goto Github PK

View Code? Open in Web Editor NEW
6.0 2.0 0.0 247 KB

The Spite Framework is a C# library meant to simplify designing and implementing turn-based gameplay by providing some boilerplate code.

License: MIT License

C# 100.00%
turns gameplay battle spite-framework

spite-framework's People

Contributors

greenstack avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

spite-framework's Issues

Battle End Condition Builder/Class

It might be nice to be able to create battle end conditions as a class that can immediately end the battle when the conditions are met in addition to or in place of the current methods. This will require some exploration.

Simplify getting the player with priority

Regardless of the turn scheme, every game has a notion of who's "turn" it is (the exception is with games where turns are taken simultaneously, but in that case, it's everyone's turn for the most part). I think that the best way to handle this is by implementing a DoesTeamHavePriority or some similarly named method that accepts a team and returns true. In default turn schemes where entities take the priority, the method can check the teammate's team. Making this a virtual method would allow custom implementations of this determination. Adding a method to the arena that delegates to this would also prove useful.

Commands with a null executor cause exceptions

In this particular example, the offending code can be found on line 42 of TeamPhase.cs:

return command.Executor.ResponsibleTeam == CurrentTeam &&
	(command.Executor as ITappableTeammate)?.IsTapped != true;

There should be a null check on the command.Executor property here. If the null check fails, I think raising an exception (such as a NullObjectException) with a message something along the lines of "The command's executor has not been set yet" would be great.

Let Spite be cloned into a Unity Project

Right now, Spite can't be directly cloned into Unity projects because the framework uses C# features not available in Unity (namely, certain C# 8.0 features). Since I want Spite to be as compatible with as many engines and frameworks as possible, I'm going to make the target Unity version Unity 2019 since that has support until 2022 (Unity 2018 loses support this year). This means that Spite should only use features available in C# 7.3 (source).

Once Unity 2019 leaves LTS in 2022, we can look into updating available language features to what Unity 2020 supports - in other words, we have Spite supporting the oldest available LTS version of Unity.

That said, I'm open to discussion for this (for example, maybe we target Unity's recommended release, which in this case is Unity 2020. This way, we keep a balance of getting to use newer language features. Maybe that's what we do once Spite gets its first full release.)

Part of the solution for this is making sure that Spite doesn't use a C# version greater than 7.3.

Add Stat types

Stats are common in turn-based games. Adding basic stats would be very useful.

Stats should be architected to support various numeric types and should eventually support some kind of pipeline pattern. It doesn't need to be exactly like this, but I'm willing to bet there's a lot to learn here. But that's out of the scope for this issue. For now, I just want there to be some kind of serializable container for these stat types.

Implement some Int Stat

Before we get that wonderful INumeric interface with .NET 6/Unity, I think having some int stats would be useful.

Some of the int stats I would like to see include:

  • Centralized stat (a stat whose current value centers on a particular point)
  • A clamped stat (a stat whose current value is clamped to a certain range)

Others that I think of can be added here.

Introduce Sides

Though the concept of Sides was removed in 0.2.0-alpha, there is another way in which they can be useful. Sides can be considered a group of allied teams.

Potential benefits of introducing sides:

  • Sides aren't directly controlled by a player or AI while a Team is.
  • Sides can simplify teams finding allied, opposing, or neutral teams - if a team has a reference to its Side, it can just grab the teams contained by that side.
  • Victory can be determined on a side-by-side basis over a team-by-team basis (though we may want to preserve this functionality).

I don't see Sides as an 0.2.0-alpha feature, but rather as a 0.3.0-alpha. This is up for discussion, however.

Team/Side naming is inconsistent

The way it stands now, Teams and Sides are used interchangeably in the framework. This isn't ideal, since everywhere where Sides is used, an ITeam object is expected.

In the framework itself, the phase "Side" occurs ~20 times; "Team" occurs far more frequently. Since "Side" variables and methods accept ITeam objects, I believe it would be better to replace the term "Side" with "Team". This way, we can also reserve the term "Side" for something different in the future if need be.

No Pipeline for .NET Framework Exists Yet

In previous versions of the framework, there was a pipeline for .NET Framework. However, when I converted the project to be primarily .NET Core, I didn't keep the old GitHub pipeline for .NET. We should reintroduce that pipeline and include a badge for that in the README.md.

Allow turn managers to track turn numbers and know when the turn number has incremented

This is going to look different for each type of turn scheme. In general, it is going to advance when each team or each unit has been able to act at least once. In other turn schemes, however, it might not make sense for each turn scheme to say which turn number it is. Perhaps the best way to accomplish this is through an ITurnCounter interface that turn managers can implement if needed (and in general, they do). Furthermore, there should be an event that's triggered when the count goes up.

Update Arena Builder unit tests

The following things need to have unit tests associated with them:

  • The Alliance Graph is set regardless of if there's a name for the arena or not (ran into this today)
  • Exceptions should be thrown when TurnManagers are invalid
  • Test creation of DiscretePlayerTurnManagers
  • Exceptions should be thrown if the Alliance Graph isn't set up (since the turn manager currently requires this, though it might not be a requirement with 0.4.0-alpha)

Update Maximum Version of C# to 8.0

Unity 2021.2 has been released, which brings full C# 8 support and limited C# 9 support. The features from C# 9 that Unity has don't seem too useful to me at the moment, so I think it's best to limit the language version to C# 8 so the compiler can tell us what's good and what's not in any given profile.

This will also require us to update the Unity package.json file to change the minimum supported version of Unity to 2021.2.

Update tappable characters to consume "actions"

Many games allow characters to perform multiple types of actions in a turn before getting tapped. Storing this as an integer would grant much more flexibility than a binary "is (not) tapped." New methods should include ConsumeAction(int) and perhaps ConsumeAllActions.

Getting a single opposing team is difficult

Currently, in 2-sided games, it's not very easy to get the opposing team of another team.

Here's the current method used in SpiteBattleship (BattleshipTeam's DetermineStanding implementation):

foreach (var team in context.GetTeamsOpposing(this))
{
    if (!team.AreAnyEntitiesAlive())
    {
        // There's only two teams in battleship, so we can easily determine this.
        CurrentStanding = TeamStanding.Victorious;
        break;
    }
}

Considering the prevalence of two-sided matches, there should be some way to get the singular opposing team. I'm not a fan of having to use a for loop on it.

Whatever the solution is, it should also support multi-sided games as well.

Introduce Alliance Graphs

An Alliance Graph is a graph data structure that contains the relationships between teams. A node in the graph is a team, and each edge in the graph is the relationship between the teams. This solution can help solve the problem posited by #5 by providing various helper methods to traverse/search the graph for specific relationships.

Resources don't work with Unity

A lot of exception messages are used in Spite that depend on the .NET resources functionality. However, since Unity can't use these, when an exception is thrown by Spite, the runtime can't find the proper resource for the message, which throws another exception, burying the original exception under another (in fact, the only way to figure out what the original exception was is to look at the code where the new exception was thrown from). This happens when Spite is included as a package (with source code). Even should this not be the case when using Spite.dll in Unity, this greatly increases the difficulty of using Spite in Unity.

Concrete Turn Managers: Team/Player-Based

There are a lot of possible turn schemes, but provided some simple concrete turn schemes could help expedite the development of turn-based games.

This issue focuses on creating a turn-manager that will work for games where the player orders all units to act until all are tapped, like in Fire Emblem. Once all units have acted or the player ends their turn, priority is handed to the next team in the list.

Explore pre-battle phase

Though not every game is going to want it, a pre-battle phase could be useful. We'll want to explore this, especially in regards to default turn managers.

Add events for teams to listen to teammates' status

This can help make the determination of a team's own status easier and more up-to-date.

I envision this as an event on the ITeammate interface and the Team can register itself to.

Questions to answer:

  • Is this applicable to a wide range of turn-based games?

Change ITeam.Members from ICollection to IList

Being able to index teammates directly instead of having to rely on solutions like Linq would be a huge benefit. I also can't really think of any good reason why a team would want to hold enemies as a set, map, or so forth.

Allow for discrete use of arenas

Many game engines and frameworks don't allow devs to take total control of the game loop. Currently, the Arena only works from the inside - nothing from the outside can pass in input. Once DoBattle is called on the Arena, the arena enters an infinite loop; that is, it becomes the game loop.

This behavior should still be supported (as it seems to work fine for text-based games), but there needs to be a way to have the Arena exist separately from the core game loop.

This will probably introduce several major API changes from 0.1.0-alpha.

Clean up the codebase

We need to make sure that there are:

  • No warnings
  • Standardize to tabs (look into making GitHub not use 8-space width tabs)
  • Standardize line endings (Unix-style)
  • Make sure each file has a newline at the end
  • Remove all obsolete methods

Ensure New Code Is Compatible with Minimum Supported Unity Version

I don't want new versions of Spite to break Unity projects due to C# features that Unity may not yet support.

I think the easiest way to do this is to set the project's C# version to one that matches the lowest supported Unity project. This allows us to not have to set up some kind of pipeline and have the validation at compile time.

When major versions of Spite are released, we can drop support for older Unity versions then. This may also be a good time to revisit what the minimum version of Unity we want to support is.

Add a TapAllUnitsCommand

There are some common commands that should be included by default, such as a TapAllUnitsCommand and a corresponding action. This is mostly applicable for discrete team turn schemes. It would tap all units on the team, ending the turn for the player issuing the command. The reason I don't call this an EndTurnCommand is because ending a turn will look different for different turn schemes.

Make Arenas generic for teams

Currently, when a team queries an arena for any team, it needs to cast the team into the expected team implementation. By making Arenas somewhat generic, like Arena<T> : IArena where T : ITeam, teams can reasonably query the Arena for teams without needing to cast to the specific type.

This will introduce several API changes and raises a few questions and concerns:

  • Should the IArena interface be genericized as well? Or should we have a non-generic arena?
  • Do we want teams to only accept Arenas that are templated to themselves?

The following changes will also need to be made:

  • The ArenaBuilder class will also need to become generic.
  • Anywhere Arenas are used will need to be updated with the change.

Make TeamBuilder fully generic

Currently, TeamBuilder's Start() and Finish() methods are templates accepting a type that extends ITeam.

I believe it would make more sense for the TeamBuilder itself to be a template class, simplifying the team creation process.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.