Jump to content


Manuel777

Member Since 25 Nov 2006
Offline Last Active Today, 08:12 AM

Topics I've Started

Cant Run Any Ubuntu Games..

09 June 2013 - 02:22 AM

Soo. after some struggle (libopenal and such) I was ble to get a game executed, but it crashed inmediately howing me this little log:

 

Spoiler

 

I am running a relatively fresh installation of Ubuntu 13.04, and just updated all packages trough the package manager (terminal shows theres nothing left to update)
My graphics card is a Nvidia GForce 9500 and it has the latest drivers installed too.. any clues?


No way to check if a ds_map exists..

13 February 2013 - 10:36 PM

Im sure there is a reason for this, but why does GM never had a way to check if a ds_map exists? the function ds_map_exists() only checks if a key inside an existant map exists, I could really use a function to actually test if a ds_map index exists at all :/

either that, or, is there a way to do it at all right now??

Ouya Support Patch

12 February 2013 - 06:05 PM

IMPORTANT EDIT: This patch is soon to become obsolete as YoYoGames will add OUYA gamepads support natively trough the gamepad_ functions, wich should happens anytime now (next update after 1.1.1013), this means that most of this patch will become obsolete by then.

If you only wish to use the gamepads then this patch will not be nessesary anymore, but if you wish to use the In App Purchases (or at least give it a try), then you will still need the patch.

 

 

Me and jtn0514 have been working on this little patch for GameMaker Studio, so it can have complete support for the OUYA console, it was difficult, but we finally managed to get a relatively bug-free patch that works pretty well!

Features (as of now) are listed below:

  • Complete controller support (all four controllers, axis, triggers, etc)
  • Axis deadzones fix (you can change the threshold)
  • Button states
  • Button and keyboard mapping (similar to keyboard_set_map())
  • In app purchases (product lists, receipts, buy, uuid)

Known bugs:

  • Sometimes joystick axis (LS, RS, triggers) get stuck on a static position (especially in the X axis, may be a hardware problem!)
  • Receipts list is reaturned empty when decripting it (within the ODK), this causes you NOT being able if an item was purchased.
  • ..?

You will need the GameMaker scripts to get it working properly, you can either download an example .gmz project (simplest way), or the individual .gml and constants file:
OUYA-GMS.gmz

(right click, 'save target as')
OUYA_scripts.gml
constants.txt
constants are imported into GMS, in Resources -> Define Constants

The latest ODK (OUYA Developement Kit) can be found here:
OUYA ODK
I always use the latest, 1.0.0 as of now.

Java extension files:
gmc.zip

List of GameMaker Studio supported version, and changelog:

Spoiler

I will always and only use the latest releases of GMS to develop this patch, and most probably wont add old versions support, altrough th steps of the instalation can be used in olders version of GameMaker Studio, I cant guarantee they will work.


Setting up everything:
To get everything working you will need to insert the code on the GMS AndroidManifest.xml and RunnerActivity.java files.
The AndroidManifest.xml can be found at: %APPDATA%\GameMaker-Studio\Android\runner\AndroidManifest.xml
There, open and edit with any code/text editor. you should find the following lines:

<intent-filter>
<action android:name= "android.intent.action.MAIN"/>
<category android:name= "android.intent.category.LAUNCHER"/>
</intent-filter>

and insert the OUYA intent, like so:

<intent-filter>
<action android:name= "android.intent.action.MAIN"/>
<category android:name= "android.intent.category.LAUNCHER"/>
<category android:name= "tv.ouya.intent.category.GAME"/>
</intent-filter>

The same process is explained at the OUYA docs as well.

Now, I am using Halo shg GMExtensions method to include In App purchases into GMS, so go to that topic and follow only step 1 in the first post. Once that is done, extract the java extension files (gmc.zip) inside this folder:
%appdata%\GameMaker-Studio\Android\runner\

A new folder named \gmc should be created along with the already-existing \com and \YYAndroidPackageDomain ones.
 
If you havent done so, install your key.der file to %appdata%\GameMaker-Studio\Android\runner\src\res\raw\
To find your key.der file, go into your OUYA's developer console, and create a new game (or access the game you want to test), there you should be able to download the new key file.
 
