Categories
computer games design games design network programming

Realm of the Mad God – a great game, interesting monetization

I’ve recently been playing the excellent Realm of the Mad God – a very fast-paced 2d co-operative shooter. My feeling is that it’s going to be one of the most important games of 2011/2012, as it continues to grow in popularity. Typical experience of this game is that within 30 seconds of being dumped into the main level, you’re surrounded by monsters, and then surrounded by other players, all on the same screen as you, blasting away in a rainbow of colours.

Sounds good. As if that’s not enough … it’s the guys who’ve been working with AmitP (Amit J Patel) (Amit maintains one of the best up-to-date collections of links and algorithms for indie game-developers). If you haven’t seen Amit’s pages, I recommend browsing through the blog – his links collection is OK, but his blog posts on algorithm design are excellent. If you get as far as the posts on “how I auto-generated a realistic 3D-world”, you may notice a striking similarity to the 2D worlds used in RotMG …

Anyway, it parallels an idea for an MMO shooter I’ve had kicking around for a long, long time. For me, it’s been a delight to see what works (and doesn’t) about the core ideas. The RotMG authors have done a great job of making a fast, simple, quick, easy-to-grasp game.

The Good

Fast. No barriers to play

This is how MMO-shooters should be: fast, furious, permadeath – but very quick to get back into the fray. You should expect to die tens of times every hour.

Permadeath – but paralled with some perma-advancement

Your progress is split evenly between items (which can be banked) and avatar stats (which are lost forever upon death).

Perma-advancement increases variety, unlocks new features

With 10 classes, there’s plenty of variety – and each class can only be unlocked by achieving a minimum level of progress with one or more other classes.

NB: this part could be improved and expanded IMHO. In particular, the classes are wonderfully varied – but merely unlocking classes isn’t enough these days. Plenty of games have shown that permanent-unlocks work best when there’s a variety of game-features in there. Also, the classes themselves would work better if there were some cross-effects (c.f. Diablo 2’s Lord of Destruction expansion, which had abilities in one class improve abilities in your older classes, re-vitalizing them for re-play)

Free game, paying is optional – payment kicks in when you’re most bought-in to the design

Free players get a tiny storage for permanent items (1/50th of what paying players get – it’s not enough! … so pay!), and are only allowed 1 class “alive” at once.

In a delicious twist, if you don’t pay for the game, the only way to take advantage of a newly-unlocked class is … to commit suicide … since you’re only allowed a single character per account (unless you pay)

You can ONLY benefit from other players, never suffer

(there’s actually a case where you can suffer, sadly – Thief’s get killed as a secondary-effect of other players teleporting to them, since the game doesn’t have a “prevent people from teleporting to me” flag)

This is the one that should have most wannabe-MMO-designers sitting up and paying attention. If you group-up with other players:

  1. You all get the same experience-points as if you’d single-handedly killed every monster
  2. You get the points just for being nearby – no need to score hits just to “tag” it for yourself
  3. Mob strength is constant, but player damage is multiplicative on number of players present

Net effect:

Every player is willing and eager (*) to collaborate with every other player, without words being exchanged, without fear of being ripped-off.

In a game that’s fast paced and frantic, you don’t have to keep pausing to negotiate. Other players can ONLY benefit you, so … run with them.

(*) – or just ignores the other players. Their presence doesn’t provide negative impact on you. It’s only their absence that is negative (in game-design terms).

Interesting design choices for lag

As a real-time game with dozens of players on screen at once, lag is guaranteed to effect gameplay. We’re always saying “try to work around lag through game-design changes”, so here’s the decisions they made:

  1. When packets are lost, everything moves in exactly the same direction it was going, at exactly the same speed, forever
  2. “Speed” used above is the “on-screen speed, including any rubber-banding effect”
    • FAIL: this means monsters and players often move MANY times faster than they are allowed to – so that when the lag stops, the side-effects are magnified
  3. Your avatar can’t be hit NOR damaged while it’s missing packets from the server
    • For the early parts of the game, this *almost* completely fixes lag problems
  4. Projectiles (bullets etc) that your client didn’t receive are queued up and sent to you all in one go once the packet-dropping stops
    • FAIL: this multiplies the damage output of enemies (NB: not players!), breaking all the designed-in balance in the game
    • In mid to late game, this ruins the gameplay – players end up running around never seeing a single enemy, because if you’re close enough to see it, a single flicker of lag will cause you to receive ZERO damage initially, followed by MORE damage than the monster is capable of – delivered instantaneously
  5. The client is authoritative on player liveness/death
    • MILD FAIL: in effect, coupled with the other features of the game, and the lack of lag compensation … this means you CAN and SHOULD (and, for some cases, effectively: MUST) cheat. You can run a bot on your machine – and if the network is less than perfect, you have to, in order to play the game properly.

