Skip to content

For Contributors

Nick Martin edited this page Oct 23, 2017 · 9 revisions

Welcome!

And thank you for contributing to CodeCarnage! This page is designed to help you become more familiar with how CodeCarnage works on a technical level. Please save this page for reference.

Contribution Guidelines

Contributors are always welcome, and without their help, CodeCarnage would not be where it is today. While some general guidelines are laid out here, contributors are encouraged to help in any way they would like so long as their issues are properly tagged and they assign the correct reviewer (see below).

Pull Requests

Since contributors do not have the rights to modify the repository directly, please fork our repository and make your changes on your forked copy. For more information on forking, please see the GitHub documentation on forking a repository.

Once you are satisfied with your edits and believe that you have successfully addressed the issue in question, please submit a pull request from your forked repository's branch into our main develop branch. In your pull request, it is very important that you state which issue you are addressing by referencing that you are closing it. For example, please see the main contributor pull requests and note that each one states, somewhere, that the pull request is "closing #x", where x is the number of the issue being closed.

Branches

In general, there are no rules pertaining to branching in our repository. However, that being said, no pull requests into master will be accepted. Additionally, pull requests are only 100% guaranteed to be incorporated in the main development cycle if they are made into the develop branch.

Tags

We do not recommend placing tags in the repository unless extremely necessary. Tags in the repository will be reviewed with extreme discretion and only necessary tags will be incorporated into the main fork.

Code Review

The four main project developers are each assigned to a specific role and know that area of the code well. As a result, please assign reviewers to your code based on the list below if your code significantly altered that reviewer's share of the code base.

  • Jacob Ekstrum (j3kstrum) - The Game Engine (and most areas that interface directly with the Tiled library).
  • Nick Martin (nmartin5) - The GUI (and anything else graphical or that handles events)
  • Sean Brais (seanbrais) - The Game Model, including abstract entities, players, and game logic.
  • David Olsen (islanddove) - The Scripting Component, where the building blocks from the user's GUI script are applied to the game's variables.

How It Works

This section explains how CodeCarnage is structured and how it functions. After reading this section, you should be fully prepared to being working on contributing to the CodeCarnage project.

The Basics

