Using Distributed Version Control with Unity Free Edition

Whether working with a team of developers or solo the benefits of version control are extremely worth the effort.  I won’t get into the differences between centralized and distributed version control, there is plenty written on the subject.  In this walk-through I will be using git.  If you’re familiar with using GIT (either via git-bash, or git-gui) great, you will follow right along.  However if you’re new to GIT or version control in general no sweat, github just released a new client application that makes version control a snap.

Using Unity with GitHub:Windows

1) Grab the GitHub for Windows installer, and install on your machine.

2) Signup for a free account with GitHub.

3) Setup your project in Unity

4) Enable Meta Files in Unity by selecting ‘Edit>Project Settings>Editor’ and selecting ‘Meta Files’ in the ‘Enable Version Control’ option.

5) Finish whatever features/bugs you are working on and save the project, and close Unity.

6) Delete the ‘Library’ directory from your project with your file manager.

7) Fire up GitHub:Windows and login with your github account.

8) On the user screen on GitHub Windows select, ‘create one’ (a new repos).

9) Browse to the location of your Unity Project, if you select the projects top-level directory GitHub Windows will automatically name the repository the same name.

10) Open the Repo by clicking on the right-pointing arrow, write your commit message and commit the project to the ‘master’ branch.

11) Publish the commits to the GitHub server.

12) The next time you open your project in Unity, or the first time a team member opens the project after forking it from GitHub follow these steps.

12a) Open Unity by double clicking the icon, and immediately pressing and holding the <ALT> key, this opens Unity in the ‘Project Wizard’.

12b) Select your project and open it in Unity.  Unity will automatically create the Library directory on your local machine, this directory should NOT be included in your version control.

13) Open .gitignore (in your projects top level directory) with a text editor, and add ‘Library/’

14) Now just follow good DVC practices by commiting often and making copious commit notes. This basic workflow was derrived from Unity’s documentation for external version control which can be found HERE.  If you have any questions or comments please let me know either in the comment section here or on my twitter feed.

Reustonium

Dictator – Dev Blog Week 1

Project Workflow – Dictator

I recently got to spend some time with a great friend doing some mountain climbing in the Pacific Northwest.  While waiting for our flights home we started discussing game development and the idea of ‘Dictator’ was born.

Dictator will be a FPS with persistence, perma-death, and a social economy.  Since we live in different cities, efficiently working on this project will require the use of some project and code management tools.  In the last week I have explored several software development tools including Jira with Greenhopper, Trello, and ScrumNinja.  Also, I have previous experience with Test Track and Target Process at my day job.

Jira with Greenhopper is a very robust and flexible tool, however for this project it falls under the category of ‘overkill’.

Trello is a clean web-based task board, but leaves a bit to be desired for software development projects.

However, ScrumNinja seems just right.

ScrumNinja

ScrumNinja is self billed as “—the world’s most elegant, intuitive, easy-to-useagile tool that does all the awesome things you want and need it to do.”  While that might be an overstatement, ScrumNinja does provide a fantastic tool for creating project backlogs, setting sprints, and tracking deliverables.

Backlog

The backlog is the place where all future user stories are stashed.  Each user story contains several smaller tasks which are assigned directly to the story.  When creating each task I like to record the expected time to complete it (in hours); then each story is assigned ‘story points’ which are used to keep sprints at manageable sizes.  I have been assigning 1 story point for each quarter of an hour I expect that story’s sub-tasks to take to complete.

As your project progresses ScrumNinja calculates your “project velocity” that is how many stories points on average you accomplish during a sprint.  This average velocity is used to size subsequent sprints.

Card Wall

The Cardwall is where you track the stories and tasks in the current sprint. Each task can be either pending, in-progress, or done.  When each story is complete the sprint progress updates the number of story points completed.

Burndown Chart

The burndown chart displays the target story points remaining, team trend, and the team performance.  Since we have only been using this tool for a few days I don’t have too much experience monitoring the burndown chart yet.  I’m looking forward to seeing how accurate my task-time estimation is, and how well ScrumNinja is able to scale sprints.

Dictator Wiki

The only other productivity tool we plan on using is a Media wiki page for working out development decisions, and project direction.

Dictator Wiki

This is a link to our wiki page, it contains all the development decisions we are working on for each sprint.  The idea is that a wiki is a good format for sharing ideas, and tracking project direction decisions.

Closing

That’s it for now, all we have right now are tools and ideas. Time to get to work!

Reustonium

First “Complete” Game

It’s been a while since I’ve posted anything new on here, I’ve been busy just quite.  After fumbling around with Java for the better part of 3 months I decided to try my hand at Unity.

If you head over to my Game page you can see my first completed game.  I followed the path set forth in Will Goldstone’s Unity Game Development Essentials.  While I admit it isn’t a game of my own creation and it’s not long; it is my first complete attempt at creating something with any language or game engine.