Overall, apart from the massive security flaw (where anyone could write a bot to be invulnerable – and the developers are encouraging them to do so), it seems very close to a good solution for an MMO shooter.

I’m surprised by the way they approached the “save up the enemy bullets, then unleash them all at once”. My guess is that it wasn’t designed, it was just an accident: maybe they took a slightly lazy approach to compensating for lag (they don’t), and the net effect is this. It looks very much like what you get when using TCP for game-data packets (I really hope they’re not using TCP; if so, most of the lag is the developers’ own fault)

The Bad

I’ve unlocked half the classes, and looked at what classes other people play (and which classes rise high on the leaderboards). There’s good variety, and almost all the classes get used – even the beginning class, the one you get for free, works well.

Except one.

Unfortunately, at around 50% through unlocking the special classes, one of the classes is horribly unbalanced. The Assassin (which is supposedly an upgraded Thief – but is a massive downgrade) is almost impossible to play. The special ability fails completely when there’s lag (which is frequent in this game), and the class is the weakest, lowest-range of the lot. Looking around, you rarely see Assassins (I suspect: you only see them when people are desperately trying to upgrade them, to get past this dull and frustrating point in the upgrade tree).

Worse, because the *only* way to unlock the higher level classes is to reach the level cap with this class … you’re forced to play it. Over and over again. Watching the bad game-design … over and over … and over … again.

Every time the assassin dies, it’s like another twist of the knife:

We know you don’t enjoy this

We know that a mistake in our game design has you stuck here

(and our overall game design makes that “mistake” into “a disaster”)

We know that this whole process is turning “a class that wasn’t much fun” into “a class you hate”

And there’s nothing you can do about it!

So, single-handedly, it’s driven me to *not* purchase any game credit. I’d enjoyed the game enough to that point that I’d already decided to buy it – and if this had been on iTunes, I’d have paid already. But since it’s not an iPhone/iPad game, and paying for it is a bit more difficult, I hadn’t made the payment yet.

As it stands, I’m still playing occasionally, but now it’s for research rather than for enjoyment, which is a great pity.

Monetization: money thrown away

I think the developers are missing an ENORMOUSLY successful way to make money from this game. In fact, it’s so big, I suspect they could increase their revenues by a substantial multiplier.

With a permadeath game, there really is no need to actually delete the dead character. If the player isn’t paying, they are forced to kill their character sooner or later to change characters.

Taking a leaf from Flickr’s book, why not keep ONE single character in storage, with a tempting “buy now, for goodies *and to have this one returned to you, ready to play*”?

I’d set it so that when you change class (if you’re a free player), only the last character of the PREVIOUS class is retained. If you switch from Warrior to Knight, you can die many times as a Knight, and your Warrior remains on ice. But if you then grow tired of the Knight and switch to a Rogue … the Warrior is tipped out, and replaced with the last Knight you had.

i.e. you setup the exact flow of decision-making and options and “safety” that the player would have had, if only they’d purchased sooner, and allow them to benefit from it retroactively – if only they make the decision to pay.

Of course, it’s a very limited “retroactively” – it’s a sampler, to let you see the benefits of paying.

(*) – Flickr’s early promise was “upload your photos in highest resolution, you can view them for free – but only low-res versions. HOWEVER, we keep the high-res versions for you – forever, for free – until you decide to purchase a subscription. At which point, not just your new photos, but ALL your photos, become magically available at highest res”. It was a great way of simultaneously offering a high-value to paying customers, while making non-paying customers feel they weren’t committing themselves to loss. It reassured a lot of potential customers at a time when Flickr wasn’t yet famous, and most people weren’t yet “hooked” – it bridged that gap.

Analyse this

So, the interesting question is: how common is this problem?

Are the dev team correlating “players who pay” and “the point at which they pay”?

More importantly, are they correlating “players who DON’T pay” and “how their experience differed from the average”?

The last time I saw an MMO with a level-based kick in the teeth this bad … was in Tabula Rasa. We had a point where poor signposting by the quest designers meant many players were given quests that were many levels too hard for them, and effectively impossible to do. Those players died over and over and over again in a short time – and they hated it.

