Thursday, September 15, 2016

Candy Kid Press Release

A Press Release is an official statement issued to give information on particular matters e.g. Video Games! Here is the official Press Release for Retro Candy Kid and its full implementation with the assistance from @PhilipGHarris [writer, developer, designer] using MailChimp to distribute the Press Release accordingly.

Let's check it out!

MailChimp
MailChimp is an email marketing service used to directly send commercial messages, typically to a group of people, using email. MailChimp offers these main features: Campaigns | Templates | Lists | Reports:
 Campaigns   Campaigns are how you send template emails to the contacts in your MailChimp list.
 Templates   A template is an HTML file used to create the layout and basic design for a campaign.
 Lists   A MailChimp list is a powerful and flexible tool that helps you manage your contacts.
 Reports   MailChimp reports analyze clicks, opens, subscribers’ social activity, e-commerce data.

Therefore, let's use MailChimp to complete Press Release for Retro Candy Kid. Action the following tasks:
  • Get Promo Codes
  • Build Email List
  • Build Template
  • Send Campaign
Promo Codes
Generate iOS promo codes: Log in iTunes Connect. Select My Apps | Candy Kid | Features | Promo Codes.
Enter a number of Promo Codes required for Press Release (e.g. max 100) | Click Generate Codes button. Check "I have read and agree to the terms presented above". Generate Codes and download as a txt file.

Lists
MailChimp | Lists | Create List | Create List | Enter the following details to complete the list information:
 List name  CandyKidList
 Default From email address  steven_boland@hotmail.com
 Default From name  StevePro Studios
 Remind people how they signed up to your list  Enter reminder information
 Contact information for this list  Enter contact information

Next page: View subscribers | Import subscribers | CSV or tab-delimited text file | Next | Upload CSV file. Browse to CSV file and Check "I understand that my billing plan may be automatically upgraded" | Next. Match any unmatched columns: "Make a Selection" | New column name | e.g. COUPON | Save | Import.

Finally, ensure columns can be used as placeholders in Template: Settings | List fields and *|MERGE|* tags. Ensure the "Field label and type" values are aligned to the "Put this tag in your content" values!
 FULLNAME  FNAME  LNAME  COMPANY  EMAIL  COUPON
 Steven Boland  Steven  Boland  StevePro Studios  steve@stevepro.com  YY3FR7L7NNY3
 Suzanne Boland  Suzanne  Boland  FN Days Ltd  suzanne@stevepro.com  7YHALRJ39FJX
 Adriana Boland  Adriana  Boland  Stinky Inky Co.  adriana@stevepro.com  N6X4L79KKLNK
IMPORTANT: tags have maximum 10x characters thus better use "COMPANY" instead of ORGANIZATION.

Templates
MailChimp | Templates | Create Template | Code your own | Paste in code | Select | Edit code | ENTER:

Retro Candy Kid is a top-down maze chase video game inspired by the 8-bit title "Candy Kid".

Candy Mama enemies are always out to get you as you try and eat all the candy to complete the level. Simple!

Try it for yourself with this free iOS Promo Code: *|COUPON|*

Retro Candy Kid is available on mobile platforms (iOS / Android / Kindle) and PC.

You Tube http://www.youtube.com/watch?v=rEWGOwq4yAI
Facebook http://www.facebook.com/CandyKidVideoGame



Retro Candy Kid includes the following key features that were not available in the original 8-bit title:
 - All 100x levels are unlocked.
 - Double bonus pts available.
 - Giant candy for extra lives.
 - Free man every 20,000 pts.
 - Open tunnels or closed exits.
 - Avoid trees or Death trees.
 - God mode for invincibility.
 - Unlimited game continues.

Company Bio
StevePro Studios is an independent game developer that builds and publishes 80s retro arcade video games! The studio was founded by Steven Boland "SteveProXNA" in January 2007 as a "one man team of one" and is currently based in Dublin, Ireland.

Fact Sheet
The original 8-bit title Candy Kid was a "type-in" video game published by New Zealand's Sega Computer Magazine in the September 1984 issue, pages 17-18. Inspired by the Sega Retro Gaming scene, "Candy Kid" was re-written as "Retro Candy Kid" by StevePro Studios in September 2015.

Price point
 USD   0.99
 GBP   0.79
 EUR   0.99
 JPY     120
 AUD   1.49
 CAD   1.19
 NZD   1.29
 CNY   6.00

Contact
 Blog
 Email
 Phone
 StevePro Studios
 steven_boland@hotmail.com
 +353 877 541 327
 Linked In
 Twitter
 Skype
 StevePro Studios
 @SteveProXNA
 SteveProXNA

Best,
Steven Boland.
Note: *|COUPON|* placeholder in the Press Release text will be substituted with promo code from list.

Campaigns
Although you can create campaigns directly from Campaigns tab, a simpler method is through Templates:

MailChimp | Templates | Click "Edit" dropdown to right of Template saved | Create Campaign. Choose a list to get started e.g. CandyKidList. Send to entire list | Next [bottom]. Enter following Campaign Info:
 Campaign name  RetroCandyKidCampaign
 Email subject  Retro Candy Kid – Awesome Arcade Action
 From name  StevePro Studios
 From email address  steven_boland@hotmail.com

Note: leave all checkboxes unchecked except the Personalize the "To" field. Set *|FNAME|* for recipient. Next Template | Next Confirm | Review summary all correct. Finally, Prepare for launch and Send Now!
Note re-send: MailChimp | Campaigns | Click "View Report" dropdown to right of Campaign | Replicate.

Summary
After campaign is successfully sent, the main Dashboard will report all activity; which includes: 24-hour performance, Top links clicked, Subscribers with most opens, Top locations by opens and much more...!

