Thursday, July 12, 2012

Stirrings of an RTS Game

The main goal at Rubicite is for us to keep moving in a financially sound direction as a software development company. For the foreseeable future, that means focusing a large majority of our efforts on development for paying clients. However, at our core, we want to be a game development company. To that end, one of our partners spends the majority of their time pushing forward on our first game - a third-person shooter in which an advanced race of snails battles against several enemies. You'll definitely hear more on that as it moves forward - eventually we will be posting it on Kickstarter to get sufficient funding to commit more resources. But that's not what I'm here to talk about today...

The snail game is our first game. With any luck, it will see a 2013 release. As exciting as it is, I'm much more excited for our second game. By all counts, it will probably be a 2015 release, but plenty of things could happen to move that forward or backward between now and then. Currently, it's in the early concept stages, and it's becoming my baby. Here's a bit about what we know:

The gameplay style will be modeled after Myth and Myth2 (no, not Myst): a couple of games developed by Bungie in the late 90's (prior to that whole Halo thing). That means it will be a real-time strategy game with viritually no resource-management, where the driver for the gameplay is using combat tactics with a relatively small number of units and a realistic physics engine. This means that the terrain you choose for your battles will matter. Having a height advantage will impact the performance of your ranged units. Formations and micro-management will turn the tide of battle between two otherwise equal forces.

Currently, we are quite a ways from implementing any of that. Like I said, early concept stages. What I'm slowly developing now is the backstory for the game. Which is both driven by the unit classes I envision, and drives me to create new classes to fit the story. Both, in turn, will drive the level design that will be central to many elements of the gameplay.

The story is centered around a post-apocalyptic Earth. I haven't decided for sure what caused the apocalypse, but I'm leaning heavily toward a series of comet/asteroid collisions. In the time between the apocalypse event and when the game starts, months (or years) have passed. A shortage of resources has led to civilization breaking down, with many small groups forming and warring with each other. Many have died since, but some groups are pushing for a brighter future. Much of the world's ammo and weaponry were rendered useless during the destruction from the apoc event. The majority of what is left has been exhausted from the wars. Meaning that where war is concerned, humanity has largely returned to a time of modern versions of medieval weapons. Guns and other more modern weaponry still exist, but ammo is in such short supply that they are rare.

Oh, and there are some non-human creatures (not in the way you're thinking) with unique anatomy that will have meaningful impact to both story and gameplay.

The major story element I'm currently struggling with is how to explain a way that these creatures can communicate with humans.

Once it's all said and done, I expect to end up with a novel that mirrors the story of the game. I look forward to releasing it, almost as much as I look forward to the game itself.

Thursday, June 7, 2012

Paypal IPN and PDT in ASP.net

To support a customer who needs to process payments through Paypal, I created a small code package that encapsulates the functionality necessary for the operations used in Paypal's Payment Data Transfer (PDT) and Instant Payment Notification (IPN). This way, the code is reusable for future projects within Rubicite. I'm sharing it on Github, so that it can save some time for the rest of the world: https://github.com/jgb146/Paypal-util

Most of the functionality involved is derived from various tutorials in Paypal's documentation, but this way everything is encapsulated into a single pdt_hander object, or a single ipn_handler object (depending on which technology you're using). The resulting object automatically takes the steps required for confirming the contents with Paypal, and then provides you with access to your payment information through a Dictionary.

To use either component, simply instantiate the object and provide the required information. For PDT, that means including the transaction ID that Paypal sent, your PDT ID token, and an optional boolean to indicate whether or not you are using Paypal's sandbox. For IPN, the only parameter to include is an optional boolean to indicate whether or not you are using Paypal's sandbox. Use looks roughly like this:

IPN:
protected void Page_Load(object sender, EventArgs e)
{
    processIpnPost();
            
    Response.Clear();
    Response.StatusCode = 200;
    Response.Write("");
    Context.ApplicationInstance.CompleteRequest();
}

public void processIpnPost()
{//process the IPN post
    
    //use ipn_handler util to get response and load into a dictionary
    PayPalUtil.ipn_handler ipn_handler = new PayPalUtil.ipn_handler();
    Dictionary dic_ipnResponse = ipn_handler.dic_data;
    
    //deal with invalid responses
    if (dic_ipnResponse["response"] != "VERIFIED")
        return;

    //---Insert code to use dic_ipnResponse to process the transaction
}

PDT:
protected void Page_Load(object sender, EventArgs e)
{
    ProcessTransaction();
}

protected void ProcessTransaction()
{
    //deal with unspecified transactions
    if ((Request["tx"] == null) || (Request["tx"] == ""))
    { 
        InvalidTransaction();
        return; //stop processing; 
    }
                
    //use the transactionID in the GET to request & process PDT data
    my_pdt_handler = new PayPalUtil.pdt_handler(Request["tx"], PDT_ID_Token);

    //deal with invalid responses
    if (my_pdt_handler.dic_data["response"] != "VERIFIED")
    { 
        InvalidTransaction(Request["tx"], my_pdt_handler.dic_data);
        return; //stop processing; 
    }

    //---Insert code to use my_pdt_handler.dic_data to process the transaction           
}

