Ludum Dare 33 “You are the Monster” Entry

I wasn’t really inspired by the theme this Ludum Dare and I think that always tends to show. You can see the game here and vote on it here. Since it’s just html, css, and non-obfuscated js feel free to look at the code.

My main takeaways were:

  1. Keeping a blog makes me significantly better and showing my progress.
  2. CSS animations have gotten WAY easier to work with since I last did them.
  3. Kind of obvious but when making games in niche genres it’s easier to get attention from the hardcore fans. My game got a fair amount of hits from the clicker/idle subreddit.
  4. I managed to finish something even after I sort of lost motivation and had several other things to do during the weekend, so that’s a big improvement over previous jams.

Tools:

  • Visual Studio Express 2012 Web
  • jQueryUI

A few in progress shots of the order I did things in:

  1. Skeleton layout
  2. 1Layout

  3. Button Handcursor And Satisfying number animation complete with formatting of dummy info
  4. 2HandcursorAndNumberAnimation

  5. Stats Popup
  6. 3StatsPopup

  7. Dynamic Button inserts and Tooltips
  8. 4DynamicButtonInsertAndTooltips

  9. Button content updates
  10. 5ButtonContentLiveSite

  11. Logic working on everything
  12. 6LogicWorksCostsGrayedTitleBarUpdates

  13. Real art
  14. 7RealArtIsFun

  15. Floaty Text!!!!!!
  16. 8FloatyTextInAllBrowsers

  17. Toast Popups and Save load
  18. 9ToastPopupsAndSaveLoad

  19. Win condition
  20. 10WinMenu

  21. Final  including weird css bug fixes.
  22. 11Final

 

 

What happens when you’re really tired and google for transparent images because you’re trying to figure out a really dumb IE fading bug:
DumbShitToGoogleFor

Local flash game leaderboard tutorial

Update I’m stopping updating my whole blog and don’t have time to fix the confusing points of this post so if you get stuck there are some questions about this post answered on This StackOverflow question.

This tutorial is about how to create a local leaderboard in ActionScript 3, the principles will work on mobile in AIR or on the web. See completed project at the end of the post.

In AS3 ais used to store data to the player’s computer. In the case of a local leaderboard we want to store high score’s between games and then display them in a sorted order. Note since we’re only storing data locally ( as opposed to networked ) this will only show score’s on that machine and more complex methods would require a server component.

1. Initialize where data will be saved

Main.as 

private var m_FlashCookie:SharedObject;
private function init(e:Event = null):void
{
  //...
  m_FlashCookie = SharedObject.getLocal("LeaderboardExample");
  //...
}

2. “Play Game” and store the results of that player’s session. In the case of the example this is simply done using static variables in the Main document class.

StateGame.as 

Main.EntryScore = parseInt(m_InputBoxScore.text);
Main.EntryName = m_InputBoxName.text;

3. Fetch our saved leaderboard object of high scores. shared_object.data[“KEY_NAME”] will return null if nothing has been stored with that key.

StateLeaderboard.as

// Shared Objects store everything as untyped objects so we cast it back to an array as we will store it later
var arr:Array = Main.Inst.getSaved("TopScores") as Array;
if ( arr == null)
  arr = new Array();

//----------------------------

Main.as
public function getSaved(key:String):Object
{
  return m_FlashCookie.data.key;
}

4. Push the latest score that the last gameplay session added into the array storing the leaderboard data

StateLeaderboard.as 

// create the object that stores the data that just got created from our last gamestate
// we can add multiple stats in here if we wanted, for example "enemies killed" and "coins collected"
// in this case we just use score as an example so we have only one number to sort on
var latest_score_object:Object = {
  name: Main.EntryName,
  score: Main.EntryScore
};
// push the last score onto the list
arr.push( latest_score_object );

Note: this means that we might now have 11 scores in the array instead of the top 10.

5. Sort the leaderboard so it’s in the order we want it to be in

StateLeaderboard.as 

// sort the list from highest to lowest based on the "score" figure.
// the key here can be anything stored in the lastest_score_object entry.
arr.sortOn("score", Array.NUMERIC | Array.DESCENDING);

6. Remove extra entries in the array so we only save the “top 10”

StateLeaderboard.as 

// if adding the score from the last game made it so there were more than 10 items of the list, remove the last #11.
// since the array was sorted on the line above that means that the last score will be in the right place regardless
if ( arr.length < NUM_SCORES_SAVED )
{
  arr.pop();
}

7. Flush/Save the new leaderboard This makes it correct for next time.

StateLeaderboard.as 

// This key name must match the name we used above in step 3.
Main.Inst.saveData("TopScores", arr);

//--------------------

Main.as

// Function to store data by key.
public function saveData(key:String, dataToSave:Object):void
{
  m_FlashCookie.data.key = dataToSave;
  var flushStatus:String = null;
  try
  {
    flushStatus = m_FlashCookie.flush(10000);
  }
  catch (error:Error)
  {
    trace("Error...Could not write SharedObject to disk\n");
  }
  if (flushStatus != null)
  {
    switch (flushStatus)
    {
      case SharedObjectFlushStatus.PENDING:
        trace("Requesting permission to save object...\n");
        m_FlashCookie.addEventListener(NetStatusEvent.NET_STATUS, onFlushStatus);
        break;
      case SharedObjectFlushStatus.FLUSHED:
        trace("Value flushed to disk.\n");
      break;
      }
    }
}

8. Loop through all the leaderboard data and display it in a human readable way.

StateLeaderboard.as 