Wednesday, August 31, 2016

GitHub Cheat Sheet

Subversion (SVN) client–server model makes it easy to checkout source code from server-side centralized repository [repo], make local changes to working copy on client, and commit changes back to the server.

Whereas Git: a distributed version control system, unlike most client-server systems, every Git directory is full-fledged repository [repo] complete with history + independent of network access or central server.

Differences like these may be challenging at first. Therefore, let's smooth the transition from SVN to Git:

Let's check it out!

Pre Requisites
Here are the Atlassian Git tutorials this post makes reference to. Attached is basic diagram for Newbies: Note: in the simplest terms, git pull [not pictured] does a git fetch followed by a git merge.

Download Git distributed version control system for Windows or Mac. Setup Git global configuration here:
 Windows  C:\Users\<username>\.gitconfig
 Mac OS/X  /Users/<username>/.gitconfig

Here are basic commands to get and set Git global user name and user email throughout all repositories:
 User name  git config --global --get user.name
 git config --global user.name "SteveProXNA"
 User email  git config --global --get user.email
 git config --global user.email "steven_boland@hotmail.com"

Git Clients
There are free Git clients available for Windows and Mac such as GitHub Desktop and SourceTree however these show complex branched code which can be overwhelming for Newbies. Let's focus on simpler tools:
   SVN  GIT
 Windows  TortoiseSVN  TortoiseGit
 Mac OS/X  svnx  Gitbox
Note: Gitbox non-commercial version only allows one repository at a time but often that can be sufficient.

IMPORTANT:
If you have Cygwin installed on Windows then ensure TortoiseGit settings do NOT use Unix Git.exe Path:

GitHub
Create an account on github.com if you have not already done so. Read the guide is another good start. Choose Start a Project | Enter the name of your new repo e.g. "MyCoolRepo" and initialize with README: Launch command prompt. Type 3x variants of following git clone command to checkout local repository:
git clone https://github.com/SteveProXNA/MyCoolRepo.git MyCoolRepo
git clone https://<username>@github.com/SteveProXNA/MyCoolRepo.git MyCoolRepo
git clone https://<username>:<password>@github.com/SteveProXNA/MyCoolRepo.git MyCoolRepo
As a convenience, cloning automatically creates a remote connection called origin pointing back to the original repository. This makes it easier to interact with the repository. Also, default branch is master.
repo   local    master
repo   remote   origin/master
When you push to origin/master [remote] you will be prompted with whatever credentials are required. Note: here all git clone repos are done via https protocol. Checkout here for SSH git clone repo setup.

Configure current user name and email for repo activity, especially if you have multiple Github accounts:
 User name  git config --get user.name  git config user.name "SteveProXNA"
 User email  git config --get user.email  git config user.email "steven_boland@hotmail.com"

Note: local Git repo information can be found in hidden .git folder at root level where repository is cloned:
 Windows  C:\Users\<username>\GitHub\SteveProXNA\MyCoolRepo\.git\config
 Mac OS/X  /Users/<username>/GitHub/SteveProXNA/MyCoolRepo/.git/config

IMPORTANT:
If you push code changes using TortoiseGit then you may need to change Global User Info name + email; especially if you git clone repository using credentials that are different from the global GitHub account.

Windows Explorer | Right click MyCoolRepo directory | TortoiseGit | Settings | Git [OK] Configure source:

Before making any changes to the repo, prepare working environment to detect changes via Git tools:
 Windows  Explorer | Right click MyCoolRepo directory | TortoiseGit | Check for modifications
 Mac OS/X  Finder | Navigate to MyCoolRepo directory | Drag MyCoolRepo into Gitbox application

Command Prompt
Developers will add changes from the working directory to staging area and commit changes to local repo. When they push from local repo [master] to remote repo [origin/master] changes are available on server.

TortoiseGit + Gitbox can co-ordinate this activity, however, here are some command prompt equivalents:
 git status  List which files are staged, unstaged, and untracked.
 git add file  Stages file from working directory to staging area.
 git reset file  Unstages file from staging area to working directory.
 git commit file  Commits file from staging area to the local repo.
 git push  Push files from local repo to remote [origin] repo. [SVN Commit]
 git clean -df  Remove untracked directories and untracked files from current directory.
 git reset --hard  Reset staging area and working directory to match most recent commit.
 Obliterates all uncommitted changes so be careful using this command!
IMPORTANT: you cannot seem to commit an empty directory; add dummy README file here as needed.

Commit Comparison
One of the more challenging aspects found during the SVN to Git transition is difference between commit.

SVN commits working copy changes from client to server whereas Git commits from staging area to local repo only; git status shows staged + unstaged files thus how do you list all local commits for next push?

Windows right click MyCoolRepo directory | Git Sync... | Click "Out ChangeList" tab | lists local commits.
Mac OS/X in Gitbox each commit listed but not yet pushed is displayed with a dot on the left hand side.

Logging
Whereas git status lets you inspect the working directory and staging area the git log command lets you list the project history, filter and search for specific changes and only operates on the committed history.
 git status
 git log
 git log --grep="SteveProXNA"
 git log --author="SteveProXNA"
 git log --grep="commit"
 git log --merges
 git log -S"today"
 git log --oneline
 git log --graph --decorate --oneline
 git log --oneline master..MyNewBranch
 git log --pretty=format:"%cn committed %h on %cd"
 git log --after="2016-4-1"

