How can I convert a paid iOS game to a free game with in game purchases?

| | August 7, 2015

I have developed a game for iOS that has had a decent amount of downloads, but I think I would get significantly more revenue if I were to convert the game to free to play, with in app purchases (especially since some competitors products are now free to download with in app purchases).

My question is what is the best way to go about converting to a free game with in app purchases without annoying the existing users?

On upgrading I’d like the people who previously paid for the app to have access to all the in-app purchases because I don’t want to make them have to pay for content they previously had, and I don’t want to make all the content (that is currently in the game) free.

Best memory allocation strategy for iOS?

| | August 7, 2015

I’m debating myself about memory allocation on iOS. I write most of my code in C++ and I really like using ObjectPools, FreeLists, etc. In order to pre-allocate a lot of the stuff that I’ll be constantly “alloc/dealloc” during the course of my game, ( like particles, game entities, etc ).

Still on iOS, it’s not like we are developing for a console like PSP, where I can know for fact that I’ll get a fixed amount of memory. iOS , will issue “memory warnings” when the system needs memory.

Does anyone have some suggestions about this ? Is it too serious since the new iPod touch/iPhone 4 are carrying more RAM ? or it’s still a big concern?

Restricting joystick within a radius of center

| | August 7, 2015

I’m using Unity3d iOs and am using the example joysticks that came with one of the packages. It works fine but the area the joystick moves in is a rectangle which is unintuitive for my type of game. I can figure out how to see if the distance between the center and the current point is too far but I can’t figure out how to constrain it to a certain distance without interrupting the finger tracking.

Here’s the relevant code:

using UnityEngine;
using System.Collections;
public class Boundary 
{
public Vector2 min = Vector2.zero;
public Vector2 max = Vector2.zero;
}