Notice: the default key.der file is useless (filled with ones), since you should only use your own key (wich is why I havent supplied a working one), as it is a certificate that identifies your game on the OUYA store!


Now, go to the RunnerActivity.java file, located at:
%APPDATA%\GameMaker-Studio\Android\runner\src\YYAndroidPackageDomain\YYAndroidPackageCompany\YYAndroidPackageProduct\RunnerActivity.java

Find the next import line:

import org.ini4j.Ini;

And add the next lines afterwards:

import org.ini4j.Ini;

import tv.ouya.console.api.*;
import android.view.MotionEvent;
import java.text.DecimalFormat;

After that, and inside the class declaration, paste this code:

public static final int OUYA_DS_MAP = RunnerJNILib.dsMapCreate();

It should look like this:

public class RunnerActivity extends Activity implements SensorEventListener
{
// The Singleton for RunnerActivity
public static final int OUYA_DS_MAP = RunnerJNILib.dsMapCreate();

public static RunnerActivity CurrentActivity;
[..]

 
Find this:

RunnerJNILib.Init( this );

 
It should be insude the method onCreate(), right after that line paste the next lines so it looks like this:

RunnerJNILib.Init( this );
        Log.i("yoyo", ">> OuyaController.init()");
        OuyaController.init( this );
        Log.i("yoyo", ">> OuyaController initialized...");

Now, find the method onKeyDown(), and replace the entire method by this, new one:

   @Override
    public boolean onKeyDown( int keyCode, KeyEvent event ) {
     try {
            int player = OuyaController.getPlayerNumByDeviceId(event.getDeviceId());
 
            boolean handled = false;
            String ouya_result = "d"+String.valueOf(player).toString();
 
            //Handle the input
            switch (keyCode) {
                case OuyaController.BUTTON_O:
                        ouya_result += String.valueOf("O").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_U:
                        ouya_result += String.valueOf("U").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_Y:
                        ouya_result += String.valueOf("Y").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_A:
                        ouya_result += String.valueOf("A").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_DPAD_UP:
                        ouya_result += String.valueOf("Up").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_DPAD_RIGHT:
                        ouya_result += String.valueOf("Right").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_DPAD_DOWN:
                        ouya_result += String.valueOf("Down").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_DPAD_LEFT:
                        ouya_result += String.valueOf("Left").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_L1:
                        ouya_result += String.valueOf("L1").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_L2:
                        ouya_result += String.valueOf("L2").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_L3:
                        ouya_result += String.valueOf("L3").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_R1:
                        ouya_result += String.valueOf("R1").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_R2:
                        ouya_result += String.valueOf("R2").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_R3:
                        ouya_result += String.valueOf("R3").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_MENU:
                        ouya_result += String.valueOf("Menu").toString();
                    handled = true;
                    break;
                default:
                        ouya_result += String.valueOf("None").toString();
                        // Enable to debug only!
                    //handled = true;
                    break;
            }
 
            if (handled == true) {
                    Log.i( "yoyo", "OUYA Down "+ouya_result);
                    RunnerJNILib.dsMapAddString(OUYA_DS_MAP, ouya_result, "1");
                    return true;
                }
 
        // record the key events ready to be passed down to the game
        if (keyCode != 0) {
                RunnerJNILib.KeyEvent( 0, keyCode );
            }
        
        if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || 
                (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) || 
                (keyCode == KeyEvent.KEYCODE_HOME) || 
                (keyCode == KeyEvent.KEYCODE_MENU))
                        return super.onKeyDown(keyCode, event );
                else
                return true;
        } catch (RuntimeException e) {
            Log.i("yoyo", e.getMessage());
            throw new RuntimeException(e);
        }
    }

