Android App – “Random Adventure”

It’s no secret that I’m a fan of old-school ASCII rouguelikes, I run a UnNethack server – guis.es. Being on the android binge that I’m currently enjoying I decided to have a play with one of these from the play store. I stumbled upon “Random Adventure” and damn I was impressed, it’s awesome. Here is the official site with a link to the reddit and a way to donate. It’s being developed by one person, so if you are they and reading this.. cudos, great game!

So lets get down to it, the fun stuff. Quite a few issues with this app, the most basic being debugging being enabled, and wow there’s a lot of stuff being debugged, probably helps a lot when coding the game:

debugging enabled

Next up, storage… nicely done in easy to read/edit text files.. most of the data is in JSON format. With this you can edit the current map, monsters, names, quests and of course all of your player stats:

playerinfo

Of course I couldn’t help myself:

modified char

Lastly I decided to have a look at the code.
No proguard or obfuscation etc, awesome, that’s what I like to stumble into.

There wasn’t much to really play with here, can change how the game works, make killing a low level give loads of XP, start location, names of plants/monsters/pets… not having any kind of online component I wasn’t expecting to find much.

I did however find what pentesters would call “developer code left in production environment” or gamers would call “cheat codes”. as follows:

if (paramString.equalsIgnoreCase("archibug"))
      {
        this.player = new Player(this, "Archibug", paramIsland);
        this.player.setLevel(100);
        this.player.setMaxItems(120);
        this.player.setGold(10000000);
        this.player.setBaseAttack(66 + this.startingAttack);
        this.player.setDefense(33 + this.startingDefense);
        this.player.setBaseSpeed(10 + this.startingSpeed);
        this.player.checkAddItem(new Boat(this.main));
        this.player.checkAddItem(new Boat(this.main));
        for (int i = 0; i < 50; i++)
          this.player.checkAddItem(new Orb(this.main));
        this.player.checkAddItem(new Gem(this.main));
        this.player.checkAddItem(new Backpack(this.main, 100));
        this.player.checkAddItem(ItemGenerator.generateRandomWeapon(this.main, 98));
        this.player.checkAddItem(new Armor(this.main, 98, OreType.DIAMOND, ArmorType.BODY));
        this.player.checkAddItem(new Armor(this.main, 98, OreType.DIAMOND, ArmorType.FEET));
        this.player.checkAddItem(new Armor(this.main, 98, OreType.DIAMOND, ArmorType.HANDS));
        this.player.checkAddItem(new Armor(this.main, 98, OreType.DIAMOND, ArmorType.HEAD));
        this.player.checkAddItem(new Armor(this.main, 98, OreType.DIAMOND, ArmorType.LEGS));
        this.player.checkAddItem(new Armor(this.main, 98, OreType.DIAMOND, ArmorType.NECK));
        this.player.checkAddItem(new Armor(this.main, 98, OreType.DIAMOND, ArmorType.RING));
        this.player.checkAddItem(new Armor(this.main, 98, OreType.DIAMOND, ArmorType.RING));
        this.player.addSkill(SkillGenerator.generateConsiderSkill(this.main, 1));
        this.player.addSkill(SkillGenerator.generateWeatherSkill(this.main, 1));
        this.player.addSkill(SkillGenerator.generateInvisibleSkill(this.main, 1));
        this.player.addSkill(SkillGenerator.generateVisionSkill(this.main, 1));
        this.player.addSkill(SkillGenerator.generateFireCampSkill(this.main, 1));
        this.player.addSkill(SkillGenerator.generateSenseDangerSkill(this.main, 1));
        Ability localAbility = new Ability(this.main, AbilityType.BUTCHER_MONSTER);
        localAbility.setLevel(9);
        localAbility.setExperience(198);
        localAbility.setExpToNextLevel(Experience.getAbilityProgressNeeded(localAbility));
        this.player.addAbility(localAbility);
        this.player.setMaxItems(10);
        this.main.makeToast("Archibug mode enabled!");
      }
      else if (paramString.equalsIgnoreCase("archi50"))
      {
        this.player = new Player(this, paramString, paramIsland);
        this.player.setLevel(50);
        this.player.setGold(100000);
        this.player.setBaseAttack(25 + this.startingAttack);
        this.player.setDefense(15 + this.startingDefense);
        this.player.setBaseSpeed(10 + this.startingSpeed);
        this.player.checkAddItem(new Armor(this.main, 49, OreType.BRONZE, ArmorType.BODY));
        this.player.checkAddItem(new Armor(this.main, 49, OreType.BRONZE, ArmorType.FEET));
        this.player.checkAddItem(new Armor(this.main, 49, OreType.SILVER, ArmorType.HANDS));
        this.player.checkAddItem(new Armor(this.main, 49, OreType.BRONZE, ArmorType.HEAD));
        this.player.checkAddItem(new Armor(this.main, 47, OreType.STONE, ArmorType.LEGS));
        this.player.checkAddItem(new Armor(this.main, 48, OreType.GOLD, ArmorType.NECK));
        this.player.checkAddItem(new Weapon(this.main, 48, OreType.SILVER, WeaponType.SWORD));
      }
      else if (paramString.equalsIgnoreCase("archi100"))
      {
        this.player = new Player(this, paramString, paramIsland);
        this.player.setLevel(100);
        this.player.setGold(500000);
        this.player.setBaseAttack(50 + this.startingAttack);
        this.player.setDefense(30 + this.startingDefense);
        this.player.setBaseSpeed(20 + this.startingSpeed);
        this.player.checkAddItem(new Armor(this.main, 99, OreType.BRONZE, ArmorType.BODY));
        this.player.checkAddItem(new Armor(this.main, 99, OreType.BRONZE, ArmorType.FEET));
        this.player.checkAddItem(new Armor(this.main, 99, OreType.SILVER, ArmorType.HANDS));
        this.player.checkAddItem(new Armor(this.main, 99, OreType.BRONZE, ArmorType.HEAD));
        this.player.checkAddItem(new Armor(this.main, 99, OreType.STONE, ArmorType.LEGS));
        this.player.checkAddItem(new Armor(this.main, 99, OreType.GOLD, ArmorType.NECK));
        this.player.checkAddItem(new Weapon(this.main, 98, OreType.SILVER, WeaponType.SWORD));
      }

For those that don’t understand this, when you start a new game you get to give your player a name. If you name them either “archibug”, “archi50” or “archi100” your character will start with various perks.

Archibug – The most powerful with level 100, 120 max items, 10000000 gold, decent attack (66), defence (33) and speed (10) along with awesome armour and loads of “orbs”
Archi50 – player starts at level 50 with 100000 gold, average attack (25), defence (15) and speed (10) stats and mediocre armour
Archi100 – level 100, 500000 gold, 50 attack, 30 defence and 20 speed with the same armour as “Archi50” but better with stats.

Yes in the code there is a boolean flag to disable ads, which I presume is the difference between the free and paid for versions. but don’t do that, the game is awesome and we should support solo devs like this.

I hope people found this interesting or useful. The game really is awesome, I’d recommend downloading it at the least, and if you like it please do donate to the dev or buy the paid-for version.

One thought on “Android App – “Random Adventure”

Leave a Reply