The dev team knew “you’re not supposed to do that quest”, but often they (randomly) gave it to new players as the first quest. I wasn’t privy to the arguments over whether this needed to be changed (and there were definitely arguments), but I did see the analytics that eventually got produced. They showed an almost perfectly smooth, averaged, graph of player behaviour – bar a big notch at this particular location. It stuck out like Rudolph’s nose on a snowy day.

I wonder if there’s a similar notch in RotMG? For a game that’s almost *designed* to drive people to rage-quit … what stats do they see on “what the last thing was before a player stopped playing forever?” … and what stats do they see on “…stopped playing for a long time, but eventually came back”?

Categories
amusing

What google.com would look like … designed by a GeoCities user

http://wonder-tonic.com/geocitiesizer/content.php?theme=2&music=1&url=google.com

(see what I did there? topical music + animated gif combo!)

Categories
amusing

Cloud Computing: Google Translate has stopped speaking Chinese, and we can’t get it back

Finally, I worked out how to type pinyin on a mac, using only the keyboard.

Nǐ hǎo!

Only, GoogleTranslate acts like a prick, and pretends it has no idea what you’re saying. This, Google, is just silly:

(for comparison, I tested – if you hit the “switch” button, and type “Hello”, you can copy the output, hit switch again, and Google still pretends you’re talking gibberish)

To add insult to injury, if you don’t manually hit the “Turn OFF instant translate”, it keeps manually switching the From language … to English. Every time you type a letter, it reverts to “English –> English”. HOW MANY WORDS IN ENGLISH EVER USE ACUTE, GRAVE, OR CIRCUMFLEX? Sigh. Not very smart.

Worst bit is … this was working fine a couple of months ago. Then Google “rewired it”, and now it’s broken. My friends at Google say this (constantly breaking things, never letting the user keep a working version) is “good” and “the future” because it puts control into Google’s hands: one version, on all desktops. If this is the future of Cloud Computing, Cloud Computing is dead and buried already… Version control is not a “feature”, it’s a right.

Categories
computer games games design games industry games publishing iphone

TCE iPhone Games by Indie (and mainstream) Game Professionals

TheChaosEngine – private forums hangout for games-industry professionals. There’s an epic thread on there where people post projects they / their team / their employer has published on iPhone. It’s currently 40 pages long, so I went through and pulled out the links to the iTunes pages for each game.

NB: these run the gamut from “my first iPhone app” to “large-team of developers working for multinational publisher”. Quality here will vary hugely – YMMV!

Also, interesting to note … these are listed in order of posting to the forums, so … as you go down the list, you’re seeing an evolution over time of personal/indie (and occasionally “big team / AAA”) games on the app store.