Command Prompt II
After developers (eventually) push changes from local repo to remote, here are some more commands:
 git branch  Lets you create, list, rename, and delete branches.
 git checkout  Lets you navigate between branches created by git branch.
 git merge  Lets you integrate independent lines of development into a single branch.
 git rebase  Process of moving branch to new base commit to maintain linear history.
 git fetch  Imports remote changes but does not integrate changes into local repo.
 git pull  Equivalent to a git fetch followed by a git merge. [SVN Update]

Branching
Unlike SVN, Git differentiates between local and remote branches: local branches exist only on the local machine for local user whereas remote branches are branches pushed to origin and are accessible to all.
git branch                              ; list local  branches
git branch -r                           ; list remote branches
git branch -a                           ; list all    branches [local + remote]
Create branches:
git branch MyNewBranch                  ; create local  branch
git push origin MyNewBranch             ; pushes remote branch
Delete branches:
git branch -d MyNewBranch               ; delete local branch if merged changes
git branch -D MyNewBranch               ; delete local branch unconditionally
git push origin --delete MyNewBranch    ; delete remote branch
General update commands to synch github remote and local repository:
git remote update               ; if remote stale then update to synch latest
git fetch --all --prune         ; if delete on one computer and replicate to other
Detached HEAD
HEAD points to specified branch. When you checkout a commit, it switches into "detached HEAD" state from rest of project. If you were to develop in this state then there would be no branch to get back to.

Tagging
Similar to SVN, Git tags are symbolic names for a given revision: code snapshot implemented by git tag.
 Windows  Explorer | Right click MyCoolRepo directory | TortoiseGit | Create Tag... | Enter Tag
 Mac OS/X  Gitbox application | Click dropdown list next to "pull" button | New tag... | Enter Tag

  Here are some command prompt equivalents:
 git tag  ; show tag on local
 git push origin --tags ; push tag to remote
  Also synchronize Git tags with remote:
 git tag -l | xargs git tag -d
 git fetch
Finally, if remote stale then git remote update and replicate to another computer git fetch --prune --tags.

Merging
Merging integrates changes from one source branch into a destination branch and combines histories of both branches. Merging is non-destructive: neither branch is changed in any way, however, the merged branch may have an extraneous merge commit every time you need to incorporate upstream changes.

Fast-Forward Merge
When there is linear path from current branch tip to target branch, instead of actually merging branches, all Git has to do to integrate the histories is move ["fast forward"] current branch tip up to target branch.
git checkout -b MyNewBranch master      ; create branch and switch
                                        ; add and commit to branch
git checkout master                     ; switch to the trunk node
git merge MyNewBranch                   ; merge branch up to trunk
git branch -d MyNewBranch               ; delete local branch
3-Way Merge
Occurs when it is impossible for Git to perform a fast-forward merge as there is no way to move current branch tip to target branch without backtracking. Very common when branch takes long time to develop.
git checkout -b MyNewBranch master      ; create branch and switch
                                        ; add and commit to branch
git checkout master                     ; switch to the trunk node
                                        ; add and commit to master
git merge MyNewBranch                   ; merge branch up to trunk
git branch -d MyNewBranch               ; delete local branch

Rebasing
Rebasing is an alternative to merging and moves the entire source branch to the tip of destination branch by incorporating all new commits. Rebasing re-writes project history by eliminating unnecessary commits.
git checkout -b MyNewBranch master      ; create branch and switch
                                        ; add and commit to branch
git checkout master                     ; switch to the trunk node
git rebase MyNewBranch                  ; rebase branch upto trunk
git branch -d MyNewBranch               ; delete local branch

Merging vs. Rebasing
The benefit of rebasing is a much cleaner project history. Rebasing eliminates all the unnecessary merge commits required by git merge resulting in a perfectly linear project history followed up to the feature tip.
IMPORTANT: the Golden Rule of Rebasing stipulates never to use git rebase command on public branches!

Pull Request
GitHub fosters a fast, flexible, collaborative development process where you work with or without others. Here, you can sign into GitHub and fork an existing repository and create pull request to merge changes.
Choose repository to actively collaborate e.g. MonoGame. Click "Fork" button top right. Choose location. There should now be repository forked under your username ready to git clone and commit changes to:
git clone https://<username>:<password>@github.com/SteveProXNA/MonoGame.git MonoGame
git config user.name "SteveProXNA"
git config user.email "steven_boland@hotmail.com"
Commit changes to local repo and push from local repo [master] to remote repo [origin/master] as usual. However, create pull request to integrate changes from your forked remote repository to the source repo.

Click "New pull request". This prompts "Comparing changes" dialog for the source repository + your fork.
https://github.com/MonoGame/MonoGame/compare/master...SteveProXNA:master
   User  Repo
 Source  MonoGame  https://github.com/MonoGame/MonoGame
 Fork  SteveProXNA  https://github.com/SteveProXNA/MonoGame

Click "Create Pull Request". Owner receives email notification to view proposed changes to integrate. Click "Merge pull request" to merge changes back into source repository and automatically close Pull Request.
IMPORTANT: if you would like to keep up to date with the source repository then follow these short steps:
git clone git@github.com:SteveProXNA/MonoGame.git
cd C:\Users\<username>\GitHub\SteveProXNA\MonoGame
git remote add upstream git://github.com/MonoGame/MonoGame.git
git fetch upstream
git pull upstream master

Imperatives
Here is a short list of git commands that is imperative that you should not do; especially to public history:

Don’t Reset Public History
You should never reset commits pushed to a public repository. Reset a commit poses serious problems for collaboration: when developers sync up with your repo, it'll look like project history abruptly disappeared.

Don’t Rebase Public History
Similar to git reset, you should never rebase commits that have been pushed to a public repository. The rebase would replace old commits with new ones and look like part of project history abruptly vanished.