protected void InvalidTransaction(String pStr_transactionID = "", Dictionary pDic_data = null)
{//invalid transaction -> handle however you feel is best

}

Tuesday, June 5, 2012

New Directions & New Digs

Things at Rubicite have been a bit tumultuous of late. One of our partners (we'll call him X) decided to leave the company. X and our CEO are brothers, and family drama entered into work on more than one occasion - something for which they were both at fault. In the end, X chose to leave because the stressful conditions that this created weren't worth it in his eyes. All parties were happy and pleasant about the break; we took X out to lunch at his favorite restaurant (a tradition I enjoyed at NSA, and one I intend to continue here with Rubicite).

A few things will be happening as a result of this. First, Rubicite is buying X's shares. That's creating some difficulty because X held around 35% of the company and a large chunk of our financial assets are in a set of invoices that haven't yet been paid. In the end, he's going to have to wait a few weeks for the final payout. And we're going to be strapped for cash for a few weeks until some invoices get paid.

Second, the remaining partners all have more ownership of Rubicite now. X's shares are being split proportionally to our previous distribution, which takes me from 15% to around 23%.

Third, I get X's office. That was going to happen anyway, since X worked from home a lot. But the timing worked out pretty well, since I just got my new desk delivered and it was going to make my old office pretty crammed. The new office is bigger than my old one (around 14 x 11 instead of 11 x 10), and it has two windows. In the new office, the desk fits comfortably, with room for a nice seating area should I need it.

Fourth, Rubicite's finances should improve more quickly. For at least the last six months, X has been working on internal projects that did not make us money right now. Among other things, those projects included coding for our first computer game, and improvements to Grinderschool. Both were valued contributions, but having a large portion of our work-force not on paying work led to slower growth than we might have seen otherwise. Instead, we will now see slower improvements to Grinderschool and the game will likely take a bit longer to get to the point of seeking funding, BUT we should be making money significantly more quickly than we are spending it - meaning salary increases should be a bit less distant on the horizon.

Finally, the rest of us will have to adjust our work in order to keep moving forward on the projects X was working on. We want to do so in a way that will lead to minimal drain on our billable time. That will probably mean some extra hours for each of us here and there, and it will also probably mean that X's projects slow down a bit. I'm becoming a bit excited at the prospect of getting my hands into the mix for our first game - previously I had envisioned myself as being more-or-less only in the web development side of Rubicite.

We are having a company meeting later this week to look at finances and develop the future work-plan for Rubicite. More will certainly be decided then.

Monday, May 21, 2012

Serving Unlimited Domains From IIS, pt 2

Last time, I posed the question of how to serve unlimited domains from IIS. I got to digging around, found some options myself, and had some better options revealed to me by folks in the Tulsa WebDevs Facebook group and by my partners here at work. So here are the options, as I currently understand them:

1) Build It Into The Code
Probably the best option is to programmatically create bindings in IIS6 and/or in IIS7. This way everything is integrated into the webapp, meaning there's no muss or fuss outside of the app. It requires a bit more work in the app itself, but the benefits of keeping things clean and keeping all the functionality around this action inside the single codebase are almost definitely worth it.

2) PowerShell
Another option is to set up a script for powershell to have it handle this stuff based on the script detecting changes to the database. This would work well also, but has the drawback of creating two codebases to maintain.

3) Remove Domain Bindings
This StackOverflow answer led me to try removing the existing domain from the webapp's bindings in IIS. Making this change resulted in being able to reach my webapp by just visiting the IP address (so the binding was no longer an issue). And the one domain we have set for this webapp so far still reached the desired site as well. So it seems that the solution could be as simple as to have no host/domain listed in the bindings on IIS. As long as only one site does this, all traffic that does not match another binding loads that site. A big upside here is that it takes less time/effort than any of the coding solutions mentioned above. The downside is that you can only have one site on the server perform this way, and you can no longer have the server locked to only serving content with recognized domains.

Friday, May 18, 2012

Serving Unlimited Domains From IIS, pt 1

In an upcoming version of a currently-in-development webapp, I need to serve multiple domains from a single site. The code on the site will recognize the individual domains and vary the content accordingly. I do not know all of the domains that we will be serving, as clients can add new domains to their site. The coding parts, I know how to do - when clients add a domain, there will be a corresponding entry into our database and that will act as a key to control which set of content is shown.