TCE games, in first-launched order (earliest first)

  1. http://toucharcade.com/2008/12/12/ivory-tiles-a-unique-iphone-puzzle-game/
  2. http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=298060143&mt=8
  3. http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=289208006&mt=8
  4. http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=303057162&mt=8
  5. http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=305889055&mt=8&s=143441
  6. http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=307740243&mt=8
  7. http://zenbound.com/itunes
  8. http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=307117698&mt=8
  9. http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=311115651&mt=8
  10. http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=318996099&mt=8&s=143441
  11. http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=317781445&mt=8
  12. http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=321510472&mt=8
  13. http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=323694495&mt=8
  14. http://bit.ly/ifistchaosengine
  15. http://appshopper.com/utilities/isundial-2
  16. http://bit.ly/qqq_iphone
  17. http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=333962577&mt=8
  18. http://itunes.com/app/Coretex
  19. http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=334682266&mt=8
  20. http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=334683021&mt=8
  21. http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=335955369&mt=8
  22. http://tinyurl.com/yc9bpr5
  23. http://itunes.apple.com/us/app/revz/id352513901?mt=8
  24. http://itunes.apple.com/gb/app/fm-2010/id352933624?mt=8
  25. http://itunes.apple.com/gb/app/koan/id366816832?mt=8
  26. http://itunes.apple.com/us/app/tiki-towers/id298127125?mt=8
  27. http://ultrablast.net/
  28. http://bit.ly/aurifi_itunes
  29. http://itunes.apple.com/gb/app/denki-blocks/id371685186?mt=8
  30. http://bit.ly/yatr_iphone
  31. http://bit.ly/qqq_worldfoot
  32. http://itunes.apple.com/au/app/gamebook-adventures-2-the/id375065935?mt=8
  33. http://itunes.apple.com/app/id356565414?mt=8
  34. http://itunes.apple.com/app/reckless-racing/id386234787?mt=8
  35. http://itunes.apple.com/gb/app/tiltstorm/id392545121?mt=8
  36. http://itunes.apple.com/us/app/awakening-the-dreamless-castle/id386161821?mt=8
  37. http://itunes.apple.com/au/app/gamebook-adventures-1-an-assassin/id352871101?mt=8
  38. http://itunes.apple.com/au/app/gamebook-adventures-4-revenant/id395652668?mt=8
  39. http://itunes.apple.com/gb/app/cricket-captain-2010/id406333955?mt=8
  40. http://itunes.apple.com/us/app/pocket-frogs/id386644958?mt=8&partnerId=30&siteID=0JkCNyaaKoo
  41. http://itunes.apple.com/us/app/sky-burger/id311972587?mt=8&partnerId=30&siteID=0JkCNyaaKoo
  42. http://itunes.apple.com/us/app/scoops-ice-cream-fun-for-everyone/id291591378?mt=8&partnerId=30&siteID=0JkCNyaaKoo
  43. http://itunes.apple.com/us/app/dizzypad-frog-jump-fun/id357104694?mt=8&partnerId=30&siteID=0JkCNyaaKoo
  44. http://itunes.apple.com/us/app/textropolis/id301643671?mt=8&partnerId=30&siteID=0JkCNyaaKoo
  45. http://itunes.apple.com/gb/app/kamicrazy/id299644692?mt=8
  46. http://itunes.apple.com/us/app/bubble-dreams/id400309976?mt=8&ls=1
  47. http://itunes.apple.com/au/app/gamebook-adventures-5-catacombs/id422246290?mt=8
  48. http://itunes.apple.com/gb/app/family-games/id417601428?mt=8
  49. http://itunes.apple.com/gb/app/moving-day/id395714931?mt=8&ign-mpt=uo%3D4
  50. http://itunes.apple.com/gb/app/to-fu-the-trials-of-chi/id436987555?mt=8
  51. http://itunes.apple.com/gb/app/bashi-blocks/id441051678?mt=8
  52. http://itunes.apple.com/gb/app/magnetic-billiards-blueprint/id432152950?mt=8
  53. http://itunes.apple.com/au/app/specky-mark-of-the-year/id458244379?mt=8
  54. http://itunes.apple.com/gb/app/quarrel-deluxe/id453203047?mt=8
  55. http://itunes.apple.com/us/app/death-at-fairing-point-a-dana/id445507820?mt=8
  56. http://itunes.apple.com/us/app/lap-uranus/id447548601?ls=1&mt=8
  57. http://itunes.apple.com/app/cutesy-the-quest-unicorn/id463920538?mt=8
  58. http://itunes.apple.com/app/funpark-friends/id444438531?mt=8
  59. http://itunes.apple.com/gb/app/myragdoll-3d/id444210353?mt=8
  60. http://itunes.apple.com/gb/app/puzzler-world-2/id465620717?mt=8
  61. http://itunes.apple.com/app/shark-jug/id473563382
  62. http://itunes.apple.com/au/app/mini-motor-racing/id426860241?mt=8
  63. http://itunes.apple.com/gb/app/grabatron/id481309065?mt=8
  64. http://itunes.apple.com/us/app/leapin-frogs/id487318065?mt=8
  65. http://itunes.com/apps/gravityrocks
  66. http://itunes.apple.com/app/puzzle-bonsai/id491318778?mt=8
  67. http://bit.ly/lighthousegame
  68. http://itunes.apple.com/us/app/my-coin-match/id472717295?mt=8
  69. http://itunes.apple.com/gb/app/froad/id469021974?mt=8
  70. http://j.mp/EufloriaHD
  71. http://itunes.apple.com/us/app/end-night-hd/id498102948?ls=1&mt=8
  72. http://smallgreenhill.com/ballonawall/index.php
  73. http://itunes.apple.com/us/app/rune-raiders/id497702195?mt=8

Non-chronological

These posters didn’t provide a real iTunes link – I had to hunt it down on their websites – so they’re out of order:

  1. http://itunes.apple.com/us/app/ax-raven-elite/id331999733?mt=8
  2. http://itunes.apple.com/us/app/red-card-rampage/id388957922?mt=8
  3. http://itunes.apple.com/us/app/wordsnap-contraption/id412453514?mt=8&ls=1
  4. http://bit.ly/zSf5vc