Do the same with the proceeding onKeyUp() method, using this code instead:

   @Override
    public boolean onKeyUp( int keyCode, KeyEvent event ) {
     try {
            int player = OuyaController.getPlayerNumByDeviceId(event.getDeviceId());
 
            boolean handled = false;
            String ouya_result = "u"+String.valueOf(player).toString();
 
            //Handle the input
            switch (keyCode) {
                case OuyaController.BUTTON_O:
                        ouya_result += String.valueOf("O").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_U:
                        ouya_result += String.valueOf("U").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_Y:
                        ouya_result += String.valueOf("Y").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_A:
                        ouya_result += String.valueOf("A").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_DPAD_UP:
                        ouya_result += String.valueOf("Up").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_DPAD_RIGHT:
                        ouya_result += String.valueOf("Right").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_DPAD_DOWN:
                        ouya_result += String.valueOf("Down").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_DPAD_LEFT:
                        ouya_result += String.valueOf("Left").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_L1:
                        ouya_result += String.valueOf("L1").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_L2:
                        ouya_result += String.valueOf("L2").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_L3:
                        ouya_result += String.valueOf("L3").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_R1:
                        ouya_result += String.valueOf("R1").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_R2:
                        ouya_result += String.valueOf("R2").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_R3:
                        ouya_result += String.valueOf("R3").toString();
                    handled = true;
                    break;
                case OuyaController.BUTTON_MENU:
                        ouya_result += String.valueOf("Menu").toString();
                    handled = true;
                    break;
                default:
                        ouya_result += String.valueOf("None").toString();
                        // Enable to debug only!
                    //handled = true;
                    break;
            }
 
            if (handled == true) {
                    Log.i( "yoyo", "OUYA Up "+ouya_result);
                    RunnerJNILib.dsMapAddString(OUYA_DS_MAP, ouya_result, "1");
                        return true;
                }
 
                RunnerJNILib.KeyEvent( 1, keyCode );
        if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || 
                (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) || 
                (keyCode == KeyEvent.KEYCODE_HOME) || 
                (keyCode == KeyEvent.KEYCODE_MENU))
                        return super.onKeyUp(keyCode, event );          
                else
                return true;
        } catch (RuntimeException e) {
            Log.i("yoyo", e.getMessage());
            throw new RuntimeException(e);
        }
    } 
 
    @Override
    public boolean onGenericMotionEvent( MotionEvent event ) {
     try {
            int player = OuyaController.getPlayerNumByDeviceId(event.getDeviceId());
 
            String ouya_result = String.valueOf(player).toString()+"Axis";
 
            String res = "";
            Float axis = Float.MIN_NORMAL;
            
            if (event.getActionMasked() == MotionEvent.ACTION_MOVE) {
                    DecimalFormat dec = new DecimalFormat("#.#####");
                    Float flv = Float.MIN_NORMAL;
 
                    flv      = event.getAxisValue(OuyaController.AXIS_LS_X);
                    if (flv == null) { flv = Float.MIN_NORMAL; }
                    res     += dec.format( flv );
                    res     += " ";
 
                    flv      = event.getAxisValue(OuyaController.AXIS_LS_Y);
                    if (flv == null) { flv = Float.MIN_NORMAL; }
                    res     += dec.format( flv );
                    res     += " ";
 
                    flv      = event.getAxisValue(OuyaController.AXIS_RS_X);
                    if (flv == null) { flv = Float.MIN_NORMAL; }
                    res     += dec.format( flv );
                    res     += " ";
 
                    flv      = event.getAxisValue(OuyaController.AXIS_RS_Y);
                    if (flv == null) { flv = Float.MIN_NORMAL; }
                    res     += dec.format( flv );
                    res     += " ";
 
                    flv      = event.getAxisValue(OuyaController.AXIS_L2);
                    if (flv == null) { flv = Float.MIN_NORMAL; }
                    res     += dec.format( flv );
                    res     += " ";
 
                    flv      = event.getAxisValue(OuyaController.AXIS_R2);
                    if (flv == null) { flv = Float.MIN_NORMAL; }
                    res     += dec.format( flv );
                    res     += " ";
                    //Log.i( "yoyo", "OUYA Axis "+res);
                    RunnerJNILib.dsMapAddString(OUYA_DS_MAP, ouya_result, res);
            }
        } catch (RuntimeException e) {
            Log.i("yoyo", e.getMessage());
            throw new RuntimeException(e);
        }
        return true;
    }

After having modified both files sucessfully, we need to install the OUYA ODK, (asumming you already downloaded it) the ODK library (.jar) can be found on the ODK .zip at \OUYA-ODK\libs\ouya-sdk.jar, copy that file to:
%APPDATA%\GameMaker-Studio\Android\runner\libs

That should be it!, now open the test .gmz and compile to test if everything is Ok, if not, double check you have followed all steps correctly.

