Noble Master Games
Noble Master Games



Dev. Blog

Noble Master Developer's Blog

May 1, 2013

Noble Master Games: Sales & Income for 2012

Filed under: Business,Development — noblemaster @ 17:21

I have been asked I few times regarding my income (i.e. game sales) and what I am doing all the time. Basically, as some of you know, “Noble Master Games is a single member company, it’s more or less me doing most of the work. I spend about 10-12h/day including weekends (sometimes I take a day off) developing games, programming, fixing bugs, marketing, talking to customers, keeping up-to-date with latest tech, contributing to open source projects, coordinating with contractors, paying bills, accounting, maintaining servers, posting in forums and so forth. I generally contract out all the artwork, music, translations and modding out if I can. I have a few great artists, musician and modders I work with. I couldn’t do it without them!

So now, how much did I make in 2012 (in US Dollars) based on my taxes filed?

  Gross Income:                    $162'324
  Expenses:                       -$130'755
  Taxes:                           -$15,324
  Total Income:                     $36,246

Please note the Gross Income refers to all income (about 99.5% game sales) over all games and platforms (see below). I don’t have any other income. The Expenses include to a large part contract payments for art & graphics, music, translations and modding. A large portion of it is used too for hosting fees/internet, marketing, accounting/financial transaction fees, hardware (e.g. devices for testing), software (e.g. Photoshop), developer fees (e.g. Apple), business fees, phone/fax and smaller office expenses (e.g. paper, stamps & the like), personal retirement payments and health insurance. A small portion has been used to fund open source projects or sponsor tournaments (e.g. Age of Conquest).

So basically this leaves me with a total of about $36,246 for personal expenses such as food, rent, utilities, transportation, personal entertainment and such, i.e. my personal income. To be fair, the Expenses includes about 40% of my rent and my utility bill as I am able to deduct it from taxes but the rest has to come off from the $36,246.

Based off my actual income, I can make more money working for a company, for example Google, than working for myself, so why am I doing it? First of all it is to a big part “fun” to have your own company and develop games. Also, there is no boss to report to. Although I spend a lot of time working, I can choose freely when I want to take a break. So no, I am not complaining. I am not poor but I am also not bathing in Champagne. I wish I could afford to hire 1 or 2 people full-time to work together with as things can get lonely at times. Generally, it’s difficult to say if I am able to continue doing this in the future as it the actual income is little bit low to sustain over a longer period of time. Also, it doesn’t look like sales will increase this year unless I am able to complete a new game soon. Demise of Nations is planned for release towards the end of this year.

If you like strategy games and you like to see more of it, please don’t pirate but support the following games.

  • Age of Conquest: a medieval Risk-like turn-based strategy game (PC, Mac, Linux, Android, iOS). Includes ONLINE multiplayer.
  • Tropical/Desert Stormfront: a modern real-time strategy game (PC, Mac, Linux, Android, iOS). Includes multiplayer via LAN/internet
  • Demise of Nations: in the making. Follow my twitter feed @noblemaster for latest updates.

Please note, you are not only supporting me, but you also support all the people I work with (which I prefer to pay decent so they don’t have to starve) including Antony Hager (Artist), Nick Lee (Artist, previous), Sean Beeson (Music) amongst many others. Also, you indirectly support 3rd party companies which products and services I purchase (software, hardware, internet services). You also support Open Source projects, namely libGDX and LWJGL, two excellent projects amongst many others out there.

Feel free to comment or ask questions! Thanks, Christoph, a.k.a noblemaster.

March 1, 2013

Demise of Nations: Rome – in the Works!

Filed under: Announcement,Business,Development — Travis @ 14:48

After throwing around a few ideas internally last year, Noble Master Games have decided to develop a hexagon turn-based strategy game.  It will take place during the Roman Era on a large map of Europe featuring many factions from that time. The game will include several single player scenarios and campaigns. Demise of Nations: Rome will support a wide array of operating systems including PC, Mac, Linux, Android, and iOS. The game is planned to be released later this year in 2013.

Demise of Nations: Factions

Demise of Nations: Factions

Demise of Nations: Rome will contain over 30 factions, each having their own uniquely created banner to distinguish them from each other, much like the ones shown above. Confirmed factions include, Armenia, Britannia, Carthage, Dacia, Egypt, Gaul, Germania, Greek Cities, House of Brutii, House of Julii, House of Scipii, Macedon, Numidia, Parthia, Pontus, Rebels, Scythia, Seleucid Empire, Senate SPQR, Spain, and Thrace.

