Developing Multiplatform Game With Libgdx – part 3 – tile background

Going Further: Background Implementation

So, Vladimir, are we finally ready to actually do something now? Damn right we are! In this lesson, let’s make a background and give our game the pixel-artsy feel. Go to our new amazing GameScreen, and add a new declaration at the start of the class:

private Stage gameStage;

In Libgdx, The stage is used to position UI elements in a nice way and read incoming UI events. It makes our job much easier.

We will initialize it with a new ViewPort. ViewPort limits the area of the screen which we are able to see. Since our game will be run on multiple devices with different screens, we need to make sure that every player will be able to play it, no matter his screen size. Libgdx offers lots of different viewports (you can read more about it here: https://github.com/libgdx/libgdx/wiki/Viewports). We’re going to use FixViewport, this will allows us to make sure that width/height proportions are kept, the main characters are going to be drawn in the middle and the background (which will be made from tiles) is going to be extended depending on the actual size of the screen.

First, let’s introduce a constant values for game width and height (these will be the minimal field width / height and will be extended according to window proportions). Since our tiles are really small, I’m choosing 192 for width and 128 for height (basically, 192 / 16 = 12 tile width, 128 / 16 = 8 tile height.).

public final int STAGE_W = 192;
public final int STAGE_H = 128;

Then, in our GameStage contructor, let’s initialize our gameStage, by passing our spriteBatch and new Viewport as parameters.

The whole part of code will look like this now:

public final int STAGE_W = 192;
public final int STAGE_H = 128;

public GameScreen(DodgingHero _game) {
    super(_game);
    batch = new SpriteBatch();

    ExtendViewport viewp = new ExtendViewport(STAGE_W, STAGE_H);
    gameStage = new Stage(viewp, batch);
}

 

Basically, we tell our gameStage to use our new extendviewport and to scale the screen accordingly. No matter the window size, the coordinates on the screen are always going to be at least STAGE_W x STAGE_H (192×128 in this case).

Splitting game update logics from drawing

Now, let’s split the screen update part from the actual drawing part. Make a new function update:

private void update(float delta)
{
    gameStage.act(delta);
}

The function updates the contents of the stage. We don’t really have any right now, but it will be useful later on. Delta is the time that passed since the rendering of the previous frame. If our stage has any animations, it basically adjusts them accordingly.

Now, let’s add a call of our update function inside the render function. After the screen is cleared (glClear command), issue a draw command to our stage. It will apply the stages camera settings and our further drawing will be done in the coordinates system we requested during constructor call.

Change the values in glClearColor to 0, 0, 0, 1 (Red, Green, Blue, Alpha). This will set the clear color to black, away from annoying red.

@Override
public void render (float delta) {
    update(delta);

    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    gameStage.draw();

    gameStage.getBatch().begin();
    gameStage.getBatch().draw(game.res.ground, 0, 0);
    gameStage.getBatch().draw(game.res.wall, 0, 16);
    gameStage.getBatch().end();
}

Finally, in dispose() function, call gameStage.dispose(). The gameStage takes up resources that needs to be manually disposed of when we exit our game. Add super.dispose() call, which is a call to parent’s (DefaultScreen) dispose method (nothing’s there yet, but it’s a good idea to do it nonetheless in case we change something in the future).

@Override
public void dispose()
{
    super.dispose();
    gameStage.dispose();
    batch.dispose();
}

Run the game. You should see something like this:

How Tiles Look At First

How Tiles Look At First

As you see, the tiles have increased in size! However, if you try resizing the window, the image stretches uncomfortably.

Uncomfortable Resize

Uncomfortable Resize

This is because our viewport is not being updated. In GameScreen, add resize function:

@Override
public void resize(int w, int h) {
    super.resize(w, h);
    gameStage.getViewport().update(w, h, true);
}

This one is called on every resize, effectively resizing our viewport on every change of window size.

Proper Resize

Proper Resize

The image is smaller, but dimensions are at least kept (and not stretched).

Filling the background with tiles

Finally, let us get to the background. In our main game package, create a new one called “graph” In my case, it is com.coldwild.dodginghero.graph

Inside that package, create a new Java Class, named “Background.” Create an empty public constructor (we’ll need it in later lessons).

Then, get to the drawing function. The current goal is quite simple: make a floor background with a wall behind. Let’s introduce the draw method, which will draw the background on the given Stage using Resource pack that we’ve loaded.

public void draw(Stage stage, Resources res){}

Make sure to include the proper stage package (alt+enter when your cursor is on Stage, then select the Stage from libgdx).

The current background idea is simple: fill the top row of the screen with wall tiles and the other parts with floor tiles. We’ll need two for cycles for that. One that goes from top to bottom and the other one inside it that goes from left side to right side. But first, go to Resources and introduce new constant TILE_SIZE (which, obviously, indicates our file size). We will use it for background drawing.

Get back to Background class file. Let’s raw the ground first, and then we’re going to worry about the walls.

public void draw(Stage stage, Resources res)
{
    stage.getBatch().begin();

    for (int y = (int)stage.getHeight(); y >= -Resources.TILE_SIZE; y -= Resources.TILE_SIZE)
    {
        for (int x = 0; x < stage.getWidth(); x += Resources.TILE_SIZE)
        {
            stage.getBatch().draw(res.ground,
                    x, y,
                    0, 0,
                    Resources.TILE_SIZE, Resources.TILE_SIZE,
                    1.01f, 1.01f,
                    0);
        }
    }
    stage.getBatch().end();
}

We’re going from the height of the stage (stage.getHeight) to the lower border and filling every row with tiles. Hold on a second, why are we using such a complicated draw procedure? We’re doing it because otherwise the images will experience tearing on stage resize. (If you figure out a better way – let me know, seriously).

Uncool black lines (poor resize result)

Uncool black lines (poor resize result)

Now, let’s add the Background declaration and initialization to our GameScreen. Add the line    Background bg; near the other declarations. In GameScreen constructor, add bg initialization:

bg = new Background();

 

And finally, we must make a call to bg.draw during our rendering. Add it before gameStage.draw() call. bg.draw(gameStage, game.res);

Run the game. The screen should be filled with floor tiles now. The only thing left now is to add wall tiles.

Right before stage.getBatch().end();, add another for cycle:

for (int x = 0; x < stage.getWidth(); x += Resources.TILE_SIZE)
{
    stage.getBatch().draw(res.wall, x, stage.getHeight() - Resources.TILE_SIZE, 0, 0, Resources.TILE_SIZE, Resources.TILE_SIZE, 1.01f, 1.01f, 0);
}

 

Run the game, see the background that stretches and handles any screen size well. Congratulations! Your background is complete.

Git Commit with code changes from this lesson: https://github.com/vladimirslav/dodginghero/commit/b15fa65097d8d1366955000e3b9dac594a6085cc

More on viewports:
https://github.com/libgdx/libgdx/wiki/Viewports

Developing Multiplatform Game With Libgdx – part 2 – project structure

Heya! The next lesson adresses the project structure and introduces asset packing. The video turned out to be a bit confusing, but the extended transcript is below. Let me know if you have any questions!

What is a game and how we build it

If we think about it, what is a game? Let’s check out the main file, DodgingHero. If we really dumb it down, the game is a cycle of displaying info and getting user’s feedback. The game screen actually renews many times per second (FPS, frames per second, actually indicate this exact value). The render() function in Libgdx is doing exactly this. It cleans the screen (glClear command), then it draws our own things.

The create() function initializes our game. Those are the operations that need to be done once. Mainly, it’s resource allocation. We need to load the textures/sprites only once (the line img = new Texture(“badlogic.jpg”); does exactly that). We also initialize SpriteBatch (batch = new SpriteBatch();), essentially this is the structure that sends the commands to our graphic card.

On the opposite side, we have dispose() function, that is called after our game is done running. We need to free up resources. And this is exactly happens in this particular case: both batch and img are being disposed.

Now that we have a very general idea what’s going on, I’m going to tell you how I usually structure my projects. A good project structure ensures that project maintenance and code updates will go much smoother. As they say, “hours of planning can save you weeks of programming.”

Preparing our art

First thing first, let’s find some art for our prototype. I usually use opengameart if I want to build something fast, and this case will be no exception. After some search, I found http://opengameart.org/content/tiny-16-basic – tileset with some monsters and humans which we can use for our game prototype. I’m going to pick the tiles they have, pick two of them and will use them to show our initial background, repeated the tiles for the background. Essentially I’m doing some extra work here (because the tilesets on the link are already very neatly organized), but I need to show you what’s going on by an example.

In our project root folder (the same folder where we have “android”, “core”, “html” … folders) , let’s make a folder named “assets.” Inside that folder, make another folder, named “unpacked.” From the tileset, cut out one floor and one wall tile (I usually use paint.net, http://www.getpaint.net/index.html for that purpose, but the simple ‘paint’ will do for now).Each image should be 16×16 pixels in size, save them as ground.png and wall.png accordingly. Now, we have two tile sprites, but what do we do with them? For a better performance, all sprites should be put into spritesheets. (It takes time for the graphic card to switch between textures/sprites). It’s really not a problem for modern computers most of the time (for a small game), but I’d rather teach you to do things the ‘proper’ way first. In our Android Studio, go to desktop package and open DesktopLauncher. For Desktop version, we’re going to add texture packing. (Whenever we run desktop version, the sprites are going to be packed into one file. We’ll be able to use this this pre-generated file in the other platforms, like android). The main reason I’m doing it this way is because TexturePacker is not supported by some of our platforms (at least HTML), so I’d rather execute it on Desktop only.

In DesktopLauncher class, add the following private function:

static void Pack()
{
      TexturePacker.Settings settings = new TexturePacker.Settings();
      settings.maxHeight = 2048;
      settings.maxWidth = 2048;
      settings.pot = true;
      TexturePacker.process(settings, "../../assets/unpacked", "packed", "game");
}

Then, right at the start of main() function, add the call to Pack() function, it will look like this now:

public static void main (String[] arg) {
   Pack();
   LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
   new LwjglApplication(new DodgingHero(), config);
}

Loading the art

Select the DesktopLauncher configuration and run our program on it (first launch might take some time). Now go and check the android\assets\ folder. There should be a new directory, “packed” there. Inside that directory, there should be two files: game.png and game.atlas. First one is the picture of two tiles put together. The other one is actually a text file (you can check it out with any text editor, I use Notepad++). It is, like extensions says, an atlas, that describes different sprites in it and coordinates of those sprites in our new big picture.

Now we’ll have to load this atlas. The next thing we do, make a resource class, which will hold the graphical data. Make it in the same package as your main game class. In my case, I right click on “com.coldwild.dodginghero”, choose “New” and pick “Java Class.”

create-new

New Class Creation

Name it “Resources.” This one will be responsible for loading and storing the assets for our game. Go to your new file, and inside Resources class declare the public constructor and TextureAtlas variable gameSprites.

public class Resources {

    TextureAtlas gameSprites;

    public TextureRegion ground;
    public TextureRegion wall;

    public Resources()
    {
        gameSprites = new TextureAtlas(Gdx.files.internal("packed/game.atlas"));
        ground = gameSprites.findRegion("ground");
        wall = gameSprites.findRegion("wall");
    }

    public void dispose()
    {
        gameSprites.dispose();
    }
}

Before constructor declaration, we declare TextureAtlas named “gameSprites”– this is the thing that is going to store our spritesheet  with game characters and background.

dispose() function will be called after the end of our program, to unload all resources that have been used.

We put the initialization of the gameSprites into our constructor with the following line:

    gameSprites = new TextureAtlas(Gdx.files.internal("packed/game.atlas"));

This will take the generated atlas from ourproject/android/assets/packed/ folder. After that, declare two TextureRegion variables, ground and wall right after gameSprites atlas.

TextureAtlas gameSprites;

public TextureRegion ground;
public TextureRegion wall;

 

Great, now let’s assign some values in our constructor. It’s not hard: just add the following lines:

ground = gameSprites.findRegion("ground");
 wall = gameSprites.findRegion("wall");

 

The final result should look like this:

public class Resources {
 
     TextureAtlas gameSprites;
 
     public TextureRegion ground;
     public TextureRegion wall;
 
     public Resources()
     {
         gameSprites = new TextureAtlas(Gdx.files.internal("packed/game.atlas"));
         ground = gameSprites.findRegion("ground");
         wall = gameSprites.findRegion("wall");
     }
 
     public void dispose()
     {
         gameSprites.dispose();
     }
 }

 

Testing what we have

Now ground and wall point to the specific tiles and we’re be able to draw them! Now go to your main class file (in my case it’s DodgingHero.java) in core folder and add new public variable, Resources right at the start of the file. You should initialize it at the start of create() function. Remove the “img” variable and all code related to it from the file. You won’t need it anymore. Let’s just test if we can draw our simple tiles. In dispose function, add res.dispose(); Final result should look like this:

  
 public class DodgingHero extends ApplicationAdapter {
     public Resources res;
     SpriteBatch batch;
 
     @Override
     public void create () {
         res = new Resources();
         batch = new SpriteBatch();
     }
 
     @Override
     public void render () {
         Gdx.gl.glClearColor(1, 0, 0, 1);
         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
         batch.begin();
         batch.end();
     }
 
     @Override
     public void dispose () {
         batch.dispose();
     }
 }

Now, for the sake of testing our tiles, let’s add simple drawing between batch.begin() and batch.end() inside our render() function:

@Override
 public void render () {
     Gdx.gl.glClearColor(1, 0, 0, 1);
     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
     batch.begin();
     batch.draw(res.ground, 0, 0);
     batch.draw(res.wall, 0, 16);
     batch.end();
 }

This way we should draw the wall above the ground. The first parameter is the sprite that we want to draw, the next is the coordinates(x, y). Unless you change something, the x coordinates are going from left side of the screen to right side (0->width) and y is going from bottom to top (0->height). 0 means the lowest point of the window. Run the program and you should see both small tiles drawn at the left side of the screen:

gamescreen

Our work in progress!

Adjusting Code Structure

So, Vladimir, are we ready to build the game right here? Hell no. It might seem like a good idea to write all code here, but it will quickly become bloated if nothing is done: imagine that we have to program all the menus and screens in one file. The way I usually do it is to split every separate screen into a separate file and do the rendering/control checking there. The good news is that libgdx allows you to do this quite easily.

In our core/java/com.yourname.gamename package, create a new package called “screens.” There, we’ll add the DefaultScreen parent class, which will store the link to our game object (and will be able to access our resources from there), from which we’ll inherit the next screens.

newpkg

New Package Creation

Right click on the “screens”, package select “new” -> “Java Class.” Name it DefaultScreen, make it implement Screen (public class DefaultScreen implements Screen), add the necessary import from Libgdx by placing map cursor over “Screen” and pressing alt+enter. Press alt-enter again to automatically implement the missing methods. Don’t touch them. (for now). Now, we’ll do two things:

  • Declare a variable of our main class (it will point out to game)
  • Create a constructor for DefaultScreen

That should not take much time:

public class DefaultScreen implements Screen {
 
     public DodgingHero game;
 
     public DefaultScreen(DodgingHero _game)
     {
         game = _game;
     }

 

Very good, our DefaultScreen class is ready.

Now we should implement the actual game screen. Right click on screens package, add new Java Class, let’s name it GameScreen. GameScreen should extend the Default Screen. (public class GameScreen extends DefaultScreen). Press alt+enter to implement the default constructor. Your class should look like this:

public class GameScreen extends DefaultScreen {
     public GameScreen(DodgingHero _game) {
         super(_game);
     }
 }

 

Now go to your main class (in my case it’s DodgingHero), and blatantly cut-paste render() function from there to GameScreen. Change the input parameters to accept float delta (public void render (float delta)). We now have this:

 

public class GameScreen extends DefaultScreen {
     public GameScreen(DodgingHero _game) {
         super(_game);
     }
 
     @Override
     public void render (float delta) {
         Gdx.gl.glClearColor(1, 0, 0, 1);
         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
         batch.begin();
         batch.draw(res.ground, 0, 0);
         batch.draw(res.wall, 0, 16);
         batch.end();
     }
 }

batch is unresolvable. We need to move it from main class here. Main class should be very small now:

 public class DodgingHero extends ApplicationAdapter {
     public Resources res;
 
     @Override
     public void create () {
         res = new Resources();
     }
 
     @Override
     public void dispose () {
         res.dispose();
     }
 }

 

The last thing to do is to change batch.draw calls. We don’t have res variable here, but we can access it via our game variable. Change batch.draw(res.ground, 0, 0); to batch.draw(game.res.ground, 0, 0); Do the same change with wall. The final GameScreen class should look like this:

public class GameScreen extends DefaultScreen {
 
     SpriteBatch batch;
 
     public GameScreen(DodgingHero _game) {
         super(_game);
         batch = new SpriteBatch();
     }
 
     @Override
     public void render (float delta) {
         Gdx.gl.glClearColor(1, 0, 0, 1);
         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
         batch.begin();
         batch.draw(game.res.ground, 0, 0);
         batch.draw(game.res.wall, 0, 16);
         batch.end();
     }
 
     @Override
     public void dispose()
     {
         batch.dispose();
     }
 }

Run the game now. Oh no! What do we have in front of us? It’s a black screen! Something went wrong. No worries, the issue is that we moved the code to the separate screen, but did not instantiate it in any way. We need to tell our game to explicitly switch to it. Go back to our main class, and do two things:

  • Change class declaration: public class DodgingHero extends ApplicationAdapter { should change to public class DodgingHero extends Game {
  • At the end of create() function add the following line: setScreen(new GameScreen(this)); Press alt+enter to resolve and auto-import GameScreen class

Run the game now. You should see the red screen with two tiles at the bottom. It might not look as much, but our project has changed a lot. After this, we’ll be able to independently work on specific screens, and adding new screens (like main menu, credits, etc) won’t be a problem.

 

Git Commit: https://github.com/vladimirslav/dodginghero/commit/d02228f6ecb39fdbf98bb4ad54e57b5fb8f29b73

I’ve taken assets from: http://opengameart.org/content/tiny-16-basic, they are made by Lanea Zimmerman. I’ve cut separate tiles so it would be easier to follow (see my git repo).

You might want to check https://libgdx.badlogicgames.com/documentation.html for more details and in-depth descriptions.

Developing Multiplatform Game With Libgdx – part 1

Hey everyone!
After learning things from different tutorials on Internet, I wanted to contribute something. There are lots of tutorials on how to make games. I want to make a tutorial that would go through the whole process: from setting up the work environment to game publishing.

Here’s the video of the project, but in case you’re more into reading, the transcript is given below.

Setting up our project

I’ll be making a multiplatform game that you will be able to run on PC, but my end goal is to publish it on Android. You don’t really need the Android device to follow this tutorial: I’ll explain how to make the game run on your desktop machine, without the need to launch it on Android.

The game idea is simple: on half of the screen, we have a 4×4 field and a character that moves between tiles to dodge enemy attacks. On the right side, there’s an enemy (or group of enemies) that stand and attack the hero (or, rather, some of the tiles).

Game Idea

Game Idea

If anyone promises to make you a gamedev expert simply from doing one tutorial – he’s probably lying. In this tutorial, the end goal is to make a game, but it’s up to you, my reader, to continue perfecting your skills. To me, game programming is a matter of curiosity and experimenting. You’ll have the initial base, but it’s up to you to try new things and experiment by trying out new ideas in the way you want to.

Requirements (In order of installation):

Here’s more info on preparing the environment in case you’re struggling with something: Link to Libgdx Article

Extra tools I’m using:

  • Git Client (For Source control), I’m using the command tools, but you can GUI at https://desktop.github.com/
  • Far Manager (For easier file managing + command line tools), get it for free at http://www.farmanager.com/ If you don’t want to use it, simply use windows explorer + command prompt

Creating Version Control Repository

You can skip this step if you want to, but I strongly advise you to store your code somewhere. Version control, like git/svn/mercurial is a perfect way to do this. Since this is a public project (you will be able to see my code), I will use github to create a project. If you want to focus on private projects, you can use mercurial (hg) or git, in combination with http://bitbucket.org, which provides free storage for your code soruce control.

First, create a new project (repository). Then, pull it to your machine. With git, I use the following command:

git clone http://linktomyrepo

With hg, it’s something similar:

hg clone http://linktomyrepo

Setting Up The Game Project Itself

After you install JDK8 and Android Studio, it’s time to launch Libgdx Setup App.

Gdx Project Setup Screen

Gdx Project Setup Screen

You can name the project however you want to. I’ll name mine Dodging Hero. The package name should be somewhat descriptive. The usual format is com.yourname.gamename, in my case (Since I’m the owner of coldwild games studio), I’m going to name it com.coldwild.dodginghero.

The game class is where the initial setup and high-level launch things happen. The name should not contain spaces.

The destination is up to you, if you are using source control, just pick the folder where you’ve checked out the Git repository. Try not to have destinations with spaces though. Might save you for potential issues later on. Android SDK is the folder of your android software development kit. It should have been installed with Android Studio. In my case the folder is G:\android

In sub Projects, you generally pick the Platforms that you want to support. This will probably require extra work, but we’re not here to rest. Mark “Desktop”, “Android”, “Ios”, “Html”

Extensions are the helping tools/code snippets and libraries that can make development much easier. Put the checkboxes under following options: “Freetype”, “Tools”, “Controllers”. Uncheck everything else. If you hover the mouse buttons on checkboxes, you are told what every tool means, feel free to read up on the other ones on internet and use them wisely when developing your next games.

To explain a bit more of our choices: “Freetype” – this is the font generation, OpenGL (which is basically behind libgdx) cannot simply display True Type Fonts (.ttf) that are used in our operating systems, so we’ll need to generate the images that contain letters in order to. “Tools” are various supporting functions, in our case we’ll need Texture Packer that comes with them. It will allow us to pack all of our smaller images into one big image, which can be faster process by graphic cards. “Controllers” is the controller/joystick support, I think it will be nice if we add it for our desktop if we have time.

Finally, press “Generate.” You might get a warning telling you that android build tools version is newer. Don’t mind it, confirm the build. After that, you’ll get a warning about Freetype extension not compatible with sub module HTML. This is perfectly fine, we’re not going to use it there. Go ahead and say “Yes, build it!” After that, the process starts, the dependencies are downloaded and after some time the generation is complete.

The time has come to import our project into Android Studio. Open up Android Studio, go to “File” -> “Open” -> go to your generated project folder and select “build.gradle” file. After that, the project is being imported. Great, we have our project opened! Congratulations on finishing the first step.

Setting up the Desktop Version

First thing’s first, let’s make testing the game comfortable without having to run it on Android. We’re going to configure libgdx project to run as a desktop application. In Android Studio, go to Run -> Edit Configurations -> Press the ‘+’ Icon (Add new configuration) -> select ‘Application.’

runsettings

Launcher Settings

At the top of the window that appeared, in the “Name” field, replace “Unnamed” to “Desktop Launcher.” (or whatever name you want to, this is purely cosmetical and is there for your own convenience).
In Main Class field, select your “DesktopLauncher” class.
The working directory should be located in YourProjectFoler/android/assets. This is necessary so that our desktop application would be able to read sprites intended for android.
Use Classpath of module” should list “desktop.”
Press OK.

The new option should appear in the dropdown list on top of the screen (near the run button triangle). Choose it.

Then press “Run” button. (The green triangle to the right) or simply press “Shift + F10.” This will build and launch your program. Here’s what you should see:

Great, you’re the boss! You see the initial screen, this is what the template project for libgdx looks like.

result

Initial Screen

Going Further, Project Structure Explained

In the panel on the left, you see the list of our subprojects/packages.

There’s the core module, which contains the code of our game. It is universal for all platforms (Desktop/Android/Ios/Html). But if you go for the desktop folder, you’ll see that it contains DesktopLauncher class. It is responsible for running our game on Desktop Platforms. We’ll be writing the Desktop Specific code here. Same is relevant for all the other platforms. For example, our Android Package Folder will contain ad handling code. Since the mechanism of how ads are displayed will probably be different on every platform, we can’t put Admob’s code (google’s library for displaying ads on Android) into core folder.

Project Structure

Project Structure

That concludes lesson 1. In lesson 2, we’ll try loading sprites and create a simple background.

Git commit: https://github.com/vladimirslav/dodginghero/commit/c37a9292d8bf06551abb8f5db289e1f033d5effc

Some Practical Things I’ve learned from developing my first game

Developing your first game is like walking into uncharted waters. You might read up a lot, but you will still encounter some problems that will be avoided on your next game. Here’s what I’ve noticed while working on my first big game.

Error Handling and Reporting

What seems like a luxury at first, quickly becomes a necessity when your game goes live. Build your system with that in mind. Steam offers a good error reporting service in case the game crashes, but it needs the data to send. In my case – I hold the stack of function calls and some arguments (about 10 entries) so there would be at least some information on when the game crashed. It’s not always enough, but it’s better than nothing.

Savegames

You ought to start thinking about implementing savegames at once. The more your game grows, the more data is added (i.e. player in my game had no need to save an army at first, but it became a must later on). The longer you wait, the harder it will be to implement. When I realized that I needed map savegames in Blades of the Righteous (already when the game has been released), I had to drop everything and work 3 days, 12hours nonstop just to implement and test everything. The rush and stress could have been avoided had I planned it right at first.

Literals

Sure, sometimes you just want to make a button and hardcode “Start” on it. My advice: don’t. Move all the string literals that you have in code (those that are visible to your users) into an external file. That way when you want to translate the game, the process won’t be painless. Right now I’d have to rewrite everything if I wanted to translate my game (I might actually do this).

Screen Resolution

Especially if you are working on 2d game. Read up on how others solve it. I had to realize that it’s the problem only after release (when people started explicitly asking for fullscreen). I’ve intended the game to be windowed, like “Knights of Pen and Paper”, first part (Awesome game, love it). However, I’ve been getting lots of requests to support fullscreen. In this cases, you can stick to your opinion (“Working as intended!”) or actually listen to people and their wishes. Making good resolution support also makes your game much more easier to record for letsplayers.

I think that’s all I can remember for now. If you have any similar experiences and things your are paying attention to – feel free to share them in comments.

Blades of the Righteous retrospective

It’s been almost 4 months since I’ve left the job to finish my game and potentially work on my other projects. I would not say that those 4 months felt like being in an avalanche. Rather, I felt like a small insignificant boat floating through the ocean. Not in a bad way. Except that maybe eventually the boat flips over because of the huge waves, the fisherman drowns and nobody can find him, while his wife is weeping back home and cursing the day he decided to go into an open sea and children become delinquents because they have no father figure which results in a dysfunctional family. Nevertheless, I think this is a good time to sum up some of my results and start writing them down.

It’s hard to focus on what I want to write. At one hand, I want to share my experiences. On the other hand, why should you care? So I am going try to write a small cycle of articles on how I planned, built and marketed my turn based strategy game, Blades of the Righteous. All of them are told from the programmer’s viewpoint and I’m hoping they will give some insights to those that are starting gamedev. I am not a huge fan of vague descriptions: “write to youtubers,” “split your code into smaller parts“ and “get lots of tasks so you won’t procrastinate” – those descriptions don’t usually say much to me. That’s why I don’t try to read self-help books anymore. When I write something, I’ll start with the general example and then describe how I did it.

Some background for the context: I am just an average dude. I’ve developed the game for about 2 years. Past 4 months – I quit my job to develop it full-time. It’s a turn-based strategy game, and has about 2500 activations on Steam (not much), about 90% of those were sold through the bundles (will cover it in separate article). I think this can be achieved by anyone if you work on it. But do you actually need something like that? It’s up to you to decide.

The game idea was born in early 2014. I was playing “Last Remnant” and thought that battle-system there was cool: although being turn-based, the game gave action feel and did not feel slow at all because lots was going on at the same time. So yes, iteration one: turn-based game with indirect ordering, units decide what they want to do on their own.

I’ve spent about 6 months of programming while working full-time and studying in the university. Spoiler alert: the result was as good as a broccoli pizza. Nevertheless, at that time I thought: “Cool, I’ve finished a game.” The same feeling that toddler experiences when he puts on his pants for the first time. The parents are excited, but nobody else cares.

Naturally, the game is done. “Gotta put it on greenlight then!” The first days were easy: you get lots of attention because Steam puts your game to the front page of Greenlight. I also got support from Latvian game developer association (shout out to gamedev.lv, thanks a lot!). Got about 200 ‘yes’ votes from that. After that, the votes were not coming, but I received an email from Groupees bundle. It gave me another 600 votes and the game was still hanging (as of Dec 2014). You get lots of comments: do not ignore them, users often know better. I wrote everything down and then tried to adjust it. The bundle turned out great, but there was still not enough votes. I put the game in that state on itch.io, sold it to one person, felt good “My first dollar, someone paid me!” (remember the toddler comparison). Thought “At least I tried.” Time to bury the dead game like you would bury the hatchet, so I wrote post-mortem (with greenlgiht statistics, in case you’re interested: http://vladimirslav.com/2014/12/blades-of-the-righteous-postmortem/ ). I successfully switched to my studies and was not doing any more game programming. That is, until the game passed the Greenlight in March 2015. Organically. I got ~300 votes just randomly. The game got greenlit with 1079 votes “for” and 1338 votes “against” (45:55 ratio).

Now here’s the catch and the main thing that I want you to understand from this article: if your game is good (or, rather, interesting to majority of the people), you’ll pass the greenlight by itself, I’d say in 2-3 months tops. The best games are much faster than this (2-3 weeks). The greenlight bundles definitely help, but if you don’t get any fans from the greenlight campaign – don’t expect your game to be received well (at least at first). But the fact that the game took 5 months to get greenlit and a special bundle promotion should have probably been my warning signal. But with the state of mind I had at that moment, I’d ignore it even if I saw a harp-playing angel who sang “drop your game m8” while staring directly into my eyes.

My current algorithm to game-development now if I want to make a game (and what you probably should do too unless you know what you’re doing) and get it to Steam:

  • Spend no more than 3 months on somewhat-polished prototype with minimal functions
  • Show it to my friends and make them play the game. Collect feedback.
  • Put the screenshots on twitter regularly, use #screenshotsaturday
  • If the game does not get enough traction on Steam and you see why (a lot of users will leave comments) – drop it.

The thing is, the greenlight decision motivated me to spend another year rewriting my game to (what I perceived) a decent level. I love my game and I love developing it, but it won’t be able to sustain me. If you have your game as a pet project – do whatever you want. If your well-being depend on it: do not ignore the signs. I’m going to describe the rework and second life of Blades of the Righteous, as well as what I think makes turn-based games great in my next article.

As a side note, I’ve put another game on Greenlight some time ago and got lots of those “game publishing proposals.” Not going to delve into that, but I think you must read this article (and never agree to those deals): http://morrisonlee.com/2016/05/23/game-publishers-in-2016-how-to-throw-your-lifes-work-away-in-seconds/

2d Fog of War with Sprites in Unity

When developing my casual roguelike, Wild West Pigeon, I’ve encountered a need to close parts of the map with fog of war. My game is turn-based, meaning I need to recalculate fog of war once every turn and not dynamically.

A lot of solutions recommend shaders, but I could not find any articles if I want other, albeit less prettier, solution (You might need this, for example, because not all Android phones prior to Android 4.0 support shaders – check this stack overflow reply). Therefore, I’ll try to share my knowledge on how I addressed the issue.

Fog of War Tile GameObject

  • There are lots of way to do fog of war sprite, but I made a simple black square (1×1). If you want your fog of war smoother and prettier – make a larger square with blurred sides.
  • Add it as an asset to your game project.
  • Create an empty object
  • Add a sprite renderer to it – set the sprite as your “Fog of War” sprite
  • Make a new sorting layer (call it “Fog of War” or something like that) – make it to be the last layer drawn (In my case, the order is following: Default -> Floor -> Floor_Destructibles -> Items -> Units -> Fog Of War) so that fog of war sprites would be drawn above all else.
  • Move the object to prefab.
  • Create an empty GameObject in your scene, name it “FOVPanel” or something like that, this will aggregate your ‘fog of war’ tiles.

Logics

What we need to do now – is to look at every player turn and check what tiles are revealed and need hiding. For this purpose – fog of war is regenerated after every move. Whenever new Fog of War tiles are created – their parent is assigned to FOVPanel object and on the next turn all of FOVPanel object’s current children are deleted and replaced by a newly-calculated and instantiated FOV tiles. Each game will be different, but in my game, when the level is generated, I have an array boolean revealedTiles[][] that takes the width and height of my map whenever new level is initialized.

I’ll try to describe the logics behind it – but I’ll show you my code as well in case you are interested.

  • You can attach your new script to “FOVPanel” object or whichever object you want, just make sure your player object will be able to access it. I’ve attacked it to my game manager (singleton static persistent object).
  • When level loads, mark all tiles in revealedTiles as false
  • Reveal some tiles around your player, i.e. make every tile around him visible (8 tiles around the player, 1 tile where player stands)
  • After player moves – call recalculation function, it makes sure that the tile the player moved to is set as true in revealedTiles, then calls the recursive calls to simple ‘raycasting’ function that checks which tiles are open (note – I call it ‘Raycasting’, not sure how it’s called ‘scientifically’ – I just imagine that we are sending rays of light towards direction where player looks)
  • The raycasting function goes forward, checks every tile row and sees if that’s an obstacle. If that’s an obstacle – reveal the tile, but don’t go forward. If there’s no obstacle – reveal the tile and go to next row.
  • The ray expands gradually: i.e. at first we reveal one tile in front of our hero, on the next tile column we reveal up to 3 tiles, on the next tile column we reveal up to 5 tiles, etc.
  • At first – imagine the simple ray that goes forward – you just reveal all tiles in front of it until you encounter an obstacle.
  • After that – try to improve it by making a corner-case (pun intended) so that leftmost and rightmost revealed tile would go deeper one level and make sure that the next column is revealed a bit more. See image below. The hero (‘H’) expands his view depending on the distance of the tiles.
Raycasting Example

Raycasting Example

Full Fog of War module code here:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class FOV : MonoBehaviour {

    [HideInInspector] public GameObject fovPanel;
    public GameObject fovTile; //That's your previously created Fog of War tile - assign in editor!

    void Awake()
    {
        fovPanel = GameObject.Find("FOVPanel");
    }

    // max revealed tile depth (from start)
    public const int MAX_RANGE = 5;

    /*
     level - how far we've already gone with our raycasting
     x - current tile x position
     y - current tile y position
     directionX - make sure it's -1, 0 or 1 (0 if directionY is not 0)
     directionY - make sure it's -1, 0 or 1 (0 if directionX is not 0)
    */
    public void RayCasting(int level,
                           int x,
                           int y,
                           int directionX,
                           int directionY,
                           bool leftCorner,
                           bool rightCorner)
    {
        // that's the board script: it handles all the board logics
        BoardManager board = GameManager.instance.boardScript;
        // continue only if we have not surpassed the max distance
        if (level < MAX_RANGE)
        {
            // if we are out of bounds
            if (x < 0 || y < 0 || x >= board.maxX || y >= board.maxY)
            {
                return;
            }
            else
            {
                // ok, we're here, mark the tile as revealed
                board.revealedGrid[x, y] = true;
                // but does the tile blocks visibility? if visibilityGrid[x, y] is true, then player can see through the tile
                // what's behind it
                if (board.visibilityGrid[x, y])
                {
                    // our ray expands gradually. therefore if we are located on the corner tiles
                    // of the current ray level - we need to expand further on the next level
                    if (leftCorner)
                    {
                        if (directionX != 0)
                        {
                            // if we are moving horizontally, expand ray below or above (that's why we adjust y by directionX)
                            // the left corner tile ray would go something like that
                            // level
                            // 0 1 2
                            // . . *
                            // . * *
                            // * * .
                            RayCasting(level + 1, x + directionX, y + directionX, directionX, directionY, leftCorner, false);
                        }
                        else
                        {
                            // else
                            RayCasting(level + 1, x + directionY, y + directionY, directionX, directionY, leftCorner, false);
                        }
                    }
                    
                    // same as with left corner
                    if (rightCorner)
                    {
                        if (directionX != 0)
                        {
                            RayCasting(level + 1, x + directionX, y - directionX, directionX, directionY, rightCorner, false);
                        }
                        else
                        {
                            RayCasting(level + 1, x - directionY, y + directionY, directionX, directionY, rightCorner, false);
                        }
                    }

                    // we raycast forward in any case
                    // level
                    // 0 1 2
                    // . . .
                    // * * *
                    // . . .
                    RayCasting(level + 1, x + directionX, y + directionY, directionX, directionY, leftCorner, false);
                }
            }
        }
        else
        {
            return;
        }
    }

    public void Recalculate(int x, int y) {
        BoardManager board = GameManager.instance.boardScript;
        // the player moves here
        board.revealedGrid[x, y] = true;

        // raycast to all directions
        RayCasting(0, x, y, 0, 1, true, true);
        RayCasting(0, x, y, 0, -1, true, true);
        RayCasting(0, x, y, 1, 0, true, true);
        RayCasting(0, x, y, -1, 0, true, true);
    }


    protected const int MAX_X_LOOKUP = 20;
    protected const int MAX_Y_LOOKUP = 10;

    // redraw based on position of camera 
    // (currentX and currentY most often is the center of the screen, where player stands)
    public void Redraw(int currentX, int currentY)
    {
        // redraw the Fog of War tiles
        List<GameObject> children = new List<GameObject>();
        // first we gather all children of FOVPanel
        foreach (Transform child in fovPanel.transform)
        {
            children.Add(child.gameObject);
        }

        // then we delete them
        foreach (GameObject child in children)
        {
            Destroy(child);
        }

        BoardManager board = GameManager.instance.boardScript;

        // then we draw new Fog of War tiles
        for (int x = -MAX_X_LOOKUP + currentX; x < MAX_X_LOOKUP + currentX + 1; x++)
        {
            for (int y = -MAX_Y_LOOKUP + currentY; y < MAX_Y_LOOKUP + currentY; y++)
            {
                if (x < 0 || y < 0 || x > board.maxX - 1 || y > board.maxY - 1)
                {
                    continue;
                }


                if (board.revealedGrid[x, y] == false)
                {
                    Vector3 pos = new Vector2(x, y);
                    GameObject obj = Instantiate(fovTile, pos, Quaternion.identity) as GameObject;
                    obj.transform.parent = fovPanel.transform;
                }
            }
        }
    }
}

Let me know if you see any mistakes or know how to do it better! If you want to see how the final result works, you can check out my game on Google Play market: Wild West Pigeon.

Memory Management in TCP Chat Server using libuv

I’ve recently had a task to build a single-threaded tcp chat server and client based on an event loop (using non-blocking asynchronous approach). While this seemed like a time-consuming task to me at first, there are already some solutions that can make your life much easier.

For technology stack I’ve decided to use libuv for async event loop and networking – http://libuv.org/
You can find the final source code here: https://github.com/vladimirslav/libuv-chat, in this post I’ll go through the crucial parts (i.e. the parts where I actually got stuck). For the good examples of libuv you can look up https://nikhilm.github.io/uvbook/ – but it does not offer good advice on memory management (at least yet, at the moment of writing this post).
Unsurprisingly, the server turned out to be a biggest struggle, the memory management part being most problematic. Since the language of choice is C++, the memory management is important: i am using RAII principle for resource management. We are going to make a singleton class ‘ChatServer’.

To Initialize the Server

 The whole event system is based on a loop (warning: not safe for multi-threads), so we initialize the loop first. The server socket is in fact a stream – it is used to send/receive events. Variables ‘loop’ and ‘server’ are parts of ChatServer class.
    uv_loop_init(&loop);
    // then, we initialize tcp server socket
    uv_tcp_init(&loop, &server);

    // "0.0.0.0" means that we listen on all available interfaces and not binding ip
    // to a specific address
    sockaddr_in addr;
    uv_ip4_addr("0.0.0.0", port, &addr);
    uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0);

    // start listening: server is the socket stream,
    // DEFAULT_BACKLOG is int with max queued connections
    // the third parameter is a callback that is called when new client connects
    int err = uv_listen((uv_stream_t*) &server, 
                        DEFAULT_BACKLOG, 
                        [](uv_stream_t* server, int status)
                        {
                            ChatServer::GetInstance()->OnNewConnection(server, status);
                        });

On New Connection

When new connection is incoming, we need to decide what to do with it. I have a special object “ChatSession” that handles this stuff, but if I try to give most relevant things:
        ChatSession newSession; 
        // connection is also a stream - it is used to exchange data/events between
        // client and server
        newSession.connection = std::make_shared();
         
        // let's init our connection stream to start receiving/sending data
        uv_tcp_init(&loop, newSession.connection.get());
    
        if (uv_accept(server, (uv_stream_t*)newSession.connection.get()) == 0)
        {
            // set up read callbacks
            uv_read_start((uv_stream_t*)newSession.connection.get(),
                          alloc_buffer, 
                          [](uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
            {
                ChatServer::GetInstance()->OnMsgRecv(stream, nread, buf);
            }); 

            // do post-processing, a good idea would be to add a new session
            // to the list of some sort
        } 
        else
        {
            // error handling: forcefully close the connection stream
            uv_read_stop((uv_stream_t*)newSession.connection.get());
        }
    }
    else
    {
        // error handling
    }

Memory Management when writing to stream

Note that std::bind won’t work for setting callbacks, thus we need this small hack with lambdas. libuv itself is written in C so it won’t allow to use class methods as callbacks that simply. Now, the read is pretty much straight-forward, but I had the most problems with write callback. After we read the message and trying to send it further, we need to make a new request structure.

    uv_write(req,
             connection,
             message->GetBuf(),
             1,
             [] (uv_write_t* req, int status)
             {
                 ChatServer::GetInstance()->OnMsgSent(req, status);
             });

Where “req” is message write request struct (uv_write_t), unique to every message that is currently being sent. The whole challenge is that req should be kept even after OnMsgSend is done. We’d need some kind of Memory Pool for that. Solved it like this:

class ReqPool
{
public:
    ReqPool();
    uv_write_t* GetNew();
    void Release();
protected:
    std::queue<std::unique_ptr>unused;
    std::queue<std::unique_ptr>used;
};

ReqPool::ReqPool()
{
}

uv_write_t* ReqPool::GetNew()
{
    if (unused.empty())
    {
        used.push(std::move(std::unique_ptr(new uv_write_t)));
    }
    else
    {
        used.push(std::move(std::unique_ptr(unused.front().release())));
        unused.pop();
    }

    return used.back().get();   
}

void ReqPool::Release()
{
    unused.push(std::move(std::unique_ptr(used.front().release())));
    used.pop();
}

Whenever we are going to send a new request, we get a new uv_write_t structure from the memory pool (either unused one, of if all are already assigned – create a new one.

    uv_write_t* req = msg_queue.requests.GetNew();

After the program stops running – all the structures are going to be deleted by themselves. You can check the full code here: https://github.com/vladimirslav/libuv-chat

My experience on placing the game on Steam

As my game “Blades of the Righteous” is going to be published soon – I want to write a brief article to sum up the effort of integrating the Steam API into the game that perhaps will comfort the developers that are only planning to do so. When I first got access to Steam, I had some worries and concerns. As I look back, I want to address them once again.

First thing first: If you have worries about “not being able to do it” – don’t. SteamAPI integration itself is very well documented and shown in the video manuals. The DLL file is added. You areliterally guided through every step. I wrote my game in C++ – all I needed to do is include some headers, link Steam static library and put a dll into the release folder. There’s also a video how to upload the build of your game to store. (There’s also a script for that so this one is covered absolutely).

Achievements: Steam provides super-easy system to implement game achievements. You don’t need to do much on your side (just make sure to put the right ‘achievement-complete’ calls in the relevant parts of the game). The persistent variables are also provided by Steam: you can save, for example, the total win count for the player (the Steam handles the saving) that will keep through gaming sessions.

Trade cards: I suggest you implement them, since there are going to be people that will want your game just for the cards (your game will also show when someone filters games by trading card support on Steam). Start preparing those as soon as you get the Steam access. Steam gives you guidelines how you need to format them – talk to your designed and start working. In my case it took 3 days to fill all the requirements (and prepare card-specific images and backgrounds). For card support, you’ll need 6 badges (80×80 each), at least 5 emoticons (each 18×18 and 54×54), 5 cards and 5 backgrounds as rewards (1920×1080).

Same thing goes for shop / backgrounds: ideally, while you program, you need someone to start formatting the media / preparing the logos and images.

You’ll want to get the Steam Store Page out there as soon as possible (something that I failed to do) – so start completing the checklist (you will be provided one). Took me about 2 weeks to do everything. On the side of Steam, it takes them about 4 days to review the store page and cards and approve them.

Don not be lazy and register on Google Analytics: you will be able to include the analytics id for data gathering and extra statistics might always come in handy.

Here’s how the final store page looks like: http://store.steampowered.com/app/421140

So yes, if you are planning to put your game out there – it is going to take some effort, but I can guarantee you that it won’t be that hard. Good luck!

An amateur research of stock trading + Learning GO Lang

I’ve been looking into a possibility to get familiar with GO language for some time, but recently I had a reason: a weekend project where I could test a theory about stock trading.

I’ve entered a discussion with my colleagues about why it does not work to buy stock right before the ex-div date to receive the dividends and then to sell them right away. In my experience, it has a simple explanation: after the ex-dividend date, the price drops accordingly to the amount of dividends paid. But let’s have a deeper look and see if it’s really like that.

For that, I will need to get a list of stock symbols, then get the list of ex-div dates for some years and compare historical prices before and after dividend payment to check if it would have been financially viable to buy stock right before ex-div date and sell them afterwards (in my experiment – 5 days prior to ex-div to buy and 5 days prior to ex-div to sell).

Let’s start with stockparser package, the core concepts, file Stockparser.go. Set up imports and structure to store stock record results after simulated trading:

package stockparser

// set up imports
import (
    "fmt"
    "net/http"
    "encoding/csv"
    "io"
    "strconv"
    "strings"
    "time"
    "math"
    "os"
)

// string formats to access yahoo finance api and get csv-formatted data
// list of historical dividend payments and their dates:
const DIVIDEND_LIST_FORMAT =     "http://real-chart.finance.yahoo.com/table.csv?s=%s&a=00&b=1&c=%d&d=12&e=31&f=%d&g=v&ignore=.csv";
// list of prices on days prior/after the ex-div dates:
const CLOSE_PRICE_LIST_FORMAT =  "http://real-chart.finance.yahoo.com/table.csv?s=%s&a=%d&b=%d&c=%d&d=%d&e=%d&f=%d&g=d&ignore=.csv";

// struct to store Stock Parsing result for sorting/comparison purposes later
type StockRecord struct {
    Symbol string
    Earnings float64
}

To get a stock record data, we will need the following information. First, fetch the ex-dividend dates and the amount paid, then go through each date and get the prices before and after, then calculate the profits. The dividend list fetching is going to be reviewed first.

Function getYearsDividend takes the http link and fetches the csv data from it. It is pretty straightforward: try to get the data, if something is returned go line-by-line:

func getYearsDividend(yearLink string) [][]string {
    
    var result [][]string
	response, err := http.Get(yearLink);
	if err != nil {
            fmt.Println(err)
	} else {
            defer response.Body.Close()
            csvr:= csv.NewReader(response.Body)
            rec, err := csvr.Read()
            var first bool = true
        
            for err == nil {
                if (first) {
                    // ignore first line as it contains the names of the columns
                    // but not the data
                    first = false;
                } else {
                    result = append(result, rec)
                }
                rec, err = csvr.Read()    
            }
        
            if err != io.EOF {
                fmt.Println(err)
            }
	}
   

    return result
}

ReadDividendData (Important: capital leter first – it is going to be exported for use in other files) function gets the list of dividend payments for symbol in the years between(including) yearStart and yearEnd. It takes additional parameters: baseMoney is how much money (in USD) is going to be invested in stock purchase, daysBuyBefore and daysSellAfter indicate how many days do we wait before buying and selling (and takes the historical prices for these days accordingly – if ex-div is fifth of February 2015, and daysBuyBefore equals 2, the system is going to try to fetch historical closing price of February third) and finally, commission value shows how much money to be substracted from baseMoney as payment for the deal (my bank takes a fixed amount).

    const DATE_INDEX int = 0
    const DIVIDEND_INDEX int = 1

func ReadDividendData(symbol string,
                      yearStart int,
                      yearEnd int,
                      baseMoney int,
                      daysBuyBefore int,
                      daysSellAfter int,
                      commission float64) StockRecord {
    // this will store the sum of all possible trades for that symbol
    // that were made during the given time frame
    var sum float64 = 0;
    
    var link_str string
    // form the link - insert the value
    link_str = fmt.Sprintf(DIVIDEND_LIST_FORMAT, symbol, yearStart, yearEnd)
    
    // get the array of dividends - dates/amounts paid
    // yahoo finance csv format requested by format link
    // just includes the date and dividend in one string
    var date_dividend [][]string = getYearsDividend(link_str) 

    // create a log file to store extended data
    f, err:= os.Create("res/" + symbol + ".txt")    
    if err == nil {
        defer f.Close()
        // go through every date-dividend record and calculate the total sum
        // from every one of them
        for line := range date_dividend {
            var divPrice float64 = 0
            // convert the dividend price from string to float
            divPrice, err := strconv.ParseFloat(date_dividend[line][DIVIDEND_INDEX], 64)
            if (err == nil) {
                if err == nil {
                    sum += calculateDividendSum(symbol,
                                                date_dividend[line][DATE_INDEX],
                                                divPrice,
                                                daysBuyBefore,
                                                daysSellAfter,
                                                baseMoney,
                                                commission,
                                                f)
                }
            } else {
                f.WriteString(err.Error())
            }
        }
    }
    
    f.WriteString("\n=========\n")
    f.WriteString("Final Sum: " + strconv.FormatFloat(sum, 'f', 3, 64))
    
    return StockRecord{symbol, sum};    
}

The next intermediate function is calculateDividendSum which fetches historical prices:

const DATE_YEAR_INDEX = 0;
const DATE_MONTH_INDEX = 1;
const DATE_DAY_INDEX = 2;

const HISTORICAL_HIGH_INDEX = 2;

func calculateDividendSum(symbol string,
                          dateUnprocessed string, 
                          dividendBonus float64,
                          daysBuyBefore,
                          daysSellAfter,
                          moneyForPurchase int,
                          commission float64,
                          f *os.File) (result float64) {
    result = 0
    // date is passed as yyyy-mm-dd
    // first explode it into logical chunks, removing "-" and placing
    // year, month and day into separate indexes of a string array
    var dateSeparated []string = strings.Split(dateUnprocessed, "-")
    
    // then convert them to numbers
    var year int64
    year, _ = strconv.ParseInt(dateSeparated[DATE_YEAR_INDEX], 10, 64)
    
    var month int64
    month, _ = strconv.ParseInt(dateSeparated[DATE_MONTH_INDEX], 10, 64)
    
    var day int64
    day, _ = strconv.ParseInt(dateSeparated[DATE_DAY_INDEX], 10, 64)

    // calculate the dividend date
    var divDate time.Time = time.Date(int(year), time.Month(month), int(day), 0, 0, 0, 0, time.UTC)
    // then substract given amount of days to get the date when we purchase the stock
    var buyDate time.Time = divDate.AddDate(0, 0, -daysBuyBefore)
    // then add given amount of days to get the date when we sell the stock
    var sellDate time.Time = divDate.AddDate(0, 0, daysSellAfter)
    
    var datalink string
    openYear, openMonth, openDay := buyDate.Date()
    closeYear, closeMonth, closeDay := sellDate.Date()

    // form the proper link to request a historical dates between buy and sell date
    datalink = fmt.Sprintf(CLOSE_PRICE_LIST_FORMAT,
                           symbol,
                           int(openMonth) - 1,
                           openDay,
                           openYear,
                           int(closeMonth - 1),
                           closeDay,
                           closeYear)

    response, err := http.Get(datalink);
    fmt.Println("========");
    fmt.Println("Getting Data from: " + datalink + " , dividend date: " + divDate.String());

    if err != nil {
        fmt.Println(err)
    } else {
        defer response.Body.Close()
        // the csv format:
        // Date,Open,High,Low,Close,Volume,Adj Close
        csvr:= csv.NewReader(response.Body)
        rec, err := csvr.ReadAll()
        
        if (err == nil) {
            f.WriteString("===========\n");
            f.WriteString("Getting Data from: " + datalink + " , dividend date: " + divDate.String())
            f.WriteString("\n")

            var buyCost float64 = 0
            var sellCost float64 = 0
            
            // buy price is at the bottom of the list (earliest date)
            // respectuflly, sell price is on top (we sell for that price)
            buyCost, errBuy := strconv.ParseFloat(rec[len(rec) - 1][HISTORICAL_HIGH_INDEX], 64);
            sellCost, errSell := strconv.ParseFloat(rec[1][HISTORICAL_HIGH_INDEX], 64)
            if errBuy == nil && errSell == nil && err == nil {     
                result = summarizeData(buyCost, sellCost, dividendBonus, float64(moneyForPurchase), commission, f)
            }                
        }
	}
    
    return result
}

The final function is summarizeData which simply adds values together:

func summarizeData(buyPrice float64,
                   sellPrice float64,
                   dividendBonus float64,
                   budget float64,
                   commission float64,
                   f *os.File) float64 {
                    
    // how many stock can we buy with money we have? 
    // substract commission from our budget and divide by price of one stock
    var buyAmount int = int(math.Floor((float64(budget) - commission) / buyPrice));
    
    // how much money we actually spent? 
    // they can be leftover money if we had budget if we have
    // for example 40 USD in remaining budget and one stock price is 30 USD
    var buyMoneySpent float64 = float64(buyAmount) * buyPrice + commission;
    
    // how much money do we get from selling by sellPrice 
    // after we get the dividend? substract commission 
    // because it is charged on sell operations too
    var sellMoneyGained float64 = float64(buyAmount) * sellPrice - commission;
    
    // how much money did we actually get from dividend?
    // multiply stock amount with dividend payout for one stock
    var dividendMoneyGained float64 = dividendBonus * float64(buyAmount);
    
    // calculate final balance
    var balance float64 = dividendMoneyGained + sellMoneyGained - buyMoneySpent;
    
    // log into file
    // Proper way would be to make one more function
    // But since this is a weekend project
    // I try to forgive myself
    var logData = fmt.Sprintf(`BUYPRICE: %f,
                               MONEY SPENT TO BUY: %f,
                               AMOUNT BOUGHT: %d,
                               SELLPRICE: %f,
                               DIVIDEND PRICE: %f,
                               AMOUNT GAINED FROM DIVIDENDS: %f,
                               AMOUNT GAINED FROM SELL: %f,
                               TOTAL PROFIT IN THE END OF THE TRANSACTION: %f`, 
                               buyPrice,
                               buyMoneySpent, 
                               buyAmount,
                               sellPrice,
                               dividendBonus,
                               dividendMoneyGained,
                               sellMoneyGained,
                               balance)     
    f.WriteString(logData);
    f.WriteString("");
    
    return balance
}

The main File stock.go is simple: read csv file with list of symbols on my computer (it should be customized according to your list):

package main

import (
    "fmt"
    "stockparser"
    "os"
    "time"
    "encoding/csv"
    "io"
    "sort"
    "strconv"
)

// you need those functions in order to sort the stock records:
type byEarnings []stockparser.StockRecord
func (arr byEarnings) Len() int { return len(arr) }
func (arr byEarnings) Swap(i, j int) { arr[i], arr[j] = arr[j], arr[i] }
func (arr byEarnings) Less(i, j int) bool { return arr[i].Earnings < arr[j].Earnings } 

func main() {
    csvfile, err:= os.Open("companylist.csv")
    
    if err != nil {
        fmt.Println(err)
        return
    }
    
    defer csvfile.Close()
    
    var records byEarnings
    
    reader := csv.NewReader(csvfile)
    rec, err := reader.Read()
    var first bool = true
    var counter int = 0
    fmt.Println("Reading data...")
    for err == nil {
        if (first) {
            first = false;
        } else {
            fmt.Println("Reading line " + strconv.Itoa(counter))
            records = append(records, stockparser.ReadDividendData(rec[0], 2012, 2015, 4000, 5, 5, 18));
            // set the delay in order not to flood the yahoo server with http request
            time.Sleep(5000 * time.Millisecond)
        }
        rec, err = reader.Read()
        counter++
    }
    
    if err != io.EOF {
        print(err)
    }
    
    fmt.Println("Sorting Data")
    sort.Sort(records)
    fmt.Println("Done")
    
    for _,element := range records {
        fmt.Println("S: " + element.Symbol + " Earnings: " + strconv.FormatFloat(element.Earnings, 'f', 3, 64))
    }
    
}

To sum things up: in the end we have a GO program that fetches the data from yahoo finance and summarizes it in order to evaluate stock purchases right before ex-div payouts. I might make a separate article if I find results interesting enough (and if I got the large enough list of stock symbols to evaluate). You can get the full source code at my github:
https://github.com/vladimirslav/go-dividend-checker

Implementing A* algorithm using C++ templates

While developing my game, blades of the righteous, I’ve decided to make better pathfinding both for AI and for the player (the units can be given orders to move through multiple tiles – we need to find the optimal path). As I’m probably going to encounter the problem quite often in my next games, I’ve decided to make a universal function for pathfinding that returns the tile path through the generic field. The use of C++ template comes to mind.

Used this article as a reference: http://www.gamedev.net/page/resources/_/technical/artificial-intelligence/a-pathfinding-for-beginners-r2003

 

A bit of a background: I usually make 2d game maps as 2d array of pointers to units. If tile is empty, it contains nullptr. Otherwise it points to the unit.

Unit* field[FIELD_W][FIELD_H]
field[0][0] = nullptr; // field with coordinates 0,0 is empty
field[1][1] = myUnit; // field with coordinates 1,1 contains myUnit

Seems pretty straightforward, but the problems began when I’ve introduced the units that take two tiles. The Unit class still has only one coordinate pair (x and y), but now the width has been added into the equation. That adds lots of border cases, like:

  • What happens, if our unit of length 2 tries to reach unit to the right of it? For the sake of example, let’s say that our unit is on tile (1,1), the unit that we need to reach is on (7, 1). In that case, the final destination is going to be (1,5) – because our unit occupies both (1,5) and (1,6) and therefore stands near by (1,7)
  • What happens if both units have the length of 2 tiles? What happens if our target is to the right? Then we’d have to approach (targetX – 2, targetY) coordinates.
  • What if our destination tile is empty, but is on the border of the map? That means our unit would not be able to stand there because he lacks length.

Additional data structures/functions are introduced:

// tile, == operator needed to use it with std::find
struct TileCoords
{
    int x;
    int y;
    bool operator==(const TileCoords& other) const
    {
        return x == other.x && y == other.y;
    }
};

// inner tile info, necessary for use within algorithm:
struct TileInfo
{
    TileCoords comeFrom;
    bool isStartingTile;
    bool isVisited;
    int G; // in my case - basically distance from starting tile if you follow 
           // the chosen path (in more generic case: how expensive is it to get here)
    int H; // our guess how much we need to move to reach destination from 
           // that time (it's inaccurate most of the time, but we need to use something as a prediction)
};

using tile_list = std::vector; // define a variable type name for better code readability

// do given x and y coordinates belong to the field with width w and height h?
bool areValidCoordinates(int x, int y, int w, int h) 
{
    return (x >= 0 && y >= 0 && x < w && y < h);
}

// prediction function for H value, basically calculates the distance between two points
int HFunc(int xStart, int yStart, int xDest, int yDest) 
{
    return std::abs(xStart - xDest) + std::abs(yStart - yDest);
}

Therefore, to make A* as generic as possible, we will need a function template:

template <typename T> tile_list Astar(T*** field, // link to the battlefield
                          size_t w, // battlefield width
                          size_t h, // battlefield height
                          bool(*checkFunc)(const T*), // function that checks whether 
                                                      // the given field is available
                                                      // to be moved on
                          int xStart, // starting tile x (where the units stands at)
                          int yStart, // starting tile y (where the unit stands at)
                          int xDest,  // destination tile x
                          int yDest, // destination tile y
                          bool include_destination, // do return destination tile 
                                                    // in the resulting final path?
                          int unit_w) //unit width
{
    if (areValidCoordinates(xStart, yStart, w, h) == false)
    {
        return {}; //empty list
    }

    // check if unit can actually fit in destination
    if (include_destination)
    {
        for (int newX = xDest + 1; newX < xDest + unit_w; newX++)
        {
            if (areValidCoordinates(newX, yDest, w, h) == false)
            {
                return{}; // empty list, one of the destination tiles is out of bounds
            }

            if (checkFunc(field[newX][yDest]) == false)
            {
                return{}; // empty list, one of the destination tiles is occupied
            }
        }
    }

    tile_list closed_set;
    tile_list open_set;

    std::vector<std::vector> evaluatedCoords(w); // array of array

    // initialize values, calculate initial predictions:
    for (size_t x = 0; x < w; x++)
    {
        evaluatedCoords[x] = std::vector(h);
        for (size_t y = 0; y < h; y++)
        {
            evaluatedCoords[x][y].isVisited = false;
            evaluatedCoords[x][y].G = 0;
            evaluatedCoords[x][y].H = HFunc(x, y, xDest, yDest);
        }
    }

    bool destinationReached = false;
    // add starting tile to open list
    evaluatedCoords[xStart][yStart].G = 0;
    evaluatedCoords[xStart][yStart].isStartingTile = true;
    evaluatedCoords[xStart][yStart].isVisited = true;

    if (areValidCoordinates(xStart, yStart, w, h))
    {
        open_set.push_back({ xStart, yStart });
    }

    // while we have not reached destination
    // and there are tiles that can still be evaluated
    while (open_set.empty() == false && destinationReached == false)
    {
        TileCoords currentTile;
        int minF = w * h; // minimum cost that is required to reach destination
        size_t tileNum;   // tile index number
        // select assumed lowest-cost path
        for (size_t i = 0; i < open_set.size(); i++)
        {
            int F = evaluatedCoords[xStart][yStart].G + evaluatedCoords[xStart][yStart].H;
            if (F < minF)
            {
                tileNum = i;
                currentTile = open_set[tileNum];
                minF = F;
            }
        }

        // make an array of adjacent coordinates
        TileCoords adjacentCoordinates[] = { { currentTile.x - 1, currentTile.y }, 
                                                { currentTile.x + 1, currentTile.y },
                                                { currentTile.x, currentTile.y - 1 },
                                                { currentTile.x, currentTile.y + 1 } };

        // ... then go through it and check the new possible tiles
        for (int i = 0; i < sizeof(adjacentCoordinates) / sizeof(*adjacentCoordinates); i++)
        {
            if (areValidCoordinates(adjacentCoordinates[i].x, adjacentCoordinates[i].y, w, h))
            {
                if (std::find(closed_set.begin(), closed_set.end(), adjacentCoordinates[i]) == closed_set.end())
                {
                    int adjX = adjacentCoordinates[i].x; // to make code look cleaner
                    int adjY = adjacentCoordinates[i].y; 
                    // if this tile has not been visited:
                    if (std::find(open_set.begin(), open_set.end(), adjacentCoordinates[i]) == open_set.end())
                    {
                        // we found are destination
                        if (adjX == xDest && adjY == yDest)
                        {
                            evaluatedCoords[xDest][yDest].comeFrom.x = currentTile.x;
                            evaluatedCoords[adjX][adjY].comeFrom.y = currentTile.y;
                            destinationReached = true;
                            break;
                        }

                        // see if found tiles are valid through the whole unit width
                        bool validTiles = true;
                        for (int newX = adjX; newX < adjX + unit_w; newX++)
                        {
                            // coordinates are valid?
                            if (areValidCoordinates(newX, adjY, w, h) == false)
                            {
                                validTiles = false;
                                break;
                            }

                            // field can be visited?
                            if (checkFunc(field[newX][adjY]) == false)
                            {
                                validTiles = false;
                                break;
                            }
                        }
                        
                        // if newfound tile is OK:
                        // we have an unocupied field
                        if (validTiles)
                        {
                            // say that we've came to evaluated coordinates from the current tile
                            evaluatedCoords[adjX][adjY].comeFrom.x = currentTile.x;
                            evaluatedCoords[adjX][adjY].comeFrom.y = currentTile.y;
                            evaluatedCoords[adjX][adjY].G = evaluatedCoords[currentTile.x][currentTile.y].G + 1;
                            open_set.push_back(adjacentCoordinates[i]);
                        }
                    }
                    else
                    {
                        // if we visited this tile already
                        if (evaluatedCoords[adjX][adjY].G > evaluatedCoords[currentTile.x][currentTile.y].G + 1)
                        {
                            // but the path would be shorter if we moved to this tile
                            // from the other one
                            evaluatedCoords[adjX][adjY].comeFrom.x = currentTile.x;
                            evaluatedCoords[adjX][adjY].comeFrom.y = currentTile.y;
                            evaluatedCoords[adjX][adjY].G = evaluatedCoords[currentTile.x][currentTile.y].G + 1;
                        }
                    }
                }
            }
        }

        // move the current tile to visited
        closed_set.push_back(currentTile);
        // remove it from unvisited tiles
        open_set.erase(open_set.begin() + tileNum);
    }

    if (destinationReached)
    {
        // let's make a path
        // go backwards from destination
        tile_list path;
        if (include_destination)
        {
            path.push_back({ xDest, yDest });
        }

        TileCoords currentTile = evaluatedCoords[xDest][yDest].comeFrom;

        // ... until we reach the starting tile
        while (currentTile.x != xStart || currentTile.y != yStart)
        {
            path.push_back(currentTile);
            currentTile = evaluatedCoords[currentTile.x][currentTile.y].comeFrom;
        }

        return path;
    }
    else
    {
        // could not find a way - return nothing
        return {};
    }
}

 

 

As a bonus, here’s the episode from the reworked battle system: