5
\$\begingroup\$

Many of the variables in my 2D mining game were declared as constants like so:

DWConstants.h

static const int kBlockSpriteWidth = 64;
static const float kBufferFactor = 2.5;
static const int kMaxBlockDamage = 3;

This was all well and good for initial testing, but I soon found out that there were quite a few variables that I wanted to be able to adjust based on what device the game was running on. I thought about a couple approaches to this, and I decided on this one. The values of the variables are set based on the memory of the device. I would love to know what you think.

DWMemoryConstants.h

#import <Foundation/Foundation.h>

@interface DWMemoryConstants : NSObject

@property int startingChunks;
@property int chunkSize;
@property int chunksToGenerate;
@property float maxZoom;

@end

DWMemoryConstants.m

#import "DWMemoryConstants.h"

@implementation DWMemoryConstants

-(instancetype) init {
    self = [super init];
    if (self) {

        unsigned long long memorySize = [NSProcessInfo processInfo].physicalMemory;
        unsigned long long memSize = memorySize/1000/1000;

        if (memSize < 256) {
            _startingChunks = 0;
            _chunkSize = 0;
            _chunksToGenerate = 0;
            _maxZoom = 0.00;
        } else if (memSize >= 256 && memSize < 800) {
            //ipod 5 is in this range
            _startingChunks = 8;
            _chunkSize = 16;
            _chunksToGenerate = 4;
            _maxZoom = 0.45;
        } else if (memSize >= 800 && memSize < 1800) {
            //ipad 4 will fall in this range
            _startingChunks = 10;
            _chunkSize = 18;
            _chunksToGenerate = 6;
            _maxZoom = 0.25;
        } else if (memSize >= 1800 && memSize < 2800) {
            //previous typical settings
            _startingChunks = 10;
            _chunkSize = 24;
            _chunksToGenerate = 8;
            _maxZoom = 0.05;
        } else if (memSize >= 2800) {
            _startingChunks = 12;
            _chunkSize = 30;
            _chunksToGenerate = 10;
            _maxZoom = 0.04;
        }
    }
    return self;
}

@end

As always, I am open to any sort of feedback about the code.

\$\endgroup\$
  • \$\begingroup\$ I have minimal Obj-C experience, but I think for a game, adding the nonatomic qualifier to the properties can actually have a performance impact. \$\endgroup\$ – glampert Oct 17 '14 at 22:24
  • \$\begingroup\$ BTW, the title doesn't quite make sense. Do you mean that your code is too slow on the iPod? Have you profiled and pinpointed the problem in the specific section? \$\endgroup\$ – glampert Oct 17 '14 at 22:26
  • 1
    \$\begingroup\$ The title means that I have to adjust certain parts of the code to get it to run efficiently on different devices. \$\endgroup\$ – bazola Oct 17 '14 at 22:27
  • \$\begingroup\$ What are the exact devices you notice the differences on? Are they both running the same OS exactly? \$\endgroup\$ – nhgrif Oct 21 '14 at 11:30
  • \$\begingroup\$ iPod5 versus iPad4 (versus macbook simulator, but that doesn't really count, although it is much faster than the first two). Not entirely sure they have the exact same OS, but they do have different amounts of memory and different processor speeds. \$\endgroup\$ – bazola Oct 21 '14 at 11:59
3
\$\begingroup\$

I think using memory size is an interesting idea. You may want to define the values with an expression (e.g. startingChunks = round(memSize / 600) * 2 + 8), rather than an else-if chain, tho if you want to target specific devices, an if-else chain is acceptable.

Old:

if (memSize < 256) {
    _startingChunks = 0;
    _chunkSize = 0;
    _chunksToGenerate = 0;
    _maxZoom = 0.00;
} else if (memSize >= 256 && memSize < 800) {
    //ipod 5 is in this range
    _startingChunks = 8;
    _chunkSize = 16;
    _chunksToGenerate = 4;
    _maxZoom = 0.45;
}
  1. Underscores are annoying, is there any reason you use them in those variable names? If it's supposed to denote constants, doesn't the name work well enough? It shouldn't be doubted that chunkSize, for instance, won't change if you know how the app works. And if in a future update you want it to change, you could change it without renaming.
  2. if (memSize < 256) {} else {} – in the else block, memSize must be >= 256. So there's really no need to add that to the else if.

With my changes:

if (memSize < 256) {
    startingChunks = 0;
    chunkSize = 0;
    chunksToGenerate = 0;
    maxZoom = 0.00;
} else if (memSize < 800) {
    //ipod 5 is in this range
    startingChunks = 8;
    chunkSize = 16;
    chunksToGenerate = 4;
    maxZoom = 0.45;
}
\$\endgroup\$
  • 2
    \$\begingroup\$ "Underscores are annoying, ... " – In Objective-C, the compiler automatically "synthesizes" instance variables for properties, these variables have an underscore prepended. So the instance variable for @property int chunkSize; is _chunkSize. On the other hand, one should not use the property accessors in the init method itself because the object is not yet fully initialized (this is not a strict rule however and discussed controversially). – So _chunkSize = 0; (with the underscore) in the init method is quite common in Objective-C. \$\endgroup\$ – Martin R Oct 18 '14 at 9:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.