Jenkins
Integrate all GitHub Plugins with Jenkins. Assume MSBuild setup in Manage Jenkins | Configure System:
 Name  JenkinsMSbuild
 Path to MSBuild  C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
Next, install plugins: Manage Jenkins | Manage Plugins | GitHub Plugin. You may need to install Git plugin.

Navigate to Jenkins | New Item | Create Freestyle project. Ensure the following build configurations set:
 Source Code Management => Git Repositories
 Repository URL  https://github.com/SteveProXNA/MyCoolRepo
 Credentials  <username>:<password>
 Branches to build  Branch Specifier (blank for 'any') */master



 Build a Visual Studio project or solution using MSBuild
 MSBuild Version  JenkinsMSbuild
 MSBuild Build File  MyCoolRepo.sln
 Command Line Arguments  /p:Configuration=Debug
 /p:Configuration=Release

 Execute Windows batch command
 Command  "C:\Program Files (x86)\NUnit 2.5.7\bin\net-2.0\nunit-console-x86.exe"  MyCoolRepo.UnitTests/UnitTests.nunit

Summary
Additional topics that could explored include git stash to push unfinished changes onto a stack that can be popped off later and git submodule to keep another Git repo in subdirectory very similar to SVN Externals.

Monday, July 4, 2016

SVN Externals Application II

In the previous post, we checked out SVN Externals to build an XNA solution with the majority of game code written in an external library and scaled out across multiple game clients including Android + iOS.

As an example, the XNA and System Testing snake simulation was scaled to demonstrate SVN Externals.
However, all code here is in trunk; larger scale development requires release tags and feature branches. Let's check it out!

Pre Requisites
This post assumes you already have Tortoise SVN installed on Windows and svnx installed on Mac OS/X.
Also, consider configuring the $SVN_EDITOR on Windows and Mac OS/X in order to edit SVN properties:
set SVN_EDITOR=notepad.exe     ; Windows PC
export SVN_EDITOR=vi           ; Mac OS/X
Conventions
This post uses the following convention to substitute "$DEMO" for root node of all demo code samples:
$DEMO = https://svn/Demo       ; Subversion
$DEMO = C:\svn\Demo            ; Windows PC
$DEMO = /svn/Demo              ; Mac OS/X

Subversion
Create top level Demo node in Subversion SVN. Add 1x sub-node for XNA library and 4x sub-nodes for each client: WP7, Windows, Android, iOS. Ensure all sub-nodes have branches, tags and trunk folders:
 Alias  Platform  Development  Framework  Description  Source Code
 XNA  Windows PC  Visual Studio 2010  XNA 4.0  Game library  Download
 WP7  Windows PC  Visual Studio 2010  XNA 4.0  Game client  Download
 Win  Windows PC  Visual Studio 2012  MonoGame 3.4  Game client  Download
 And  Mac OS/X  Xamarin Studio  MonoGame 3.5  Game client  Download
 iOS  Mac OS/X  Xamarin Studio  MonoGame 3.5  Game client  Download

Tagging
Before beginning new development, it's often best practice to tag your current release build from trunk.

Note: when you create a tag in Subversion, you are not tagging the SVN Externals repository, you are tagging your working copy. If you do not specify the revision then SVN Update will always get latest!

Therefore, you should always explicitly set the revision of svn:externals property when you create a tag:
svn propset svn:externals 'Common -r2276 $DEMO/XNA/trunk/XNA.Common' .

If you have Tortoise SVN 1.9.4 installed then you can use the new --pin-externals option for svn copy. This will automatically set the SVN revision in the tag for you without manual lookup in the SVN logs.
svn copy --pin-externals svn:externals $DEMO/trunk $DEMO/tags/1.0.0.0 -m "1.0.0.0"

For completeness, here are all TAGS 1.0.0.0 cut from previous SVN Externals Application blog post:
 Alias  Command
 XNA  svn copy --pin-externals $DEMO/XNA/trunk $DEMO/XNA/tags/1.0.0.0-XNA -m "1.0.0.0-XNA"
 WP7  svn copy --pin-externals $DEMO/WP7/trunk $DEMO/WP7/tags/1.0.0.0-WP7 -m "1.0.0.0-WP7"
 Win  svn copy --pin-externals $DEMO/Win/trunk $DEMO/Win/tags/1.0.0.0-XNA -m "1.0.0.0-Win"
 And  svn copy --pin-externals $DEMO/And/trunk $DEMO/And/tags/1.0.0.0-And -m "1.0.0.0-And"
 iOS  svn copy --pin-externals $DEMO/iOS/trunk $DEMO/iOS/tags/1.0.0.0-iOS -m "1.0.0.0-iOS"

SVN Upgrade
On Mac OS/X it is most likely that you cannot use the new --pin-externals option for svn copy as the svn version is too low. Here are some basic instructions to upgrade to, for example, SVN 1.8 on Mac OS/X.

However, upgrading may cause svnx incompatibility. Also, higher versions may require an upgrade to serf. A better approach may be to cut all tags on Windows PC and SVN Update all tags on Mac OS/X.

Branching
Larger features usually require longer development time and it's often best practice to cut feature branch from trunk. Applying SVN Externals to branching and merging back into trunk may result in a similar flow:

 1. Cut branches: XNA library and Win client (and other clients)
 2. Update SVN Externals in Win client to XNA branch (not trunk)
 3. Make all code feature changes in XNA library and Win client
 4. Merge XNA library [trunk down to branch + branch up to trunk]
 5. Merge Win client [trunk down to branch + branch up to trunk]
 6. Delete dead branches cut from above accordingly

