Wednesday, June 29, 2016

Code Philosophy


As mentioned before, I started with this idea that I would write "engine code" for my Card game, where I could basically play a full game in the console without even touching Unity.   I left hooks in my code so that information could be passed back to the UI whenever an event happened.  For instance, here's a sample of code from my "attack" function.


string AttackResult = bf.processAttack(nextCard);
//Play the attack animation on the player ("Active" or "Defending" returned) or on the card ("Card")
//Play the attack animation + the ability animation on any other ("Stalwart" or "Evasion" or "Retaliation")
//Update the defending card and/or player health in UI

//If there is a card there check to see if it's health is <= 0
if (nextCard <= bf.defendingBattlefield.Count - 1)
{
 //Check to see if the card was killed
 if (bf.defendingBattlefield[nextCard].health <= 0)
 {
  // Remove the card from the battlefield
  Card deadCard = bf.defendingBattlefield[nextCard].card;
  bf.defendingBattlefield.RemoveAt(nextCard);

  // Add the static card to the defending player's graveyard
  bf.defendingGraveyard.Add(deadCard);
  // Play animation from battlefield to graveyard 
 }
}

//Lower the boost, if any
bf.processRelevantAffix_AttackEnd();

//Update the UI with the card's lowered attack

I left myself notes to remind me that when implementing a function I'd need to return something to the UI, so that an animation could be played.  I didn't think of this from the start, so some refactoring was needed.   This caused me to move some of the logic from the "engine" code into my "driver" (which will end up being the UI code).   Something to keep in mind when starting my next project as well, if I follow the same backend/frontend paradigm.   

Impact With Unity
There were some growing pains when migrating my code over to Unity.   Firstly and most importantly, Unity uses .NET 2.0 so a lot of the code for SQLite that I was using was unusable when I moved it over to Unity.   My plan was to make a DLL and just put it into Unity.  However, because of the differing function sets this did not work.  I worked and worked at the DLL and ended up just moving the code in file by file, fixing code as I went along.  

I still like the DLL idea - but I'll work on getting that going another time.

S/O to http://hilite.me/ for formatting my code for this post!

My Environment

Here are the technologies I'm using to create my first Unity game:

- Unity 5.   I chose this because of the plethora of information available and great tutorials everywhere.   I also especially appreciate the company and their goals: "the democratization of game development".

- Visual Studio 2015 -- I went back and forth between this and MonoDevelop, which is the other editor that comes bundled with Unity.  This won out because of it's support, maturity, features, and comfort level for me.    I was a .NET developer in a previous life, so this just made sense.  I'm doing my development in Unity exclusively in C#.

- SQLite database -- this holds all of my card details from generating new cards from scratch, to saving Decks full of cards and more.   I use a firefox addon called "SQLite Manager" to manage my database in a UI.

- SourceTree (Git) - this is my source control.  It took me a minute to set up and understand fully, but I feel pretty comfortable now pushing my code to the central server, and can even switch back and forth between my laptop and desktop PC with ease.  This goes for both the C# code and the Unity project (after some ".gitignore" fiddling).

- Gimp - very useful as an image editor, although for very minor things I still use MS Paint.

- Trello - used for issue tracking, worklist, and feature control.   I also have a list of completed items so I can look and see how far I've come (stay motivated).

- Artwork - mostly "borrowed" for now, to be replaced later once my game is nearing completion.


What I'm working on

There's a card game that I have for my phone that Free To Play but limits how much you can play based on a real life timer.  I love the mechanics, so I'm recreating this game (plus some enhancements of course) in Unity.   It's 2D, so there won't be lighting/camera/shading issues hopefully.   There aren't many tutorials on Unity in regards to TCG/CCG on YouTube, so I'm hoping to fill in some of this gap.   I'm not a video content creator (yet) though, so part of the motivation of this blog is to keep some of my video ideas in blog form.  I feel that since I'm going through these growing pains right now I'm uniquely qualified to teach from a beginner's standpoint. 