Categories
iphone programming

Firefox Auto-restore (after a crash): Impressive stuff

For a couple of years now, Firefox has had a nifty feature where if it crashes – for ANY reason – the next time you run it, it gives you a “menu” of the windows you had open, and lets you selectively re-open them. As a bonus, this menu is just a plain window – you can ignore it (if you’re too busy right now), and open some other windows in parallel.

(even if it’s not Firefox that crashed – e.g. a laptop battery ran out, or someone tripped over your power cable – you still get this window. This is a huge help on OS X, which crashes quite a lot if you’re running Apple’s dev tools :))

I’d wondered a few times “what happens if it crashes again, before you’ve selected which things from that menu you want to re-open?”

I just found out the hard way: actually, it gives you a new menu, where one of the items is … the previous menu. It nests, all the way down (I had a crash-of-a-crash-of-a-crash – and I got everything back perfectly. Very useful, too – one of the deeply nested open windows was an important form I’d forgotten I’d not yet sent).

On the downside, if you close Firefox, and re-open it normally, the menu gets blown away – but that’s probably to do with the “five-years-and-counting still unfixed” bugs in Firefox where “remember open windows on startup” doesn’t work properly (there’s some epic threads in their bug tracker, many complaints, but no fix yet).

Still, for the most part, this is a very nice approach to application-crashing. One to remember when designing your own document-based applications…

Categories
entity systems games design programming

Entity Systems: what makes good Components? good Entities?

In the ongoing, epic comments (300+ and counting!) for my Entity Systems posts, one of the recurring questions is:

What makes a good Component?
How should I split my conceptual model into Entities and Components?
How should I split my algorithms and methods into Systems?

It’s often difficult to answer these questions without concrete examples, which are thin on the ground.

Good news, then…

Paul Gestwicki runs a CS315: Game Programming course, and last year his students used an Entity System to implement their game – Morgan’s Raid. In a recent email conversation, he mentioned he’d been monitoring the actual number – and nature – of the Components and Systems that the teams developed and used on the project.

He’s now posted this list, along with some brief analysis.

All systems and Components

Read Paul’s post – there are some caveats he mentions, and there’s a useful diagram showing roughly how many systems were using each component.

I strongly recommend you play the game too (it’s free, and quick to play) so you can get an idea straight away – just from the names – what data and code some of these contain.

To recap, here’s the list:

“For your reading convenience, here’s a simple tabular view of the systems and components

Systems Components
BackgroundTileSystem
CityNameSystem
DestinationSystem
FadingSystem
GPSToScreenSystem
HoverableSystem
ImageRenderingSystem
IntInterpolationSystem
MinimumSleepTimeSystem
MorganLocationSystem
NightRenderingSystem
OnClickMoveHereSystem
OnScreenBoundingBoxSystem
RaidSoundSystem
RailwaySystem
ReputationSystem
RevealingTextSystem
SpeedSystem
StepwisePositionInterpolationSystem
SunSystem
TimePassingSystem
TimeTriggeredSystem
TownArrivalSystem
TownArrowSystem
TownUnderSiegeSystem
AnimationRenderable
ArrivesAtTownIndex
BackgroundTile
BeenRaided
CentersOnGPS
CityData
CityImages
CityName
CityPopulation
CityTargets
CommandPoint
Destination
DoesCityHaveMilitia
DoesCityLoseGame
DoesCityWinGame
GPSPosition
GPSPositionList
HasMorganGPS
Hoverable
ImageRenderable
ImageRenderLayer
InGameTime
IntInterpolated
MinimumSleepTimeOverride
Morgan
MorganLocation
MovesOnClick
OnClickMoveHere
OnScreenBoundingBox
OnScreenBoundingBoxList
PositionInterpolated
Raidable
Raider
Railway
Reputation
ReputationValue
RevealingText
Road
RoadsToCity
RouteTaken
Speed
Sun
Terrain
TimeToRaid
TimeTriggeredEvent
TownAdjacency
TownArrow
TownUnderSeige

Things I noticed straight away:

  1. There’s approximately 2:1 ratio of “components” to “systems”
  2. In Paul’s post, all the Systems are accessing *something*
  3. In Paul’s post, quite a few Components are NOT accessed
  4. A couple of components are used by almost every System
  5. The names of some Systems suggest they’re very trivial – perhaps only a dozen lines of effective code
  6. The names of some Components suggest they’re being designed in an OOP hierarchy