Implementation
1. Cut branches: XNA library and Win client (and other clients)
svn copy $DEMO/XNA/trunk $DEMO/XNA/branches/FeatureX -m "FeatureX"
svn copy $DEMO/Win/trunk $DEMO/Win/branches/FeatureX -m "FeatureX"

2. Update SVN Externals in Win client to XNA branch (not trunk)
Launch command prompt, navigate to $DEMO\Win\branches\FeatureX\$FOLDER where $FOLDER is the parent folder that hosts Windows Game project. Common branched XNA library code will be linked here.
cd $DEMO/Win/branches/FeatureX
svn propget -R svn:externals

cd $FOLDER
svn propedit svn:externals .
Edit SVN Externals Subversion Properties from previous to current:
 Previous  Current
 $DEMO/XNA/trunk/XNA.Common Common  $DEMO/XNA/branches/FeatureX/XNA.Common Common
svn update
svn commit -m "Update branch"

3. Make all code feature changes in XNA library and Win client
After making all code changes to feature branch, ensure you increment the build number for next release. Navigate to game client AssemblyInfo.cs file. Increment AssemblyVersion + AssemblyFileVersion values:

For example increment version from previous "1.0.0.0" to current "1.1.0.0"
 Platform  File  Property
 Android  AndroidManifest.xml  Increment Version number
 iOS  Info.plist  Increment Version
Note: updated version number should be synch'd in Xamarin Studio Project Options | Application tab


4. Merge XNA library [trunk down to branch + branch up to trunk]
First, merge trunk down to branch (as changes may have been checked-in on trunk prior to the merge)
cd $DEMO/XNA/branches/FeatureX
svn update
svn merge $DEMO/XNA/trunk
svn commit -m "Merge trunk down to branch"

Next, merge branch up to trunk to (re-)integrate changes from shared XNA library to all upstream clients
cd $DEMO/XNA/trunk
svn update
svn merge --reintegrate $DEMO/XNA/branches/FeatureX
svn commit -m "Merge branch up to trunk"

5. Merge Win client [trunk down to branch + branch up to trunk]
Important: first revert SVN Externals in Win client to XNA trunk as XNA trunk and branch are now synch'd
cd $DEMO/Win/branches/FeatureX
svn propget -R svn:externals

cd $FOLDER
svn propedit svn:externals .
Edit SVN Externals Subversion Properties from previous to current:
 Previous  Current
 $DEMO/XNA/branches/FeatureX/XNA.Common Common  $DEMO/XNA/trunk/XNA.Common Common
svn update
svn commit -m "Revert branch"

Next, merge trunk down to branch
cd $DEMO/Win/branches/FeatureX
svn update
svn merge $DEMO/Win/trunk
svn commit -m "Merge trunk down to branch"

Finally, merge branch up to trunk
cd $DEMO/Win/trunk
svn update
svn merge --reintegrate $DEMO/Win/branches/FeatureX
svn commit -m "Merge branch up to trunk"

6. Delete dead branches cut from above accordingly
svn delete $DEMO/XNA/branches/FeatureX -m "Delete branch"
svn delete $DEMO/Win/branches/FeatureX -m "Delete branch"

For completeness, here is one way to remove the SVN Externals property from working copy folder:
svn propdel svn:externals $DEMO/Win/branches/FeatureX/$FOLDER

Tagging
When it is appropriate, tag the new build as per updated build version number 1.1.0.0 from above:
 Alias  Command
 XNA  svn copy --pin-externals $DEMO/XNA/trunk $DEMO/XNA/tags/1.1.0.0-XNA -m "1.1.0.0-XNA"
 WP7  svn copy --pin-externals $DEMO/WP7/trunk $DEMO/WP7/tags/1.1.0.0-WP7 -m "1.1.0.0-WP7"
 Win  svn copy --pin-externals $DEMO/Win/trunk $DEMO/Win/tags/1.1.0.0-XNA -m "1.1.0.0-Win"
 And  svn copy --pin-externals $DEMO/And/trunk $DEMO/And/tags/1.1.0.0-And -m "1.1.0.0-And"
 iOS  svn copy --pin-externals $DEMO/iOS/trunk $DEMO/iOS/tags/1.1.0.0-iOS -m "1.1.0.0-iOS"


Summary
To summarize, here code has been shared from a single external library across multiple game clients; However, SVN Externals could be used to scale out shared data + content across multiple clients too!

Wednesday, June 1, 2016

SVN Externals Application

In 2015, Candy Kid was written in XNA as a simple maze chase video game. The majority of game code was written in an external library and scaled out across multiple game clients including Android and iOS. In order to avoid problems with Copy + paste programming to multiple clients, SVN Externals was used.
Let's check it out!

SVN Externals allow an Subversion repository to be checked out within a directory in that working copy. Here all common code in external repository linked through "Common" directory across multiple clients.

Pre Requisites
This post assumes you already have Tortoise SVN installed on Windows and svnx installed on Mac OS/X.
Also, consider configuring the $SVN_EDITOR on Windows and Mac OS/X in order to edit SVN properties:
set SVN_EDITOR=notepad.exe     ; Windows PC
export SVN_EDITOR=vi           ; Mac OS/X
Conventions
This post uses the following convention to substitute "$DEMO" for root node of all demo code samples:
$DEMO = https://svn/Demo       ; Subversion
$DEMO = C:\svn\Demo            ; Windows PC
$DEMO = /svn/Demo              ; Mac OS/X
Example
As an example, let's scale the XNA and System Testing snake simulation to demonstrate SVN Externals. Create top level Demo node in Subversion SVN. Add 1x sub-node for XNA library and 4x sub-nodes for each client: WP7, Windows, Android, iOS. Ensure all sub-nodes have branches, tags and trunk folders:
 Alias  Platform  Development  Framework  Description  Source Code
 XNA  Windows PC  Visual Studio 2010  XNA 4.0  Game library  Download
 WP7  Windows PC  Visual Studio 2010  XNA 4.0  Game client  Download
 Win  Windows PC  Visual Studio 2012  MonoGame 3.4  Game client  Download
 And  Mac OS/X  Xamarin Studio  MonoGame 3.5  Game client  Download
 iOS  Mac OS/X  Xamarin Studio  MonoGame 3.5  Game client  Download