Currently my card game has a backend engine/database and can create a random level 1-25 card with 1-5 "stars".   My background is in application development, so I took the tact of writing "engine" code before I started really implementing things in Unity.    Basically, this means I can play the game in a console without it rendering anything in a UI to the screen.   I'm using an object oriented approach with a SQLite backend database to hold a lot of configuration information about my cards.

 In the frontend my Unity scene can create a card with full details (health, attack, level, stars, artwork, card text) and place it in 1-5 predetermined positions on the screen.   It can also clear the cards currently on the board.    This may not sound like much, but it has been a month of working on it (not full time of course) and I couldn't be prouder of it so far!

My goals with this game are to create a working product that can be played by anyone (not just me)!  This means working on polishing the game after it's "functionally complete".  So many voices in the podcasts that I listen to that espouse the virtues of actually completing a game.   I want to "make it clunky", meaning making it go "clunk" whenever someone clicks something or moves an asset.   I want there to be both visual and audio feedback, and I want it to feel like a great game. 

Reincarnation into Unity

I am restarting this blog and re-dedicating it to Unity.   It's an amazing time to be a game developer right now, with Unity 5.0 and Unreal Engine both being free (to a certain extent on each, but nearly 100% free).   So, here I am to throw away my unread book on OpenGL and start from the start with my intro into Unity game development.  

First, I'll start by listing some resources I've loved using to get started again on Game Development.

1) Unity3D.com - tons of great tutorials on the engine and all of the documentation

2) answers.unity3d.com - haven't got a ton of usage out of this yet but I have asked a few questions.  You have to have a certain amount of rep to ask a question and not have it sit in the "waiting to be approved" step.   However, I don't know anything about Unity so how am I supposed to get upvoted?  Answers take a long time.

3) TheDebugLog.com - great podcast about Unity game development and game development in general.  Keeps me motivated, keeps me informed about the state of game dev.

4) Game Devs Like You podcast - another great podcast about game development in general.   Good to keep a pulse on the industry.

5) Twitter hashtags:  #gamedev #madewithunity #unitytips  -- I'll peruse through these and find some good stuff now and then

I'll update this post as I think of more useful Unity and game dev related stuff.

Tuesday, June 25, 2013

Curveball

I want to make a multi-player version of this.

Click to Play!

Wednesday, October 28, 2009

Introduction to Ajax




When you go to google and start typing in a query, you get a dropdown list of what google thinks you might be typing. If you're not aware, the way they do that is by using Ajax, a way of transferring data between the server and your browser without sending the entire page back in forth. By sending smaller packages, it gives the illusion of seamless data transfer. It's like having your own personal google right in your browser. So, today I set out to demystify the creature known as Ajax!

My search started at W3C Schools, where else? Their Ajax tutorial is of course top notch - I'll summarize it in my own words though.

The driver behind Ajax is Javascript. Javascript creates the object (XMLHttpRequest) that talks back and forth with the server. Javascript passes it any variables. Javascript sets the return string into an appropriate container. W3C Schools break down (rightly so) the javascript functions you will need to get your Ajax-enabled page up and running:

Someone set us up the bomb XMLHttpRequest object

<script>
var xmlhttp

function GetXmlHttpObject()
{
if (window.XMLHttpRequest)
{
// code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
}
if (window.ActiveXObject)
{
// code for IE6, IE5
return new ActiveXObject("Microsoft.XMLHTTP");
}
return null;
}
</script>

The above code will declare a variable to hold the XMLHttpRequest object. Important to note is that it's outside the declaration of the function. Making it global allows it to be accessible from multiple functions. After that, the function to instantiate the XMLHttpRequest object is pretty straightforward. It needs to be set up one way for older IE browsers, and another way for more modern browsers.

Ok we have a function to set up the XMLHttpRequest object, now you need a function to actually make the Ajax call!

Fetch!
function ajaxFunction(parameterValue)
{
//Set up the XMLHttpObject
xmlhttp = GetXmlHttpObject();

//Set the object's state change event to run our handler
//We will define the 'stateChanged' function in just a second
xmlhttp.onreadystatechange=stateChanged;

//Set up the URL
var url = "serverJob.aspx"
url = url + "?parameter=" + parameterValue

//Send the XMLHttpObject off to the server
xmlhttp.open("GET", url, true);
xmlhttp.send(null);
}