In later era scenarios and campaigns, other factions will appear, Alemanni, Berbers, Bergundii, Celts, Eastern Roman Empire, Franks, Goths, Huns, Lombardi, Roxolani, Sarmatians, Sassanids, Saxons, Slavs, Vandals, and Western Roman Empire. Below is an early alpha screenshot of the game.

Demise of Nations: Alpha Screenshot

Demise of Nations: Alpha Screenshot

Please contact us if you would like to be part of the beta-testing team.

November 21, 2012

Tropical + Desert Stormfront released on iPhone and iPad

Filed under: Announcement,Development — noblemaster @ 13:32

As of today, Tropical and Desert Stormfront have finally been released on iOS. The games use the excellent libgdx framework which made porting from Desktop/Android to iOS a breeze.

Tropical Stormfront and Desert Stormfront are the first ever libgdx games to be released on the iOS platform. The games can be played on all iOS touch-screen devices including the iPhone, iPod Touch, iPad and iPad mini. The games work both on retina and non-retina screens.

Store/Download Links:

Special Thanks:

Screenshot 1: Desert Stormfront for iOS

Screenshot 1: Desert Stormfront for iOS

Screenshot 2: Desert Stormfront for iOS

Screenshot 2: Desert Stormfront for iOS

Screenshot 3: Tropical Stormfront for iOS

Screenshot 3: Tropical Stormfront for iOS

Screenshot 4: Tropical Stormfront for iOS

Screenshot 4: Tropical Stormfront for iOS


November 1, 2012

ISO 4217 Currency List (

Filed under: Development — noblemaster @ 13:27

I wasn’t able to find a good currency implementation over enums in Java, so here is my own. The table contains all the currencies of ISO 4217 as of November 1, 2012. The currencies are mapped to their corresponding countries. And yes, this is Public Domain. Feel free to steal the code and modify it in any ways you please.

For the countries, please use the excellent implementation of all the country codes by Takahiko Kawasaki. You need to do a rename from “Country” to “CountryCode” if you use Takahiko’s implementation :)

 * The currencies (ISO 4217). Reference: Wikipedia ISO 4217.

* TODO (last update: 2012-11-01): *

  • need to add "Kosovo" to EURO list (no ISO Country code yet!) *