NB: I haven’t had time to look at the source code, but it’s freely downloadable here, so I’d recommend having a look if you have time.

How many Components per System?

I’ve generally started people off with: “aim for 1:1 ratio”. This is mainly to kick them out of the traditional class-based OOP mindset. In practice, there’s really no need to stick to that religiously – once you get the hang of ES design, you should be freely adding and subtracting components all over the place.

In reality, the pressures on “number of systems” and “number of components” are independent. Ideally, you add a new system when you have a major new concept to add to your game – e.g. “previously I was using hand-made jumping, now I want to add a complete physics-driven approach. This will mean changing collision-detection, changing the core game-loop, etc”.

Ideally, you add a new component when you have a new “dimension” to the game objects. For instance, if you’re adding a physics System, you may not need to add any new Components – it might be that all you need is Location (containing x,y,x position and dx,dy,dz velocity) and RenderState (containing screen-pixels x,y) – and that you already have those components.

Zero systems per component

One of the advantages of an ES is that old code can just fall off the radar and disappear. So I’m not surprised at all to see some components that appear to be unused – and it’s MUCH easier to simply delete this code from your project than it would be on a traditional OOP project. Does anything reference that data? If so, it’s a set of particular systems. For each system, you can look at MERELY the system and the component, and make a very quick decision about whether you still need this access – or if you can refactor to move (some of) it somewhere else. The amount of code you need to read to make such decisions safely is typically very small – i.e. easy, quick, and less error-prone.

Many systems per component

This is fine. However, it can also be an early-warning sign of a design or code-architecture bug. Sometimes, there are components that – innately – are just needed all over the place. For instance, in a team-based game, the component saying which “team” a given object/player/item/building belongs to is likely to affect almost every piece of algorithm code across the board. It’ll be referenced by many systems.

On the flip-side, it may be a sign that you’ve put too much data into one component. There are two usual versions of this:

  1. You have – say – 8 variables in the struct where you should instead have two structs (components), one with 5 variables, the other with 3.
  2. You have – say – 4 variables in the struct, but different systems are using those variables to mean different things. It works OK for now, but it’s very fragile – as soon as the different meanings diverge even a little, your code is going to start breaking

Of course, you get this exact problem in traditional OOP setups, but with an ES it’s trivial to fix. Split – or duplicate – the Component, change a few references in the Systems, and you’re done. If it turns out a week later that the split wasn’t necessary – or worse, was a step backwards (e.g. you find yourself frequently synching the data between those components) – it’s extremely cheap to swap it back.

By contrast, with OOP, this is a nightmare scenario, because you have to worry about every method on the original class. Does that method:

  1. Need to exist on both the new classes, or just one?
  2. Work correctly for the new class it will be on – or does it currently rely on some of the data (and shoudln’t) and will need to be re-written?
  3. Get used by other parts of the codebase in ways that will break if/when you split the class?

Thoughts, Suggestions?

…this is just a lightning quick analysis, but I strongly invite you to do you own digging into the classes – and the codebase – and come up with your own thoughts and feedback. We have here a convenient, real-life, list of components/systems – something to dig our teeth into, and debate the rights and wrongs of each decision. And I’m sure the students involved on the project would be interested in your feedback on their approaches :)

Did this post help you?

Support me on Patreon, writing about Entity Systems and sharing tech demos and code examples

Categories
iphone programming

2 reasons to beware Apple’s NSDictionary, and CoreData

Ever seen this hard to notice bug in an iPhone / Mac project? Caused by a flaw (bug?) in Apple’s own API:

NSDictionary * map;

NSObject * key;
NSObject * value;

// NB: next line will frequently crash at runtime
// …but even if doesn’t crash, it probably won’t do
// what you’d expect it to:
[map setObject:value forKey:key];

if( value != [map objectForKey:key] ) // HA!
{
NSAssert( 1 == 0, @”What the **** just happened??” );
}

NSDictionary is one of the nastier things I’ve seen in a programming language: in an Object-Oriented Language, it’s a class that refuses to take Objects as arguments, *but pretends to*. If you attempt it, it either crashes, or it invalidates your objects, breaking contracts all over the place.

ObjC’s bizarre design

In the days pre-OOP, a “dictionary” was something that mapped:

“a string”
to
“anything” (usually: basic datatypes – e.g. strings, integers, floats, etc).

In the days of OOP, the same thing is usually called a “map” (which is a better term) – although the terms are synonymous – and maps:

“an object”
to
“another object”

