I Have Working Enemies

I’ve successfully made the enemy programs move and attack the player’s programs autonomously. They use my Dijkstra function to work out the shortest route to get within attacking range of a player program, then take that route and attack. It updates when the grid changes and avoids obstacles. Obligatory video:

This is significant. The enemy AI is probably the hardest part of the game to create. At least one person abandoned his Nightfall Incident based project after hitting a wall with the AI. It’s quite simple, and I could always improve it, but the fact that I’ve now got it working means I’ve overcome probably the most significant hurdle. It means I’m much more likely to complete this game and succeed where at least eight other people have failed.

I’m Still Alive…

I haven’t posted any updates in 8 days. That’s because I’m writing the AI for enemy programs. It’s probably the hardest part, and involves abstract things like working out routes to the player’s programs, deciding which one to attack etc., so I can’t easily post videos or screenshots that show what I’ve done.

Currently I’ve gotten as far as working out which squares the programs could move to to get within attacking range. Now I’m writing a function that decides which of those squares to move to and which program to attack, based on how many sectors the player’s programs have, the attacking strength of the enemy program, and the health of the enemy program. After that I’ll make the attacks functional for both player and enemy programs, then I’ll probably be able to make a few playable levels.

The enemy AI is unique in that it’s harder to replicate than other things. For almost everything else, all the levels, programs, etc. in the original Nightfall Incident, I can clearly see the information I need just by running the game. (I completed it so can access all the levels) For the enemy AI, I can see what programs do and where they move, but I can’t see the logic that made those decisions. This means it’s nearly impossible to exactly recreate the AI.

Instead I’m creating my own that moves towards programs in a similar way, but tries to be smart with deciding which programs to attack. For example, imagine there are two player programs with two and three sectors respectively, and two different enemy programs with attacks that remove two and three sectors respectively. If the enemy programs choose their victims arbitrarily, it may well end up with the three sector enemy program attacking the two sector player program and vice versa, killing the two sector program but leaving the former three sector program with one sector. However, if it’s smart about its decisions, the three sector enemy program will attack the three sector player program and vice versa, killing them both and winning the game for the enemy.

Moving Squares

I used my Dijkstra’s algorithm implementation to add squares that make it clear where programs can move:

The translucent overlays are on squares that the Hack could get to within three moves. It takes obstacles into account, and updates as things move and the grid changes.

Dijkstra’s Algorithm

I implemented Dijkstra’s algorithm in order to determine how many moves it will take a program to get to a particular grid square. It will be useful both for enemy AI and displaying which squares are within the movement range of a program. It takes obstacles into account.

I made it display the numbers on the grid for illustrative purposes, and to make sure it was working. Each number is how many moves it would take the green slingshot program to get to that square.

Playable Demo

I’ve made available a playable demo of Nightfall Hacker. Currently you can only move two different programs around a grid, but here it is. (I tried, but failed, to embed it in this page)

To play, select one of the spawn points, then select either Hack or Slingshot from the list. When you’ve spawned some programs, click the start button. To move a program, click it, then click one of the highlighted squares to move to it.

Sectors/Health is Working

This was more challenging than the prior parts, but I have sectors working properly, including the joints between them and allowing the player to move the head of the program through its own sectors, which was a difficult mechanic to get right. Obligatory video:

I did this by storing the position of each sector in an array, in chronological order. It pops the last sector from the list if the length of the array is greater that the maximum program size.

For the joints/squares that connect each sector in the same program, I iterate through each sector position and, if two squares are adjacent in a row or column, draw a translucent rectangle between them. With every move, I clear them and redraw them. There might be a more efficient way to do it, but I couldn’t be bothered to work it out.

I Have Movement

Not only have I made the programs move, I’ve also made them avoid other programs and empty squares. See the video:

I did this by storing the layout of the grid in a 2-dimensional array. When the player selects a program, the script gets the 4 surrounding spaces, determines which of them are empty squares, and displays the movement overlay squares accordingly. When the player clicks on one of those squares, it clears them, moves the program node to the clicked square, updates the level array, and repeats the process.

Because it also builds the level from the level array at the start of a battle, people should be able to make their own levels by editing a text file. I might add a level editor at some point.

Next I’ll work on either limiting the movement based on the program’s speed, or adding sectors to the programs.

Populating the GUI

I’ve written some of the code that displays information on the in-battle interface depending on which program is selected. See the video:

I haven’t done the description of the actions at the bottom of the panel yet. That is slightly more complicated, and I might do that after I finish the actions themselves. I also demonstrate the option to move the panel to the right or left of the screen.