public class Joystick : MonoBehaviour{ 
static private Joystick[] joysticks;                    // A static collection of all joysticks
static private bool enumeratedJoysticks=false;
static private float tapTimeDelta = 0.3f;               // Time allowed between taps

public bool touchPad;                                   // Is this a TouchPad?
public Rect touchZone;
public Vector2 deadZone = Vector2.zero;                     // Control when position is output
public bool normalize = false;                          // Normalize output after the dead-zone?
public Vector2 position;                                    // [-1, 1] in x,y
public int tapCount;                                            // Current tap count

private int lastFingerId = -1;                              // Finger last used for this joystick
private float tapTimeWindow;                            // How much time there is left for a tap to occur
private Vector2 fingerDownPos;
private float fingerDownTime;
private float firstDeltaTime = 0.5f;

private GUITexture gui;                             // Joystick graphic
private Rect defaultRect;                               // Default position / extents of the joystick graphic
private Boundary guiBoundary = new Boundary();          // Boundary for joystick graphic
public Vector2 guiTouchOffset;                      // Offset to apply to touch input
private Vector2 guiCenter;                          // Center of joystick

private Vector3 tmpv3;
private Rect tmprect;
private Color tmpclr;

public float allowedDistance;

public enum JoystickType 
{
    movement, rotation
}

public JoystickType joystickType;

public void Start()
{
    // Cache this component at startup instead of looking up every frame    
    gui = (GUITexture) GetComponent( typeof(GUITexture) );

    // Store the default rect for the gui, so we can snap back to it
    defaultRect = gui.pixelInset;   

    if ( touchPad )
    {
        // If a texture has been assigned, then use the rect ferom the gui as our touchZone
        if ( gui.texture )
            touchZone = gui.pixelInset;
    }
    else
    {               
        // This is an offset for touch input to match with the top left
        // corner of the GUI
        guiTouchOffset.x = defaultRect.width * 0.5f;
        guiTouchOffset.y = defaultRect.height * 0.5f;

        // Cache the center of the GUI, since it doesn't change
        guiCenter.x = defaultRect.x + guiTouchOffset.x;
        guiCenter.y = defaultRect.y + guiTouchOffset.y;

        // Let's build the GUI boundary, so we can clamp joystick movement
        guiBoundary.min.x = defaultRect.x - guiTouchOffset.x;
        guiBoundary.max.x = defaultRect.x + guiTouchOffset.x;
        guiBoundary.min.y = defaultRect.y - guiTouchOffset.y;
        guiBoundary.max.y = defaultRect.y + guiTouchOffset.y;
    }
}

public void Disable()
{
    gameObject.active = false;
    enumeratedJoysticks = false;
}

public void ResetJoystick()
{
    if (joystickType != JoystickType.rotation)
    {
        //Don't do anything if turret mode
        // Release the finger control and set the joystick back to the default position
        gui.pixelInset = defaultRect;
        lastFingerId = -1;
        position = Vector2.zero;
        fingerDownPos = Vector2.zero;

        if ( touchPad ){
            tmpclr  = gui.color;
            tmpclr.a = 0.025f;
            gui.color = tmpclr;
        }   
    }
    else {
                    //gui.pixelInset = defaultRect;
        lastFingerId = -1;
        position = position;
        fingerDownPos = fingerDownPos;

        if ( touchPad ){
            tmpclr  = gui.color;
            tmpclr.a = 0.025f;
            gui.color = tmpclr;
        }
    }
}

public bool IsFingerDown()
{
    return (lastFingerId != -1);
}

public void LatchedFinger( int fingerId )
{
    // If another joystick has latched this finger, then we must release it
    if ( lastFingerId == fingerId )
        ResetJoystick();
}

public void Update()
{   
    if ( !enumeratedJoysticks )
    {
        // Collect all joysticks in the game, so we can relay finger latching messages
        joysticks = (Joystick[])  FindObjectsOfType( typeof(Joystick) );
        enumeratedJoysticks = true;
    }   

    //CHeck if distance is over the allowed amount
    //Get centerPosition

    //Get current position

    //Get distance

    //If over, don't allow

    int count = iPhoneInput.touchCount;

    // Adjust the tap time window while it still available
    if ( tapTimeWindow > 0 )
        tapTimeWindow -= Time.deltaTime;
    else
        tapCount = 0;

    if ( count == 0 )
        ResetJoystick();
    else
    {
        for(int i = 0;i < count; i++)
        {
            iPhoneTouch touch = iPhoneInput.GetTouch(i);            
            Vector2 guiTouchPos = touch.position - guiTouchOffset;

            bool shouldLatchFinger = false;
            if ( touchPad )
            {               
                if ( touchZone.Contains( touch.position ) )
                    shouldLatchFinger = true;
            }
            else if ( gui.HitTest( touch.position ) )
            {
                shouldLatchFinger = true;
            }       

            // Latch the finger if this is a new touch
            if ( shouldLatchFinger && ( lastFingerId == -1 || lastFingerId != touch.fingerId ) )
            {

                if ( touchPad )
                {
                    tmpclr = gui.color;
                    tmpclr.a = 0.15f;
                    gui.color = tmpclr;

                    lastFingerId = touch.fingerId;
                    fingerDownPos = touch.position;
                    fingerDownTime = Time.time;
                }

                lastFingerId = touch.fingerId;

                // Accumulate taps if it is within the time window
                if ( tapTimeWindow > 0 )
                {
                    tapCount++;
                    print("tap" + tapCount.ToString());
                }
                else
                {
                    tapCount = 1;
                    print("tap" + tapCount.ToString());
                    //Tell gameobject that player has tapped turret joystick
                    if (joystickType == JoystickType.rotation) {
                        //TODO: Call!
                    }
                    tapTimeWindow = tapTimeDelta;
                }

                // Tell other joysticks we've latched this finger
                foreach ( Joystick j in joysticks )
                {
                    if ( j != this )
                        j.LatchedFinger( touch.fingerId );
                }                       
            }               

            if ( lastFingerId == touch.fingerId )
            {   
                // Override the tap count with what the iPhone SDK reports if it is greater
                // This is a workaround, since the iPhone SDK does not currently track taps
                // for multiple touches
                if ( touch.tapCount > tapCount )
                    tapCount = touch.tapCount;

                if ( touchPad )
                {   
                    // For a touchpad, let's just set the position directly based on distance from initial touchdown
                    position.x = Mathf.Clamp( ( touch.position.x - fingerDownPos.x ) / ( touchZone.width / 2 ), -1, 1 );
                    position.y = Mathf.Clamp( ( touch.position.y - fingerDownPos.y ) / ( touchZone.height / 2 ), -1, 1 );
                }
                else
                {                   
                    // Change the location of the joystick graphic to match where the touch is
                    tmprect = gui.pixelInset; 
                    tmprect.x = Mathf.Clamp( guiTouchPos.x, guiBoundary.min.x, guiBoundary.max.x );
                    tmprect.y = Mathf.Clamp( guiTouchPos.y, guiBoundary.min.y, guiBoundary.max.y );

                    //Check distance
                    float distance = Vector2.Distance(new Vector2(defaultRect.x, defaultRect.y), new Vector2(tmprect.x, tmprect.y));
                    float angle = Vector2.Angle(new Vector2(defaultRect.x, defaultRect.y), new Vector2(tmprect.x, tmprect.y));
                    if (distance < allowedDistance) {
                        //Ok
                        gui.pixelInset = tmprect;
                    }
                    else {
                                                 //This is where I don't know what to do...
                    }


                }

                if ( touch.phase == iPhoneTouchPhase.Ended || touch.phase == iPhoneTouchPhase.Canceled )
                    ResetJoystick();                    
            }           
        }
    }

    if ( !touchPad )
    {
        // Get a value between -1 and 1 based on the joystick graphic location
        position.x = ( gui.pixelInset.x + guiTouchOffset.x - guiCenter.x ) / guiTouchOffset.x;
        position.y = ( gui.pixelInset.y + guiTouchOffset.y - guiCenter.y ) / guiTouchOffset.y;
    }

    // Adjust for dead zone 
    float absoluteX = Mathf.Abs( position.x );
    float absoluteY = Mathf.Abs( position.y );

    if ( absoluteX < deadZone.x )
    {
        // Report the joystick as being at the center if it is within the dead zone
        position.x = 0;
    }
    else if ( normalize )
    {
        // Rescale the output after taking the dead zone into account
        position.x = Mathf.Sign( position.x ) * ( absoluteX - deadZone.x ) / ( 1 - deadZone.x );
    }

    if ( absoluteY < deadZone.y )
    {
        // Report the joystick as being at the center if it is within the dead zone
        position.y = 0;
    }
    else if ( normalize )
    {
        // Rescale the output after taking the dead zone into account
        position.y = Mathf.Sign( position.y ) * ( absoluteY - deadZone.y ) / ( 1 - deadZone.y );
    }


}

}