What did Apple/NextStep/Crazy-Guys-Behind ObjC do?

NSDictionary: maps:

“STRINGS ONLY” (no objects allowed!)
to
“OBJECTS ONLY” (no core datatypes allowed!)

But … I can use an NSObject as key?

Yep – but Apple’s internal implementation takes a *copy* of the object, and uses that as a key – rather than using the object that you gave it. This is a common problem in OOP languages and implementations of Map – e.g. Java does the same thing.

Unfortunately, this means that you can call “setObject:forKey:”, and then “objectForKey:” will return nil *for the same key*.

In Java and other OOP languages, you are required to implement a custom “isObjectEqualToObject” method. In ObjC too – except that that method is ILLEGAL if you’re using CoreData.

And ObjC will crash too, as a bonus

I’ve never seen this in other OOP languages, but in ObjC *additionally*: if you don’t manually add to the object you pass-in … it crashes at runtime. Yay!

How come? AFAICT, Apple’s header file is wrong:

– (void)setObject:(id)anObject forKey:(id)aKey // You lie!

it seems the implementation of that method is:

– (void)setObject:(id)anObject forKey:(id<NSCopying>)aKey; // the correct signature?

Net result? Code that happily compiles … will crash. ARGH!

Two reasons to beware…

…so what’s the other one?

Ah, just the one we see again and again on live projects, wasting hours and hours of time:

NSDictionary* dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
object1, key1,
object2, key2,
nil];

NSLog( @”dictionary = %@”, dictionary ); // but it only has one key/value pair. ?!?!?

Ah, well … that nil … what happens when object2 is nil? Oh, damn.

What about if key2 is nil? Now we’re really nasty … we’ve given it “half” of key/value pair. Nice!

Categories
programming

GitHub for Mac: don’t use it :(

It looked so good, finally – a decent Git client for Mac.

But, no. It just – simply – doesn’t work (version 1.2.1). Great for browsing, but sometimes you simply can’t commit changes to a repository! (a few hours earlier, it was committing fine. Nothing had changed in the meantime)

And what do you get as an error, when you try?

“A git error occurred.”

Seems the folks at GitHub know this is unacceptable. Because they also put a message onto the (invisible) system console:

-[GHErrorSheetController presentWithError:] [Line 84]
Presenting with error, but let’s do better guys: Error Domain=GHGitControllerErrorDomain Code=556 UserInfo=0x117f63fa0 “A git error occurred.”

For the record, there was nothing wrong, and no errors – all other clients worked fine. So it’s probably an internal problem with GitHub’s code. They know it’s a problem (they wrote an error for it) but they won’t tell you what that problem is. Classy :)

Categories
amusing marketing and PR programming security server admin system architecture web 2.0

Ruby on Rails dead. All sites p0wned. GitHub shoots the messenger?

Two things here: if you run any Rails site, check out the security hole ASAP if you haven’t already. You might be safe – but given that even GitHub wasn’t, I’d double check if I were you. (The Rails community seemingly isn’t patching it – and there’s nothing recent on the Security list. Which leaves me going: WTF? The evidence is right there on GitHub of how bad this is right now, in the wild).

Secondly … what just happened? Apart from doom and gloom and “the end of every unpatched Rails site on the planet”, there’s a fun story behind this one. As someone put it “it’s the whitest of white-hat attacks” (i.e. the “attacker”‘s motives appear extremely innocent – but foolish and naive)

It seems that GitHub got hit by the world’s nastiest security hole, in Rails – trivial to take advantage of, and utterly lethal. The hole appears to allow pretty much anyone, any time, to do anything, anywhere – while PRETENDING to be any other user of the system. So, for instance, in the attack itself, someone inserted arbitrary source code into a project they had no right to.

Hmm. That’s bad. It effectively destroys GitHub’s entire business (it’s already fixed, don’t worry)

But it gets worse … it’s a flaw in the RoR framework, not GitHub itself (although apparently GitHub’s authors were supposed to know about the flaw by reading the Rails docs, as far as I can tell from a quick glimpse at the background). Rails authors have (allegedly) known about it and underestimated how bad it is in the wild, and left Rails completely open with zero security by default.

So, allegedly, the same attack works for most of the web’s large Web 2.0 sites – any of them that run on Rails.

WTFOMGBBQ!

Who was the perpetrator of this attack? Ah, well…

made an impossible issue, a post that GitHub’s database believed was created 1,000 years in the future.

