Author Topic: FlxTweaks - Dynamically load variables from a Google Spreadsheet  (Read 5566 times)

IQpierce

  • Gamewright
  • Member
  • **
  • Posts: 39
  • Karma: +2/-0
    • View Profile
    • Deep Plaid Games
Hey, I've been using Flixel for a while, mostly for a project I was prototyping with a game designer friend here in Austin.

At one point I decided that I needed to expose the "tweak variables" in this prototype so that the designer could tweak the numbers in the game directly and get the feel he was looking for. Inspired by this blog by a developer of PushButtonEngine, I thought that the best way to expose this would be to make a Google Spreadsheet that could contain all the variables; the spreadsheet could be edited by me or the designer, and the game would read them and load the values in the spreadsheet to be used in the game. (This even allows reloading variables dynamically at runtime without reloading!)

This turned out to be a somewhat finicky process, but I got it working and thought I would share the results with the Flixel community.

The code is a single self-contained class, FlxTweaks.as: http://DeepPlaid.com/FlxTweaks/FlxTweaks.as

And I made a simple example to demonstrate usage...
You can play the example here: http://www.deepplaid.com/FlxTweaks/TweaksExample.swf
And the spreadsheet (which is publicly editable by anyone!) containing the 3 tweak values ("gravity", "jumpForce", and "moveSpeed") is here: https://spreadsheets.google.com/ccc?key=0Av_wyO3Jq2o6dElFM1kyaFpzNlpTSHhnN3JDNnQ4d0E&hl=en

Try moving left and right and jumping (using SPACE or Z). Then try changing any of the values in the Google Spreadsheet; hit F1 (you don't even have to reload the game!); and try messing around in the game some more. You should see the new variables being used within a couple seconds of hitting F1, at most.

Finally, all the source for this example, as well as a .PHP file which is necessary to host as a "proxy" for serving the Google Spreadsheet data, can be downloaded from here: http://www.deepplaid.com/FlxTweaks/TweaksExample.zip

Regarding that PHP file I mentioned... Flash can't directly access Google Spreadsheet data due to permissions issues, but an intermediate PHP file can do so. So long as Flash CAN access the domain that the PHP file is on, everything will work fine.

(If you use this method in a publicly-released game, PLEASE RE-HOST THIS PROXY PHP FILE ON YOUR OWN SERVER AND POINT YOUR GAME TOWARDS THAT ONE, NOT THE ONE ON DEEPPLAID.COM THAT I USE IN THE EXAMPLE!)

How to use it in your code: In keeping with the pragmatic philosophy of Flixel, I tried to make it as simple and straightforward, but flexible, as possible. The FlxTweaks has one static function, "loadVars", which takes:

  • An Object ("obj"), which the variables from the spreadsheet will be loaded into.
  • A URL for a spreadsheet's XML data (for the example, this is https://spreadsheets.google.com/feeds/list/tIE3Y2hZs6ZSHxg7rC6t8wA/od6/public/basic ... note that the spreadsheet should be set up to "publish to the web", and have the option to "automatically republish when changes are made" checked; I believe it also needs to have "visibility" set to "all"... I haven't experimented with just making this visible to specific users... remember that you can make a spreadsheet visible to all but only editable by some).
  • A proxy URL (a path to a hosted GoogleSpreadsheetProxy.php file that I already talked about).
  • A function to call when loading is done (optional).
  • An array of parameters to pass to the function called when loading is done (optional).

The function will load the spreadsheet data. It expects variable names to be in column A of the spreadsheet, with the corresponding value for each variable in column B. For each of these key/value pairs, it will put them into "obj":

Code: [Select]
obj[ key ] = value;
This means that "obj" could just be an Object, used as an associative array, and that any values in the spreadsheet will be put into it blindly, and your code could even respond dynamically to what values it does or doesn't find in "obj" after it's loaded.

OR, if you want to be more strict, you can do what I do: make a specific, non-dynamic class ("ExampleGameTweaks" in my code) which has a value for each tweak variable desired, and pass an instance of this class in as "obj". So long as every value in the spreadsheet has the name of a set-able value in that class, everything will behave fine. (This even works if the value being set is actually a setter!) But if a variable is in the spreadsheet but isn't in the class, you'll get a runtime error.

