October 18, 2019

## Introduction

This article is the third part of a tutorial aiming at discovering Svelte while building a game. I also wrote a short post on Svelte and the idea behind this tutorial. Below you can find the links to check those posts or other parts of the tutorial.

In this part we will focus mostly on how to implement an upgrade system.

Now we will implement upgrades for our game. Upgrades are buyable bonuses that grants bonuses to production in many way. The most straightforward is giving a multiplier bonus to the production of a building. That’s what we will be working on right now. Note that Clicker Idle upgrades gives a bonus to buildings depending on how many specific building has been bought by the player (not the total number of building the player has, because we have buildings producing other buildings). We will have to track that number bought to implement the upgrades.

Also Derivative Clicker gives the same bonus to all the buildings on the same row (all the buildings on the top row are tier1 buildings, producing a currency, then tier2 buildings on the second row produces tier1 buildings and so on and so forth for tier3, tier4…).

An example: if the bonus is 1% bonus to tier1 building for each tier1 buildings bought, if you buy 5 “1th Derivative” and 5 “Combinatorics” buildings, you have 10% bonus to all of those buildings.

### Differentiating building bought and building total.

To do that first thing is to create a variable in `store.js` to handle the new information.

 `````` 1 2 3 4 5 6 7 8 9 10 11 `````` ``````/* store.js */ ... // first level buildings export const firstDerivativeNum = writable(0); export const firstDerivativeBoughtNum = writable(0); export const combinatoricsNum = writable(0); export const combinatoricsBoughtNum = writable(0); // second level buildings export const secondDerivativeNum = writable(0); export const secondDerivativeBoughtNum = writable(0); ``````

Now that we have that, we can define props for the buildings and adjust the template:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 `````` `````` ... ``````

And now we can import the new stores and pass them to our Building components:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 `````` `````` ... ``````

### Fixing an accidental bug feature

In the last part we introduced a bug. A building’s cost is dependent on how many of that building there are. But now that other buildings can generate buildings themselves, that’d be better if the cost would be associated with how many buildings were bought, not how many there are in total. Because we already solved the issue of differentiating bought versus total, the fix is as simple as:

 ``````1 2 3 4 5 6 7 8 `````` `````` ``````

### A new component for upgrades

Let’s define a new component. To do that, let’s create a new file called `Upgrade.svelte`.

Their states will be:

• how many we bought (you can buy the same upgrade many times)
• they will have a cost that scale of of how many we bought
• they’ll have a name

Upgrade component has a lot in common with the Building component, it is even a subset of it. We can copy the Building component and remove what we don’t need. (Mostly anything that has to do with producing things).

The result is this:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 `````` `````` ``````

Then as usual we need to define new variables in the store to hold the number of upgrade bought:

 ``````1 2 3 4 `````` ``````/* store.js */ ... // upgrades export const firstRowBoughtNum = writable(0); ``````

And finally let’s use the new component in `App.svelte`:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 `````` `````` ...
``````

I made another big ugly thing here, using the div around the `<Upgrade>` tag to push it down the page. We will refactor all those ugly bits at the end of the tutorial because let’s face it it’s not the most interesting things to spend time on right now. But keep in mind that this is not the nicest way to do it.

### Updating the production to take into account upgrades

Now we have to modify how `Building.svelte` calculate how it produces its currency.

We need to have a props to know the bonus given by the upgrade.

Also we need to move things a bit, before we had a variable `buildingProduction = 1` which is gonna be replaced by a reactive declaration taking account the bonus given by the upgrade given as a prop, and this will impact `productionPerTick`.

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 `````` `````` ``````

We used `Math.floor()` to restrict the upgrade bonus to only whole number, so if a building produce initially 10 unit of currency each tick, with a bonus of 25%, it actually produces 12 unit per tick and not 12.5. For now I will let it that way, even so the upgrade is weaker than what is advertised, it is made to deal only with Integer (Num) and not Float or Double. Another way to do this is to calculate correctly the upgrade without flooring or rounding and to only apply the rounding on the number when we display it.

Note also that is the formula we have twice the magic number `1` which refers to the initial number of unit produced by the building. I will let it that way for now, but in the future we will change it to allow for more flexibility when creating buildings.

Next we need to change `App.svelte` to calculate the upgrade bonus and pass it to the buildings. For now for each building of the first tier we will get 25% bonus. These numbers are for development purpose and will be changed when we will balance the game progression.

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 `````` `````` ...
``````

Great! Now we can buy upgrades for our first tier buildings :)