Classy. Dangerous (high risk of someone calling the police and the lawyers), but if people won’t believe you, and *close* your issues, claiming it’s not that important, what more amusing way to prove them wrong?

Whoops, shouldn’t have done that

I can’t state this strongly enough: never attack a live system. Just … don’t.

Any demonstration of a security flaw has to be done very carefully – people have been arrested for demonstrating a flaw allegedly *at the owner’s request*, because under some jurisdiction’s it’s technically a crime even if you’re given permission. In general, security researchers never show a flaw on a real system – they explain how to, and do it on a dummy system, so no-one can arrest them.

(why arrest the researcher? Usually seems to be no reason beyond ass-covering by executives and lawyers, and a petty vindictiveness)

Homakov appears to have been ignorant of this little maxim, hence I’m writing it here, let as many people as possible know: never attack a live system (unless you’re very sure the owners and the police won’t come after you)!

GitHub’s response

On the plus side, they fixed it within hours, on a weekend. And then proceeded to tell every single user what had happened. And did so in a clever way – they put a block on all GitHub accounts that practically forces you to read their “here’s what happened, but we’ve fixed it” message. They could have kept it quiet.

Which is all rather wonderful and reassuring.

On the minus side, IMHO they rather misrepresented what actually happened, portraying it more as a malicious attack, and something they fixed, rather than what it was – the overspill from an argument between developers on some software that GitHub uses.

And they initially reported they’d “suspended” the user’s account. Normally I’d support this action – generally it’s a bad idea to let it be known you’ll accept attacks and not fight back. But in this case it appears that GitHub didn’t read the f***ing manual, and the maintainers apparently (based on reading their tickets on the GitHub DB) refused to accept it was a serious problem – and apparently didn’t care that one of their own high-profile clients was wide open and insecure. The attack wasn’t even against GitHub per se – it was against the Rails team who weren’t acting. IF it had e.g. been a defacement of GitHub’s main site, that would have been different, both in impact and in intent. Instead, the attack appears to be a genuinely dumb act by someone being naive.

Seems that GitHub agreed – although their reporting is a bit weak, it happened days ago, but they never thought to edit any of their material and back-link it.

“Now that we’ve had a chance to review his activity, and have determined that no malicious intent was present, @homakov’s account has been reinstated.

…and it’s pleasing to see that their reaction included a small mea culpa for being unclear in what they expect (although anyone dealing with security ought to be aware of this stuff as “standard practice”, sometimes it’s not security experts who find the holes):

“We haven’t been as clear as we should have been on how to responsibly disclose security problems, and for that I’m sorry. To prevent future confusion about security-related account suspension, and to make explicit our stance on responsible disclosure, we have added a section entitled Responsible Disclosure of Security Vulnerabilities to our Security policy.”

Rails’s response

I’d expect: shame, weeping, and BEGGING the web world to forgive their foolishness. I’m not sure, but it’s going to be interesting to watch. As of right now, the demo’s of the flaw are still live. I particularly like one commenter’s:

drogus closed the issue 5 days ago

kennyj commented

5 days ago

“I’m closing it (again).
@drogus was close it, but it still open.
github bug?”

Closed

kennyj closed the issue 5 days ago

“github bug?” LOL, no – massive security flaw :).

Categories
agile programming

Awesome GIT client for Mac

I’ve only played with this for a few minutes, but so far it seems to have an excellent, simple, clear GUI with the core features I’d expect. Way better than any other Git client I’ve seen for Mac. And it’s free!

GitHub for Mac v1.2.1 (NB: works with any Git server, not just GitHub.com!)

I’ve noticed some cosmetic bugs – e.g. it renders all the user-account avatars completely wrong (puts wrong image next to each commiter) – so I’d advise “use this with caution” until you’re sure it’s got no fatal bugs. Although, since it’s from GitHub.com, I expect it’s pretty robust.

Categories
amusing MMOG development network programming programming system architecture

Mongo DB is WebScale. MySQL is not WebScale.

There’s good reasons for adopting Mongo, I’m unconvinced (but open-minded) that performance is one of them. Here’s a ROFLMAO viewpoint on it:

“If your write fails, you’re ****ed”

Obviously, MySQL’s not perfect, but in most cases I’ve seen, it’s been lack of competence on the developer side, and the lack of basic DBA skills – not problems with MySQL itself – that’s broken scalability. In which case, I’m a little suspicious that a company that fails to scale MySQL will equally fail to write their code correctly on Mongo. In many ways, throwing away SQL makes it much easier to prevent scalability…