If the spreadsheet-loading fails for some reason, the callback function will still be called, but the failure will be logged in the console.

Known issues, and things I'd like to add:
  • During tested I noticed that I pointed this to a spreadsheet that wasn't yet publishable; though the console didn't report a failure to load, no tweaks were actually loaded. Basically I think it didn't get a 404 (it got a "can't access spreadsheet" page from Google instead), so it thought it succeeded. Still, it should be fairly obvious that it failed in this case since none of your tweaks will actually be showing up. But I should add handling for this
  • Currently this just treats the spreadsheet as a big list of key/val pairs. The PushButton Engine usage appears to be more complex and allow for a meaningful 2D matrix of data to be set up. Although you can do a lot with key/val pairs, maybe there should be an alternate handling mode that lets you lay out 2D tables of data in the spreadsheet, and causes each them to be automatically loaded into associative arrays in code.

Hopefully this is useful for a lot of people to make their variables more exposed for tweaking, and especially to allow an interface for quickly tweaking variables without even having to reload, much less rebuild, the game! Let me know if there are issues with this.

This is the first time I've made an addition to Flixel - I guess I'll go look into whether there's a process to add this file to the git repo now? Thought I would share this here first. Should I add this to FlashGameDojo perhaps?
« Last Edit: Sun, Dec 5, 2010 by IQpierce »
I'm just one guy trying to make some interesting decisions!

IQpierce

  • Gamewright
  • Member
  • **
  • Posts: 39
  • Karma: +2/-0
    • View Profile
    • Deep Plaid Games
Also, I like the idea that we now have a "wikified game"... the game here:
http://www.deepplaid.com/FlxTweaks/TweaksExample.swf

Is having its functionality driven completely by the publicly-editable data here:
https://spreadsheets.google.com/ccc?key=0Av_wyO3Jq2o6dElFM1kyaFpzNlpTSHhnN3JDNnQ4d0E&hl=en

...If we wanted, the Flixel community could use this as a testbed for what combination of gravity, jumpForce, and moveSpeed values felt ideal for a simple platformer, and continually tweak these numbers into perfection...

...Or they could immediately change moveSpeed to be negative so that all movement is backwards...

...Or they could delete all these variables and add nonsense ones, so that the game will crash at runtime. :) Oh well that's the power of wiki, and I assume these spreadsheets have the ability to roll back to previous revisions if someone breaks it!

I'm just one guy trying to make some interesting decisions!

Billy

  • Active Member
  • ***
  • Posts: 159
  • Karma: +0/-0
  • Herper of Derps
    • View Profile
    • billy.wenge-murphy.com
Quote
and I assume these spreadsheets have the ability to roll back to previous revisions if someone breaks it

They do. I've administered one before with dozens of people screwing around. If you have the privileges there's a menu for it.

IIRC you can also protect certain fields, so you can protect the names of the variables and not the values. That would be helpful :P edit: Guess it's rows+columns.
« Last Edit: Sun, Dec 5, 2010 by Billy »

IQpierce

  • Gamewright
  • Member
  • **
  • Posts: 39
  • Karma: +2/-0
    • View Profile
    • Deep Plaid Games
Nice. I just tried "freezing" the first column, I wonder if that will work.

Not too worried about the "griefing" element since it seems like a pretty helpful, constructive community around here.  ;D
I'm just one guy trying to make some interesting decisions!

Yinan

  • Member
  • **
  • Posts: 19
  • Karma: +0/-0
    • View Profile
well thats all nice... but you stil can't change the variable in runtime, or at least your example swf does not listen to the changes in the spreadsheet in runtime... so this is pretty much useless unless i did somethig wrong?

IQpierce

  • Gamewright
  • Member
  • **
  • Posts: 39
  • Karma: +2/-0
    • View Profile
    • Deep Plaid Games
If you press F1 in my example game at any time, the game will go re-fetch the values from the spreadsheet, and you'll see it using the new values immediately.

Try playing the example game and changing the jump power factor between, like, 1 and 1000, and then refreshing in the game by hitting F1! You'll see the tweaks applied in realtime without having to reload the game.

I'm just one guy trying to make some interesting decisions!

keptblue

  • Member
  • **
  • Posts: 57
  • Karma: +0/-0
    • View Profile
    • EXTLABS
this is an awesome idea. thank you for sharing.