• Register

The world of Let Thrones Beware is yours to conquer. Occupy countries, seize planets, dominate solar systems, and expand your sphere of influence across galaxies. Unlock a detailed technology tree containing hundreds of unique items that provide meaningful contributions to the progress of your society. Deploy your forces to conquer enemy territory and occupy their cities. Expand your reach to the stars and seize what is rightfully yours. Combine technologies to design and produce weapons of war based on your priorities.

Post article RSS Articles

Welcome to part two of our code review - in which we start to tackle the substantive problems of implementing hex-based combat. We'll do this in two steps: firstly, we'll take stock of what currently exists by examining how the code-base currently generates terrain and going over how it's stored in the database. Secondly, we'll begin implementation - by developing a new database architecture.

Part One
When we find ourselves in a campaign, one of the first things we need to do is initialize a battlefield for the troops to fight over. In the current implementation, battlefields are transitory creatures; they're created for a campaign and discarded when combat finishes.

  // Establish Battlefield
  $battlefield = $this->New_Battlefield( $gamedata[ 'field_length' ], $gamedata[ 'field_width' ] );

That's a pretty simple implementation, isn't it? Hooray for easy to remember. Let's delve deeper and see what this does for us!

  // This method creates a battlefield array $length by $width elements
  //
  // Composition (array)
  //    - 'terrain' => terrain type
  //    - 'side' => side
  //    - 'army' => army
  //    - 'division' => division
  private function New_Battlefield( $length, $width )
  {
    $rv = FALSE;
    $battlefield = array();

    for( $i = 1; $i < $length; $i ++ )
    {
      for( $j = 1; $j < $width; $j ++ )
      {
        $battlefield[ $i ][ $j ] = array( 'terrain' => 0, 'side' => NULL, 'army' => NULL, 'division' => NULL );
      }
    }

    $rv = $battlefield;

    return $rv;
  }

Okay! So ... that's it. It spins up a multi-dimensional array containing essentially a bunch of nulls, and that's it. How groundbreaking and innovative.Well, if there's nothing more here, let's check out the database and see what interesting things we can find.

CREATE TABLE IF NOT EXISTS `campaign_logging` (
...snip...
  `position_length` tinyint(3) unsigned DEFAULT NULL,
  `position_width` tinyint(3) unsigned DEFAULT NULL,
...snip...
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=99991 ;

Alas, my secret shame. The battlefield is a simple x,y coordinate for tracking division positions during combat. There's no greater purpose, and there's no differentiation between terrain types. City icons are pasted into the display algorithm and have little consequence to the battle. It's all a big to-do about nothing!

Part Two
Fortunately, since the whole point of this exercise is to improve upon the existing feature-set, we're in a good place to make up for past mistakes.

Let's start by talking goals. Obviously, we want to make things better through redesign, so what are things that we can do?

  1. For starters, by stuffing the battlefield into a database in between combat rounds (and by that I mean storing more than x,y coordinates for armies), we can make the battlefield persistent during a campaign. Duels between divisions could blow holes in the ground (granting moving penalties and cover bonuses, for example), and destroyed divisions could leave wreckage on the battlefield.
  2. Right now battles are strictly two-army affairs. By reworking the map into a hex grid, we could theoretically support up to six opposing sides (or armies) at once! That would make for a much more interesting and dynamic combat experience, especially when you start to consider alliance versus alliance battles and other interesting slugfests.
  3. If we've got a persistent battlefield stored in the database, what else can we do with it? Well, since battles occur at nodes, and cities are built at the very same nodes, we can link the two together, so that cities are accurately depicted on the battlefield. This might be fun for a couple reasons - players will have to think about the tactical considerations of where to place their buildings, it would help unify the game into one organic unit rather than a bunch of disconnected pieces, and the battles of yesteryear would be splashed across the ground like some sort of macabre history text.
  4. What's more, if we link node and battlefields together, we can start to much about with point-specific terrain and climate. There's no reason that every battlefield needs to be a lush meadow when it could just as easily be mountainous terrain or a nightmarish swamp. I could also rethink how the resource system is implemented and have each game predetermine what resource exists at each node, rather than having players pick when they colonize; this would certainly make some nodes more strategically valuable than others, and hopefully provoke a an interesting expansion dynamic.

This is a pretty awesome list of advantages over the current system, so let's forge ahead! I'm basing a lot of the mechanics on a series of excellent posts made by Amit over at Red Blob Games (Here's a crazy coincidence - Amit wrote the BBS game Solar Realms Elite, that game's successor, Barren Realms Elite was the game that originally inspired me to start game design)This will be how do I define the data structure we will use:

CREATE TABLE `planet_node_hex` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`node_id` INT UNSIGNED NOT NULL ,
`x` TINYINT NOT NULL ,
`y` TINYINT NOT NULL ,
`terrain_id` TINYINT UNSIGNED NOT NULL ,
`structure_id` SMALLINT UNSIGNED NOT NULL
) ENGINE = INNODB;