Ok, a few important things to note here. The way we are going to pass parameters to the server is in the QueryString. As you can see, we set up a URL that has a parameter and a parameter value in the familiar way you might pass form data in standard HTML. The open() command takes 3 parameters: the method to use (GET or POST), the url we want to do the work, and a boolean signifying whether or not we want it to run asynchronously (I can't see a time where we wouldn't, but hey). Then we send it off on it's merry way, and continue doing whatever it was we were doing. The event handler should handle the rest:

The function 'stateChanged' will take care of the data as it comes back from the server.

Yeah yeah I gots ya stinkin data, now whatcha wants me ta do wit it?
function stateChanged()
{
if (xmlhttp.readyState==4)
{
document.getElementById("yourOutputControl").innerHTML=xmlhttp.responseText;
}
}

This convenient table from W3C Schools should pretty much sum up what's going on here
We want to wait for the state to be equal to 4 (completed), and the data to be back from the server. Once it is, we set the response text to a control. That's what's going on inside the if-statement. Get a reference to your control and set the value.

That's pretty much it! We create an XMLHttpRequest object, we send it a QueryString, and it sends us a result string in return. That's an important point. The only exchanges are parameter strings and a single return string. Ok, one final piece of the puzzle remains. What's going on inside serverJob.aspx? Quite simply, it's a standard ASPX page that returns a single string:

<%
Response.Expires = -1
dim m as myObject
dim returnString as string = m.doSomeWork(Request.QueryString("parameter"))

Response.Write(returnString)
%>

"Response.Expires = -1" means that we won't cache this aspx page, ever, since we want it to run "fresh" every time we request it. After that, you are free to declare instantiations of your objects, make database calls, and code to your heart's desire. In the above example, I've declared an object of type myObject and had it do some work based on the parameter that was passed in on the QueryString. Pretty simple! Again, the important thing to note here is there is one string that is returned, and instead of using the "return" keyword, we use Response.Write.

So there it is, your first introduction to Ajax! I can't believe it's taken me this long to get into it, when it really is so simple. I'd love to hear your Ajax adventures, tips, or questions, so leave them in the comments!

Thursday, October 8, 2009

Getting data out of an Oracle database and into your VB.NET program!




The client has data, it's in a database, and he wants it presented in a nicer format. Sounds familiar? It should, because that's 80% of what you're going to run into in your life as a developer! So, how the heck do we get data from there to here?

So here's what you want to import:

Imports Microsoft.VisualBasic
Imports Oracle.DataAccess.Client


Then you want to declare a connection string:

Dim connectionString As String = "User Id=userIDHere;Password=passwordHere;Data Source=schemaNameHere;"

Then, open an Oracle connection using your connection string as a parameter:

Dim conn As New OracleConnection(connectionString)
conn.Open()

Now that you have a connection open, you can send it a request. Create a query string and then an OracleCommand object.

Dim query As String = "select * from tableName where condition = value"
Dim command as OracleCommand = New OracleCommand(query)
command.Connection = conn
command.CommandType = CommandType.Text

Don't forget that when you're going to access the database, it may throw an exception at you. So give it the ole college TRY:


Try
Dim reader as OracleDataReader = command.ExecuteReader()
While (reader.Read())
Dim stringValue as string = CType(reader.GetValue(0), String)
Dim intValue as Integer = CType(reader.GetValue(1), Integer)
End While
Catch ex as Exception
'Send a message to the user
Finally
' Dispose OracleCommand object
command.Dispose()
' Close and Dispose OracleConnection object
conn.Close()
conn.Dispose()
End Try


So there's a quick overview of opening an Oracle database and retrieving some database from it. One more note, if you want to insert, update, or delete from the database, use the ExecuteNonQuery() command in lieu of the ExecuteReader() command, as such:

Dim status As Integer = cmd.ExecuteNonQuery()


So there you have it, opening an Oracle database from VB.NET. Questions? Comments? Leave them below and I'll get back to you as soon as possible.