So the later portion of the code handles the updated position of the joystick thumb. This is where I’d like it to track the finger position in a direction it still is allowed to move (like if the finger is too far up and slightly to the +X I’d like to make sure the joystick is as close in X and Y as allowed within the radius)

Thanks for reading!

What is an active Indie iOS development community?

| | August 7, 2015

I’ve just gotten into iOS development, and would love to develop some games, but need inspiration/support, all that stuff a great community gives you.

Does anyone know of a community to get involved with?

Promoting independent iOS games

| | August 7, 2015

Possible Duplicate:
What are effective marketing strategies for iPhone games?

I’m interested in promoting my latest iOS game. What have you done that really helped spread the word? Any smaller game review sites that were helpful? How about publishing?

Recommended hardware for developing ios games?

| | August 7, 2015

I know you have to have mac os x to use xcode and thus to develop/compile apps for the iphone. And I’m not exactly wanting to go the hackintosh way, so I’m looking at buying a used mac.

What specs are recommended. If I buy a cheap mac mini that has only 1gb of ram would that be enough? (I’m not talking about using that to create the graphics/audio, I’ll use my normal windows/ubuntu pc for that). I’m just talking about being able to use xcode and write applications.

I’m trying to spend the least amount I can without running into problems developing the app.

What are the basics in game architecture? How do you create your game skeleton such that it doesn't stay in your way?

| | August 7, 2015

There must be some best practices on how you create your game architecture/skeleton.
One of the best resources that I found is:
http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
My primely focus is for iOS games using cocos2d.

What is your know how on this topic?

Map file format for Real-time strategy game

| | August 7, 2015

I am planing to create a 2D RTS game on iPhone using cocos2d, besides the tile map, any other suggestion for storing the map details for the game?

Would be nice if a GUI editor is also provided.

Is it true that to test a game on the iPhone or iPad, we either need to pay $99 to join Apple Developer program, or jailbreak the iPad?

| | August 7, 2015

To test a program for iPhone or iPad, seems like the only way is to join the Apple Developer program and pay $99 per year? Can you also jailbreak the iPhone or iPad and be able to test it?

RTS game engine for iOS/iPhone

| | August 7, 2015

Anyone know any free or non-free RTS engine that can be used for iOS game development?