Time to get to work on two new projects which I should have more information about in the very near future.

Alpine Adventure – Input Handling

Below is my Keyboard Input card within the Input Handling list on my Trello page.  It details which input functionality I expect to need in the game.

As I’ve been learning Java I have taken a look at several source-code examples from previous Ludum Dare competitions (a 48-hour game jam where entrants work solo on a game which must include a theme which is announced at the start of the weekend).  Being a big Minecraft fan I’ve spent a lot of time checking out Notch’s recent #LD48 entry ‘minicraft’.

Below is the code (which I have essentially pilfered from Notch) to handle keyboard input for Alpine Adventure.

Alpine Adventure – Task Tracking

Alpine Adventure Task List

I wanted to share a new collaborative workflow tool which I’ve stumbled across called Trello. Trello allows for highly customized lists to track anything you want, for the development of Alpine Adventure I setup trello to help me sort out the features which I’d like to include and tasks required to achieve those features.

Here is a ‘Legend’ board I keep open at all times to keep me focused on what this game is about.

Alpine Adventure – 2D Mountain Climbing RPG

Overview
It’s time to start working on my first game, ‘Alpine Adventure’ a 2D mountain climbing RPG. The game will be a tile based RPG where the player explores the wilderness trying to reach the summit of a mountain. You start out with nothing but the clothes on your back, but as you gain experience you earn coin to spend on gear at the merchant in town.

Task List
Alpine Adventure Task List
I will follow up with a detailed breakdown of the task-list that’s up on Trello

Experimenting with Swing: Health Status – Part 3

In Part 2, I showed how to create a simple health value display with two buttons, one to ‘hurt’ the player and one to ‘heal’ the player.  This post will show how to display and update a health status bar each time the health value is changed.

 

 

 

In this post we will be making a newer version of this application which will include a graphical bar representing the health value.

 

 

 

After clicking on the ‘hurt’ button several times you can see that the healthStatus JLabel has updated, and the healthBar has redrawn.

 

 

 

To get started first we create instance variables…
[pyg language="java" style="manni"]
public class Main {

int healthval = 100;

Bar healthBar;
JLabel healthStatus = new JLabel(“HP: ” + healthval);
[/pyg]
Next our program call

[pyg language="java" style="manni"]
public static void main(String[] args){
Main gui = new Main();
gui.start();
}
[/pyg]

Here we have our start() method where you should note that the healthStatus JLabel get’s a preferred size assigned to it, so that when frame.pack() get’s called the size of the frame remains constant.

[pyg language="java" style="manni"]
public void start(){
JFrame frame = new JFrame();
JPanel buttonPanel = new JPanel();
JPanel barPanel = new JPanel();

JButton heal = new JButton(“Heal”);
JButton hurt = new JButton(“Hurt”);
healthStatus.setPreferredSize(new Dimension(45,10));

heal.addActionListener(new HealListener());
hurt.addActionListener(new HurtListener());

healthBar = new Bar(healthval);

buttonPanel.add(heal);
buttonPanel.add(hurt);
barPanel.add(healthStatus);
barPanel.add(healthBar);

frame.getContentPane().add(BorderLayout.NORTH, barPanel);
frame.getContentPane().add(BorderLayout.SOUTH, buttonPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.pack();
}
[/pyg]

Finally for the Main.java class we have our two action listeners (one for each button…

[pyg language="java" style="manni"]
class HealListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
healthval++;
healthBar.setVal(healthval);
healthStatus.setText(“HP: ” + healthval);
}
}
[/pyg]

[pyg language="java" style="manni"]
class HurtListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
healthval–;
healthBar.setVal(healthval);
healthStatus.setText(“HP: ” + healthval);
}
}
[/pyg]

Next we need to create a Bar.java class to create the healthBar, and to provide the Bar.setVal(int) method.

[pyg language="java" style="manni"]
package healthbar;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JComponent;

public class Bar extends JComponent{

private int healthval;

public Bar(int hv){
setPreferredSize(new Dimension(100,10));
this.healthval = hv;
}

public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.PINK);
g.fillRect(0,0, 100, 10);
g.setColor(Color.red);
g.fillRect(0, 0, healthval, 10);
}

public void setVal(int val){
healthval = val;
repaint();
}
}
[/pyg]

Here is the full Main.java class…

[pyg language="java" style="manni"]
package healthbar;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Main {

int healthval = 100;

Bar healthBar;
JLabel healthStatus = new JLabel(“HP: ” + healthval);

public static void main(String[] args){
Main gui = new Main();
gui.start();
}

public void start(){
JFrame frame = new JFrame();
JPanel buttonPanel = new JPanel();
JPanel barPanel = new JPanel();

JButton heal = new JButton(“Heal”);
JButton hurt = new JButton(“Hurt”);
healthStatus.setPreferredSize(new Dimension(45,10));

heal.addActionListener(new HealListener());
hurt.addActionListener(new HurtListener());

healthBar = new Bar(healthval);

buttonPanel.add(heal);
buttonPanel.add(hurt);
barPanel.add(healthStatus);
barPanel.add(healthBar);

frame.getContentPane().add(BorderLayout.NORTH, barPanel);
frame.getContentPane().add(BorderLayout.SOUTH, buttonPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.pack();
}

class HealListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
healthval++;
healthBar.setVal(healthval);
healthStatus.setText(“HP: ” + healthval);
}
}

class HurtListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
healthval–;
healthBar.setVal(healthval);
healthStatus.setText(“HP: ” + healthval);
}
}

}
[/pyg]

Experimenting with Swing: Health Status – Part 2

Health Status Part 1 showed a simple JFrame and a way to decrement and display a players health value. One of the shortcomings of that code was the inablilty to register multiple action listeners within the same class.  The way around that is inner classes.  As you can see in the code below the HealthBar class no longer implements the ActionListener.  We have assigned the task of listening to a couple of new inner classes (HealListener, and HurtListener).  It is these subclasses which handle the action events for each of the buttons. Now we are able to increment the health as well as decrement the health.

[pyg language="java" style="manni" ]
package gui1;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

public class HealthBar{

int healthval = 100;

JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton heal = new JButton(“Heal”);
JButton hurt = new JButton(“Hurt”);
JLabel health = new JLabel(“HP: ” + healthval);

public static void main(String[] args){
HealthBar bar = new HealthBar();
bar.go();
}

public void go(){

frame.getContentPane().add(BorderLayout.SOUTH, panel);
frame.getContentPane().add(BorderLayout.CENTER, health);
health.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(heal);
panel.add(hurt);
hurt.addActionListener(new HurtListener());
heal.addActionListener(new HealListener());

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(150,150);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}

class HurtListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
healthval–;
health.setText(“HP: ” + healthval);
}
}
class HealListener implements ActionListener{
public void actionPerformed(ActionEvent ev) {
healthval++;
health.setText(“HP: ” + healthval);
}
}
}[/pyg]

Up next I will work on making the health status a graphical bar, as is probably most common in games.

Experimenting with Swing: Health Status – Part 1

Today I’m experimenting with the very simple concept of displaying and updating a players health value.  The key concepts in this example are:

  • Displaying a Gui with Swing
  • Implementing an Action Listener to wait for a button press

Here is the first try at some code to display and update a players health value…

[pyg language="java" style="manni" ]

package gui1;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

public class HealthBar implements ActionListener{

int healthval = 100;

JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton heal = new JButton(“Heal”);
JButton hurt = new JButton(“Hurt”);
JLabel health = new JLabel(“HP: ” + healthval);

public static void main(String[] args){
HealthBar bar = new HealthBar();
bar.go();
}

public void go(){

frame.getContentPane().add(BorderLayout.SOUTH, panel);
frame.getContentPane().add(BorderLayout.CENTER, health);
health.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(heal);
panel.add(hurt);
hurt.addActionListener(this);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(150,150);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
public void actionPerformed(ActionEvent ev) {
healthval–;
health.setText(“HP: ” + healthval);
}
}[/pyg]

When we run this code you see a small JFrame displaying the HP value and two buttons, one to “hurt” and one to “heal”.  Given the code above anytime the user hits the “Hurt” button the action listener assigned to that button calls the “actionPerformed” method and executes the code which decrements the ‘healthval’ integer then updates the text of the JLabel ‘health’.

 

 

 Here you can see that the JLabel ‘health’ updates after clicking “hurt”.  Currently there is no action listener registered with the ‘Heal’ button.  Let’s fix that in Part 2

Raison d’être: Why Start a Game Dev Blog?

Raison d’être -  the sole or ultimate purpose of something or someone.

What is the purpose of this blog?

Alpine Indie will chronicle the journey of a novice programmer as he works towards his dream of creating a kickass Alpine Mountaineering game.  Every success, every failure, and the code to go along with it will be documented here.  It is my hope that during the life span of this blog somebody will see the work accomplished here and take away something valuable.

Who is Reustonium?

I am a mechanical engineer with very little in the way of programming knowledge, even less artistic ability, and meager writing skills.  What I lack in formal training I hope to make up for with passion and hard-work.

What’s your plan? You can’t code, you can’t draw and you can barely write.

Geez, kind of critical of my current ability eh?  The first step is to learn a language, JAVA.  My first several posts will cover my progress through Head First Java, an excellent introduction to Java.

Head First Java

The next several steps will be comprised of trial and failure, I will be making prototype games, they will suck. hard.  But from these failures we will learn and given time and effort the prototypes will get better.  Beyond that it’s anyone’s guess.

With that, it’s time to get cracking.  If this seems like something interesting to you, or if you have any advice please drop me a line.