One thing that is far from perfect is `\$: firstTierBuildingBought = \$firstDerivativeBoughtNum + \$combinatoricsBoughtNum;`. Every time we are gonna add a new tier1 building, we are gonna need to update this. For now we will keep it that way but maybe later on we will find a way to simplify this.

If you looked carefully at the last code snippet we used a placeholder for the upgrade bonus of “2nd Derivative” `<Building name="2nde Derivative" currencyProduced={firstDerivativeNum} numberOfBuilding={secondDerivativeNum} numberOfBuildingBought={secondDerivativeBoughtNum} upgradeBonus={0}></Building>`.

That would be better to implement the upgrade for that tier of building too and it is pretty straightforward.

First we need to add a new value in the store:

 ``````1 2 3 `````` ``````/* store.js */ ... export const secondRowUpgradeBoughtNum = writable(0); ``````

We will also modify `Upgrade.svelte` to make the initial cost of each upgrade different and we will also change the formula for the cost:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 `````` `````` ... ``````

Then we can modify `App.svelte` to define the bonus for second tier building (100% bonus for each building of tier 2 bought).

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 `````` `````` ...
``````

This time we pass an initial cost to the upgrade so that the first upgrade cost 100 time less than the second.

Also I put the Buildings into div to make the second tier building on a row below the first tier building. As usual, it is to not use CSS now, but at the end we’ll do a cleanup phase to use proper semantic for HTML and use CSS when needed.

### Add a second tier building

A last thing before wrapping up this part, we’ll add a second tier2 building that will produce `Combinatorics` to make things even (two tier1, two tier2 and two upgrades). To do that we need to have the proper values in `store.js` then adding the component into `App.svelte`.

 ``````1 2 3 4 5 6 7 8 `````` ``````/* store.js */ ... //second level buildings ... export const probabilityNum = writable(0); export const probabilityBoughtNum = writable(0); ... ``````
 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 `````` `````` ... ``````

This works fine and to finalize it, we should modify the function that display the currency the building is producing:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 `````` ``````/* utils.js */ import { ..., combinatoricsNum } from './store.js' // Returns a string representing `currency`. If `c` is not recognized, returns '?' export function currencyToString(c){ ... ... else if (c === combinatoricsNum) result = " Combinatorics" ... } ``````

That will display nicely on the new building that he is producing “Combinatorics”.

## Recap

It’s the end of this part, this time we implemented a new tier2 building and a basic upgrade system. The full code follows:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 `````` ``````

You have {\$money}{currencyToString(money)} and {\$proofs}{currencyToString(proofs)}!

``````

Building:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 `````` `````` ``````

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 `````` `````` ``````

store:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 `````` ``````/* store */ import { writable } from 'svelte/store'; export const money = writable(20); export const proofs = writable(0); // first level buildings export const firstDerivativeNum = writable(0); export const firstDerivativeBoughtNum = writable(0); export const combinatoricsNum = writable(0); export const combinatoricsBoughtNum = writable(0); // second level buildings export const secondDerivativeNum = writable(0); export const secondDerivativeBoughtNum = writable(0); export const probabilityNum = writable(0); export const probabilityBoughtNum = writable(0); // upgrades export const firstRowUpgradeBoughtNum = writable(0); export const secondRowUpgradeBoughtNum = writable(0); ``````

And finally utils:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 `````` ``````/* utils.js */ import { money, proofs, firstDerivativeNum, combinatoricsNum } from './store.js' // Returns a string representing `currency`. If `currency` is not recognized, returns '?' export function currencyToString(c){ let result = "?"; if (c === money) result = "\$"; else if (c === proofs) result = " proofs" else if (c === firstDerivativeNum) result = " 1st Derivative" else if (c === combinatoricsNum) result = " Combinatorics" return result; } ``````

The result in picture:

You can also play with the game and the code in the Svelte REPL or just enjoy the game made so far (hosted by Surge).

## Going further

If you want to go further and see if you understood how the game works, here is some elements you can try to add to the game:

• another tier1 building that cost `proof` and generate money(and called “Computer” if you want to follow closely Derivative Clicker).
• another tier2 building that costs `proof` and generates `Computer` (see the point above) called “Assembly line”

## What’s next?

Next article will be the conclusion on this tutorial, with resources for going further and my opinion on Svelte so far.

The next part is here: COMING SOON

If you have questions, suggestions or want to discuss about this subject, I'd be more than happy if you reach me at contact@julienrouse.com. See also my open invite
Nifty tech tag lists from Wouter Beeftink