CodeCarnage is built entirely in Java. The graphics libraries use the Tiled framework (see also: http://mapeditor.org) and JavaFX to display graphics. As a result of using Tiled, much of the game data resembles the Tiled data structure. That is, the Game Map is composed of several different stacked layers. Each layer has tiles associated with it, each of which can be changed at any given game turn. The engine ticks away at each turn, ensuring that the entire turn's computation and data manipulation takes as close to 250 milliseconds as possible (though this number is subject to change).

The Code

The flowchart on the CodeCarnage website gives a good idea of how CodeCarnage is structured. It serves as a wonderful reference while working with the code base.

CodeCarnage Source Code Flowchart

The Website

Speaking of which, we strongly recommend that you visit the CodeCarnage website for the most up-to-date information regarding the project.

Sample Program Flow

When CodeCarnage is executed, in general, the following program flow occurs:

  1. The main function is called in src/main/java/common/Main.
  2. A MenuGUI object is created from src/main/java/gui/menu/MenuGUI, and its start() method is invoked by JavaFX on the JavaFX thread.
  3. The MenuGUI prepares for input.
  4. Input is received, and the game creates a new ScriptingGUI from src/main/java/gui/scripting/ScriptingGUI.
  5. The ScriptingGUI and its src/main/java/gui/scripting/ScriptingController object receive and process user script input.
  6. The user submits their script, and error checking is performed.
  7. A new GameGUI object is created from src/main/java/gui/game/GameGUI. This creates a new Engine.
  8. The new src/main/java/engine/core/Engine is initialized. It loads the game map and its resources through Tiled and over the internet.
  9. The engine passes the loaded map to the parseEntityMap function in the game utilities and retrieves the parsed map whose data structure is appropriate for CodeCarnage.
  10. This map is passed to a new src/main/java/utilities/models/Game object, which initializes the players.
  11. The GameGUI is loaded onto the screen and calls startUIUpdateThread().
  12. startUIUpdateThread() creates a new Service - a Thread-like object that is fully compatible with JavaFX and is reusable.
  13. We start ticking. Therefore at each 250 millisecond interval, the following steps are performed until the game is over.
  14. The engine will call all game logic functions through its tick() function and will then wait until the 250 millisecond interval has elapsed. It does this by iterating over each player's commands and performing the first one according to the logic defined in the scripting area. The new game map is returned with all of the changes applied.
  15. The GameGUI will check that the game is over and display a results screen and exit if so.
  16. "Deltas" are identified. These are the squares that have changed since the last tick and that need to be redrawn.
  17. "Deltas" are applied. The GameGUI redraws these squares using the new graphical values.
  18. Return to step 14 and repeat.

Code Details

Now that we're more familiar with the overall structure of CodeCarnage, let's dive into the more intricate details of how each section of the program works.

The Test Package

This package contains all of the unit testing code for the project, organized in the same structure as the main package.

The Main Library Package

This sub-package of main contains all local, non-gradle dependencies for CodeCarnage. In particular, this contains our custom version of the Tiled library. Manipulating the Tiled source code should be unnecessary for contributors, and we therefore do not address the tiled package in CodeCarnage.

The Main Resources Package

This sub-package of main contains all of the local resources used for CodeCarnage. In the past, this folder used to contain separate resource folders for each operating system. Since the resource cloud update, this is no longer the case, and the resources package has shrunk significantly.

The Main Java Package

The sub-package of main contains the vast majority of the source code of CodeCarnage.

The Common Package

The common package contains all code that is significantly utilized by more than one other package. It contains the exceptions used in the program, logger functions, and game constants.

The Utilites Package

This package contains all of the Game Logic / Game Models for CodeCarnage. Inside utilities there are two packages, entities and models.

Firstly we will look at entities. This package contains the Player.java and Empty.java classes, each derived from the Entity.java class. Each tile of the Map holds one of these two objects, and is used to represent and coordinate logic throughout the game. The Player entity holds various data for the player, such as Damage, Shield Strength, Health, Location etc. The Empty entity is used to represent a empty tile on the map.

Now looking at models, this contains all of the Game Logic for CodeCarnage. Three main classes allow this functionality.

EntityTile.java holds a reference to the Tiled tile, as well as a reference to the corresponding Entity(Either a player or empty entity). Every tile on the GameMap holds an entity tile.

GameMap.java holds a representation of the Map that is rendered on screen. Currently contains a 25 x 15 grid of EntityTiles (though this may change if another tileset/map is used). It also provides an API for the game to move tiles around on the map, altering the game when collisions and out of bounds operations will occur when moving.

Lastly, we have Game.java. As the name implies, this contains the meat of the game logic and commands that are used. When creating a new Game, you must pass in a reference to a GameMap, which will contain the initial game state and corresponding assets rendered and loaded from the Tiled library. The game class acts as a API for the scripting module, containing method calls for each command, as well as holding data utilized in the scripts. The game class also acts as a API for the Engine, where the engine will execute game.nextTurn() to obtain a new update for the map and progress through the game.

For more information on the utilities package, please contact Sean Brais (seanbrais) by creating a GitHub question.

The GUI Package

This package contains the Java FX code for the graphical interfaces and its events. Each class also has a corresponding fxml file, which is used by Java FX SceneBuilder to make modifications to the UI. This can also be changed directly, and objects can also be accessed via the corresponding Controller class.

game.GameGUI represents the window that appears during gameplay. This window is responsible for the rendering of the tiles on the screen as the gameplay goes on.

menu.MenuController contains all of the event handling required by the menu.

menu.MenuGUI represents the user menu window and its instantiation.

scripting.Behavior, scripting.BehaviorList, scripting.ChoiceButton, and scripting.ScriptButton are all abstractions of existing Java FX elements. These are used for event handling and styling purposes.

scripting.MouseEvents contains the MouseEvent handlers for events that are triggered in scripting.ScriptingController. These mouse events are used during script creation.

scripting.ScriptingController is used to assign all of the event handlers to the Java FX elements used by scripting.ScriptingGUI.

scripting.ScriptingGUI represents the script creation window. This window contains all of the FXML elements created by the user during script creation. Some of these controls have events that are managed by scripting.ScriptingController. Some of these events have been moved to scripting.MouseEvents for organization.

For more information on the GUI package, please contact Nick Martin (nmartin5) by creating a GitHub question.

The Engine Package

The Engine package holds the game engine, which is responsible for high-level processing of the game's components. It is also responsible for turn timing (ticking) and for orchestrating any network-based interactions.

For more information on the Engine package, please contact Jacob Ekstrum (j3kstrum) by creating a GitHub question.

The Interpreter Package

This package contains code that is used to transfer information from the GUI to the game model.

Check.java holds a condition, ScriptCommand.java holds a list of Checks, and the 'enumerations' folder holds a number of enumerators that specify the Commands, Conditionals, Data, and Operators for Check.java and ScriptCommand.java to use.

Check.java uses a passed-in PlayerID to determine if a condition is true, while ScriptCommand.java uses a passed-in PlayerID to modify the state of the game. The command specified in ScriptCommand.java will only execute if all elements of its Check.java List return true.

The GameGUI.java class in the GUI package creates a List of ScriptCommand.java, each with its own list of Check.java. The list of ScriptCommand.java is accessed by the game engine in engine/core/Engine.java. There, in the method tick(), the engine iterates over the list of ScriptCommand.java for each player, passing in the PlayerID to ensure the correct data is modified.

For more information on the Interpreter package, please contact David Olsen (islanddove) by creating a GitHub question.

Recommended Development Environment

We strongly recommend that the IntelliJ IDEA integrated development environment is used. However, so long as the core build principles are followed from the next section, any IDE can be used.

If the IntelliJ IDEA IDE is used, please be sure to make the CodeCarnage folder (i.e., the folder directly above src/ and website/) the root of your project. Then, please expand the src/main and src/test folders. Mark src/main/java as a sources root, src/main/resources as a resources root, src/test/java as a test source root, and src/test/resources as a test resources root. To set a folder as a root folder, right click the folder and navigate to "Mark Directory as."

Linux operating systems are the most straightforward and require the least setup. However, Windows development is also perfectly acceptable. While Mac development has not been attempted, there should be no reason why that would not work as well.

Building and Running the Project

This project is intended for Java 1.8, and therefore the Java 1.8 SDK will be required to build and run.

If you are running on Linux, you likely already have Gradle installed. If you are not running Linux or the gradle command fails when executed in a terminal, you will need to install Gradle.

With both Gradle and the JDK installed, you can navigate to the CodeCarnage root folder (that is, the folder containing src/ and website/) and execute the following command as an all-in-one:

gradle buildJar

The above command calls many sub-commands and will clean the repository, build the source code, run all unit tests and verify their success, and build the resulting JAR file that is ran for CodeCarnage (which may be placed in build/libs/CodeCarnage-all.jar or similar).

The commands below may also be helpful:

  • gradle cleanIdea - Removes all files required for IntelliJ to run and manage the project. This is perfect for acquiring a clean slate for other commands to run on.
  • gradle idea - Build the IntelliJ dependencies for running CodeCarnage
  • gradle clean - Cleans the built source code for CodeCarnage, which is also perfect for acquiring a clean slate for other commands.
  • gradle build - Builds the source code for CodeCarnage with the most recent changes, verifying that the code compiles.
  • gradle test - Runs all CodeCarnage unit tests and verifies their success.

These commands can be run together. For example, Jacob frequently runs the following gradle chained command:

gradle clean cleanIdea idea build test buildJar

Note that gradle commands are not case-sensitive. If you would like to see the other custom gradle configurations for the CodeCarnage project, please see the build.gradle file in the root project directory. More information is also available on Gradle's website.

Next Steps

Now that you're familiar with all of the CodeCarnage software, why not take a look at our open issues and find one that suits you? We would love your help!

Having Trouble?

If you're having trouble, we strongly suggest first visiting the CodeCarnage Website.

If you cannot resolve your issue by looking at the website or reviewing this wiki page, then please use the links below to contact the core development team on GitHub: