1
0
Fork 0
mirror of https://github.com/Acamaeda/The-Modding-Tree.git synced 2024-11-21 16:13:55 +00:00

Merge branch 'pr/13' into dev

This commit is contained in:
Acamaeda 2020-10-27 17:42:53 -04:00
commit 424911cabd
17 changed files with 420 additions and 568 deletions

View file

@ -1,53 +1,47 @@
# The-Modding-Tree
The main way to add content is through creating layers. You can either add a layer directly in the layers object in layersSupportjs,
or declare it in another file and then do "`addLayer(layername, layerdata)`"
(good for breaking things up into smaller files). The existing layers are just examples and can be freely deleted.
You can also use them as references and a base for your own layers.
The main way to add content is through creating layers. You can either add a layer directly in the layers object in [layerSupport.js](/js/layerSupport.js), or declare it in another file and register it by calling `addLayer(layername, layerdata)`. There is an example layer registration in [layers.js](/js/layers.js) showing the recommended method. It is just an example and can be freely deleted. You can also use it as a reference or a base for your own layers.
The first thing you need to do is to edit the modInfo at the top of game.js to set your modID (a string). A
unique modId will prevent your mod's saves from conflicting with other mods.
The first thing you need to do is fill out the modInfo object at the top of [mod.js](/js/mod.js) to set your mod's name, ID (a string), and other information. A unique modId will prevent your mod's saves from conflicting with other mods. Note that changing this after people have started playing will reset their saves.
Most of the time, you won't need to dive deep into the code to create things, but you still can if you really want to, for example to add new Vue components in [v.js](/js/v.js).
The Modding Tree uses [break\_eternity.js](https://github.com/Patashu/break_eternity.js) to store large values. This means that many numbers are `Decimal` objects, and must be treated differently. For example, you have to use `new Decimal(x)` to create a `Decimal` value instead of a plain number, and perform operations on them by calling functions. e.g, instead of `x = x + y`, use `x = x.add(y)`. Keep in mind this also applies to comparison operators, which should be replaced with calling the `.gt`, `.gte`, `.lt`, `.lte`, `.eq`, and `.neq` functions. See the [break\_eternity.js](https://github.com/Patashu/break_eternity.js) docs for more details on working with `Decimal` values.
Most of the time, you won't need to dive deep into the code to create things, but you still can if you really want to.
Almost all values can be either a constant value, or a dynamic value. Dynamic values are defined by putting a function that returns what the value should be at any given time.
All display text can use basic HTML elements (But you can't use most Vue features there).
The Modding Tree uses break_eternity.js to store large values. This means that many numbers are Decimal objects,
and must be treated differently. For example, you have to use `new Decimal(x)` to create a Decimal value instead of a
plain number, and perform operations on them by calling functions. e.g, instead of `x = x + y`, use `x = x.add(y)`.
While reading this documentation, the following key will be used when describing features:
Almost all values can be either a constant value, or a dynamic value. Dynamic values are defined by putting a function
that returns what the value should be at any given time.
- No label: This is required and the game may crash if it isn't included.
- **sometimes required**: This is may be required, depending on other things in the layer.
- **optional**: You can leave this out if you don't intend to use that feature for the layer.
- **assigned automagically**: This value will be set automatically and override any value you set.
- **deprecated**: This feature is not recommended to be used anymore, and may be removed in future versions of TMT.
All display text can be basic HTML instead (But you can't use most Vue features there).
## Table of Contents
# Table of Contents:
## General:
### General
- [Getting Started](getting-started.md): Getting your own copy of the code set up with Github Desktop.
- [Main mod info](main-mod-info.md): How to set up general things for your mod in mod.js.
- [Main mod info](main-mod-info.md): How to set up general things for your mod in [mod.js](/js/mod.js).
- [Basic layer breakdown](basic-layer-breakdown.md): Breaking down the components of a layer with minimal features.
- [Layer features](layer-features.md): Explanations of all of the different properties that you can give a layer.
- [Custom Tab Layouts](custom-tab-layouts.md): An optional way to give your tabs a different layout.
You can even create entirely new components to use.
- [Custom Tab Layouts](custom-tab-layouts.md): An optional way to give your tabs a different layout. You can even create entirely new components to use.
- [Updating TMT](updating-tmt.md): Using Github Desktop to update your mod's version of TMT.
## Common components
### Common components
- [Upgrades](upgrades.md): How to create upgrades for a layer.
- [Milestones](milestones.md): How to create milestones for a layer.
- [Buyables](buyables.md): Create rebuyable upgrades for your layer (with the option to make them respec-able).
Can be used to make Enhancers or Space Buildings.
- [Clickables](clickables.md): A more generalized variant of buyables, for any kind of thing that is sometimes clickable.
Between these and Buyables, you can do just about anything.
- [Buyables](buyables.md): Create rebuyable upgrades for your layer (with the option to make them respec-able). Can be used to make Enhancers or Space Buildings.
- [Clickables](clickables.md): A more generalized variant of buyables, for any kind of thing that is sometimes clickable. Between these and Buyables, you can do just about anything.
## Other components
### Other components
- [Challenges](challenges.md): How to create challenges for a layer.
- [Bars](bars.md): Display some information as a progress bar, gague, or similar. They are highly customizable,
and can be horizontal and vertical as well.
- [Bars](bars.md): Display some information as a progress bar, gauge, or similar. They are highly customizable, and can be horizontal and vertical as well.
- [Subtabs and Microtabs](subtabs-and-microtabs.md): Create subtabs for your tabs, as well as "microtab" components that you can put inside the tabs.
- [Achievements](milestones.md): How to create achievements for a layer (or for the whole game).
- [Infoboxes](infoboxes.md): Boxes containing text that can be shown or hidden.

View file

@ -1,61 +1,50 @@
# Achievements
Achievements are awarded to the player when they meet a certain goal, and give some benefit.
Currently, they are pretty basic, but additional features will be added later to help.
Achievements are awarded to the player when they meet a certain goal, and optionally give some benefit. Currently they are pretty basic, but additional features will be added later to help.
You can make global achievements by putting them in a side layer (make its row "side" instead of a number)
You can make global achievements by putting them in a side layer by making its row equal to "side" instead of a number.
Useful functions for dealing with achievements and implementing their effects:
- hasAchievement(layer, id): determine if the player has the Achievement
- achievementEffect(layer, id): Returns the current effects of the achievement, if any
- hasAchievement(layer, id): determine if the player has the Achievement.
- achievementEffect(layer, id): Returns the current effects of the achievement, if any.
Achievements should be formatted like this:
```js
achievements: {
rows: # of rows
cols: # of columns
11: {
name: "Blah",
more features
}
etc
}
achievements: {
rows: # of rows,
cols: # of columns,
11: {
name: "Blah",
more features
},
etc
}
```
Each achievement should have an id where the first digit is the row and the second digit is the column.
Individual achievement can have these features:
- name: **optional**, displayed at the top of the achievement. The only visible text.
It can also be a function that returns updating text. Can use basic HTML.
- name: **optional**. displayed at the top of the achievement. The only visible text. It can also be a function that returns updating text. Can use basic HTML.
- done(): A function returning a boolean to determine if the achievement should be awarded.
- tooltip: Default tooltip for the achievement, appears when it is hovered over. Should convey the goal and any reward for
completing the achievement. It can also be a function that returns updating text. Can use basic HTML.
- tooltip: Default tooltip for the achievement, appears when it is hovered over. Should convey the goal and any reward for completing the achievement. It can also be a function that returns updating text. Can use basic HTML.
- effect(): **optional**. A function that calculates and returns the current values of any bonuses from the achievement. Can return a value or an object containing multiple values.
- effect(): **optional**, A function that calculates and returns the current values of any bonuses from the achievement.
Can return a value or an object containing multiple values.
- unlocked(): **optional**. A function returning a bool to determine if the achievement is visible or not. Default is unlocked.
- unlocked(): **optional**, A function returning a bool to determine if the achievement is visible or not. Default is unlocked.
- onComplete() - **optional**. this function will be called when the achievement is completed.
- onComplete() - **optional**, this function will be called when the achievement is completed.
- style: **optional**. Applies CSS to this achievement, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).
- style: **Optional**, Applies CSS to this achievement, in the form of an object where the keys are CSS attributes,
and the values are the values for those attributes (both as strings)
- layer: **assigned automagically**. It's the same value as the name of this layer, so you can do `player[this.layer].points` or similar.
- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
- id: **assigned automagically**. It's the "key" which the achievement was stored under, for convenient access. The achievement in the example's id is 11.
- id: **Assigned automagically**. It's the "key" which the achievement was stored under, for convenient access.
The achievement in the example's id is 11.
- goalTooltip: **optional, deprecated**. Appears when the achievement is hovered over and locked, overrides the basic tooltip. This is to display the goal (or a hint). It can also be a function that returns updating text. Can use basic HTML.
- goalTooltip: **optional, depracated** Appears when the achievement is hovered over and locked, overrides the basic tooltip.
This is to display the goal (or a hint). It can also be a function that returns updating text. Can use basic HTML.
- doneTooltip: **optional, depracated** Appears when the achievement is hovered over and completed, overrides the basic tooltip.
This can display what the player achieved (the goal), and the rewards, if any.
It can also be a function that returns updating text. Can use basic HTML.
- doneTooltip: **optional, deprecated**. Appears when the achievement is hovered over and completed, overrides the basic tooltip. This can display what the player achieved (the goal), and the rewards, if any. It can also be a function that returns updating text. Can use basic HTML.

View file

@ -1,39 +1,36 @@
# Bars
Bars let you display information in a more direct way. It can be a progress bar, health bar, capacity gague, or anything else.
Bars let you display information in a more direct way. It can be a progress bar, health bar, capacity gauge, or anything else.
Bars are defined like other Big Features:
```js
bars: {
bigBar: {
display() {return "Blah"},
etc
}
bars: {
bigBar: {
direction: RIGHT,
width: 200,
height: 50,
progress() { return 0 },
etc
}
},
etc
}
```
Features:
- direction: UP, DOWN, LEFT, or RIGHT (not Strings). Determines the direction that the bar is filled as it progresses.
RIGHT means from left to right.
- direction: UP, DOWN, LEFT, or RIGHT (not strings). Determines the direction that the bar is filled as it progresses. RIGHT means from left to right.
- width, height: The size in pixels of the bar, but as Numbers (no "px" at the end)
- width, height: The size in pixels of the bar, but as numbers (no "px" at the end).
- progress(): A function that returns the portion of the bar that is filled, from "empty" at 0 to "full" at 1.
(Nothing bad happens if the value goes out of these bounds, and it can be a number or Decimal).
- progress(): A function that returns the portion of the bar that is filled, from "empty" at 0 to "full" at 1. (Nothing bad happens if the value goes out of these bounds, and it can be a number or `Decimal`)
- display(): **optional**, A function that returns text to be displayed on top of the bar, can use HTML.
- display(): **optional**. A function that returns text to be displayed on top of the bar, can use HTML.
- unlocked(): **optional**, A function returning a bool to determine if the bar is visible or not. Default is unlocked.
- unlocked(): **optional**. A function returning a bool to determine if the bar is visible or not. Default is unlocked.
- baseStyle, fillStyle, borderStyle, textStyle: **Optional**, Apply CSS to the unfilled portion, filled portion, border, and
display text on the bar, in the form of an object where the keys are CSS attributes, and the values are the
values for those attributes (both as strings).
- baseStyle, fillStyle, borderStyle, textStyle: **Optional**, Apply CSS to the unfilled portion, filled portion, border, and display text on the bar, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).
- layer: **assigned automagically**. It's the same value as the name of this layer, so you can do `player[this.layer].points` or similar.
- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
- id: **Assigned automagically**. It's the "key" which the bar was stored under, for convenient access.
The bar in the example's id is "bigBar".
- id: **assigned automagically**. It's the "key" which the bar was stored under, for convenient access. The bar in the example's id is "bigBar".

View file

@ -2,34 +2,33 @@
This is a very minimal layer with minimal features. Most things will require additional features.
```js
p: {
startData() { return { // startData is a function that returns default data for a layer.
unlocked: false, // You can add more variables here to add them to your layer.
points: new Decimal(0), // "points" is the internal name for the main resource of the layer.
}},
addLayer("p", {
startData() { return { // startData is a function that returns default data for a layer.
unlocked: true, // You can add more variables here to add them to your layer.
points: new Decimal(0), // "points" is the internal name for the main resource of the layer.
}},
color: "#FE0102", // The color for this layer, which affects many elements
resource: "prestige points", // The name of this layer's main prestige resource
row: 0, // The row this layer is on (0 is the first row)
color: "#4BDC13", // The color for this layer, which affects many elements.
resource: "prestige points", // The name of this layer's main prestige resource.
row: 0, // The row this layer is on (0 is the first row).
baseResource: "points", // The name of the resource your prestige gain is based on
baseAmount() {return player.points}, // A function to return the current value of that resource
baseResource: "points", // The name of the resource your prestige gain is based on.
baseAmount() { return player.points }, // A function to return the current amount of baseResource.
requires: new Decimal(200), // The amount of the base needed to gain 1 of the prestige currency.
// Also the amount required to unlock the layer.
type: "normal", // Determines the formula used for calculating prestige currency.
exponent: 0.5, // "normal" prestige gain is (currency^exponent)
requires: new Decimal(10), // The amount of the base needed to gain 1 of the prestige currency.
// Also the amount required to unlock the layer.
gainMult() { // Returns your multiplier to your gain of the prestige resource
return new Decimal(1) // Factor in any bonuses multiplying gain here
},
gainExp() { // Returns your exponent to your gain of the prestige resource
return new Decimal(1)
},
type: "normal", // Determines the formula used for calculating prestige currency.
exponent: 0.5, // "normal" prestige gain is (currency^exponent).
layerShown() {return true}, // Returns a bool for if this layer's node should be visible in the tree.
gainMult() { // Returns your multiplier to your gain of the prestige resource.
return new Decimal(1) // Factor in any bonuses multiplying gain here.
},
```
gainExp() { // Returns your exponent to your gain of the prestige resource.
return new Decimal(1)
},
layerShown() { return true } // Returns a bool for if this layer's node should be visible in the tree.
})
```

View file

@ -1,69 +1,63 @@
# Buyables
Buyables are usually things that can be bought multiple times with scaling costs. If you set a respec function,
the player can reset the purchases to get their currency back.
Buyables are usually things that can be bought multiple times with scaling costs. If you set a respec function, the player can reset the purchases to get their currency back.
The amount of a buyable owned is a Decimal.
You can get or set the amount of a buyable with getBuyableAmt(layer, id) and setBuyableAmt(layer, id, amt).
You can use buyableEffect(layer, id) to get the current effects of a buyable.
The amount of a buyable owned is a `Decimal`.
Useful functions for dealing with buyables and implementing their effects:
- getBuyableAmt(layer, id): get the amount of the buyable the player has
- setBuyableAmount(layer, id, amount): set the amount of the buyable the player has
- buyableEffect(layer, id): Returns the current effects of the buyable, if any.
Buyables should be formatted like this:
```js
buyables: {
rows: # of rows
cols: # of columns
respec() {}, //**optional**, implement it to reset things and give back your currency.
// Having this function makes a respec button appear
respecText:// **optional**, text that appears on the respec button
showRespecButton(){} //**optional**, a function determining whether or not to show the button. Defaults to true if absent.
sellOneText, sellAllText:// **optional**, text that appears on the "sell one" and "sell all" buttons respectively (if you are using them)
11: {
display() {return "Blah"},
etc
}
buyables: {
rows: # of rows,
cols: # of columns,
11: {
cost(x) { return new Decimal(1).mul(x || getBuyableAmt(this.layer, this.id)) },
display() { return "Blah" },
canAfford() { return player[this.layer].points.gte(this.cost()) },
buy() {
player[this.layer].points = player[this.layer].points.sub(this.cost())
setBuyableAmount(this.layer, this.id, getBuyableAmt(this.layer, this.id).add(1))
},
etc
}
},
etc
}
```
Features:
- title: **optional**, displayed at the top in a larger font
It can also be a function that returns updating text.
- title: **optional**. displayed at the top in a larger font. It can also be a function that returns updating text.
- cost(): cost for buying the next buyable. Can have an optional argument "x" to calculate the cost of the x+1th object,
but needs to use "current amount" as a default value for x. (x is a Decimal).
Can return an object if there are multiple currencies.
- cost(): cost for buying the next buyable. Can have an optional argument "x" to calculate the cost of the x+1th object, but needs to use "current amount" as a default value for x. (x is a `Decimal`). Can return an object if there are multiple currencies.
- effect(): **optional**, A function that calculates and returns the current values of bonuses
of this buyable. Can return a value or an object containing multiple values.
- effect(): **optional**. A function that calculates and returns the current values of bonuses of this buyable. Can return a value or an object containing multiple values.
- display(): A function returning everything that should be displayed on the buyable after the title, likely
including the description, amount bought, cost, and current effect. Can use basic HTML.
- display(): A function returning everything that should be displayed on the buyable after the title, likely including the description, amount bought, cost, and current effect. Can use basic HTML.
- unlocked(): **optional**, A function returning a bool to determine if the buyable is visible or not. Default is unlocked.
- unlocked(): **optional**. A function returning a bool to determine if the buyable is visible or not. Default is unlocked.
- canAfford(): A function returning a bool to determine if you can buy one of the buyables.
- buy(): A function that implements buying one of the buyable, including spending the currency.
- buyMax(): **optional**, A function that implements buying as many of the buyable as possible.
- buyMax(): **optional**. A function that implements buying as many of the buyable as possible.
- style: **Optional**, Applies CSS to this buyable, in the form of an object where the keys are CSS attributes,
and the values are the values for those attributes (both as strings)
- style: **optional**. Applies CSS to this buyable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).
- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
- layer: **assigned automagically**. It's the same value as the name of this layer, so you can do `player[this.layer].points` or similar.
- id: **Assigned automagically**. It's the "key" which the buyable was stored under, for convenient access.
The buyable in the example's id is 11.
- id: **assigned automagically**. It's the "key" which the buyable was stored under, for convenient access. The buyable in the example's id is 11.
Sell One/Sell All:
Including a sellOne or sellAll function will cause an additional button to appear beneath the buyable.
They are functionally identical, but "sell one" appears above "sell all". You can also use them for other things.
Including a `sellOne` or `sellAll` function will cause an additional button to appear beneath the buyable. They are functionally identical, but "sell one" appears above "sell all". You can also use them for other things.
sellOne/sellAll(): **optional**, Called when the button is pressed. The standard use would be to decrease/reset the amount of the buyable,
And possibly return some currency to the player.
- sellOne/sellAll(): **optional**. Called when the button is pressed. The standard use would be to decrease/reset the amount of the buyable, and possibly return some currency to the player.
canSellOne/canSellAll(): **optional**, booleans determining whether or not to show the buttons. If "canSellOne/All" is absent but
"sellOne/All" is present, the appropriate button will always show.
- canSellOne/canSellAll(): **optional**. booleans determining whether or not to show the buttons. If "canSellOne/All" is absent but "sellOne/All" is present, the appropriate button will always show.

View file

@ -2,67 +2,63 @@
Useful functions for dealing with Challenges and implementing their effects:
- inChallenge(layer, id): determine if the player is in a given challenge (or another challenge on the same layer that counts as this one)
- hasChallenge(layer, id): determine if the player has completed the challenge
- challengeCompletions(layer, id): determine how many times the player completed the challenge
- challEffect(layer, id): Returns the current effects of the challenge, if any
- inChallenge(layer, id): determine if the player is in a given challenge (or another challenge on the same layer that counts as this one).
- hasChallenge(layer, id): determine if the player has completed the challenge.
- challengeCompletions(layer, id): determine how many times the player completed the challenge.
- challengeEffect(layer, id): Returns the current effects of the challenge, if any.
Challenges are stored in the following format:
```js
challenges: {
rows: # of rows
cols: # of columns
11: {
name: "Ouch",
etc
}
challenges: {
rows: # of rows,
cols: # of columns,
11: {
name: "Ouch",
challengeDescription: "description of ouchie",
goal: new Decimal(100),
etc
}
},
etc
}
```
Each challenge should have an id where the first digit is the row and the second digit is the column.
Individual Challenges can have these features:
- name: Name of the challenge, can be a string or a function. Can use basic HTML.
- challengeDescription: A description of what makes the challenge a challenge. *You will need to implement these elsewhere*
It can also be a function that returns updating text. Can use basic HTML.
- challengeDescription: A description of what makes the challenge a challenge. *You will need to implement these elsewhere.* It can also be a function that returns updating text. Can use basic HTML.
- rewardDescription: A description of the reward's effect. *You will also have to implement the effect where it is applied.*
It can also be a function that returns updating text. Can use basic HTML.
- rewardDescription: A description of the reward's effect. *You will also have to implement the effect where it is applied.* It can also be a function that returns updating text. Can use basic HTML.
- rewardEffect(): **optional**, A function that calculates and returns the current values of any bonuses from the reward.
Can return a value or an object containing multiple values. Can use basic HTML.
- rewardEffect(): **optional**. A function that calculates and returns the current values of any bonuses from the reward. Can return a value or an object containing multiple values. Can use basic HTML.
- rewardDisplay(): **optional**, A function that returns a display of the current effects of the reward with
formatting. Default behavior is to just display the a number appropriately formatted.
- rewardDisplay(): **optional**. A function that returns a display of the current effects of the reward with formatting. Default behavior is to just display the a number appropriately formatted.
- goal: A Decimal for the amount of currency required to beat the challenge. By default, the goal is in basic Points.
The goal can also be a function if its value changes.
- goal: A Decimal for the amount of currency required to beat the challenge. By default, the goal is in basic Points. The goal can also be a function if its value changes.
- unlocked(): **optional**, A function returning a bool to determine if the challenge is visible or not. Default is unlocked.
- unlocked(): **optional**. A function returning a bool to determine if the challenge is visible or not. Default is unlocked.
- onComplete() - **optional**, this function will be called when the challenge is completed when previously incomplete.
- onComplete() - **optional**. this function will be called when the challenge is completed when previously incomplete.
- countsAs: **optional**, If a challenge combines the effects of other challenges in this layer, you can use this.
An array of challenge ids. The player is effectively in all of those challenges when in the current one.
- countsAs: **optional**. If a challenge combines the effects of other challenges in this layer, you can use this. An array of challenge ids. The player is effectively in all of those challenges when in the current one.
By default, challenges use basic Points for the goal. You can change that using these features.
- currencyDisplayName: **optional**, the name to display for the currency for the goal
- currencyInternalName: **optional**, the internal name for that currency
- currencyLayer: **optional**, the internal name of the layer that currency is stored in.
If it's not in a layer, omit. If it's not stored directly in a layer, instead use the next feature.
- currencyLocation: **optional**, if your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way.
This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)
- completionLimit: **optional**. the amount of times you can complete this challenge. Default is 1 completion.
- completionLimit: **optional**, the amount of times you can complete this challenge. Default is 1 completion.
- style: **optional**. Applies CSS to this challenge, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).
- style: **Optional**, Applies CSS to this challenge, in the form of an object where the keys are CSS attributes,
and the values are the values for those attributes (both as strings)
- layer: **assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
- id: **assigned automagically**. It's the "key" which the challenge was stored under, for convenient access. The challenge in the example's id is 11.
- id: **Assigned automagically**. It's the "key" which the challenge was stored under, for convenient access.
The challenge in the example's id is 11.
By default, challenges use basic Points for the goal. You can change that using these features:
- currencyDisplayName: **optional**. the name to display for the currency for the goal
- currencyInternalName: **optional**. the internal name for that currency
- currencyLayer: **optional**. the internal name of the layer that currency is stored in. If it's not in a layer, omit. If it's not stored directly in a layer, instead use the next feature.
- currencyLocation: **optional**. if your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way. This is a function returning the object in "player" that contains the value (like `player[this.layer].buyables`)

View file

@ -4,53 +4,52 @@ Clickables are any kind of thing that you can click for an effect. They're a mor
DO NOT USE THESE TO MAKE THINGS THAT YOU CLICK REPEATEDLY FOR A BONUS BECAUSE THOSE ARE AWFUL.
There are several differences between the two. One is that a buyable's saved data is its amount as a Decimal, while
Clickables store a "state" which can be a number or string, but not Decimal, array, or object).
Buyables have a number of extra features which you can see on their page.
Clickables also have a smaller default size.
There are several differences between the two. One is that a buyable's saved data is its amount as a `Decimal`, while Clickables store a "state" which can be a number or string, but not `Decimal`, array, or object). Buyables have a number of extra features which you can see on their page. Clickables also have a smaller default size.
You can get and set a clickable's state with getClickableState(layer, id) and setClickableState(layer, id, state).
You can use clickableEffect(layer, id) to get the current effects of a clickable.
Useful functions for dealing with achievements and implementing their effects:
- getClickableState(layer, id): get the state of the clickable the player has
- setClickableState(layer, id, state): set the state of the buyable the player has
- clickableEffect(layer, id): Returns the current effects of the clickable, if any.
Clickables should be formatted like this:
```js
clickables: {
rows: # of rows
cols: # of columns
masterButtonPress() // **optional** If this is present, an additional button will appear above the clickables.
// pressing it will call the function.
masterButtonText: "Press me!" // **optional** text to display on the Master Button
showMasterButton(){} //**optional**, a function determining whether or not to show the button. Defaults to true if absent.
11: {
display() {return "Blah"},
etc
}
clickables: {
rows: # of rows,
cols: # of columns,
11: {
display() {return "Blah"},
etc
}
etc
}
```
Features:
- title: **optional**, displayed at the top in a larger font
It can also be a function that returns updating text.
- title: **optional**. displayed at the top in a larger font. It can also be a function that returns updating text.
- effect(): **optional**, A function that calculates and returns the current values of bonuses
of this clickable. Can return a value or an object containing multiple values.
- effect(): **optional**. A function that calculates and returns the current values of bonuses of this clickable. Can return a value or an object containing multiple values.
- display(): A function returning everything that should be displayed on the clickable after the title, likely
changing based on its state. Can use basic HTML.
- display(): A function returning everything that should be displayed on the clickable after the title, likely changing based on its state. Can use basic HTML.
- unlocked(): **optional**, A function returning a bool to determine if the clickable is visible or not. Default is unlocked.
- unlocked(): **optional**. A function returning a bool to determine if the clickable is visible or not. Default is unlocked.
- canClick(): A function returning a bool to determine if you can click the clickable.
- onClick(): A function that implements clicking one of the clickable.
- style: **Optional**, Applies CSS to this clickable, in the form of an object where the keys are CSS attributes,
and the values are the values for those attributes (both as strings)
- style: **optional**. Applies CSS to this clickable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).
- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.
- layer: **assigned automagically**. It's the same value as the name of this layer, so you can do `player[this.layer].points` or similar.
- id: **Assigned automagically**. It's the "key" which the clickable was stored under, for convenient access.
The clickable in the example's id is 11.
- id: **assigned automagically**. It's the "key" which the clickable was stored under, for convenient access. The clickable in the example's id is 11.
You can also use these features on the clickables object to add a button above all the clickables, for implementing a respec button or similar.
- masterButtonPress(): **optional**. If present, an additional button will appear above the clickables. Pressing it will call this function.
- masterButtonText: **optional**. Text to display on the Master Button.
- showMasterButton(): **optional**. A function determining whether or not to show the button. Defaults to true if absent.

View file

@ -1,53 +1,49 @@
# Custom tab layouts
Note: If you are using subtabs, tabFormat is used differently, but you still use the same format within each subtabs.
[See here for more on subtabs](subtabs-and-microtabs.md)
Note: If you are using subtabs, `tabFormat` is used differently, but you still use the same format within each subtabs. [See here for more on subtabs](subtabs-and-microtabs.md).
Custom tab layouts can be used to do basically anything in a tab window, especially combined with the "style" layer feature. The tabFormat feature is an array of things, like this:
Custom tab layouts can be used to do basically anything in a tab window, especially combined with the "style" layer feature. The `tabFormat` feature is an array of things, like this:
```js
tabFormat: ["main-display",
["prestige-button", function(){return "Melt your points into "}],
"blank",
["display-text",
function() {return 'I have ' + format(player.points) + ' pointy points!'},
{"color": "red", "font-size": "32px", "font-family": "Comic Sans MS"}],
"blank",
["toggle", ["c", "beep"]],
"milestones", "blank", "blank", "upgrades"]
tabFormat: [
"main-display",
["prestige-button", function() { return "Melt your points into " }],
"blank",
["display-text",
function() { return 'I have ' + format(player.points) + ' pointy points!' },
{ "color": "red", "font-size": "32px", "font-family": "Comic Sans MS" }],
"blank",
["toggle", ["c", "beep"]],
"milestones",
"blank",
"blank",
"upgrades"
]
```
It is a list of components, which can be either just a name, or an array with arguments. If it's an array,
the first item is the name of the component, the second is the data passed into it, and the third (optional)
applies a CSS style to it with a "CSS object", where the keys are CSS attributes.
It is a list of components, which can be either just a name, or an array with arguments. If it's an array, the first item is the name of the component, the second is the data passed into it, and the third (optional) applies a CSS style to it with a "CSS object", where the keys are CSS attributes.
These are the existing components, but you can create more in v.js:
These are the existing components, but you can create more in [v.js](/js/v.js):
- display-text: Displays some text (can use basic HTML). The argument is the text to display. It can also be a function that returns updating text.
- raw-html: Displays some basic HTML, can also be a function.
- blank: Adds empty space. The default dimensions are 8px x 17px. The argument changes the dimensions.
If it's a single value (e.g. "20px"), that determines the height.
If you have a pair of arguments, the first is width and the second is height.
- blank: Adds empty space. The default dimensions are 8px x 17px. The argument changes the dimensions. If it's a single value (e.g. "20px"), that determines the height. If you have a pair of arguments, the first is width and the second is height.
- row: Display a list of components horizontally. The argument is an array of components in the tab layout format.
- column: Display a list of components vertically. The argument is an array of components in the tab layout format.
This is useful to display columns within a row.
- column: Display a list of components vertically. The argument is an array of components in the tab layout format. This is useful to display columns within a row.
- main-display: The text that displays the main currency for the layer and its effects.
- resource-display: The text that displays the currency that this layer is based on, as well as the best and/or total
values for this layer's prestige currency (if they are put in startData for this layer)
- resource-display: The text that displays the currency that this layer is based on, as well as the best and/or total values for this layer's prestige currency (if they are put in `startData` for this layer).
- prestige-button: The argument is a string that the prestige button should say before the amount of
currency you will gain. It can also be a function that returns updating text.
- prestige-button: The argument is a string that the prestige button should say before the amount of currency you will gain. It can also be a function that returns updating text.
- upgrades, milestones, challs, achievements: Display the upgrades, milestones, and challenges for a layer, as appropriate.
- upgrades, milestones, challenges, achievements: Display the upgrades, milestones, and challenges for a layer, as appropriate.
- buyables, clickables: Display all of the buyables/clickables for this layer, as appropriate. The argument optional,
and is the size of the boxes in pixels.
- buyables, clickables: Display all of the buyables/clickables for this layer, as appropriate. The argument is optional and is the size of the boxes in pixels.
- microtabs: Display a set of subtabs for an area. The argument is the name of the set of microtabs in the "microtabs" feature.
@ -55,14 +51,12 @@ These are the existing components, but you can create more in v.js:
- infobox: Display an infobox. The argument is the id of the infobox to display.
- toggle: A toggle button that toggles a bool value. The data is a pair that identifies what bool to toggle, [layer, id]
- toggle: A toggle button that toggles a bool value. The data is a pair that identifies what bool to toggle, e.g. `[layer, id]`
The rest of the components are sub-components. They can be used just like other components, but are typically part of another component.
- upgrade, milestone, chall, buyable, clickable, achievement: An individual upgrade, challenge, etc. The argument is the id.
This can be used if you want to have upgrades split up across multiple subtabs, for example.
- upgrade, milestone, challenge, buyable, clickable, achievement: An individual upgrade, challenge, etc. The argument is the id. This can be used if you want to have upgrades split up across multiple subtabs, for example.
- respec-button, master-button: The respec and master buttons for buyables and clickables, respectively.
- sell-one, sell-all: The "sell one" and "sell all" for buyables, respectively. The argument is the id of the buyable.
- sell-one, sell-all: The "sell one" and "sell all" for buyables, respectively. The argument is the id of the buyable.

View file

@ -2,62 +2,47 @@
Welcome to The Modding Tree!
Using the Modding Tree, at its simplest level, just requires getting a copy of it onto your computer.
However, if you do it the right way, it will help in many ways.
Using the Modding Tree, at its simplest level, just requires getting a copy of it onto your computer. However, if you do it the right way, it will help in many ways.
Don't let the word "Github" scare you away. It's actually much easier to use than most people think,
especially because most people use it the hard way. The key is Github Desktop, which lets you do
everything you need to, without even touching the command line.
Don't let the word "Github" scare you away. It's actually much easier to use than most people think, especially because most people use it the hard way. The key is Github Desktop, which lets you do everything you need to, without even touching the command line.
The benefits of using Github:
- It makes it much, much easier to update The Modding Tree.
- You can share your work without any extra effort using githack, or with a bit more effort,
set up a github.io site.
- You can share your work without any extra effort using githack, or with a bit more effort, set up a github.io site.
- It lets you undo changes to your code, and to have multiple versions of it.
- It lets you collaborate with other people, if you want to.
## Getting set up with Github and The Modding Tree:
## Getting set up with Github Desktop, Visual Studio Code, and The Modding Tree:
1. Install [Github Desktop](https://desktop.github.com/) and [Visual Studio Code](https://code.visualstudio.com/).
2. Make a Github account. You can handle this on your own.
3. Log in on your browser, and go back to [The Modding Tree page](https://github.com/Acamaeda/The-Modding-Tree). At the top right,
there should be a button that says "fork". Click on it, and then on your username.
You now have your own fork, or copy, of The Modding Tree.
3. Log in on your browser, and go back to [The Modding Tree page](https://github.com/Acamaeda/The-Modding-Tree). At the top right, there should be a button that says "fork". Click on it, and then on your username. You now have your own fork, or copy, of The Modding Tree.
4. Open Github Desktop and log in. Ignore everything else and choose "clone a repository".
A "repository" is basically a "Github project", like The Modding Tree. "Cloning" is
downloading a copy of the repository to your computer.
4. Open Github Desktop and log in. Ignore everything else and choose "clone a repository". A "repository" is basically a "Github project", like The Modding Tree. "Cloning" is downloading a copy of the repository to your computer.
5. Look for The Modding Tree in the list of repositiories (it should be the only one) and click "clone".
6. Select that you're using it for your own purposes, and click continue. It will download the files and handle everything.
### Using your repository
## Using your repository
1. Click on "show in finder" to the right, and then open index.html. This will let you view and
test your project!
1. Click on "show in finder" to the right, and then open index.html. This will let you view and test your project!
2. To edit your project, click "open in VSCode" in Github Desktop.
3. Open mod.js in VSCode, and look at the top part where it says "modInfo". On the lines below that, change
the mod's name to whatever you want, and change the id as well. (It can be any string value, and it's used to determine
where the savefile is. Make it something that's probably unique, and don't change it again later.)
3. Open [mod.js](/js/mod.js) in VSCode, and look at the top part where it has a "modInfo" object. Fill in your mod's name to whatever you want, and change the id as well. (It can be any string value, and it's used to determine where the savefile is. Make it something that's probably unique, and don't change it again later or else it'll effectively wipe existing saves)
4. Save game.js, and then reload index.html. The title on the tab, as well as on the info page, will now be the new ones!
4. Save [mod.js](/js/mod.js), and then reload [index.html](/index.html) in your browser. The title on the tab, as well as on the info page, will now be the ones you configured!
5. Go back to Github Desktop. It's time to save your changes into the git system by making a "commit".
5. Go back to Github Desktop. It's time to save your changes into the git system by making a "commit". This basically saves your work and creates a snapshot of what your code looks like at this moment, allowing you to look back at it later.
6. At the bottom right corner, add a summary of your changes, and then click "commit to master".
7. Finally, at the top middle, click "push origin" to push your changes out onto the online repository.
8. You can view your project on line, or share it with others, by going to
https://raw.githack.com/[YOUR-GITHUB-USERNAME]/The-Modding-Tree/master/index.html
8. You can view your project on line, or share it with others, by going to https://raw.githack.com/[YOUR-GITHUB-USERNAME]/The-Modding-Tree/master/index.html
And now, you have successfully used Github! You can look at the [documentation](!general-info.md) to
see how The Modding Tree's system works and to make your mod a reality.
And now, you have successfully used Github! You can look at the [documentation](!general-info.md) to see how The Modding Tree's system works and to make your mod a reality.

View file

@ -7,13 +7,14 @@ In the default tab layout, the first infobox will be displayed at the very top o
Infoboxes are defined like other Big Features:
```js
infoboxes: {
infobox: {
display() {return "Blah"},
etc
}
infoboxes: {
lore: {
title: "foo",
body() { return "bar" },
etc
}
},
etc
}
```
Features:
@ -22,13 +23,10 @@ Features:
- body: The text displayed inside the box. Can be a function to be dynamic, and can use basic HTML.
- style, titleStyle, bodyStyle: **Optional**, Apply CSS to the infobox, or to the title button or body of the infobox,
in the form of an object where the keys are CSS attributes, and the values are the Values for
those attributes (both as strings).
- style, titleStyle, bodyStyle: **optional**. Apply CSS to the infobox, or to the title button or body of the infobox, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).
- unlocked(): **optional**, A function returning a bool to determine if the infobox is visible or not. Default is unlocked.
- unlocked(): **optional**. A function returning a bool to determine if the infobox is visible or not. Default is unlocked.
- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
- layer: **assigned automagically**. It's the same value as the name of this layer, so you can do `player[this.layer].points` or similar
- id: **Assigned automagically**. It's the "key" which the bar was stored under, for convenient access.
The bar in the example's id is "bigBar".
- id: **assigned automagically**. It's the "key" which the bar was stored under, for convenient access. The infobox in the example's id is "lore".

View file

@ -1,212 +1,150 @@
# Layer Features
This is a more comprehensive list of established features to add to layers.
You can add more freely, if you want to have other functions or values associated with your layer. These have special functionality, though.
This is a more comprehensive list of established features to add to layers. You can add more freely, if you want to have other functions or values associated with your layer. These have special functionality, though.
You can make almost any value dynamic by using a function in its place, including all display strings and styling/color features.
Key:
- No label: This is required and the game will crash if it isn't included.
- **sometimes required**: This is may be required, depending on other things in the layer.
- **optional**: You can leave this out if you don't intend to use that feature for the layer.
## Layer Definition features
- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
to access the save value. It makes copying code to new layers easier. It is also assigned to all upgrades and buyables and such.
- layer: **assigned automagically**. It's the same value as the name of this layer, so you can do `player[this.layer].points` or similar to access the saved value. It makes copying code to new layers easier. It is also assigned to all upgrades and buyables and such.
- name: **Optional**, used in reset confirmations (and maybe other places). If absent, it just uses the layer's id.
- name: **optional**. used in reset confirmations (and the default infobox title). If absent, it just uses the layer's id.
- startData(): A function to return the default save data for this layer. Add any variables you have to it. Make sure to use `Decimal` values rather than normal numbers.
- startData(): A function to return the default save data for this layer. Add any variables you have to it.
Any nonstandard Decimal variables need to be added to convertToDecimal as well.
Standard values:
Required:
unlocked: a bool determining if this layer is unlocked or not
points: a Decimal, the main currency for the layer
Optional:
total: A Decimal, tracks total amount of main prestige currency
best: A Decimal, tracks highest amount of main prestige currency
unlockOrder: used to keep track of relevant layers unlocked before this one.
- Required:
- unlocked: a bool determining if this layer is unlocked or not
- points: a Decimal, the main currency for the layer
- Optional:
- total: A Decimal, tracks total amount of main prestige currency
- best: A Decimal, tracks highest amount of main prestige currency
- unlockOrder: used to keep track of relevant layers unlocked before this one.
- color: A color associated with this layer, used in many places. (A string in hex format with a #)
- row: The row of the layer, starting at 0. This affects where the node appears on the tree, and which resets affect the layer.
Using "side" instead of a number will cause the layer to appear off to the side as a smaller node (useful for achievements
and statistics). Side layers are not affected by resets unless you add a doReset to them.
Using "side" instead of a number will cause the layer to appear off to the side as a smaller node (useful for achievements and statistics). Side layers are not affected by resets unless you add a doReset to them.
- resource: Name of the main currency you gain by resetting on this layer.
- effect(): **optional**, A function that calculates and returns the current values of any bonuses
inherent to the main currency.
Can return a value or an object containing multiple values.
*You will also have to implement the effect where it is applied.*
- effect(): **optional**. A function that calculates and returns the current values of any bonuses inherent to the main currency. Can return a value or an object containing multiple values. *You will also have to implement the effect where it is applied.*
- effectDescription: **optional**, A function that returns a description of this effect.
If the text stays constant, it can just be a string.
- effectDescription: **optional**. A function that returns a description of this effect. If the text stays constant, it can just be a string.
- layerShown(): A function returning a bool which determines if this layer's node should be visible on the tree.
It can also return "ghost", which will hide the layer, but its node will still take up space in the tree.
- layerShown(): A function returning a bool which determines if this layer's node should be visible on the tree. It can also return "ghost", which will hide the layer, but its node will still take up space in the tree.
- hotkeys: **optional**. An array containing information on any hotkeys associated with this layer:
- hotkeys: **optional**, An array containing information on any hotkeys associated with this layer:
```js
hotkeys: [
{key: "p", // What the hotkey button is. Use uppercase if it's combined with shift, or "ctrl+x" if ctrl is.
desc: "p: reset your points for prestige points", // The description of the hotkey used in the How To Play
onPress(){if (player.p.unlocked) doReset("p")}}, // This function is called when the hotkey is pressed.
],
{
key: "p", // What the hotkey button is. Use uppercase if it's combined with shift, or "ctrl+x" for holding down ctrl.
desc: "p: reset your points for prestige points", // The description of the hotkey that is displayed in the game's How To Play tab
onPress() { if (player.p.unlocked) doReset("p") }
}
]
```
- style: **optional**, a "CSS object" where the keys are CSS attributes ,containing any CSS that should affect this
layer's entire tab.
- style: **optional**. a "CSS object" where the keys are CSS attributes, containing any CSS that should affect this layer's entire tab.
- tabFormat: **optional**, use this if you want to add extra things to your tab or change the layout. [See here for more info.](custom-tab-layouts.md)
- midsection: **optional**, an alternative to tabFormat, which is inserted in between Milestones and Buyables in the
standard tab layout. (cannot do subtabs)
- tabFormat: **optional**. use this if you want to add extra things to your tab or change the layout. [See here for more info.](custom-tab-layouts.md)
- midsection: **optional**, an alternative to `tabFormat`, which is inserted in between Milestones and Buyables in the standard tab layout. (cannot do subtabs)
## Big features (all optional)
- upgrades: A grid of one-time purchases which can have unique upgrade conditions, currency costs, and bonuses.
[Explanations are in a separate file.](upgrades.md)
- upgrades: A grid of one-time purchases which can have unique upgrade conditions, currency costs, and bonuses. [See here for more info.](upgrades.md)
- milestones: A list of bonuses gained upon reaching certain thresholds of a resource. Often used for automation/QOL.
[Explanations are in a separate file.](milestones.md)
- milestones: A list of bonuses gained upon reaching certain thresholds of a resource. Often used for automation/QOL. [See here for more info.](milestones.md)
- challenges: The player can enter challenges, which make the game harder. If they reach a goal and beat the challenge,
they recieve a bonus.
[Explanations are in a separate file.](challenges.md)
- challenges: The player can enter challenges, which make the game harder. If they reach a goal and beat the challenge, they recieve a bonus. [See here for more info.](challenges.md)
- buyables: Effectively upgrades that can be bought multiple times, and are optionally respeccable. Many uses.
[Explanations are in a separate file.](buyables.md)
- buyables: Effectively upgrades that can be bought multiple times, and are optionally respeccable. Many uses. [See here for more info.](buyables.md)
- clickables: Extremely versatile and generalized buttons which can only be clicked sometimes.
[Explanations are in a separate file.](clickables.md)
- clickables: Extremely versatile and generalized buttons which can only be clicked sometimes. [See here for more info.](clickables.md)
- microtabs: An area that functions like a set of subtabs, with buttons at the top changing the content within. (Advanced)
[Explanations are in a separate file.](subtabs-and-microtabs.md)
- microtabs: An area that functions like a set of subtabs, with buttons at the top changing the content within. (Advanced) [See here for more info.](subtabs-and-microtabs.md)
- bars: Display some information as a progress bar, gague, or similar. They are highly customizable, and can be vertical as well.
[Explanations are in a separate file.](bars.md)
- bars: Display some information as a progress bar, gague, or similar. They are highly customizable, and can be vertical as well. [See here for more info.](bars.md)
- achievements: Kind of like milestones, but with a different display style and some other differences. Extra features are on the way at a later date!
[Explanations are in a separate file.](achievements.md)
- infoboxes: Displays some text in a box that can be shown or hidden.
[Explanations are in a separate file.](infoboxes.md)
- achievements: Kind of like milestones, but with a different display style and some other differences. Extra features are on the way at a later date! [See here for more info.](achievements.md)
- infoboxes: Displays some text in a box that can be shown or hidden. [See here for more info.](infoboxes.md)
## Prestige formula features
- type: **optional**, Determines which prestige formula you use. Defaults to "none".
"normal": The amount of currency you gain is independent of its current amount (like Prestige).
formula before bonuses is based on `baseResource^exponent`
"static": The cost is dependent on your total after reset.
formula before bonuses is based on `base^(x^exponent)`
"custom": You can define everything, from the calculations to the text on the button, yourself. (See more at the bottom)
"none": This layer does not prestige, and therefore does not need any of the other features in this section.
- type: **optional**. Determines which prestige formula you use. Defaults to "none".
- "normal": The amount of currency you gain is independent of its current amount (like Prestige). The formula before bonuses is based on `baseResource^exponent`
- "static": The cost is dependent on your total after reset. The formula before bonuses is based on `base^(x^exponent)`
- "custom": You can define everything, from the calculations to the text on the button, yourself. (See more at the bottom)
- "none": This layer does not prestige, and therefore does not need any of the other features in this section.
- baseResource: The name of the resource that determines how much of the main currency you gain on reset.
- baseAmount(): A function that gets the current value of the base resource.
- requires: A Decimal, the amount of the base needed to gain 1 of the prestige currency.
Also the amount required to unlock the layer.
You can instead make this a function, to make it harder if another layer was unlocked first (based on unlockOrder).
- requires: A Decimal, the amount of the base needed to gain 1 of the prestige currency. Also the amount required to unlock the layer. You can instead make this a function, to make it harder if another layer was unlocked first (based on unlockOrder).
- exponent: Used as described above.
- base: **sometimes required**, required for "static" layers, used as described above. If absent, defaults to 2.
Must be greater than 1.
- base: **sometimes required**. required for "static" layers, used as described above. If absent, defaults to 2. Must be greater than 1.
- roundUpCost: **optional**, a bool, which is true if the resource cost needs to be rounded up.
(use if the base resource is a "static" currency.)
- roundUpCost: **optional**. a bool, which is true if the resource cost needs to be rounded up. (use if the base resource is a "static" currency.)
- canBuyMax(): **sometimes required**, required for static layers, function used to determine if buying max is permitted.
- canBuyMax(): **sometimes required**. required for static layers, function used to determine if buying max is permitted.
- gainMult(), gainExp(): **optional**, Functions that calculate the multiplier and exponent on resource gain from upgrades
and boosts and such. Plug in any bonuses here.
- gainMult(), gainExp(): **optional**. Functions that calculate the multiplier and exponent on resource gain from upgrades and boosts and such. Plug in any bonuses here.
- onPrestige(gain): **optional**, A function that triggers when this layer prestiges, just before you gain the currency.
Can be used to have secondary resource gain on prestige, or to recalculate things or whatnot.
- resetDesc: **optional**, use this to replace "Reset for " on the Prestige button with something else.
- prestigeButtonText(): **Sometimes required**, Use this to make the entirety of the text a Prestige button contains. Only required for custom layers,
but usable by all types.
- onPrestige(gain): **optional**. A function that triggers when this layer prestiges, just before you gain the currency. Can be used to have secondary resource gain on prestige, or to recalculate things or whatnot.
- resetDesc: **optional**. Use this to replace "Reset for " on the Prestige button with something else.
- prestigeButtonText(): **sometimes required**. Use this to make the entirety of the text a Prestige button contains. Only required for custom layers, but usable by all types.
## Tree/node features
- symbol: **optional**, the text that appears on this layer's node. Default is the layer id with the first letter capitalized
- symbol: **optional**. The text that appears on this layer's node. Default is the layer id with the first letter capitalized.
- position: **optional**, Determines the horizontal position of the layer in its row. By default, it uses the layer id,
and layers are sorted in alphabetical order.
- position: **optional**. Determines the horizontal position of the layer in its row. By default, it uses the layer id, and layers are sorted in alphabetical order.
- branches: **optional**, an array of layer ids. On a tree, a line will appear from this layer to all of the layers
in the list. Alternatively, an entry in the array can be a 2-element array consisting of the layer id and a color
value. The color value can either be a string with a hex color code, or a number from 1-3 (theme-affected colors)
- branches: **optional**. An array of layer ids. On a tree, a line will appear from this layer to all of the layers in the list. Alternatively, an entry in the array can be a 2-element array consisting of the layer id and a color value. The color value can either be a string with a hex color code, or a number from 1-3 (theme-affected colors).
- nodeStyle: **optional**, a CSS object, where the keys are CSS attributes, which styles this layer's node on the tree
- tooltip() / tooltipLocked(): **optional** Functions that return text, which is the tooltip for the node when the layer
is unlocked or locked, respectively. By default the tooltips behave the same as in the original Prestige Tree.
- nodeStyle: **optional**. A CSS object, where the keys are CSS attributes, which styles this layer's node on the tree.
- tooltip() / tooltipLocked(): **optional**. Functions that return text, which is the tooltip for the node when the layer is unlocked or locked, respectively. By default the tooltips behave the same as in the original Prestige Tree.
## Other features
- doReset(resettingLayer): **optional**, is triggered when a layer on a row greater than or equal to this one does a reset.
The default behavior is to reset everything on the row, but only if it was triggered by a layer in a higher row.
(doReset is always called for side layers, but for these the default behavior is to reset nothing.)
- doReset(resettingLayer): **optional**. Is triggered when a layer on a row greater than or equal to this one does a reset. The default behavior is to reset everything on the row, but only if it was triggered by a layer in a higher row. `doReset` is always called for side layers, but for these the default behavior is to reset nothing.
If you want to keep things, determine what to keep based on the resettingLayer, milestones, and such, then call
resetLayerData(layer, keep), where layer is this layer, and keep is an array of the names of things to keep.
It can include things like "points", "best", "total" (for this layer's prestige currency), "upgrades",
any unique variables like "generatorPower", etc.
If you want to only keep specific upgrades or something like that, save them in a separate variable, then
call layerDataReset, and then set player[layer].upgrades to the saved upgrades.
If you want to keep things, determine what to keep based on `resettingLayer`, `milestones`, and such, then call `layerDataReset(layer, keep)`, where `layer` is this layer, and `keep` is an array of the names of things to keep. It can include things like "points", "best", "total" (for this layer's prestige currency), "upgrades", any unique variables like "generatorPower", etc. If you want to only keep specific upgrades or something like that, save them in a separate variable, then call `layerDataReset`, and then set `player[this.layer].upgrades` to the saved upgrades.
- update(diff): **optional**, this function is called every game tick. Use it for any passive resource production or
time-based things. diff is the time since the last tick.
Suggestion: use addPoints(layer, gain) when generating points to automatically
update the best and total amounts.
- update(diff): **optional**. This function is called every game tick. Use it for any passive resource production or time-based things. `diff` is the time since the last tick. Suggestion: use `addPoints(layer, gain)` when generating points to automatically update the best and total amounts.
- automate(): **optional**, this function is called every game tick, after production. Use it to activate any
autobuyers or auto-resets or similar on this layer, if appropriate.
- automate(): **optional**. This function is called every game tick, after production. Use it to activate any autobuyers or auto-resets or similar on this layer, if appropriate.
- resetsNothing: **optional**, returns true if this layer shouldn't trigger any resets when you prestige.
- resetsNothing: **optional**. Returns true if this layer shouldn't trigger any resets when you prestige.
- increaseUnlockOrder: **optional**, an array of layer ids. When this layer is unlocked for the first time, the unlockOrder value
for any not-yet-unlocked layers in this list increases. This can be used to make them harder to unlock.
- increaseUnlockOrder: **optional**. An array of layer ids. When this layer is unlocked for the first time, the `unlockOrder` value for any not-yet-unlocked layers in this list increases. This can be used to make them harder to unlock.
- shouldNotify: **optional**, a function to return true if this layer should be highlighted in the tree.
The layer will automatically be highlighted if you can buy an upgrade whether you have this or not.
- shouldNotify: **optional**. A function to return true if this layer should be highlighted in the tree. The layer will automatically be highlighted if you can buy an upgrade whether you have this or not.
- componentStyles: **optional**, An object that contains a set of functions returning CSS objects.
Each of these will be applied to any components on the layer with the type of its id. Example:
- componentStyles: **optional**. An object that contains a set of functions returning CSS objects. Each of these will be applied to any components on the layer with the type of its id. Example:
```js
componentStyles: {
"challenge"() {return {'height': '200px'}},
"prestige-button"() {return {'color': '#AA66AA'}},
},
componentStyles: {
"challenge"() { return {'height': '200px'} },
"prestige-button"() { return {'color': '#AA66AA'} }
}
```
## Custom Prestige type
- getResetGain(): **For custom prestige type**, Returns how many points you should get if you reset now. You can call
getResetGain(this.layer, useType = "static") or similar to calculate what your gain would be under another
prestige type (provided you have all of the required features in the layer.)
- getResetGain(): **for custom prestige type**. Returns how many points you should get if you reset now. You can call `getResetGain(this.layer, useType = "static")` or similar to calculate what your gain would be under another prestige type (provided you have all of the required features in the layer).
- getNextAt(canMax=false): **For custom prestige type**, Returns how many of the base currency you need to get to
the next point. canMax is an optional variable used with Static-ish layers to differentiate between if
it's looking for the first point you can reset at, or the requirement for any gain at all.
(Supporting both is good). You can also call getNextAt(this.layer, canMax=false, useType = "static")
or similar to calculate what your next at would be under another prestige type (provided you have
all of the required features in the layer.)
- getNextAt(canMax=false): **for custom prestige type**. Returns how many of the base currency you need to get to the next point. `canMax` is an optional variable used with Static-ish layers to differentiate between if it's looking for the first point you can reset at, or the requirement for any gain at all (Supporting both is good). You can also call `getNextAt(this.layer, canMax=false, useType = "static")` or similar to calculate what your next at would be under another prestige type (provided you have all of the required features in the layer).
- canReset(): **For custom prestige type**, return true only if you have the resources required to do a prestige here.
- canReset(): **for custom prestige type**. Return true only if you have the resources required to do a prestige here.

View file

@ -1,33 +1,30 @@
# mod.js
All of the code and data that you're likely to edit is here in mod.js! Everything in mod.js
will not be altered by updates, besides the addition of new things.
All of the non-layer code and data that you're likely to edit is here in [mod.js](/js/mod.js)! Everything in [mod.js](/js/mod.js) will not be altered by updates, besides the addition of new things.
Here's a breakdown of what's in it:
- modInfo is where most of the basic configuration for the mod is. It contains:
- name: The name of your mod. (a string)
- id: The id for your mod, a unique string that is used to determine savefile location. Setting it is important!
- author: The name of the author, displayed in the info tab.
- pointsName: This changes what is displayed instead of "points" for the main currency. (It does not affect it in the code.)
- discordName, discordLink: If you have a Discord server or other discussion place, you can add a link to it.
"discordName" is the text on the link, and "discordLink" is the url of an invite.
If you're using a Discord invite, please make sure it's set to never expire.
"discordName" is the text on the link, and "discordLink" is the url of an invite. If you're using a Discord invite, please make sure it's set to never expire.
- changelogLink: You can use this to set a link to a page where your changelog for the game is displayed.
- offlineLimit: The maximum amount of offline time that the player can accumulate, in hours. Any extra time is lost. (a number)
This is useful because most of these mods are fast-paced enough that too much offline time ruins the balance,
such as the time in between updates.
That is why I suggest developers disable offline time on their own savefile.
This is useful because most of these mods are fast-paced enough that too much offline time ruins the balance, such as the time in between updates. That is why I suggest developers disable offline time on their own savefile.
- initialStartPoints: A Decimal for the amount of points a new player should start with.
- VERSION is used to describe the current version of your mod. It contains:
num: The mod's version number, displayed at the top right of the tree tab.
name: The version's name, displayed alongside the number in the info tab.
- num: The mod's version number, displayed at the top right of the tree tab.
- name: The version's name, displayed alongside the number in the info tab.
- doNotCallTheseFunctionsEveryTick is very important. TMT calls every function anywhere in "layers" every tick to store the result,
unless specifically told not to. Functions that have are used to do an action need to be identified. "Official" functions
(those in the documentation) are all fine, but if you make any new ones, add their names to this array.
- doNotCallTheseFunctionsEveryTick is very important. TMT calls every function anywhere in "layers" every tick to store the result, unless specifically told not to. Functions that have are used to do an action need to be identified. "Official" functions (those in the documentation) are all fine, but if you make any new ones, add their names to this array.
```js
// (The ones here are examples, all official functions are already taken care of)
@ -36,8 +33,7 @@ var doNotCallTheseFunctionsEveryTick = ["doReset", "buy", "onPurchase", "blowUpE
- getStartPoints(): A function to determine the amount of points the player starts with after a reset. (returns a Decimal value)
- canGenPoints(): A function returning a boolean for if points should be generated.
Use this if you want an upgrade to unlock generating points.
- canGenPoints(): A function returning a boolean for if points should be generated. Use this if you want an upgrade to unlock generating points.
- getPointGen(): A function that calculates your points per second. Anything that affects your point gain should go into the calculation here.
@ -50,13 +46,10 @@ function addedPlayerData() { return {
}}
```
- displayThings: An array of functions used to display extra things at the top of the tree tab. Each function returns a string, which
is a line to display (with basic HTML support). If a function returns nothing, nothing is displayed (and it doesn't take up a line).
- displayThings: An array of functions used to display extra things at the top of the tree tab. Each function returns a string, which is a line to display (with basic HTML support). If a function returns nothing, nothing is displayed (and it doesn't take up a line).
- isEndgame(): A function to determine if the player has reached the end of the game, at which point the "you win!" screen appears.
Less important things beyond this point!
- maxTickLength(): Returns the maximum tick length, in milliseconds. Only really useful if you have something that reduces over time,
which long ticks mess up (usually a challenge).
- maxTickLength(): Returns the maximum tick length, in milliseconds. Only really useful if you have something that reduces over time, which long ticks mess up (usually a challenge).

View file

@ -3,41 +3,34 @@
Milestones are awarded to the player when they meet a certain goal, and give some benefit. Milestones should be formatted like this:
```js
milestones: {
0: {
requirementDesc: "123 waffles",
}
etc
milestones: {
0: {
requirementDesc: "123 waffles",
effectDesc: "blah",
done() { return player.w.points.gte(123) }
}
etc
}
```
You can use hasMilestone(layer, id) to determine if the player has a given milestone
You can use `hasMilestone(layer, id)` to determine if the player has a given milestone
Milestone features:
- requirementDesc: A string describing the requirement for unlocking this milestone. Suggestion: Use a "total".
It can also be a function that returns updating text. Can use basic HTML.
- requirementDesc: A string describing the requirement for unlocking this milestone. Suggestion: Use a "total". It can also be a function that returns updating text. Can use basic HTML.
- effectDesc: A string describing the reward for having the milestone. *You will have to implement the reward elsewhere.*
It can also be a function that returns updating text. Can use basic HTML.
- effectDesc: A string describing the reward for having the milestone. *You will have to implement the reward elsewhere.* It can also be a function that returns updating text. Can use basic HTML.
- done(): A function returning a boolean to determine if the milestone should be awarded.
- toggles: *optional*, Creates toggle buttons that appear on the milestone when it is unlocked.
The toggles can toggle a given boolean value in a layer.
It is defined as an array of paired items, one pair per toggle. The first is the internal name of the layer
the value being toggled is stored in, and the second is the internal name of the variable to toggle.
(e.g. [["b", "auto"], ["g", "auto"])
- toggles: **optional**. Creates toggle buttons that appear on the milestone when it is unlocked. The toggles can toggle a given boolean value in a layer. It is defined as an array of paired items, one pair per toggle. The first is the internal name of the layer the value being toggled is stored in, and the second is the internal name of the variable to toggle. (e.g. [["b", "auto"], ["g", "auto"])
**Tip:** Toggles are not de-set if the milestone becomes locked! In this case, you should also check if the player has the milestone.
**Tip:** Toggles are not de-set if the milestone becomes locked! In this case, you should also check if the player has the milestone.
- style: **Optional**, Applies CSS to this milestone, in the form of an object where the keys are CSS attributes,
and the values are the values for those attributes (both as strings)
- style: **optional**. Applies CSS to this milestone, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).
- unlocked(): **Optional** A function returning a boolean to determine if the milestone should be shown.
If absent, it is always shown.
- unlocked(): **optional**. A function returning a boolean to determine if the milestone should be shown. If absent, it is always shown.
- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
- layer: **assigned automagically**. It's the same value as the name of this layer, so you can do `player[this.layer].points` or similar.
- id: **Assigned automagically**. It's the "key" which the milestone was stored under, for convenient access.
The milestone in the example's id is 0.
- id: **assigned automagically**. It's the "key" which the milestone was stored under, for convenient access. The milestone in the example's id is 0.

View file

@ -5,50 +5,43 @@ Subtabs are separate sections of a tab that you can view by selecting one at the
Subtabs are defined by using the tab format like this, where each element of tabFormat is given the name of that subtab:
```js
tabFormat: {
"Main tab": {
*subtab features*
},
"Other tab": {
*subtab features*
},
etc
tabFormat: {
"Main tab": {
*subtab features*
},
"Other tab": {
*subtab features*
},
etc
}
```
Microtabs are defined similarly, and use the same features, but are defined in the "microtabs" feature. Each entry is a
group of tabs which will appear in a microtabs component. The first set, "stuff", has 2 tabs, and the second,
"otherStuff", has none.
Microtabs are defined similarly, and use the same features, but are defined in the "microtabs" feature. Each entry is a group of tabs which will appear in a microtabs component. The first set, "stuff", has 2 tabs, and the second, "otherStuff", has none.
```js
microtabs: {
stuff: {
first: {
microtabs: {
stuff: {
first: {
*subtab features*
},
second: {
*subtab features*
},
},
otherStuff: {
// There could be another set of microtabs here
second: {
*subtab features*
}
},
otherStuff: {
// There could be another set of microtabs here
}
}
```
Normal subtabs and microtab subtabs both use the same features:
# Features:
- content: The tab layout code for the subtab, in [the tab layout format](custom-tab-layouts.md)
- content: The tab layout code for the subtab, in [the tab layout format](custom-tab-layouts.md).
- style: **Optional**, Applies CSS to the whole subtab when switched to, in the form of an "CSS Object",
where the keys are CSS attributes, and the values are the values for those attributes (both as strings)
- style: **optional**. Applies CSS to the whole subtab when switched to, in the form of an "CSS Object", where the keys are CSS attributes, and the values are the values for those attributes (both as strings).
- buttonStyle: **Optional**, A CSS object, which affects the appearance of the button for that subtab.
- buttonStyle: **optional**. A CSS object, which affects the appearance of the button for that subtab.
- unlocked(): **Optional**, a function to determine if the button for this subtab should be visible.
By default, a subtab is always unlocked.
(You can't use the "this" keyword in this function.)
- unlocked(): **optional**. a function to determine if the button for this subtab should be visible. By default, a subtab is always unlocked. You can't use the "this" keyword in this function.

View file

@ -4,25 +4,18 @@ This tutorial assumes that you have used [the Getting Started Tutorial](getting-
Here's what you have to do when there's a TMT update:
1. Look at the changelog. It will warn you if the update will break anything or require any changes.
Decide if you want to try to update.
1. Look at the changelog. It will warn you if the update will break anything or require any changes. Decide if you want to try to update.
2. Open Github Desktop, and at the top middle, click "fetch origin". This will make Github Desktop get
information about the update.
2. Open Github Desktop, and at the top middle, click "fetch origin". This will make Github Desktop get information about the update.
3. Click where it says "current branch: master" at the top middle, and at the bottom of the thing
that appears, click "choose a branch to merge into master.
3. Click where it says "current branch: master" at the top middle, and at the bottom of the thing that appears, click "choose a branch to merge into master".
4. Select upstream/master. It will likely say there are conflicts, but you have tools to resolve them.
Click "Merge upstream/master into master".
4. Select upstream/master. It will likely say there are conflicts, but you have tools to resolve them. Click "Merge upstream/master into master".
5. A conflict happens when the things you're trying to merge have both made changes in the same place.
Click "open in Visual Studio Code" next to the first file.
5. A conflict happens when the things you're trying to merge have both made changes in the same place. Click "open in Visual Studio Code" next to the first file.
6. Scroll down through the file, and look for the parts highlighted in red and green. One of these is
your code, and the other is some code that will be modified by the update. Do your best to try to
edit things to keep the updated changes, but keep your content.
6. Scroll down through the file, and look for the parts highlighted in red and green. One of these is your code, and the other is some code that will be modified by the update. Do your best to try to edit things to keep the updated changes, but keep your content.
7. Continue to do this for all remaining challenges.
7. Continue to do this for all remaining changes.
8. Do any other changes required by the update, run the game, fix issues, etc.
8. Do any other changes required by the update, run the game, fix issues, etc.

View file

@ -6,56 +6,53 @@ Useful functions for dealing with Upgrades and implementing their effects:
- upgradeEffect(layer, id): Returns the current effects of the upgrade, if any
- buyUpgrade(layer, id): Buys an upgrade directly (if affordable)
Hint: Basic point gain is calculated in mod.js's "getPointGen".
Hint: Basic point gain is calculated in [mod.js](/js/mod.js)'s "getPointGen" function.
Upgrades are stored in the following format:
```js
upgrades: {
rows: # of rows
cols: # of columns
11: {
description: "Blah",
more features
}
upgrades: {
rows: # of rows,
cols: # of columns,
11: {
description: "Blah",
cost: new Decimal(100),
etc
}
},
etc
}
```
Each upgrade should have an id where the first digit is the row and the second digit is the column.
Individual upgrades can have these features:
- title: **optional**, displayed at the top in a larger font
It can also be a function that returns updating text. Can use basic HTML.
- title: **optional**. Displayed at the top in a larger font. It can also be a function that returns updating text. Can use basic HTML.
- description: A description of the upgrade's effect. *You will also have to implement the effect where it is applied.*
It can also be a function that returns updating text. Can use basic HTML.
- description: A description of the upgrade's effect. *You will also have to implement the effect where it is applied.* It can also be a function that returns updating text. Can use basic HTML.
- effect(): **optional**, A function that calculates and returns the current values of any bonuses from the upgrade.
Can return a value or an object containing multiple values.
- effect(): **optional**. A function that calculates and returns the current values of any bonuses from the upgrade. Can return a value or an object containing multiple values.
- effectDisplay(): **optional**, A function that returns a display of the current effects of the upgrade with
formatting. Default behavior is to just display the a number appropriately formatted. Can use basic HTML.
- effectDisplay(): **optional**. A function that returns a display of the current effects of the upgrade with formatting. Default behavior is to just display the number appropriately formatted. Can use basic HTML.
- cost: A Decimal for the cost of the upgrade. By default, upgrades cost the main prestige currency for the layer.
- unlocked(): **optional**, A function returning a bool to determine if the upgrade is visible or not. Default is unlocked.
- unlocked(): **optional**. A function returning a bool to determine if the upgrade is visible or not. Default is unlocked.
- onPurchase() - **optional**, this function will be called when the upgrade is purchased.
Good for upgrades like "makes this layer act like it was unlocked first".
- onPurchase() - **optional**. This function will be called when the upgrade is purchased. Good for upgrades like "makes this layer act like it was unlocked first".
- style: **optional**. Applies CSS to this upgrade, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).
- layer: **assigned automagically**. It's the same value as the name of this layer, so you can do `player[this.layer].points` or similar.
- id: **assigned automagically**. It's the "key" which the upgrade was stored under, for convenient access. The upgrade in the example's id is 11.
By default, upgrades use the main prestige currency for the layer. You can include these to change them (but it needs to be a Decimal):
- currencyDisplayName: **optional**, the name to display for the currency for the upgrade
- currencyInternalName: **optional**, the internal name for that currency
- currencyLayer: **optional**, the internal name of the layer that currency is stored in.
If it's not in a layer (like Points), omit. If it's not stored directly in a layer, instead use the next feature.
- currencyLocation: **optional**, if your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way.
This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)
- style: **Optional**, Applies CSS to this upgrade, in the form of an object where the keys are CSS attributes,
and the values are the values for those attributes (both as strings)
- currencyDisplayName: **optional**. The name to display for the currency for the upgrade.
- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
- currencyInternalName: **optional**. The internal name for that currency.
- id: **Assigned automagically**. It's the "key" which the upgrade was stored under, for convenient access.
The upgrade in the example's id is 11.
- currencyLayer: **optional**. The internal name of the layer that currency is stored in. If it's not in a layer (like Points), omit. If it's not stored directly in a layer, instead use the next feature.
- currencyLocation: **optional**. If your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way. This is a function returning the object in "player" that contains the value (like `player[this.layer].buyables`)

View file

@ -1,28 +1,28 @@
addLayer("p", {
name: "prestige", // This is optional, only used in a few places, If absent it just uses the layer id.
symbol: "P", // This appears on the layer's node. Default is the id with the first letter capitalized
position: 0, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order
startData() { return {
unlocked: true,
points: new Decimal(0),
}},
color: "#4BDC13",
requires: new Decimal(10), // Can be a function that takes requirement increases into account
resource: "prestige points", // Name of prestige currency
baseResource: "points", // Name of resource prestige is based on
baseAmount() {return player.points}, // Get the current amount of baseResource
type: "normal", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have
exponent: 0.5, // Prestige currency exponent
gainMult() { // Calculate the multiplier for main currency from bonuses
mult = new Decimal(1)
return mult
},
gainExp() { // Calculate the exponent on main currency from bonuses
return new Decimal(1)
},
row: 0, // Row the layer is in on the tree (0 is the first row)
hotkeys: [
{key: "p", description: "Reset for prestige points", onPress(){if (canReset(this.layer)) doReset(this.layer)}},
],
layerShown(){return true},
})
name: "prestige", // This is optional, only used in a few places, If absent it just uses the layer id.
symbol: "P", // This appears on the layer's node. Default is the id with the first letter capitalized
position: 0, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order
startData() { return {
unlocked: true,
points: new Decimal(0),
}},
color: "#4BDC13",
requires: new Decimal(10), // Can be a function that takes requirement increases into account
resource: "prestige points", // Name of prestige currency
baseResource: "points", // Name of resource prestige is based on
baseAmount() {return player.points}, // Get the current amount of baseResource
type: "normal", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have
exponent: 0.5, // Prestige currency exponent
gainMult() { // Calculate the multiplier for main currency from bonuses
mult = new Decimal(1)
return mult
},
gainExp() { // Calculate the exponent on main currency from bonuses
return new Decimal(1)
},
row: 0, // Row the layer is in on the tree (0 is the first row)
hotkeys: [
{key: "p", description: "Reset for prestige points", onPress(){if (canReset(this.layer)) doReset(this.layer)}},
],
layerShown(){return true}
})