Welcome to EvolvedTD, an Evolutionary Tower Defense game!
The following sections walk you through cloning, branching, pulling, commiting, pushing, and reviewing code changes using Git.
First, we get download a copy of the repository to our machine (note the use of SSH for authentication):
git clone git@github.com:tsoule88/evolvedTD.git
cd evolveTD
Now we run git status
. Notice that it will say we are "on branch
master
", this branch is the default. Its first commit is the first
commit in the repo. Commits are discrete sets of changes to the files
tracked in the repo, and what Git does is record these in a tree,
effectively keeping track of the entire history of changes to a
codebase.
Since the master
branch is special, we want to keep it stable, which
means that it should only be changed after a code review. So in order
to record and share changes that we wish to eventually merge into
master
, we commit them to a different branch and share that. Once
the branch's changes have been reviewed by our peers (on GitHub, in a
Pull Request), the entire branch is merged back into master
.
Before changing any code, we need to make a branch for what we are going to work on:
git checkout -b getting-started
This command did two things: it created the branch getting-started
and it checked the branch out, meaning that our HEAD
reference (a
pointer or marker to the checked out commit) now points to the tip of
the new branch. When we commit, it is added to the commit tree as a
child of the commit that our HEAD
reference marks. With each commit
we add to this branch, the getting-started
branch reference (and
HEAD
) is moved to the new commit, but master
(and other branches)
are not, so the history has diverged. This is a good thing, because
the differences can be compared, discussed, reviewed, and merged back
in easily via pull request.
The two things the above command did are equivalent to this:
git branch getting-started
git checkout getting-started
Git has lots of documentation; use
git help subcommand
to read it, e.g.git help checkout
.
Checking out a reference, i.e. a branch name or a commit hash, will
update the local files such that they match their state at the given
reference. If git status
indicates we have modified files (use git diff
to see the differences), then we'll either want to commit them,
or if we're not quite ready to do so, we can stash them away for
later using git stash
.
Use
git status -sb
to quickly see the current branch and changes
Whenever we start a new branch, unless another line of development
makes more sense, we should branch" it off master
, which just means
checking it out first:
git checkout master
git checkout -b new-topic
Let's say a pull request was recently merged into master
and we want
to obtain those changes. It's as easy as checking it out and pulling:
git checkout master
git pull
We should then integrate the latest changes into our topic branch, which requires merging. For most cases the merge will be trivially resolved by Git; manual intervention is only necessary if the same lines of code have been changed on each side of the merge.
Merges always merge into the current branch, from the one specified
on the command line. Since we want the changes in master
to be
merged into new-topic
, we'll start there:
git checkout new-topic
git merge master
Git will create a "merge" commit which brings the two branches of the tree together by having each as a parent, for two parent commits. Git will allow us to edit the commit message before saving it, but we should keep the summary.
Go ahead and make some changes to any tracked file and save it. Git status should now list the file as modified under "Changes not staged for commit". This means Git is aware we've changed the file, but no more. If we want to record these changes, we need to stage them to the index (i.e. staging area), which is Git-speak for marking which changes we want in the next commit (it doesn't have to include every change).
See the online documentation for more!
Unstaged changes can be seen using git diff
, and staged changes can
be seen using git diff --cached
(--staged
is an alias). The diff
command also accepts arbitrary ranges of references as well as paths
to particular files, but by default it shows the changes between our
working tree and the staging area, hence why staged changes are
excluded without the flag.
Perhaps we fixed a typo in this guide and so have modified the file
README.md
, and we want to add the all the changes in the file to the
staging area:
git add README.md
Git status should now list the modifications under "Changes to be committed".
Use
git add --patch
to interactively stage changes
To finish the commit and thus record the changes to the repository, we need to write a commit message. The first line should be a one-line summary of the changes in the commit; for longer messages, leave a blank line, and then add details. Commit messages should be imperative: "Fix bug", not "Fixed bug" or "Fixes bug", e.g.:
git commit -m "Fix typo in Getting Started"
Executing git commit
without a message will open the program defined
in our $EDITOR
environment variable, where a longer commit message
can be written.
Let's suppose we have spent the day working on a feature with its own
branch foo
. Since we work with a team, we need to share our work,
even if it's not completely finished, so we can refactor our code
based on input we receive from our peers. First, let's take a look at
our log of changes so we can remember what we've done:
git log --decorate --graph --oneline
The --decorate
flag causes references to be emitted in the log, so
we can see where each branch is. The --graph
flag draws an ASCII
tree; and --oneline
shows just each commit's summary. The top is
most recent, so we should see foo
but not master
right before
that commit's summary. Since we are using GitHub Flow,
master
and the remote branch that it tracks, origin/master
, should
always be on the same commit if we are not actively merging a
finished pull request. Once we are sure we have not erroneously
committed to master
, we will push our changes to GitHub:
git push --set-upstream origin foo
If we have not pushed this branch to GitHub before, we need to specify
it with --set-upstream origin
. When we cloned Dr. Soule's repo, Git
kept track of where it came from by adding a remote
named
origin
. We are setting origin
as the upstream repo, and adding a
new branch foo
to origin
, so that all subsequent executions of
git push
when we are on our local branch foo
will automatically
send our changes to GitHub and move the origin/foo
reference
accordingly.
Our peers can then pull our changes into their local repos by running
git pull
, and then check those changes out with git checkout foo
.
Once we've pushed our changes to GitHub, we want to
write a perfect pull request. After navigating to the
project's page, we want to find our branch foo
and click the
"Compare & review". This will present with an overview of changes
between our branch and master
. After writing the pull request, we
then submit it by clicking "Create pull request".
The PR will now be viewable to all our peers, and open for
discussion. We can add to the PR by pushing more commits to foo
; in
fact, any collaborator can do this, so don't forget to pull their
changes before continuing your work.
Before a PR can be signed-off, it needs to be able to merge cleanly,
which means merging master
into foo
, such that when we merge foo
into master
, Git will simply "fast-forward" the master
branch
reference to the merge commit at the head of foo
. Since this
commit's parents were master
and foo
to begin with, the second
merge won't make another commit as it can just move the reference
forward.
"Any sufficiently advanced technology is indistinguishable from magic." - Arthur C. Clarke
After the PR has been sufficiently reviewed and signed-off by another
team member, we will want to merge it back into master
. Since we
already took the time to ensure this will happen cleanly, GitHub
offers us a button at the bottom of the PR to automatically perform
the merge from foo
into master
, thus completing and closing the
pull request.
If published commits break the game, or for any other reason need to
be "undone", the git revert
command will create inverse
commits of the specified range, which are then committed, effectively
undoing the changes in a recorded manner. GitHub also provides a
revert
button on merged pull requests.
If you wish to use Processing from the command line (or with
processing-mode
in Emacs etc.), install the binaries through the
menu "Tools" -> "Install 'processing-java'".
Can be installed through the Processing IDE menu "Sketch" -> "Import Library" -> "Add Library" -> "Box2D for Processing". Can also be installed manually.
Box2D has an issue with memory leaks. Specifically, it keeps
references to bodies around much longer than it is supposed to. The
bodies have a userData
field with a reference to our objects
(creatures, projectiles, food, etc.). When the body sticks around with
the reference, it prevents Java's garbage collector from cleaning up
our objects.
After a long search for our memory leak, we have found that
the fix for this is to remove the reference via
body.setUserData(null)
when the body is no longer needed (that is,
in killBody()
for the respective object). Box2D bodies also have
fixture lists, which similarly need their user data set to null. If we
ever add joints, they would need to be taken care of as well. Please
ensure this is done for any new body types added to EvolvedTD. See
#203 and #205 for more information.
If you wish to add a field to the data collection there is a simple process to do so:
1) Add your data field to the correct table
2) Add your row of data to the collection.
Now your data should show up in the designated table and column in our excel and csv files.
Whenever you open the excel file it auto-populates it's information from the csv files generated by the game. It then re-populates ever minute automatically. This should mean that editing the excel file should not really be necessary. It also means that the excel file technically changes everytime it is openned, so be careful to not save it or you will have a new commit to make.
Changes to the excel file should only be saved and made in the master excel file. This is because with everyone adding different data collection, there may be several different formats for the same collumn. Thus the data file for your branch should never be merged to master, rather the master excel file should be edited after your branch has been merged.
Certain edits that you may want to do to the excel file would be coloring and formatting of the cells in the collumn of data that you added.
You can find tutorials on basic excel editing here: Easy Excel Tutorials