Sample
The following code sample builds the snake simulation initially as an XNA solution. After the code sample has be fully tested in isolation, additional clients are added to share "Common" code using SVN Externals.

XNA Game library [PC]
Launch Visual Studio 2010. Create blank solution. Add the following 4x new C#/.NET projects to solution:
 Project  Type  Dependencies  Description
 XNA  XNA 4.0 Game  XNA.Common  Entry point and game specific code
 XNA.Common  XNA 4.0 Game Library  log4net | Ninject  Generic game library for all clients
 XNA.SystemTests  Windows Class Library  NUnit [only]  Used for game library system tests
 XNA.UnitTests  Windows Class Library  NUnit | Rhino Mocks  Used for game library unit tests
Important: create a directory symbolic link using mklink to Content folder in order to run system tests.
// mklink /D C:\SnakeDemo.XNA.Content C:\SnakeDemo.XNA\bin\x86\Debug\
protected const String CONTENT_ROOT = @"C:\SnakeDemo.XNA.Content\";

Notes
Common project properties include: Treat warnings as errors "All" + Release version Debug Info "none".
Manually edit system and unit test projects in Notepad and add following XML to mitigate MSIL warning:
<PropertyGroup>
  <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>

WP7 Game client [PC]
Launch Visual Studio 2010. Create Windows Phone Game 4.0 project. Include all relevant game content.
Use SVN Externals to link common XNA library game code (above) through "Common" directory in client:

In Windows Explorer, navigate to $DEMO\WP7\trunk\$FOLDER where $FOLDER is the parent folder that hosts Windows Phone Game 4.0 project. This is where SVN Externals will link common XNA library code.

Right click $FOLDER | Tortoise SVN | Properties | New... | Externals. In popup window click New button:
 Local path:  Common
 URL:  $DEMO/XNA/trunk/XNA.Common
 HEAD revision  Checked
 Peg:  empty
Note: an optional SVN revision number can be entered in "Peg:" textbox to pin to static code check-in.

Right click $DEMO\WP7\trunk | Tortoise SVN | Check for modifications. Commit change made from SVN Externals. SVN Update to download "Common" directory from $DEMO\XNA\trunk\XNA.Common in WP7.
cd $DEMO\WP7\trunk
svn propget -R svn:externals
svn commit -m "Add SVN Externals"
svn update
Finally, in Visual Studio 2010 click "Show All Files" button. Right click "Common" directory | Include In Project. Build project. Right click $DEMO\WP7\trunk | Check for modifications. Commit changes made. Done!

iOS Game client [Mac]
Launch Xamarin Studio. Create MonoGame iPhone/iPad Application. Include all the relevant game content.
Use SVN Externals to link common XNA library game code (above) through "Common" directory in client:

Launch terminal prompt, navigate to $DEMO/iOS/trunk/$FOLDER where $FOLDER is the parent folder that hosts MonoGame iPhone/iPad Application. This is where SVN Externals will link common XNA library code.

Type in the following SVN commands:
cd $DEMO/iOS/trunk/$FOLDER
svn propget svn:externals

svn propset svn:externals 'Common $DEMO/XNA/trunk/XNA.Common' .
svn propget svn:externals

svn status
cd $DEMO/iOS/trunk
svn commit -m "Add SVN Externals"
svn update
Finally, in Xamarin Studio right click solution | Display Options | Show All Files. Right click "Common" directory | Include To Project. Build project. In svnX, Check for modifications. Commit changes made. Done!

Repeat this process for the remaining projects: Windows Game client [PC] + Android Game client [Mac]

Jenkins
Don't forget to uncheck "Ignore externals" under Subversion modules on all the automated client builds!

Summary
To summarize, SVN Externals has proved effective to scale common game code linked to multiple clients. However, all code here is in trunk; larger scale development requires release tags and feature branches.

This will be topic in the next post.

Thursday, March 17, 2016

3D City Code Complete

3D City is a simple "Shoot 'em up" video game originally programmed StevePro Studios in New Zealand, in January 1988. The game was written using BASIC programming language built on the Sega SC-3000.

Inspired from previous posts on Sega Console Programming and z88dk Programming Setup, 3D City was the impetus to build an 8-bit video game in C / Z80 assembler to target the Sega Master System (SMS).

Let's check it out!
Download source code here.

Sega Retro Gaming post documents how to play video games like 3D City on PC using Fusion emulator.
z88dk Programming Setup post documents development environment required to build C / Z80 source.
Instructions
Simple! Move target and shoot all enemy ships before they kill you. 4x misses and it is Game Over.
Hint: hold controller Button2 down while moving target slows target down for more focused attack.

ROM Hacking
You can hack this ROM! Download and dump 3Dcity.sms into Hex Editor, e.g. HxD, and modify the bytes:
 ADDRESS  VARIABLE  DESCRIPTION
 0x00C0  Death  Non-zero = invincibility!
 0x00C1  Level  0=easy (default) 1=hard.
 0x00C2  Enemy  0=3x enemies else 1 or 2.
 0x00C3  Music  0=music on otherwise off.
 0x00C4  Sound  0=sound on otherwise off.
 0x00C5  Tiles  0=tiles scroll yes else no.
 0x00C6  Stars  0=stars flash yes else no.