* This class/code is Public Domain (2012). Feel free to do anything you please. Consider visiting our website * at Noble Master. * * @author noblemaster (Christoph Aschwanden) */ public enum Currency { AED(784, Digits.DIGITS_2, "United Arab Emirates dirham", new Country[] { Country.AE }), AFN(971, Digits.DIGITS_2, "Afghan afghani", new Country[] { Country.AF }), ALL(8, Digits.DIGITS_2, "Albanian lek", new Country[] { Country.AL }), AMD(51, Digits.DIGITS_2, "Armenian dram", new Country[] { Country.AM }), ANG(532, Digits.DIGITS_2, "Netherlands Antillean guilder", new Country[] { Country.CW, Country.SX }), AOA(973, Digits.DIGITS_2, "Angolan kwanza", new Country[] { Country.AO }), ARS(32, Digits.DIGITS_2, "Argentine peso", new Country[] { Country.AR }), AUD(36, Digits.DIGITS_2, "Australian dollar", new Country[] { Country.AU, Country.CX, Country.CC, Country.HM, Country.KI, Country.NR, Country.NF, Country.TV }), AWG(533, Digits.DIGITS_2, "Aruban florin", new Country[] { Country.AW }), AZN(944, Digits.DIGITS_2, "Azerbaijani manat", new Country[] { Country.AZ }), BAM(977, Digits.DIGITS_2, "Bosnia and Herzegovina convertible mark", new Country[] { Country.BA }), BBD(52, Digits.DIGITS_2, "Barbados dollar", new Country[] { Country.BB }), BDT(50, Digits.DIGITS_2, "Bangladeshi taka", new Country[] { Country.BD }), BGN(975, Digits.DIGITS_2, "Bulgarian lev", new Country[] { Country.BG }), BHD(48, Digits.DIGITS_3, "Bahraini dinar", new Country[] { Country.BH }), BIF(108, Digits.DIGITS_0, "Burundian franc", new Country[] { Country.BI }), BMD(60, Digits.DIGITS_2, "Bermudian dollar", new Country[] { Country.BM }), BND(96, Digits.DIGITS_2, "Brunei dollar", new Country[] { Country.BN, Country.SG }), BOB(68, Digits.DIGITS_2, "Boliviano", new Country[] { Country.BO }), BOV(984, Digits.DIGITS_2, "Bolivian Mvdol (funds code)", new Country[] { Country.BO }), BRL(986, Digits.DIGITS_2, "Brazilian real", new Country[] { Country.BR }), BSD(44, Digits.DIGITS_2, "Bahamian dollar", new Country[] { Country.BS }), BTN(64, Digits.DIGITS_2, "Bhutanese ngultrum", new Country[] { Country.BT }), BWP(72, Digits.DIGITS_2, "Botswana pula", new Country[] { Country.BW }), BYR(974, Digits.DIGITS_0, "Belarusian ruble", new Country[] { Country.BY }), BZD(84, Digits.DIGITS_2, "Belize dollar", new Country[] { Country.BZ }), CAD(124, Digits.DIGITS_2, "Canadian dollar", new Country[] { Country.CA }), CDF(976, Digits.DIGITS_2, "Congolese franc", new Country[] { Country.CD }), CHE(947, Digits.DIGITS_2, "WIR Euro (complementary currency)", new Country[] { Country.CH }), CHF(756, Digits.DIGITS_2, "Swiss franc", new Country[] { Country.CH, Country.LI }), CHW(948, Digits.DIGITS_2, "WIR Franc (complementary currency)", new Country[] { Country.CH }), CLF(990, Digits.DIGITS_0, "Unidad de Fomento (funds code)", new Country[] { Country.CL }), CLP(152, Digits.DIGITS_0, "Chilean peso", new Country[] { Country.CL }), CNY(156, Digits.DIGITS_2, "Chinese yuan", new Country[] { Country.CN }), COP(170, Digits.DIGITS_2, "Colombian peso", new Country[] { Country.CO }), COU(970, Digits.DIGITS_2, "Unidad de Valor Real", new Country[] { Country.CO }), CRC(188, Digits.DIGITS_2, "Costa Rican colon", new Country[] { Country.CR }), CUC(931, Digits.DIGITS_2, "Cuban convertible peso", new Country[] { Country.CU }), CUP(192, Digits.DIGITS_2, "Cuban peso", new Country[] { Country.CU }), CVE(132, Digits.DIGITS_0, "Cape Verde escudo", new Country[] { Country.CV }), CZK(203, Digits.DIGITS_2, "Czech koruna", new Country[] { Country.CZ }), DJF(262, Digits.DIGITS_0, "Djiboutian franc", new Country[] { Country.DJ }), DKK(208, Digits.DIGITS_2, "Danish krone", new Country[] { Country.DK, Country.FO, Country.GL }), DOP(214, Digits.DIGITS_2, "Dominican peso", new Country[] { Country.DO }), DZD(12, Digits.DIGITS_2, "Algerian dinar", new Country[] { Country.DZ }), EGP(818, Digits.DIGITS_2, "Egyptian pound", new Country[] { Country.EG }), ERN(232, Digits.DIGITS_2, "Eritrean nakfa", new Country[] { Country.ER }), ETB(230, Digits.DIGITS_2, "Ethiopian birr", new Country[] { Country.ET }), EUR(978, Digits.DIGITS_2, "Euro", new Country[] { Country.AD, Country.AT, Country.BE, Country.CY, Country.EE, Country.FI, Country.FR, Country.DE, Country.GR, Country.IE, Country.IT, Country.LU, Country.MT, Country.MC, Country.ME, Country.NL, Country.PT, Country.SM, Country.SK, Country.SI, Country.ES, Country.VA }), FJD(242, Digits.DIGITS_2, "Fiji dollar", new Country[] { Country.FJ }), FKP(238, Digits.DIGITS_2, "Falkland Islands pound", new Country[] { Country.FK }), GBP(826, Digits.DIGITS_2, "Pound sterling", new Country[] { Country.GB, Country.IM, Country.GS, Country.IO }), GEL(981, Digits.DIGITS_2, "Georgian lari", new Country[] { Country.GE }), GHS(936, Digits.DIGITS_2, "Ghanaian cedi", new Country[] { Country.GH }), GIP(292, Digits.DIGITS_2, "Gibraltar pound", new Country[] { Country.GI }), GMD(270, Digits.DIGITS_2, "Gambian dalasi", new Country[] { Country.GM }), GNF(324, Digits.DIGITS_0, "Guinean franc", new Country[] { Country.GN }), GTQ(320, Digits.DIGITS_2, "Guatemalan quetzal", new Country[] { Country.GT }), GYD(328, Digits.DIGITS_2, "Guyanese dollar", new Country[] { Country.GY }), HKD(344, Digits.DIGITS_2, "Hong Kong dollar", new Country[] { Country.HK, Country.MO }), HNL(340, Digits.DIGITS_2, "Honduran lempira", new Country[] { Country.HN }), HRK(191, Digits.DIGITS_2, "Croatian kuna", new Country[] { Country.HR }), HTG(332, Digits.DIGITS_2, "Haitian gourde", new Country[] { Country.HT }), HUF(348, Digits.DIGITS_2, "Hungarian forint", new Country[] { Country.HU }), IDR(360, Digits.DIGITS_2, "Indonesian rupiah", new Country[] { Country.ID }), ILS(376, Digits.DIGITS_2, "Israeli new shekel", new Country[] { Country.IL, Country.PS }), INR(356, Digits.DIGITS_2, "Indian rupee", new Country[] { Country.IN }), IQD(368, Digits.DIGITS_3, "Iraqi dinar", new Country[] { Country.IQ }), IRR(364, Digits.DIGITS_0, "Iranian rial", new Country[] { Country.IR }), ISK(352, Digits.DIGITS_0, "Icelandic króna", new Country[] { Country.IS }), JMD(388, Digits.DIGITS_2, "Jamaican dollar", new Country[] { Country.JM }), JOD(400, Digits.DIGITS_3, "Jordanian dinar", new Country[] { Country.JO }), JPY(392, Digits.DIGITS_0, "Japanese yen", new Country[] { Country.JP }), KES(404, Digits.DIGITS_2, "Kenyan shilling", new Country[] { Country.KE }), KGS(417, Digits.DIGITS_2, "Kyrgyzstani som", new Country[] { Country.KG }), KHR(116, Digits.DIGITS_2, "Cambodian riel", new Country[] { Country.KH }), KMF(174, Digits.DIGITS_0, "Comoro franc", new Country[] { Country.KM }), KPW(408, Digits.DIGITS_0, "North Korean won", new Country[] { Country.KP }), KRW(410, Digits.DIGITS_0, "South Korean won", new Country[] { Country.KR }), KWD(414, Digits.DIGITS_3, "Kuwaiti dinar", new Country[] { Country.KW }), KYD(136, Digits.DIGITS_2, "Cayman Islands dollar", new Country[] { Country.KY }), KZT(398, Digits.DIGITS_2, "Kazakhstani tenge", new Country[] { Country.KZ }), LAK(418, Digits.DIGITS_0, "Lao kip", new Country[] { Country.LA }), LBP(422, Digits.DIGITS_0, "Lebanese pound", new Country[] { Country.LB }), LKR(144, Digits.DIGITS_2, "Sri Lankan rupee", new Country[] { Country.LK }), LRD(430, Digits.DIGITS_2, "Liberian dollar", new Country[] { Country.LR }), LSL(426, Digits.DIGITS_2, "Lesotho loti", new Country[] { Country.LS }), LTL(440, Digits.DIGITS_2, "Lithuanian litas", new Country[] { Country.LT }), LVL(428, Digits.DIGITS_2, "Latvian lats", new Country[] { Country.LV }), LYD(434, Digits.DIGITS_3, "Libyan dinar", new Country[] { Country.LY }), MAD(504, Digits.DIGITS_2, "Moroccan dirham", new Country[] { Country.MA }), MDL(498, Digits.DIGITS_2, "Moldovan leu", new Country[] { Country.MD }), MGA(969, Digits.DIGITS_07, "Malagasy ariary", new Country[] { Country.MG }), MKD(807, Digits.DIGITS_0, "Macedonian denar", new Country[] { Country.MK }), MMK(104, Digits.DIGITS_0, "Myanma kyat", new Country[] { Country.MM }), MNT(496, Digits.DIGITS_2, "Mongolian tugrik", new Country[] { Country.MN }), MOP(446, Digits.DIGITS_2, "Macanese pataca", new Country[] { Country.MO }), MRO(478, Digits.DIGITS_07, "Mauritanian ouguiya", new Country[] { Country.MR }), MUR(480, Digits.DIGITS_2, "Mauritian rupee", new Country[] { Country.MU }), MVR(462, Digits.DIGITS_2, "Maldivian rufiyaa", new Country[] { Country.MV }), MWK(454, Digits.DIGITS_2, "Malawian kwacha", new Country[] { Country.MW }), MXN(484, Digits.DIGITS_2, "Mexican peso", new Country[] { Country.MX }), MXV(979, Digits.DIGITS_2, "Mexican Unidad de Inversion (UDI) (funds code)", new Country[] { Country.MX }), MYR(458, Digits.DIGITS_2, "Malaysian ringgit", new Country[] { Country.MY }), MZN(943, Digits.DIGITS_2, "Mozambican metical", new Country[] { Country.MZ }), NAD(516, Digits.DIGITS_2, "Namibian dollar", new Country[] { Country.NA }), NGN(566, Digits.DIGITS_2, "Nigerian naira", new Country[] { Country.NG }), NIO(558, Digits.DIGITS_2, "Nicaraguan córdoba", new Country[] { Country.NI }), NOK(578, Digits.DIGITS_2, "Norwegian krone", new Country[] { Country.NO, Country.SJ, Country.BV }), NPR(524, Digits.DIGITS_2, "Nepalese rupee", new Country[] { Country.NP }), NZD(554, Digits.DIGITS_2, "New Zealand dollar", new Country[] { Country.CK, Country.NZ, Country.NU, Country.PN, Country.TK }), OMR(512, Digits.DIGITS_3, "Omani rial", new Country[] { Country.OM }), PAB(590, Digits.DIGITS_2, "Panamanian balboa", new Country[] { Country.PA }), PEN(604, Digits.DIGITS_2, "Peruvian nuevo sol", new Country[] { Country.PE }), PGK(598, Digits.DIGITS_2, "Papua New Guinean kina", new Country[] { Country.PG }), PHP(608, Digits.DIGITS_2, "Philippine peso", new Country[] { Country.PH }), PKR(586, Digits.DIGITS_2, "Pakistani rupee", new Country[] { Country.PK }), PLN(985, Digits.DIGITS_2, "Polish złoty", new Country[] { Country.PL }), PYG(600, Digits.DIGITS_0, "Paraguayan guaraní", new Country[] { Country.PY }), QAR(634, Digits.DIGITS_2, "Qatari riyal", new Country[] { Country.QA }), RON(946, Digits.DIGITS_2, "Romanian new leu", new Country[] { Country.RO }), RSD(941, Digits.DIGITS_2, "Serbian dinar", new Country[] { Country.RS }), RUB(643, Digits.DIGITS_2, "Russian rouble", new Country[] { Country.RU }), RWF(646, Digits.DIGITS_0, "Rwandan franc", new Country[] { Country.RW }), SAR(682, Digits.DIGITS_2, "Saudi riyal", new Country[] { Country.SA }), SBD(90, Digits.DIGITS_2, "Solomon Islands dollar", new Country[] { Country.SB }), SCR(690, Digits.DIGITS_2, "Seychelles rupee", new Country[] { Country.SC }), SDG(938, Digits.DIGITS_2, "Sudanese pound", new Country[] { Country.SD }), SEK(752, Digits.DIGITS_2, "Swedish krona/kronor", new Country[] { Country.SE }), SGD(702, Digits.DIGITS_2, "Singapore dollar", new Country[] { Country.SG, Country.BN }), SHP(654, Digits.DIGITS_2, "Saint Helena pound", new Country[] { Country.SH }), SLL(694, Digits.DIGITS_0, "Sierra Leonean leone", new Country[] { Country.SL }), SOS(706, Digits.DIGITS_2, "Somali shilling", new Country[] { Country.SO }), SRD(968, Digits.DIGITS_2, "Surinamese dollar", new Country[] { Country.SR }), SSP(728, Digits.DIGITS_2, "South Sudanese pound", new Country[] { Country.SS }), STD(678, Digits.DIGITS_0, "São Tomé and Príncipe dobra", new Country[] { Country.ST }), SYP(760, Digits.DIGITS_2, "Syrian pound", new Country[] { Country.SY }), SZL(748, Digits.DIGITS_2, "Swazi lilangeni", new Country[] { Country.SZ }), THB(764, Digits.DIGITS_2, "Thai baht", new Country[] { Country.TH }), TJS(972, Digits.DIGITS_2, "Tajikistani somoni", new Country[] { Country.TJ }), TMT(934, Digits.DIGITS_2, "Turkmenistani manat", new Country[] { Country.TM }), TND(788, Digits.DIGITS_3, "Tunisian dinar", new Country[] { Country.TN }), TOP(776, Digits.DIGITS_2, "Tongan paʻanga", new Country[] { Country.TO }), TRY(949, Digits.DIGITS_2, "Turkish lira", new Country[] { Country.TR }), TTD(780, Digits.DIGITS_2, "Trinidad and Tobago dollar", new Country[] { Country.TT }), TWD(901, Digits.DIGITS_2, "New Taiwan dollar", new Country[] { Country.TW }), TZS(834, Digits.DIGITS_2, "Tanzanian shilling", new Country[] { Country.TZ }), UAH(980, Digits.DIGITS_2, "Ukrainian hryvnia", new Country[] { Country.UA }), UGX(800, Digits.DIGITS_2, "Ugandan shilling", new Country[] { Country.UG }), USD(840, Digits.DIGITS_2, "United States dollar", new Country[] { Country.AS, Country.BB, Country.BM, Country.IO, Country.VG, Country.BQ, Country.EC, Country.SV, Country.GU, Country.HT, Country.MH, Country.FM, Country.MP, Country.PW, Country.PA, Country.PR, Country.TL, Country.TC, Country.US, Country.VI, Country.ZW }), USN(997, Digits.DIGITS_2, "United States dollar (next day) (funds code)", new Country[] { Country.US }), USS(998, Digits.DIGITS_2, "United States dollar (same day) (funds code)", new Country[] { Country.US }), UYI(940, Digits.DIGITS_0, "Uruguay Peso en Unidades Indexadas (URUIURUI) (funds code)", new Country[] { Country.UY }), UYU(858, Digits.DIGITS_2, "Uruguayan peso", new Country[] { Country.UY }), UZS(860, Digits.DIGITS_2, "Uzbekistan som", new Country[] { Country.UZ }), VEF(937, Digits.DIGITS_2, "Venezuelan bolívar fuerte", new Country[] { Country.VE }), VND(704, Digits.DIGITS_0, "Vietnamese dong", new Country[] { Country.VN }), VUV(548, Digits.DIGITS_0, "Vanuatu vatu", new Country[] { Country.VU }), WST(882, Digits.DIGITS_2, "Samoan tala", new Country[] { Country.WS }), XAF(950, Digits.DIGITS_0, "CFA franc BEAC", new Country[] { Country.CM, Country.CF, Country.CD, Country.TD, Country.GQ, Country.GA }), XAG(961, Digits.DIGITS_NO, "Silver (one troy ounce)", new Country[] { }), XAU(959, Digits.DIGITS_NO, "Gold (one troy ounce)", new Country[] { }), XBA(955, Digits.DIGITS_NO, "European Composite Unit (EURCO) (bond market unit)", new Country[] { }), XBB(956, Digits.DIGITS_NO, "European Monetary Unit (E.M.U.-6) (bond market unit)", new Country[] { }), XBC(957, Digits.DIGITS_NO, "European Unit of Account 9 (E.U.A.-9) (bond market unit)", new Country[] { }), XBD(958, Digits.DIGITS_NO, "European Unit of Account 17 (E.U.A.-17) (bond market unit)", new Country[] { }), XCD(951, Digits.DIGITS_2, "East Caribbean dollar", new Country[] { Country.AI, Country.AG, Country.DM, Country.GD, Country.MS, Country.KN, Country.LC, Country.VC }), XDR(960, Digits.DIGITS_NO, "Special drawing rights International Monetary Fund", new Country[] { }), XFU(-1, Digits.DIGITS_NO, "UIC franc (special settlement currency)", new Country[] { }), XOF(952, Digits.DIGITS_0, "CFA franc BCEAO", new Country[] { Country.BJ, Country.BF, Country.CI, Country.GW, Country.ML, Country.NE, Country.SN, Country.TG }), XPD(964, Digits.DIGITS_NO, "Palladium (one troy ounce)", new Country[] { }), XPF(953, Digits.DIGITS_0, "CFP franc", new Country[] { Country.PF, Country.NC, Country.WF }), XPT(962, Digits.DIGITS_NO, "Platinum (one troy ounce)", new Country[] { }), XTS(963, Digits.DIGITS_NO, "Code reserved for testing purposes", new Country[] { }), XXX(999, Digits.DIGITS_NO, "No currency", new Country[] { }), YER(886, Digits.DIGITS_2, "Yemeni rial", new Country[] { Country.YE }), ZAR(710, Digits.DIGITS_2, "South African rand", new Country[] { Country.ZA }), ZMK(894, Digits.DIGITS_2, "Zambian kwacha", new Country[] { Country.ZM }); private final String code; private final String name; private final int numeric; private final Digits digits; private final Country[] countries; private enum Digits { DIGITS_0, DIGITS_2, DIGITS_3, DIGITS_07, DIGITS_NO }; private Currency(int numeric, Digits digits, String name, Country[] countries) { this.code = name().toUpperCase(); = name; this.numeric = numeric; this.digits = digits; this.countries = countries; } /** * Returns the currency code. * * @return The code, e.g. "USD", "EUR", etc. */ public String getCode() { return code; } /** * Returns the currency name in English. * * @return The English currency name, e.g. "United States dollar". */ public String getName() { return name; } /** * Returns a list of countries that use the currency. * * @return The countries that use the currency. */ public Country[] getCountries() { return countries; } /** * Formats and outputs the amount for the given currency. * * @param amount The amount. * @return The formatted amount, e.g. "USD 10.38". */ public String format(long amount) { String formatted; switch (digits) { case DIGITS_0: { // e.g. "10" formatted = String.valueOf(amount); break; } case DIGITS_2: { // e.g. "10.99" String a = String.valueOf(amount / 100); String b = String.valueOf(amount % 100); while (b.length() < 2) { b = "0" + b; } formatted = a + "." + b; break; } case DIGITS_3: { // e.g. "10.999" String a = String.valueOf(amount / 1000); String b = String.valueOf(amount % 1000); while (b.length() < 3) { b = "0" + b; } formatted = a + "." + b; break; } case DIGITS_07: { // e.g. "10" ==> NOTE: (some special rules apply!?) formatted = String.valueOf(amount); break; } case DIGITS_NO: { formatted = String.valueOf(amount); break; } default: Log.error("Digits not implemented: " + digits); formatted = String.valueOf(amount); } return getCode() + " " + formatted; } /** * Returns the currency for the given code. * * @param code The code, e.g. "USD", "EUR", etc. * @return The corresponding currency or null if it doesn't exist. */ public static Currency find(String code) { for (int i = 0; i < values().length; i++) { if (values()[i].getCode().equals(code)) { return values()[i]; } } // not found return null; } /** * Returns the currency for the inputed country. * * @param country The country. * @return The currency or null if multiply currencies or no currencies exist. */ public static Currency find(Country country) { // use some default rules for countries with multiple currencies (should go into!) switch (country) { case BO: { return Currency.BOB; } case CH: { return Currency.CHF; } case CL: { return Currency.CLP; } case MX: { return Currency.MXN; } case US: { return Currency.USD; } case UY: { return Currency.UYU; } default: { // if default rules don't apply, let's see if we can resolve otherwise! Currency currency = null; for (int i = 0; i < values().length; i++) { Country[] countries = values()[i].getCountries(); for (int k = 0; k < countries.length; k++) { if (countries[k] == country) { if (currency != null) { // more than one currency! return null; } else { currency = values()[i]; } } } } // return the currency return currency; } } } /** * Returns the currency for the inputed country. * * @param country The country. * @param defaultCurrency The default currency to use if more than 1 currency exists or no currency exists. * @return The currency or default currency if multiply currencies or no currencies exist. */ public static Currency find(Country country, Currency defaultCurrency) { Currency currency = find(country); if (currency == null) { return defaultCurrency; } else { return currency; } } // ------------------------------------------------------------------------------------------------------------------- public String getISOCodeAlpha() { return name(); } public int getISOCodeNumeric() { return numeric; } @Override public String toString() { return code; } }

September 26, 2012

Desert Stormfront released on PC, Mac, Linux & Android

Filed under: Announcement,Development — noblemaster @ 12:40

Desert Stormfront is finally released! Desert Stormfront is a real-time strategy game inspired by the turn-based “Classic Empire” wargame by Walter Bright. Units and structures are modeled after the original following a rock-paper-scissors system. Unit movement is in real-time similar to the classic “Command & Conquer” albeit simplified aiming at a game that is easy to learn but difficult to master.

Desert Stormfront takes place in present-time Middle East. The player assumes command of the Western coalition and fights real-time battles for control of cities and oil fields in Iran, Iraq, Saudia Arabia and Afghanistan. Maps are based on real-world locations in the Middle East. The story is fictional (as of this writing). The game supports cross-platform multiplayer matches over LAN and internet including co-op multiplayer.

Key Features:

  • Real-Time Strategy (RTS) in the Middle East
  • Single Player and Multiplayer (over the LAN and Internet)
  • 30 Campaign Missions incl. Scoring/Rating
  • Random Map Generator + Skirmish Maps
  • Modes: Attack, Defense, Capture the Flag & Convoy Missions

Release Date: Sept. 26, 2012
Platforms: PC, Mac, Linux, Android
Available: via game’s website (PC, Mac, Linux) and Google Play (Android)

Desert Stormfront Screenshot 1

Desert Stormfront Screenshot 2

Desert Stormfront Screenshot 3

September 17, 2012

tiicoon – Multiplayer City Simulation – Narrated Demo

Filed under: Development — noblemaster @ 01:25

Although tiicoon (pronounced: /taɪˈkuːn/) is currently abandoned, I figured it would be nice to create a trailer. Arvid Wessman (Arvid Wessman Productions) did all the art. I did all the programming. Both art & programming are about 50% done.

August 22, 2012

How to Convert a .pfx/.p12 File to a Java Keystore (.jks) with the Java “keytool”

Filed under: Development — noblemaster @ 20:27

I managed to acquire a code signing certificate in .pfx format from Comodo. There are a couple solutions in the internet suggesting to download jetty or install OpenSSL to convert the .pfx to a Java Keystore (.jks). However, the solution is much simpler and only requires the keytool included in the Java Development Kit. The whole procedure requires 2 steps and allows creation of a custom alias for the Java Keystore.

For Step 1, we need to find the alias stored in the .pfx file. Copy your key file (e.g. keyfile.pfx) into the same folder as the Java keytool. Then run the following command in the console to create a listing of all the certificates in your keyfile.

keytool -v -list -storetype pkcs12 -keystore keyfile.pfx > keyfile.txt

Look for “Alias name:” in the outputted keyfile.txt. Your alias name should be called something like the following: “company name llc’s comodo ca limited id“.

For Step 2, we convert the keyfile.pfx to a Java Keystore. Make sure you enter the [PFX ALIAS] exactly as found in Step 1. The [JKS ALIAS] can be freely chosen and is your Java Keystore alias.

-importkeystore -srckeystore keyfile.pfx -srcstoretype pkcs12 -srcalias “[PFX ALIAS]”
-destkeystore keyfile.jks -deststoretype jks -destalias “[JKS ALIAS]”

That’s all that’s there too it; the keyfile.jks is your new Java Keystore.

August 11, 2012

Desert Stormfront – Alpha Screenshots

Filed under: Announcement,Development — noblemaster @ 01:33

I am currently trying to wrap development of Desert Stormfront. Nick sent in all the graphics a while ago. It’s all integrated and ready to go. Travis is currently working out the 30 campaign missions planned. Will hopefully be done by the end of the month and ready for beta-testing. Contact me via email (“Beta-Testing”) if you are interested in becoming a beta-tester for the game (Android, PC, Mac or Linux). Testing involves play-testing the 30 campaign missions (no technical testing required). No money paid, but you’ll receive a copy of the game for free and will have your name in the game credits.

Here is the lowdown for the game:

  • Real-Time Strategy (RTS) in the Middle East (desert)
  • single player & multiplayer
  • 30 Single Player Campaign missions
  • Random Skirmish scenario generator
  • Factions: USA, England, France, Italy, Iraq, Iran, Saudi Arabia, Egypt, Afghanistan plus a rebel faction.
  • Team-Play (included in multiplayer too)
  • 17 mobile units including: Humvees, Tanks, Artillery, 4×4, Mechanic, Trucks, Fighter Plane, Helicopter, Gunboat, Submarine, Cruiser, Aircraft Carrier, Super-Hovercraft.
  • 4 land structures: Base Station, Shipyard, Airfield, Oilfield
  • Occupy oilfields to receive income.
  • Fog of War
  • High Score & Playing Statistics
  • …and obviously Music and Sound FX

Release is planned for end of September/beginning of October. Below are some current alpha screenshots.

Desert Stormfront: Screenshot 1 (Alpha)

Desert Stormfront: Screenshot 1 (Alpha)

Desert Stormfront: Screenshot 2 (Alpha)

Desert Stormfront: Screenshot 2 (Alpha)

Desert Stormfront: Screenshot 3 (Alpha)

Desert Stormfront: Screenshot 3 (Alpha)

Desert Stormfront: Screenshot 4 (Alpha)

Desert Stormfront: Screenshot 4 (Alpha)

March 24, 2012

Tropical Stormfront: Multiplayer BETA-Test!

Filed under: Announcement,Development — noblemaster @ 03:07

Nick & me just spent a few hours alpha-testing the new multiplayer port for Tropical Stormfront. We have fixed all the bugs, so it’s running all smoothly over both LAN and internet. Nick beat me a few times, so it wasn’t going so well for me in that sense :-D

Next on the list is a beta-test 3 vs. 3 or even 4 vs. 4 (2 teams). Platforms: PC, Mac, Linux & Android. Open dates are next week Tuesday-Thursday, March 27.-29., from 09:00-17:00 (1h) next week. We will conduct a conference call via Skype (voice) while we play. I’ll host the Skype call. Someone in the group will host the game. Please enter your availability in the Doodle Poll and email me at contact [at] to participate. I’ll send the download link & Skype call information.

It’s first-come first-server – Register early!!!

February 4, 2012

Tropical Stormfront – My Poorly Narrated Trailer…

Filed under: Announcement,Development,Miscellaneous — noblemaster @ 13:20

OK, here it comes; I finally managed to produce my own game trailer for Tropical Stormfront. Please enjoy the poorly narrated goodness below…

« Newer PostsOlder Posts »