This handy table will link hexes to an existing planetary node. Depending on map size I decide to go with, we'll end up with quite a few of these suckers. Fortunately, we're in 2015, and data size constraints aren't a huge deal for a hobby project.

CREATE TABLE `terrain` (
`terrain_id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`game_style_id` TINYINT UNSIGNED NOT NULL ,
`terrain_name` VARCHAR( 32 ) NOT NULL
) ENGINE = INNODB;

Adding a terrain table will let me enhance gameplay by allowing for a nigh-unlimited number of terrain types. Fields, mountains, hills, swamps, moonrock.... the choices are endless! The game style field is a special one that crops up all over this game. Essentially, pretty much all content in the game is tied to a style, and by changing that style, one could switch from playing a journey from the early 20th century to deepspace exploration to one based around epic fantasy, or virtually any other theme.

CREATE TABLE `terrain_benefit` (
`id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`terrain_id` SMALLINT UNSIGNED NOT NULL ,
`name` VARCHAR( 32 ) NOT NULL ,
`description` VARCHAR( 256 ) NOT NULL ,
`category` VARCHAR( 32 ) NOT NULL ,
`benefit` DECIMAL( 5, 2 ) NOT NULL ,
`prefix` VARCHAR( 3 ) NOT NULL ,
`suffix` VARCHAR( 3 ) NOT NULL
) ENGINE = INNODB;

What's a moonrock hex without a bunch of associated bonuses and penalties, right? This funky table means that the benefits of terrain aren't hard-coded, making it much easier to balance down the road.

Next Time

With our data structures defined, the next installment will focus on taking advantage of the new components with game objects.

Website - Dev Blog - Facebook - @afuriousengine - /r/LetThronesBeware

Better combat through code review (A journey through the back-end code of Let Th

Better combat through code review (A journey through the back-end code of Let Th

News

On this week's episode, we begin to dig into the code behind Let Thrones Beware in an effort to make it better.

Public Alpha 10: Phase 1: New graphical interface; Phase 2: ???; Phase 3: Profit

Public Alpha 10: Phase 1: New graphical interface; Phase 2: ???; Phase 3: Profit

News

Public Alpha 10's just been launched, and it features an entirely new graphics engine built on Phaser 2.3.0!

Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account:

X

Latest posts from @afuriousengine

Learning Laravel 5 book is now available! Get it at Laravel Learning Center #laravel #php #book Learninglaravel.net via @LearningLaravel

Jul 27 2015

RT @FXS_MisterKevin: If you're confused about XCOM 2's "we lost" story, it's because we're basing it off your last classic ironman attempt. #IStoleThisJoke

Jun 1 2015

I put a hex on [terrain generation]: code review part 2 #indiedev #gamedev Wp.me

May 1 2015

Better combat through code review (A journey through the back-end code of Let Thrones Beware) #indiedev #gamedev Wp.me

Apr 29 2015

Public Alpha 10: Phase 1: New graphical interface; Phase 2: ???; Phase 3: Profit! #gamedev #indiedev Wp.me

Apr 22 2015

The world is burning! The world is burning! #gamedev #indiegamedev T.co

Apr 16 2015