The thing is, I suck at system administration. If I knew the domains ahead of time, I could simply point them to our server's IP and then create bindings in IIS to handle each. But since I do not know the domains ahead of time, I'm rather at a loss. I welcome any suggestions. Expect part 2 of this entry in the coming weeks, to reflect whatever solution I find.

Thursday, February 16, 2012

DotnetOpenAuth & Twitter

This is the first in a series of posts about using DotnetOpenAuth to provide authentication from external services. Today, we're talking about Twitter.

The first thing you need to do is to create an app with Twitter. Visit https://dev.twitter.com/apps, login, and then click "Create a new application". Fill out the simple form. Use any valid website for your site and for your callback URL - preferrably something for your specific organization or project, but if you don't have anything, just put down anything. The important thing is to make sure you fill it all out. After your app is created, you will see a details screen that includes a section of "OAuth settings". The import items for step 2 are the Consumer Key and the Consumer Secret.

Next, you need to include the Consumer Key/Secret into your .Net application. That means including the relevant data as part of your Web.config. Something like this (note that the key/secret here are for the DotNetOpenAuth sample test project; it'll look pretty silly if you forget to replace these with the values of your actual project:
<appSettings>
 <!-- Fill in your various consumer keys and secrets here to make the sample work. -->
 <!-- You must get these values by signing up with each individual service provider. -->
 <!-- Twitter sign-up: https://twitter.com/oauth_clients -->
 <add key="twitterConsumerKey" value="eRJd2AMcOnGqDOtF3IrBQ" />
        <add key="twitterConsumerSecret" value="iTijQWFOSDokpkVIPnlLbdmf3wPZgUVqktXKASg0QjM" />
  </appSettings>

Finally, we can get to coding the app. Your first step is to download the DotNetOpenAuth package. There are several different versions available, but at the time of this article the best one (read: only one I could make work for Twitter, Facebook, and OpenID) is version 3.5.0.x. Grab this, and play around with it as much as you like. Or just yank some of the dll's and move on with doing your actual project. The ones you are interested in are DotNetOpenAuth.dll and DotNetOpenAuth.ApplicationBlock.dll. They can both be found in \Samples\OAuthClient\bin\ of the repository you downloaded. Load these in as project references to your .Net app. My experience is that this works best if you place the dlls into the \bin\ folder of your app and then right-click on the project in Visual Studio to add the references.

Once you have the references set up, design the frontend. Set it up however you would like, but the key is to provide some kind of link that will prompt people to sign-in via Twitter. You can make your own, or use one of the ones that Twitter provides for you. It is the clicking of that link to which you want to attach some processing.

On the backend of your app, start off by including everything you need. Cheat by replicating the includes from the sample project (while you may not need all of them, it's easiest to start with everything and then remove the ones you know you do not need):
using System;
 using System.Collections.Generic;
 using System.Configuration;
 using System.Linq;
 using System.Web;
 using System.Web.Security;
 using System.Web.UI;
 using System.Web.UI.WebControls;
 using System.Xml.Linq;
 using System.Xml.XPath;
 using DotNetOpenAuth.ApplicationBlock;
 using DotNetOpenAuth.OAuth;

Next, include the actual login stuff in the page load:
if ((Request["openid_identifier"] == "http://twitter.com/")|| ((Request["oauth_token"] != null) && (Request["oauth_token"].Length > 1)))
{
    if (TwitterConsumer.IsTwitterConsumerConfigured)
    {
        if (IsPostBack)
        { TwitterConsumer.StartSignInWithTwitter(true).Send(); }
        else
        {
            string screenName;
            int userId;
            if (TwitterConsumer.TryFinishSignInWithTwitter(out screenName, out userId))
            {
                //userId is now a unique numeric id for the user
                //screenName is now their Twitter username

                //use these values to do whatever you want
            }
        }
    }
}

After that, you're done. Cheers, you now have their information from Twitter. Use it however you like!

Tuesday, February 14, 2012

Hiatus: Rubicite Buys Grinderschool

I've been on a blogging hiatus because I've been on a programming hiatus. The last couple of weeks have been spent doing marketing stuff to get new clients and new investors AND dealing with all of the issues that arise during a business acquisition. I've been on both sides of that acquisition as Rubicite Interactive purchased Grinderschool, effective February 1, 2012.

In the long run, this will mean a lot of good things for Grinderschool, and it will mean the addition of a profitable business line for Rubicite. On the Grinderschool side, the site has long suffered from my lack of time - I simply couldn't fit it into my schedule to give the site as much attention as it needed in order for the site to grow. Now that part of my day job is keeping the site running, that will not be an issue. Further, the development needs of the site are being spread across the staff here at Rubicite instead of falling strictly on me. That means good things for the site, as it ultimately means that development on "nice-to-have" improvements will actually happen instead of just adding to the growing list of things I'd try to tackle eventually.

Anyway, that's where I've been. But now I'm getting back into the swing of things on the development side. Expect to hear more from me soon!