If you want to include the .gml and .txt files into a new or existing project, you will also need to create a new object to handle everything, the object need to be set up as follows:
Create event:

ouya_setup();

Begin step event:


ouya_update();

After that you can start using all of the other functions, they are all well documented in the very same scripts, and are very intuitive.
 
Ps: If you are using or want to use IAPs, remember to enter your developer id!

Cheers!

Credits go to:

  • Me (Manuel Etchegaray) for developing the patch codes.
  • jtn0514 For borrowing his OUYA console to extensively test and debug everything works properly.
  • halo shg For making GMExtensions, wich is the core of the in app purchases.
  • The YoYoGames team for making such great software!

My game, on Desura!

11 January 2013 - 05:26 AM

Well, as the title says so, my latest game was just released on Desura, and it started pretty well already! I wanted to share this huge achievement with all of you guys; the GMC community, because if it wasnt because of all the great support I have always had from everyone in here, including the YYG team, this wouldnt be possible today!

Also, I wanted to highlight the importance of this, as I always see people complainig GameMaker being a "childs tool", I am not the only one using GameMaker who has just released a game on Desura or Steam, also the people behind Super Tower Rush are using it, and even the super-successful Hotline Miami was made with GameMaker! (Not to mention True Valhalla's success story..) whoa!! :D

This is just an incredible achievement for YoYoGames as well, since they are the ones re-building GM's reputation, having quality games being distributed in the major app stores thanks to GameMaker Studio, it is definately a great product with tons of potential  Posted Image


MODERATOR EDIT: The following is from a later post that explains a bit about the process of getting the game hosted. I have added it here for convenience:

I had planned release for december 12th at first, wich is when I started looking at the different distribution methods and stores. I went trough all games distribution sites I found looking how the submission process was and even submitted early releases for them to evaluate, wich, I must say, very few portals actually ven replied to.
Around december the 20-25th I released the game on Google Play (wich is the most simple submission process once you have the Developer Account) and submitted trough IndieDB for Desura evaluation. At the same time I decided to keep a "backup plan", just in case it didnt get aprooved on Desura, and created an account with FastSpring. Within two weeks of emails with the fastspring guys (who are actually the best when it comes to customer service!!) I had my custom store ready to go, and the desura guys finally replied to my Publishing request, asking me to upload an installer, and so some other changes to my game's profile in order to get it ready, like different pricings, descriptions, images, etc.
After about a week of waitings and emails sent with the Desura mods, I had my game ready to go and my FastSpring account on-hold to start selling copies of my game!

So, if anyone else is trying this, let me give you some advices:

  • Submit only quality content to the stores. Most of them manually revise every game that is submitted, and if they get a really bad game, or at least a game that they know it wont ever get sold, they probably wont even reply to you, its not worth their time.. just like that!
  • Start submitting early before release, I screwed it thinking it may take less time to set everything up, instead it took me a whole month!
  • Be patient, if they dont reply after a week its in your right to ask them what happened, but if you are not patient you will just end up being a pain in the arse.
  • Dont lie on your descriptions, dont ever say stuff like "This game is great", "8 out of 10 geeks loved it", people dont fall into that and its lame. Just describe your game, if its worth a few bucks, there has gotta be something interesting nor unique about it! Impress everyone!
  • Contact the press whenever something cool happens, they are usually actually loking for games and stuff to cover, but they wont tif the story is not interesting.
  • Get ready to send and reicieve hundreds of emails.  Posted Image

If you are looking on more info on how to do this stuff, different portals, links, and pretty much anything to help you develpoing you game, Use PixelProspectors Indie Resources guide, it helped me a lot, and I actually found some distribution methods there that I didnt even knew of  Posted Image


Ubuntu Phone OS

04 January 2013 - 02:53 PM

Posted Image


A few days this got around the web, the oficial prensentation of Ubuntu Phone OS, being based around an Android BSP it means that images will be pretty easy to install over currently existing handsets once released, like the Galaxy Nexus, like seen on this hands-on video

It looks very promising, and even trough the images and actual phones wont be available until late 2013 (if not later), the complete set of developer tools is already available to play around with!

So, wich are the chances we get this on GameMaker:Studio someday? I heard on the site the 'competition' is already making plans for it..   :whistle: