Vistulans - Game Dev Diary - Days 8-14 - Graph Logic
Tags: showdev, gamedev, csharp, unity3d
Published: 2019-12-25 12:22:12

Hello everyone, I made some significant changes in my game development project, so it's time for the second part of progress diary 😜 It was a busy and weird week since I got flu, participate in a charity event and got distracted by study exercises so I had less time to work on vistulans than I planned. Even then, I created milestone changes in projects and in this article, I am going to write about them.

### To briefly remind what the project is about:
My game named Vistulans from Vistula (Latin name of Wisła - large and long river in Poland and Slovakia, and historical Slavic tribes near) is inspired by Slavic mythology and graph-based strategy games. The game I am writing in C# with Unity Engine.

 {% github pilotpirxie/vistulans %} 

### Miracles and spells
Most of the time I spent working on miracles inspired by those from Black and White game series by Peter Molyneux and Lionhead. Firstly I had created UI buttons for casting spells, then mechanics under the hood. Three buttons I placed on the bottom of the screen as placeholders. Before engine cast spell it checks if only one vertex is selected and the special prop is set to the index of the spell. It can be set only in different mode, so based on value != -1 I changed overlay on-screen to distinguish default and casting modes making screen more violet and magic 🧚‍♀️.

```csharp
    // ...
    public void FixedUpdate()
    {
        if (SelectedVertexA != null && SelectedVertexB == null && SpellToCast != -1)
        {
            switch(SpellToCast)
            {
                case 0:
                    CastOffensiveSpell(SelectedVertexA);
                    Mana[0] -= 100;
                    break;
                case 1:
                    CastEarthquakeSpell(SelectedVertexA);
                    Mana[0] -= 300;
                    break;
                case 2:
                    CastTakeoverCast(SelectedVertexA, OwnerType.Player);
                    Mana[0] -= 500;
                    break;
            }

            SpellToCast = -1;
            _graphController.ClearSelection();
        }
    }

    public void SetSpellToCast(int spellIndex = -1)
    {
        if (spellIndex == 0 && Mana[0] >= 100
            || spellIndex == 1 && Mana[0] >= 300
            || spellIndex == 2 && Mana[0] >= 500)
        {
            if (spellIndex == SpellToCast)
            {
                SpellToCast = -1;
            }
            else
            {
                SpellToCast = spellIndex;
            }
        }
        else
        {
            Debug.Log("Insufficient mana");
        }

        _graphController.ClearSelection();
    }
    // ...
```

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/uvv18eoyo2ocjy1h52co.png)

The first spell is typical offensive like fireball or something. In mechanics aspects, this spell removes up to 100 army power from the vertex and left 1 unit if army power goes below or equal 0. So it's a great spell for making outside vertex weaker and attack like a wave.


```csharp
    // ...
    public void CastOffensiveSpell(VertexController vertex)
    {
        vertex.ArmyPower -= 100;

        if (vertex.ArmyPower < 1)
        {
            vertex.ArmyPower = 1;
        }
    }
    // ...
```
The second spell has an area of effect, it's not affecting just single vertex but all vertices of the enemy. It's extremely powerful and cost much more mana than the previous one. An earthquake like I name it, remove up to 50 army power from each vertex of the selected player with future animation of eartquake.

```csharp
    // ...
    public void CastEarthquakeSpell(VertexController vertex)
    {
        foreach (VertexController tempVertex in _vertexList)
        {
            if (tempVertex.Owner == vertex.Owner)
            {
                tempVertex.ArmyPower -= 50;

                if (tempVertex.ArmyPower < 1)
                {
                    tempVertex.ArmyPower = 1;
                }
            }
        }
    }
    // ...
```

The third and the last spell is inspired by Siren miracle from Black & White 2 game. It was extremely hard to cast this spell, but it was totally worth. Takeover (temporary name) remove half of the army power from vertices and remaining relapse to the player side also changing owner of the vertex. It may be game-changer when one of the enemies will have a well-upgraded vertex with a lot of army on it. 

```csharp
    // ...
    public void CastTakeoverCast(VertexController vertex, OwnerType whoCast)
    {
        vertex.ArmyPower -= (int)Mathf.Floor(vertex.ArmyPower * 0.5f);

        if (vertex.ArmyPower < 1)
        {
            vertex.ArmyPower = 1;
        }

        vertex.Owner = whoCast;
    }
    // ...
```

At this moment I broke working on a game for a moment because I have been working on a charity event and raising money for lonely and sick people with the local organisation. It was a spectacular success and I felt much better after this event. However, after the event, I got flu viruses, so next few days I spend with fever in bed sleeping over 18 hours per day.

Back to the game dev after creating spells and when I cure influenza a little, I added different colours for army cubes for development purposes and study showcase. We have been presenting prototypes of our games. Other games were very interesting. One guy created simple shooter with funny chickens, other team game about gathering resources and building houses, another team simple but nice looking 2D point and click game. Last presented game was VR fighting like Gorn and IMO has great potential 😃.

After the showcase, I have still about a month to complete this project. It's a very short time so in my opinion, it's better to move faster towards the end. The last thing that I add, are three buttons for menu toggle, time scale multiplier and changing part of army power to send.

```csharp
    // ...
    public void OnMenuButton()
    {
        _gameplayController.IsShowingMenu = true;
    }

    public void OnTransportPartButton()
    {
        float currentPart = _gameplayController.TransportPart;

        switch (currentPart)
        {
            case 0.25f:
                _gameplayController.TransportPart = 0.5f;
                break;
            case 0.5f:
                _gameplayController.TransportPart = 0.75f;
                break;
            case 0.75f:
                _gameplayController.TransportPart = 1f;
                break;
            case 1f:
                _gameplayController.TransportPart = 0.25f;
                break;
        }
    }

    public void OnSpeedButton()
    {
        float currentSpeed = _gameplayController.GameplaySpeedMultiplier;

        switch (currentSpeed)
        {
            case 0.5f:
                _gameplayController.GameplaySpeedMultiplier = 1f;
                break;
            case 1.0f:
                _gameplayController.GameplaySpeedMultiplier = 1.5f;
                break;
            case 1.5f:
                _gameplayController.GameplaySpeedMultiplier = 2f;
                break;
            case 2f:
                _gameplayController.GameplaySpeedMultiplier = 2.5f;
                break;
            case 2.5f:
                _gameplayController.GameplaySpeedMultiplier = 3f;
                break;
            case 3f:
                _gameplayController.GameplaySpeedMultiplier = 3.5f;
                break;
            case 3.5f:
                _gameplayController.GameplaySpeedMultiplier = 4f;
                break;
            case 4f:
                _gameplayController.GameplaySpeedMultiplier = 0.5f;
                break;
        }

        Time.timeScale = _gameplayController.GameplaySpeedMultiplier;
    }
    // ...
```

And that's it! I am now celebrating Christmas and charging power for the next challenges. But now it's time to slow down for a little and spend more time with friends and family, at least we aren't the machine but human and IMO we need some social life 🎄❤ 

I wish you a fantastic day! 😃