#ifndef _HACK_MANAGER_H_
#define _HACK_MANAGER_H_

#define PEEK(addr)   (*(unsigned char *)(addr))
#define POKE(addr, data) (*(unsigned char *)(addr) = (data))

#define HACKER_START  0x00C0

extern unsigned char hacker_death, hacker_level, hacker_enemy, hacker_music;
extern unsigned char hacker_sound, hacker_tiles, hacker_stars;

void engine_hack_manager_init()
{
  hacker_death = PEEK(HACKER_START + 0);  // 0x00C0
  hacker_level = PEEK(HACKER_START + 1);  // 0x00C1
  hacker_enemy = PEEK(HACKER_START + 2);  // 0x00C2
  hacker_music = PEEK(HACKER_START + 3);  // 0x00C3
  hacker_sound = PEEK(HACKER_START + 4);  // 0x00C4
  hacker_tiles = PEEK(HACKER_START + 5);  // 0x00C5
  hacker_stars = PEEK(HACKER_START + 6);  // 0x00C6
}

#endif//_HACK_MANAGER_H_
Credits
StevePro Studios would like to thank the following, esp. at SMS Power, for making this project possible:
 haroldoop  Adapt z88dk (C cross-compiler) for Z80 systems + generate SMS ROMs
 Maxim  BMP2Tile  Converts BMP images into 8x8 SMS tile data
 Martin  Mod2PSG2  Music tracker software for SMS sound chip
 vhelin  WLA-DX  Z80 multi platform cross Assembler package
 Martin  SMS Examine  Z80 disassembler recompilable by WLA-DX
 Bock  Meka  SMS emulator (excellent debugging features)
 Steve Snake  Fusion  SMS emulator used for general play testing
Important: the psgmod.asm file (Mod2PSG2) was customized thus ASM could be invoked from C code.

Summary
In fact, the Homebrew community at SMS Power celebrates Sega 8-bit preservation and fanaticism each year with its annual competitions. Therefore, this is an opportunity to enter 3D City for 2016. Good luck!

Friday, January 1, 2016

Retrospective VII

Last year, I conducted a simple retrospective for 2014. Therefore, here is a retrospective for 2015.

2015 Achievements
  • Consolidate numerous "XNA" ideas from this blog into single game project
  • Write C# / XNA game code linked to multiple MonoGame / Xamarin clients
  • Use 2D Independent Rendering to target a multitude of screen resolutions
  • Employ better Indie dev. source control systems + continuous integration
  • Commit to Retro Games: more active on social media Facebook + Twitter
  • Salvage ITIN acquired from "XNA and TAX" required for mobile publishing
  • Write WiX / XNA Installer seamlessly download + install PC game version
  • Self-publish Retro Candy Kid mobile platforms: iOS, Android, Kindle + PC
Note: complete game project in C# / XNA published on non-XBLIG platforms is an achievement!

2016 Objectives
  • Expand XNA / MonoGame topics to include localization, custom shaders
  • Apply similar XNA / MonoGame techniques to transition XNA / Unity3D
  • Research additional Indie portals to publish including Steam Greenlight
  • Publish more source code. Checkout sources other than CodePlex (Git)

In 2015, StevePro Studios consolidated many ideas from this Indie game development blog to produce game project to be self-published on PC (outside XBLIG) but also on mobile platforms: iOS and Android.

The game project "Retro Candy Kid" was inspired by the original 8-bit title Candy Kid: a "type-in" video game published by New Zealand's Sega Computer Magazine in the September 1984 issue, pages 17-18.

"Retro Candy Kid" was re-written in C#/XNA 4.0 and employed many techniques discussed in this blog:
 Agile Software Development  Data Driven Design
 Dependency Injection  System Testing
 IoC Container (Ninject)  Level Validation
 Unit Testing  
 Test Driven Development  

However, now that XNA is "dead", this was also an opportunity to transition away from XNA 4.0 to other options e.g. MonoGame and use Xamarin for iOS / Android port. TODO: future project may use Unity3D.

Quality vs. Velocity
Finally, by leveraging techniques (above), 95% of all game code was written in an external library that was unit tested in isolation plus integration done via system testing with minimal client UI intervention.

This development style facilitates high level of code quality written extremely fast to get the best of both worlds: Game finished in short timeframe with low (zero) bug count: critical for Indie game development!

Summary
To summarize, "Retro Candy Kid" proved successful game project because of all points outlined above.
As such, this type of game project is perfect candidate for 8-bit console port e.g. Sega Master System!

Sunday, November 15, 2015

Candy Kid is Live

Retro Candy Kid is live! The game is currently available on the iOS App Store and Android Google Play.
Additional platforms include: Amazon for Android/Kindle, Amazon for PC, itch.io for PC and Indie City.
Click here for more information on Candy Kid "How to Play" which includes secrets, hints, tips n' tricks!

Here is a complete list of all links to download and install Retro Candy Kid (includes free version)
 Platform  Device  Link  Link (FREE)
 Apple iOS  Retro Candy Kid  Retro Candy Kid FREE
 Google Android  Retro Candy Kid  Retro Candy Kid FREE
 Amazon  Android / Kindle  Retro Candy Kid  Retro Candy Kid FREE
 Amazon  PC  Retro Candy Kid  Retro Candy Kid FREE
 itch.io  PC  Retro Candy Kid  Retro Candy Kid FREE

Builds
Previous posts on Candy Kid port to iOS / Android platforms assumed pre-requisite bundle identifier, certificates and provisioning profiles setup. However, here are couple additional build settings to add:

Android Settings
In Xamarin Studio, right click project. Choose Options | Android Build | Advanced tab. Ensure all 5x Supported ABIs are checked from list to support: armeabi, armeabi-v7a, x86, arm64-v8a, x86_64:
UPDATE: Android OS 6.0.1 release seems to cause an issue with 64-bit architectures ABIs + may throw FATAL UNHANDLED EXCEPTION: NoAudioHardwareException: OpenAL drivers could not be found.

If this is the case then ensure the following 3x Supported ABIs are checked: armeabi, armeabi-v7a, x86:

iOS Settings
In Xamarin Studio, right click project. Choose Options | iOS Build. Ensure all 3x Supported architectures are checked: ARMv7 + ARMv7s + ARM64. Also, configure correct distribution signing identity + profile.

Uploading
Previous posts on Candy Kid port to iOS / Android end with deployment process: Archive for Publishing. Let's complete the deployment process: document signing the application and publishing to the stores.

Android References: Signing the Android Application package and Publishing Application to Google Play.
iOS Reference: Publishing to the App Store. Includes information to create and install Distribution Profile.

Publishing
Choose a unique game title, short description and bullet points to be applied consistently across stores.
 Title  Retro Candy Kid
 Short description  Super cool 80s retro arcade simple maze chase video game
 Keywords  80s, retro, arcade, video, game
 Full description  * Eat all candy in maze to pass each level.
 * Eat bonus optional but increases score.
 * Avoid 3x Candy Mamas who chase you.
 * Avoid trees (Death trees kill on contact).
 * Simple! Addictive! Fun!

Price Point
Should you publish your game as paid version or free? If paid then choose the price point; e.g. Tier 1:
USD   $0.99
CAD   $1.19
GBP   £0.79
EUR   €0.99
NZD   $1.29
AUD   $1.49
JPY    ¥120
CNY   ¥6.00

Images
Check out each platform: different resolutions for box art images, promotional screen shots, icons etc.
Google Play Store
 Hi-res icon  512 x 512 32-bit PNG (with alpha)
 Feature Graphic  1024 w x 500 h JPG or 24-bit PNG (no alpha)
 Promo Graphic  180 w x 120 h JPG or 24-bit PNG (no alpha)
 TV Banner  320 w x 180 h JPG or 24-bit PNG (no alpha)

iOS App Store
 4.7-inch 1334 x 750
 5.5-inch 1920 x 1080
 4-inch 1136 x 640
 
 3.5-inch 960 x 640
 iPad 1200 x 900
 iPad Pro 1200 x 900

Amazon App Store
 Small icon 114 x 114
 Large icon 512 x 512
 Screenshots 1280 x 800
 
 Amazon Fire TV Screenshots  1280 x 800
 Promotional image  1024 x 500
 

Videos
If you develop on Windows then most platforms accept MP4 videos that can be uploaded to You Tube. Good idea to crop the window borders especially on Apple otherwise you may be Metadata Rejected!

iOS App Store
Videos on App Store must be between 15-30s. Also, Apple has very strict video codec that must be set. The following assumes promotional video created using Camtasia with the same iOS resolutions (above)

Camtasia
Record 30s MP4 video for e.g. 4-inch iOS Device. Launch Camtasia | Drag MP4 file into Clip Bin twice.
Project Settings | Recording Dimensions | 1136x640 | Ok. Produce video: Custom Settings 1136x640.
 VIDEO
 Format MP4 (recommended)
 MP4 Frame rate 30 fps
 Encoding mode Bitrate
 Bitrate 1500 Kbps
 
 AUDIO
 Encode audio CHECKED
 Bitrate 48 KBPS
Bigasoft
Finally, use Bigasoft Total Converter to crop Windows borders. If you download and install this as trial software then you can only save half the output. Hence reason to double the saved MP4 video (above)
 4.7-inch 1334 x 750  Left: 16 Top: 42  Right: 10 Bottom: 10
 5.5-inch 1920 x 1080  Left: 24 Top: 58  Right: 24 Bottom: 17
 4-inch 1136 x 640  Left: 14 Top: 36  Right: 13 Bottom: 10
 iPad 1200 x 900  Left: 17 Top: 51  Right: 15 Bottom: 14

iTunes Connect
Most platforms such as Google Play Developer Console allow you to enter the Developer name, i.e.
Name other than your legal birth name to represent your Indie Game Studio e.g. StevePro Studios.

However for Apple, if you are an independent (or sole trader) then you must use your legal name;
This is what appears on iTunes; to change this as Company name then you need D-U-N-S Number.

Finally, Apple will not publish your game until you have completed "Agreements, Tax, and Banking". Entering Contact and Bank Info is clear but Tax Info may be more challenging for non-U.S. citizens!

Under Tax Info | U.S Tax Forms, there is option to enter US Tax ID. Non-U.S. citizens may apply for an ITIN if their country has a tax treaty with the U.S. thus in order to claim a reduction in U.S. income tax.
Link to complete Part II "Claim of Tax Treaty Benefits". Answers very similar to Microsoft "XNA and Tax"
The beneficial owner is claiming the provisions of Article 12 of the treaty identified on line 9a above to claim a 0% rate of withholding on (specify type of income): Royalties.
Explain the reason the beneficial owner meets the terms of the treaty article:
I am a XXXX citizen and resident of XXXX receiving royalties from U.S. source.


Amazon AppStore
Also, if you do apply for an ITIN (above) then you can re-use if/when you publish to Amazon AppStore!

Summary
Please show your support for Retro Games and buy Candy Kid today! Now available on iOS and Android.