// In this example implementation we display all our data in a single textfield.
// In a real game we'd probably work with an artist to put these on seperate lines or a grid
var myHTML:String = "";
var total_stored_scores:int = arr.length;
for (var i:int = 0; i < total_stored_scores; ++i)
{
  // loop through every entry, every entry has a "name" and "score" field as that's what we save.
  var leaderboard_entry:Object = arr[i];
				
  // is this the last score that was just entered last gamestate?
  if ( leaderboard_entry == latest_score_object )
  {
    myHTML += (i+1) + ". <b><font color=\"#0002E5\">"+ leaderboard_entry.name + " " + leaderboard_entry.score +"</font></b><br>";
  }
  else
  {
    myHTML += (i+1) + ". "+ leaderboard_entry.name + " " + leaderboard_entry.score +"<br>";
  }
}
m_TF.htmlText = myHTML;

9. Rinse, repeat and observe.

DOWNLOAD EXAMPLE:
Flash Develop or Flash Pro CC project source of the complete example.

Speedy Free Flash Game Programming Review

I’ve been away from flash for a few months and decided it was time to do a quick review. But after being a professional flash developer for several years what to do? Also I had the additional problem that I didn’t have access to useful tools like oh I don’t know the Flash Authoring tool.
I wanted to do something that was easily skinnable so it had the feel of a normal flash game that suckers would buy you would see on normal portals.

This is what I came up with after a day: FIV Find it

I used a few public domain images, FlashDevelop IDE, Paint.NET, and goldwave. I’d recommend this combination to any exploring programmer with limited art resources. Making an entire hidden object scene in a few hundred lines of code.

As for the numbers you get on Kongregate for putting less than a day of work in something and not having an artist: 200 plays and 17 cents after 3 days. Fun fact. This is with only facebook shares and being briefly listed on the new games section.

Making this tiny game was fun enough where I’ve rejuvenated my plan of constant side projects.

Annoyed at Google App Engine and Eclipse Indigo

Ugh… so always blog angry right?  This seems to be my pattern:

  1. Create blog for no apparent reason saying “one day I’ll update” because I happen to be doing something at the time that makes it easy. ( Getting a myspace account, when google bought blogger and was advertising like crazy, when I was setting up another SQL project on my site and saw a free wordpress install)
  2. Wait for months for something to happen tech wise that I can rant about ( that isn’t directly work related )
  3. Write an angry post or two about code problems that annoy me. Not that are difficult problems, just that shouldn’t exist as problems at all.
  4. Eventually forget password
  5. Goto: 1

We’re on step 3 now! Story time!

So I’ve just done my first install of Google App Engine to work on a text based RPG app project (More on that in future updates!)

So I install latest Eclipse (Indigo 3.7) and then happily try to install the google plug-in (found here: http://code.google.com/appengine/docs/java/tools/eclipse.html)

Which quickly leads to this error:

Cannot complete the install because of a conflicting dependency.
  Software being installed: Google Plugin for Eclipse 3.7 2.3.2.r37v201106211634 (com.google.gdt.eclipse.suite.e37.feature.feature.group 2.3.2.r37v201106211634)
  Software currently installed: WindowBuilder XML Core 1.0.0.r37x201106081533 (org.eclipse.wb.core.xml.feature.feature.group 1.0.0.r37x201106081533)
  Only one of the following can be installed at once:
    WindowBuilder Databinding XML Core 1.0.0.r37x201106161417 (org.eclipse.wb.core.databinding.xml 1.0.0.r37x201106161417)
    WindowBuilder Databinding XML Core 1.0.0.r37x201106081533 (org.eclipse.wb.core.databinding.xml 1.0.0.r37x201106081533)
  Cannot satisfy dependency:
    From: GWT Designer Editor 2.3.2.r37x201106201351 (com.google.gdt.eclipse.designer.editor.feature.feature.group 2.3.2.r37x201106201351)
    To: org.eclipse.wb.core.xml.feature.feature.group 1.0.0.r37x201106161417
  Cannot satisfy dependency:
    From: Google Plugin for Eclipse 3.7 2.3.2.r37v201106211634 (com.google.gdt.eclipse.suite.e37.feature.feature.group 2.3.2.r37v201106211634)
    To: com.google.gdt.eclipse.designer.editor.feature.feature.group 2.2.0
  Cannot satisfy dependency:
    From: WindowBuilder XML Core 1.0.0.r37x201106081533 (org.eclipse.wb.core.xml.feature.feature.group 1.0.0.r37x201106081533)
    To: org.eclipse.wb.core.databinding.xml [1.0.0.r37x201106081533]
  Cannot satisfy dependency:
    From: WindowBuilder XML Core 1.0.0.r37x201106161417 (org.eclipse.wb.core.xml.feature.feature.group 1.0.0.r37x201106161417)
    To: org.eclipse.wb.core.databinding.xml [1.0.0.r37x201106161417]

Ruh-roh, more time on the internet leads me to a bug in Eclipse’s database. But of course the work around doesn’t work for me there, something else must of changed since that was posted. So I need to dig through the PAIN that is getting individual updates in eclipse, which I hate digging for.

At least for me the only work around I got to work when installing Google App Engine on a fresh install was:

  1. Fail and spend way more time looking around the internet than installing something should take.
  2. Help -> Install New Software from “http://download.eclipse.org/releases/indigo”
  3. Select all things “WindowBuilder” related.
  4. Follow instructions on google tutorial ( install from “http://dl.google.com/eclipse/plugin/3.7”)
  5. PROFIT! ( probably not.)

There are some similar workarounds on posts after googling this error, but that first link is difficult to find for someone who hasn’t worked in eclipse in a few years and “Update” of course does nothing.