1
0
Fork 0
mirror of https://github.com/Acamaeda/The-Modding-Tree.git synced 2025-02-16 09:41:41 +00:00

Rebranding

This commit is contained in:
Harley White 2021-09-11 13:39:54 -04:00
parent 399d0bce9f
commit 045b7ba6b1
21 changed files with 577 additions and 585 deletions

View file

@ -1,6 +1,6 @@
MIT License
Modding Tree Copyright (c) 2020 Acamaeda
Incrementum Copyright (c) 2020 Acamaeda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
# The-Modding-Tree
# Incrementum: A Flexible Incremental Engine
An incremental game engine based on The Prestige Tree. It still requires programming knowledge, but it's mostly pretty easy things and copy/pasting.
[Look here for a tutorial on getting started with modding with TMT](docs/tutorials/getting-started.md)
[Look here for a tutorial on getting started with modding with Incrementum](docs/tutorials/getting-started.md)
You can look in the [documentation](docs/!general-info.md) for more information on how it all works, or look at the code in layers.js to see what it all looks like.

View file

@ -1,5 +1,6 @@
# Incrementum changelog:
- Changed the name to "Incrementum" and replaced all instances of "mod" with "game". game.js has been renamed incrementum.js, and mod.js is now game.js.
- Upgrade effectDisplay and grid tooltip no longer display if they return "".

View file

@ -17,14 +17,14 @@
<script src="js/technical/break_eternity.js"></script>
<script src="js/technical/layerSupport.js"></script>
<script src="js/Demo/demoMod.js"></script>
<script src="js/Demo/demoGame.js"></script>
<script src="js/technical/loader.js"></script>
<script src="js/technical/temp.js" id = "temp"></script>
<script src="js/technical/displays.js"></script>
<script src="js/game.js"></script>
<script src="js/incrementum.js"></script>
<script src="js/utils.js"></script>
<script src="js/utils/easyAccess.js"></script>
<script src="js/technical/systemComponents.js"></script>
@ -49,20 +49,18 @@
<div class="vl" v-if="player.navTab !== 'none' && tmp.other.splitScreen && player.tab!='none' && !(tmp.gameEnded && !player.keepGoing)"></div>
<div v-if="(tmp.gameEnded && !player.keepGoing)" class="fullWidth">
<br>
<h2>{{modInfo.name}} {{VERSION.withoutName}}</h2><br><br>
<h3 v-html="modInfo.winText"></h3><br>
<h2>{{gameInfo.name}} {{VERSION.withoutName}}</h2><br><br>
<h3 v-html="gameInfo.winText"></h3><br>
<h3>Please check the Discord to see if there are new content updates!</h3><br><br>
<div v-if="!player.timePlayedReset">It took you {{formatTime(player.timePlayed)}} to beat the game.</div>
<br>
<button class="longUpg can" onclick="hardReset(true)">Play Again</button>&nbsp;&nbsp;&nbsp;&nbsp;<button
class="longUpg can" onclick="keepGoing()">Keep Going</button>
<br><br><br>
<span v-if="modInfo.discordLink"><a class="link" v-bind:href="modInfo.discordLink"
target="_blank">{{modInfo.discordName}}</a><br></span>
<span v-if="gameInfo.discordLink"><a class="link" v-bind:href="gameInfo.discordLink"
target="_blank">{{gameInfo.discordName}}</a><br></span>
<a class="link" href="https://discord.gg/F3xveHV" target="_blank"
v-bind:style="modInfo.discordLink ? {'font-size': '16px'} : {}">The Modding Tree Discord</a><br>
<a class="link" href="http://discord.gg/wwQfgPa" target="_blank" v-bind:style="{'font-size': '16px'}">Main
Prestige Tree server</a><br>
v-bind:style="gameInfo.discordLink ? {'font-size': '16px'} : {}">Incrementum Discord</a><br>
<br><br>
</div>
@ -80,16 +78,13 @@
onclick="showTab('options-tab')"></img>
<div id="info" v-if="player.tab!='info-tab'" class="overlayThing" onclick="showTab('info-tab')"><br>i</div>
<div id="discord" class="overlayThing">
<img onclick="window.open((modInfo.discordLink ? modInfo.discordLink : 'https://discord.gg/F3xveHV'),'mywindow')"
<img onclick="window.open((gameInfo.discordLink ? gameInfo.discordLink : 'https://discord.gg/F3xveHV'),'mywindow')"
src="discord.png" target="_blank"></img>
<ul id="discord-links">
<li v-if="modInfo.discordLink"><a class="link" v-bind:href="modInfo.discordLink"
target="_blank">{{modInfo.discordName}}</a><br></li>
<li v-if="gameInfo.discordLink"><a class="link" v-bind:href="gameInfo.discordLink"
target="_blank">{{gameInfo.discordName}}</a><br></li>
<li><a class="link" href="https://discord.gg/F3xveHV" target="_blank"
v-bind:style="modInfo.discordLink ? {'font-size': '16px'} : {}">The Modding Tree
Discord</a><br></li>
<li><a class="link" href="http://discord.gg/wwQfgPa" target="_blank"
v-bind:style="{'font-size': '16px'}">Main Prestige Tree server</a></li>
v-bind:style="gameInfo.discordLink ? {'font-size': '16px'} : {}">Incrementum Discord</a><br></li>
</ul>
</div>
<overlay-head v-if="!(tmp.gameEnded && !player.keepGoing)"></overlay-head>

View file

@ -1,6 +1,6 @@
# The-Modding-Tree
# Incrementum: A Flexible Incremental Engine
Making a game in The Modding Tree mostly involves defining parameters or functions on objects. If you aren't following the [getting started guide](tutorials/getting-started.md), you should start by [setting up your basic mod info](main-mod-info.md) in [mod.js](/js/mod.js). It's important to set a mod id to ensure saving works properly.
Making a game in Incrementum mostly involves defining parameters or functions on objects. If you aren't following the [getting started guide](tutorials/getting-started.md), you should start by [setting up your basic mod info](main-mod-info.md) in [mod.js](/js/mod.js). It's important to set a mod id to ensure saving works properly.
Beyond that, the main way to add content is through creating layers. You can add new layers by calling `addLayer(layername, layerdata)`. There is an example of a basic layer in [layers.js](/js/layers.js). 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.
@ -8,7 +8,7 @@ You can test your mod by opening the [index.html](/index.html) file in your brow
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 [components.js](/js/components.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 (x can be a number or a string for larger values). You 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.
Incrementum 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 (x can be a number or a string for larger values). You 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.
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.
@ -29,14 +29,14 @@ While reading this documentation, the following key will be used when describing
### General
- [Getting Started](tutorials/getting-started.md): A guide to getting your own copy of the code set up with Github Desktop.
- [Making a Mod](tutorials/making-a-mod.md): A guide to using TMT to make a basic mod.
- [Main mod info](main-mod-info.md): How to set up general things for your mod in [mod.js](/js/mod.js).
- [Making a Game](tutorials/making-a-game.md): A guide to using TMT to make a basic mod.
- [General game info](main-game-info.md): How to set up general things for your game in [game.js](/js/game.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 Game Layouts](trees-and-tree-customization.md): You can get rid of the tree tab, add buttons and other things to the tree,
or even customize the tab's layout like a layer tab.
- [Updating TMT](tutorials/updating-tmt.md): Using Github Desktop to update your mod's version of TMT.
- [Updating Incrementum](tutorials/updating-incrementum.md): Using Github Desktop to update your mod's version of Incrementum.
- [Other Things](other.md): Other neat features that TMT has that don't merit their own page.
### Common components

View file

@ -1,16 +1,16 @@
# mod.js
# game.js
Most 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.
Most of the non-layer code and data that you're likely to edit is here in [game.js](/js/game.js).
Everything in [game.js](/js/game.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. Be sure to set it when you start making a mod, and don't change it later because it will erase all saves.
- gameInfo is where most of the basic configuration for the game is. It contains:
- name: The name of your game. (a string)
- id: The id for your game, a unique string that is used to determine savefile location. Be sure to set it when you start making a game, and don't change it later because it will erase all saves.
- 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.)
- modFiles: An array of file addresses which will be loaded for this mod. Using smaller files makes it easier to find what you're looking for.
- gameFiles: An array of file addresses which will be loaded for this game. Using smaller files makes it easier to find what you're looking for.
- discordName, discordLink: If you have a Discord server or other discussion place, you can add a link to it.
@ -18,12 +18,12 @@ Here's a breakdown of what's in it:
- 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 games 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.
- VERSION is used to describe the current version of your game. It contains:
- num: The game'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.
- changelog is the HTML displayed in the changelog tab. If this gets particularly long, it might be good to put in a separate file (be sure to add the file to index.html)

View file

@ -1,29 +1,29 @@
# Getting started
Welcome to The Modding Tree!
Welcome to Incrementum!
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 Incrementum, 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.
The benefits of using Github:
- It makes it much, much easier to update The Modding Tree.
- It makes it much, much easier to update Incrementum.
- 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 Desktop, Visual Studio Code, and The Modding Tree:
## Getting set up with Github Desktop, Visual Studio Code, and Incrementum:
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 [Incrementum page](https://github.com/Acamaeda/Incrementum). 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 Incrementum.
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 Incrementum. "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".
5. Look for Incrementum 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.
@ -33,9 +33,9 @@ The benefits of using Github:
2. To edit your project, click "open in VSCode" in Github Desktop.
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)
3. Open [game.js](/js/game.js) in VSCode, and look at the top part where it has a "gameInfo" object. Fill in your game'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 [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 updated! **You can reload the page every time you change the code to test it quickly and easily.**
4. Save [game.js](/js/game.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 updated! **You can reload the page every time you change the code to test it quickly and easily.**
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.
@ -43,6 +43,6 @@ The benefits of using Github:
7. Finally, at the top middle, click "push origin" to push your changes out onto the online repository.
8. You can view your project online, or share it with others, by going to https://raw.githack.com/[YOUR-GITHUB-USERNAME]/The-Modding-Tree/master/index.html. **You do NOT need to do this to test your mod locally.**
8. You can view your project online, or share it with others, by going to https://raw.githack.com/[YOUR-GITHUB-USERNAME]/Incrementum/master/index.html. **You do NOT need to do this to test your game locally.**
And now, you have successfully used Github! You can look at the next tutorial on [making a mod](making-a-mod.md), or look at the [documentation](/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 next tutorial on [making a game](making-a-game.md), or look at the [documentation](/documentation/!general-info.md) to see how Incrementum's system works and to make your game a reality.

View file

@ -1,16 +1,16 @@
# Making a Mod
# Making a Game
This guide assumes you have already gone through the [getting started guide](getting-started.md). It will walk you through the basics of using TMT to create a mod. Let's get started!
This guide assumes you have already gone through the [getting started guide](getting-started.md). It will walk you through the basics of using Incrementum to create a game. Let's get started!
## Setting up mod info
Open mod.js. This is where you define things that are for the mod in general as opposed to layer-specific. For now, modInfo, you can set the mod name and author name, and also the points name, which changes what the game calls your basic points (but they're still referred to as `player.points` in the code). **Be sure that you set a mod id as well**.
Open mod.js. This is where you define things that are for the game in general as opposed to layer-specific. For now, gameInfo, you can set the mod name and author name, and also the points name, which changes what the game calls your basic points (but they're still referred to as `player.points` in the code). **Be sure that you set a game id as well**.
One suggestion: When you're testing your mod, you should turn off offline progress in the in-game settings, and don't leave the game running when you aren't using it. You could unintentionally balance your game with large timewalls caused by this extra time.
## Making a layer
Now for the good stuff! Head into layers.js. There is a basic layer already there (although it has a few redundant things in it.) Let's see what it's doing...
Now for the good stuff! Head into layers.js. There is a basic layer already there Let's see what it's doing...
The most important thing is on the first line, where it says `addLayer("p", {` . This is how you create a new layer. The "p" here becomes the layer id, which is used throughout TMT to refer to the layer. You can change the id, but you will have to replace instances of "p" in the tutorial code as well.
@ -24,7 +24,7 @@ Reload the page to see your newly customized layer! You can ignore the other fea
## Upgrades
Upgrades are one of several Big Features in TMT, and most of them work the same way. Most of what applies to upgrades applies to milestones, buyables, etc. To add upgrades to your layer, after all of the other features, add a comma to the end of the last one, and then put:
Upgrades are one of several Big Features in Incrementum, and most of them work the same way. Most of what applies to upgrades applies to milestones, buyables, etc. To add upgrades to your layer, after all of the other features, add a comma to the end of the last one, and then put:
```js
upgrades: {
@ -50,7 +50,7 @@ Reload the page, and an upgrade will appear in the layer's tab! It will just be
cost: new Decimal(1),
```
Reload the page, and the upgrade will appear, fully formed! But it won't have any effect when you buy it! To impliment a boost, we need to go to the place where it is calculated. In this case, point gain is calculated in getPointGen in mod.js, so let's head over there.
Reload the page, and the upgrade will appear, fully formed! But it won't have any effect when you buy it! To impliment a boost, we need to go to the place where it is calculated. In this case, point gain is calculated in getPointGen in game.js, so let's head over there.
It's time to explain Decimals. Decimals are a special way of handling numbers over the normal Javascript limit. They are handled in a very different way. To perform any operations, instead of doing x = x + y, you have to do x = x.add(y). x has to be a Decimal, but y can be either a Decimal or Number (regular javascript number). A more detailed description is in [!general-info.md](/documentation/!general-info.md)

View file

@ -1,4 +1,4 @@
# Updating The Modding Tree
# Updating Incrementum
This tutorial assumes that you have used [the Getting Started Tutorial](getting-started.md), and are using Github Desktop and VSCode for your mod.

View file

@ -17,13 +17,13 @@
<script src="js/technical/break_eternity.js"></script>
<script src="js/technical/layerSupport.js"></script>
<script src="js/mod.js"></script>
<script src="js/game.js"></script>
<script src="js/technical/loader.js"></script>
<script src="js/technical/temp.js"></script>
<script src="js/technical/displays.js"></script>
<script src="js/game.js"></script>
<script src="js/incrementum.js"></script>
<script src="js/utils.js"></script>
<script src="js/utils/easyAccess.js"></script>
<script src="js/technical/systemComponents.js"></script>
@ -38,6 +38,7 @@
</head>
<body onload="load()" onmousemove="updateMouse(event)">
<div id="app">
<canvas id="treeCanvas" class="canvas" v-if="!(tmp.gameEnded && !player.keepGoing)"></canvas>
@ -48,20 +49,18 @@
<div class="vl" v-if="player.navTab !== 'none' && tmp.other.splitScreen && player.tab!='none' && !(tmp.gameEnded && !player.keepGoing)"></div>
<div v-if="(tmp.gameEnded && !player.keepGoing)" class="fullWidth">
<br>
<h2>{{modInfo.name}} {{VERSION.withoutName}}</h2><br><br>
<h3 v-html="modInfo.winText"></h3><br>
<h2>{{gameInfo.name}} {{VERSION.withoutName}}</h2><br><br>
<h3 v-html="gameInfo.winText"></h3><br>
<h3>Please check the Discord to see if there are new content updates!</h3><br><br>
<div v-if="!player.timePlayedReset">It took you {{formatTime(player.timePlayed)}} to beat the game.</div>
<br>
<button class="longUpg can" onclick="hardReset(true)">Play Again</button>&nbsp;&nbsp;&nbsp;&nbsp;<button
class="longUpg can" onclick="keepGoing()">Keep Going</button>
<br><br><br>
<span v-if="modInfo.discordLink"><a class="link" v-bind:href="modInfo.discordLink"
target="_blank">{{modInfo.discordName}}</a><br></span>
<span v-if="gameInfo.discordLink"><a class="link" v-bind:href="gameInfo.discordLink"
target="_blank">{{gameInfo.discordName}}</a><br></span>
<a class="link" href="https://discord.gg/F3xveHV" target="_blank"
v-bind:style="modInfo.discordLink ? {'font-size': '16px'} : {}">The Modding Tree Discord</a><br>
<a class="link" href="http://discord.gg/wwQfgPa" target="_blank" v-bind:style="{'font-size': '16px'}">Main
Prestige Tree server</a><br>
v-bind:style="gameInfo.discordLink ? {'font-size': '16px'} : {}">Incrementum Discord</a><br>
<br><br>
</div>
@ -79,16 +78,13 @@
onclick="showTab('options-tab')"></img>
<div id="info" v-if="player.tab!='info-tab'" class="overlayThing" onclick="showTab('info-tab')"><br>i</div>
<div id="discord" class="overlayThing">
<img onclick="window.open((modInfo.discordLink ? modInfo.discordLink : 'https://discord.gg/F3xveHV'),'mywindow')"
<img onclick="window.open((gameInfo.discordLink ? gameInfo.discordLink : 'https://discord.gg/F3xveHV'),'mywindow')"
src="discord.png" target="_blank"></img>
<ul id="discord-links">
<li v-if="modInfo.discordLink"><a class="link" v-bind:href="modInfo.discordLink"
target="_blank">{{modInfo.discordName}}</a><br></li>
<li v-if="gameInfo.discordLink"><a class="link" v-bind:href="gameInfo.discordLink"
target="_blank">{{gameInfo.discordName}}</a><br></li>
<li><a class="link" href="https://discord.gg/F3xveHV" target="_blank"
v-bind:style="modInfo.discordLink ? {'font-size': '16px'} : {}">The Modding Tree
Discord</a><br></li>
<li><a class="link" href="http://discord.gg/wwQfgPa" target="_blank"
v-bind:style="{'font-size': '16px'}">Main Prestige Tree server</a></li>
v-bind:style="gameInfo.discordLink ? {'font-size': '16px'} : {}">Incrementum Discord</a><br></li>
</ul>
</div>
<overlay-head v-if="!(tmp.gameEnded && !player.keepGoing)"></overlay-head>

View file

@ -1,8 +1,8 @@
let modInfo = {
name: "The Modding Tree",
let gameInfo = {
name: "Incrementum",
id: "modbase",
pointsName: "points",
modFiles: ["Demo/layers/c.js", "Demo/layers/f.js", "Demo/layers/a.js", "Demo/demoTree.js"],
gameFiles: ["Demo/layers/c.js", "Demo/layers/f.js", "Demo/layers/a.js", "Demo/demoTree.js"],
discordName: "",
@ -28,7 +28,7 @@ let winText = `Congratulations! You have reached the end and beaten this game, b
var doNotCallTheseFunctionsEveryTick = ["doReset", "buy", "onPurchase", "blowUpEverything"]
function getStartPoints(){
return new Decimal(modInfo.initialStartPoints)
return new Decimal(gameInfo.initialStartPoints)
}
// Determines if it should show points/sec

View file

@ -144,7 +144,7 @@ function loadVue() {
<span v-if="layers[layer].challenges[data].fullDisplay" v-html="run(layers[layer].challenges[data].fullDisplay, layers[layer].challenges[data])"></span>
<span v-else>
<span v-html="tmp[layer].challenges[data].challengeDescription"></span><br>
Goal: <span v-if="tmp[layer].challenges[data].goalDescription" v-html="tmp[layer].challenges[data].goalDescription"></span><span v-else>{{format(tmp[layer].challenges[data].goal)}} {{tmp[layer].challenges[data].currencyDisplayName ? tmp[layer].challenges[data].currencyDisplayName : modInfo.pointsName}}</span><br>
Goal: <span v-if="tmp[layer].challenges[data].goalDescription" v-html="tmp[layer].challenges[data].goalDescription"></span><span v-else>{{format(tmp[layer].challenges[data].goal)}} {{tmp[layer].challenges[data].currencyDisplayName ? tmp[layer].challenges[data].currencyDisplayName : gameInfo.pointsName}}</span><br>
Reward: <span v-html="tmp[layer].challenges[data].rewardDescription"></span><br>
<span v-if="layers[layer].challenges[data].rewardDisplay!==undefined">Currently: <span v-html="(tmp[layer].challenges[data].rewardDisplay) ? (run(layers[layer].challenges[data].rewardDisplay, layers[layer].challenges[data])) : format(tmp[layer].challenges[data].rewardEffect)"></span></span>
</span>

View file

@ -1,430 +1,79 @@
var player;
var needCanvasUpdate = true;
let gameInfo = {
name: "The ??? Tree",
id: "mygame",
author: "nobody",
pointsName: "points",
gameFiles: ["layers.js", "tree.js"],
// Don't change this
const TMT_VERSION = {
tmtNum: "2.6.6.2",
tmtName: "Fixed Reality"
discordName: "",
discordLink: "",
initialStartPoints: new Decimal (10), // Used for hard resets and new players
offlineLimit: 1, // In hours
}
function getResetGain(layer, useType = null) {
let type = useType
if (!useType){
type = tmp[layer].type
if (layers[layer].getResetGain !== undefined)
return layers[layer].getResetGain()
}
if(tmp[layer].type == "none")
return new Decimal (0)
if (tmp[layer].gainExp.eq(0)) return decimalZero
if (type=="static") {
if ((!tmp[layer].canBuyMax) || tmp[layer].baseAmount.lt(tmp[layer].requires)) return decimalOne
let gain = tmp[layer].baseAmount.div(tmp[layer].requires).div(tmp[layer].gainMult).max(1).log(tmp[layer].base).times(tmp[layer].gainExp).pow(Decimal.pow(tmp[layer].exponent, -1))
gain = gain.times(tmp[layer].directMult)
return gain.floor().sub(player[layer].points).add(1).max(1);
} else if (type=="normal"){
if (tmp[layer].baseAmount.lt(tmp[layer].requires)) return decimalZero
let gain = tmp[layer].baseAmount.div(tmp[layer].requires).pow(tmp[layer].exponent).times(tmp[layer].gainMult).pow(tmp[layer].gainExp)
if (gain.gte(tmp[layer].softcap)) gain = gain.pow(tmp[layer].softcapPower).times(tmp[layer].softcap.pow(decimalOne.sub(tmp[layer].softcapPower)))
gain = gain.times(tmp[layer].directMult)
return gain.floor().max(0);
} else if (type=="custom"){
return layers[layer].getResetGain()
} else {
return decimalZero
}
// Set your version in num and name
let VERSION = {
num: "0.0",
name: "Literally nothing",
}
function getNextAt(layer, canMax=false, useType = null) {
let type = useType
if (!useType) {
type = tmp[layer].type
if (layers[layer].getNextAt !== undefined)
return layers[layer].getNextAt(canMax)
let changelog = `<h1>Changelog:</h1><br>
<h3>v0.0</h3><br>
- Added things.<br>
- Added stuff.`
}
if(tmp[layer].type == "none")
return new Decimal (Infinity)
let winText = `Congratulations! You have reached the end and beaten this game, but for now...`
if (tmp[layer].gainMult.lte(0)) return new Decimal(Infinity)
if (tmp[layer].gainExp.lte(0)) return new Decimal(Infinity)
// If you add new functions anywhere inside of a layer, and those functions have an effect when called, add them here.
// (The ones here are examples, all official functions are already taken care of)
var doNotCallTheseFunctionsEveryTick = ["blowUpEverything"]
if (type=="static")
{
if (!tmp[layer].canBuyMax) canMax = false
let amt = player[layer].points.plus((canMax&&tmp[layer].baseAmount.gte(tmp[layer].nextAt))?tmp[layer].resetGain:0).div(tmp[layer].directMult)
let extraCost = Decimal.pow(tmp[layer].base, amt.pow(tmp[layer].exponent).div(tmp[layer].gainExp)).times(tmp[layer].gainMult)
let cost = extraCost.times(tmp[layer].requires).max(tmp[layer].requires)
if (tmp[layer].roundUpCost) cost = cost.ceil()
return cost;
} else if (type=="normal"){
let next = tmp[layer].resetGain.add(1).div(tmp[layer].directMult)
if (next.gte(tmp[layer].softcap)) next = next.div(tmp[layer].softcap.pow(decimalOne.sub(tmp[layer].softcapPower))).pow(decimalOne.div(tmp[layer].softcapPower))
next = next.root(tmp[layer].gainExp).div(tmp[layer].gainMult).root(tmp[layer].exponent).times(tmp[layer].requires).max(tmp[layer].requires)
if (tmp[layer].roundUpCost) next = next.ceil()
return next;
} else if (type=="custom"){
return layers[layer].getNextAt(canMax)
} else {
return decimalZero
}}
function softcap(value, cap, power = 0.5) {
if (value.lte(cap)) return value
else
return value.pow(power).times(cap.pow(decimalOne.sub(power)))
function getStartPoints(){
return new Decimal(gameInfo.initialStartPoints)
}
// Return true if the layer should be highlighted. By default checks for upgrades only.
function shouldNotify(layer){
for (id in tmp[layer].upgrades){
if (isPlainObject(layers[layer].upgrades[id])){
if (canAffordUpgrade(layer, id) && !hasUpgrade(layer, id) && tmp[layer].upgrades[id].unlocked){
return true
}
}
}
if (player[layer].activeChallenge && canCompleteChallenge(layer, player[layer].activeChallenge)) {
return true
}
if (tmp[layer].shouldNotify)
return true
if (isPlainObject(tmp[layer].tabFormat)) {
for (subtab in tmp[layer].tabFormat){
if (subtabShouldNotify(layer, 'mainTabs', subtab)) {
tmp[layer].trueGlowColor = tmp[layer].tabFormat[subtab].glowColor || defaultGlow
return true
}
}
}
for (family in tmp[layer].microtabs) {
for (subtab in tmp[layer].microtabs[family]){
if (subtabShouldNotify(layer, family, subtab)) {
tmp[layer].trueGlowColor = tmp[layer].microtabs[family][subtab].glowColor
return true
}
}
}
return false
// Determines if it should show points/sec
function canGenPoints(){
return true
}
function canReset(layer)
{
if (layers[layer].canReset!== undefined)
return run(layers[layer].canReset, layers[layer])
else if(tmp[layer].type == "normal")
return tmp[layer].baseAmount.gte(tmp[layer].requires)
else if(tmp[layer].type== "static")
return tmp[layer].baseAmount.gte(tmp[layer].nextAt)
else
return false
// Calculate points/sec!
function getPointGen() {
if(!canGenPoints())
return new Decimal(0)
let gain = new Decimal(1)
return gain
}
function rowReset(row, layer) {
for (lr in ROW_LAYERS[row]){
if(layers[lr].doReset) {
if (!isNaN(row)) Vue.set(player[lr], "activeChallenge", null) // Exit challenges on any row reset on an equal or higher row
run(layers[lr].doReset, layers[lr], layer)
}
else
if(tmp[layer].row > tmp[lr].row && !isNaN(row)) layerDataReset(lr)
}
}
// You can add non-layer related variables that should to into "player" and be saved here, along with default values
function addedPlayerData() { return {
}}
function layerDataReset(layer, keep = []) {
let storedData = {unlocked: player[layer].unlocked, forceTooltip: player[layer].forceTooltip, noRespecConfirm: player[layer].noRespecConfirm, prevTab:player[layer].prevTab} // Always keep these
// Display extra things at the top of the page
var displayThings = [
]
for (thing in keep) {
if (player[layer][keep[thing]] !== undefined)
storedData[keep[thing]] = player[layer][keep[thing]]
}
Vue.set(player[layer], "buyables", getStartBuyables(layer))
Vue.set(player[layer], "clickables", getStartClickables(layer))
Vue.set(player[layer], "challenges", getStartChallenges(layer))
Vue.set(player[layer], "grid", getStartGrid(layer))
layOver(player[layer], getStartLayerData(layer))
player[layer].upgrades = []
player[layer].milestones = []
player[layer].achievements = []
for (thing in storedData) {
player[layer][thing] =storedData[thing]
}
// Determines when the game "ends"
function isEndgame() {
return player.points.gte(new Decimal("e280000000"))
}
function addPoints(layer, gain) {
player[layer].points = player[layer].points.add(gain).max(0)
if (player[layer].best) player[layer].best = player[layer].best.max(player[layer].points)
if (player[layer].total) player[layer].total = player[layer].total.add(gain)
}
// Less important things beyond this point!
function generatePoints(layer, diff) {
addPoints(layer, tmp[layer].resetGain.times(diff))
}
function doReset(layer, force=false) {
if (tmp[layer].type == "none") return
let row = tmp[layer].row
if (!force) {
if (tmp[layer].canReset === false) return;
if (tmp[layer].baseAmount.lt(tmp[layer].requires)) return;
let gain = tmp[layer].resetGain
if (tmp[layer].type=="static") {
if (tmp[layer].baseAmount.lt(tmp[layer].nextAt)) return;
gain =(tmp[layer].canBuyMax ? gain : 1)
}
if (layers[layer].onPrestige)
run(layers[layer].onPrestige, layers[layer], gain)
addPoints(layer, gain)
updateMilestones(layer)
updateAchievements(layer)
if (!player[layer].unlocked) {
player[layer].unlocked = true;
needCanvasUpdate = true;
if (tmp[layer].increaseUnlockOrder){
lrs = tmp[layer].increaseUnlockOrder
for (lr in lrs)
if (!player[lrs[lr]].unlocked) player[lrs[lr]].unlockOrder++
}
}
}
if (run(layers[layer].resetsNothing, layers[layer])) return
tmp[layer].baseAmount = decimalZero // quick fix
for (layerResetting in layers) {
if (row >= layers[layerResetting].row && (!force || layerResetting != layer)) completeChallenge(layerResetting)
}
player.points = (row == 0 ? decimalZero : getStartPoints())
for (let x = row; x >= 0; x--) rowReset(x, layer)
for (r in OTHER_LAYERS){
rowReset(r, layer)
}
player[layer].resetTime = 0
updateTemp()
updateTemp()
}
function resetRow(row) {
if (prompt('Are you sure you want to reset this row? It is highly recommended that you wait until the end of your current run before doing this! Type "I WANT TO RESET THIS" to confirm')!="I WANT TO RESET THIS") return
let pre_layers = ROW_LAYERS[row-1]
let layers = ROW_LAYERS[row]
let post_layers = ROW_LAYERS[row+1]
rowReset(row+1, post_layers[0])
doReset(pre_layers[0], true)
for (let layer in layers) {
player[layer].unlocked = false
if (player[layer].unlockOrder) player[layer].unlockOrder = 0
}
player.points = getStartPoints()
updateTemp();
resizeCanvas();
}
function startChallenge(layer, x) {
let enter = false
if (!player[layer].unlocked || !tmp[layer].challenges[x].unlocked) return
if (player[layer].activeChallenge == x) {
completeChallenge(layer, x)
Vue.set(player[layer], "activeChallenge", null)
} else {
enter = true
}
doReset(layer, true)
if(enter) {
Vue.set(player[layer], "activeChallenge", x)
run(layers[layer].challenges[x].onEnter, layers[layer].challenges[x])
}
updateChallengeTemp(layer)
}
function canCompleteChallenge(layer, x)
{
if (x != player[layer].activeChallenge) return
let challenge = tmp[layer].challenges[x]
if (challenge.canComplete !== undefined) return challenge.canComplete
if (challenge.currencyInternalName){
let name = challenge.currencyInternalName
if (challenge.currencyLocation){
return !(challenge.currencyLocation[name].lt(challenge.goal))
}
else if (challenge.currencyLayer){
let lr = challenge.currencyLayer
return !(player[lr][name].lt(challenge.goal))
}
else {
return !(player[name].lt(challenge.goal))
}
}
else {
return !(player.points.lt(challenge.goal))
}
// Style for the background, can be a function
var backgroundStyle = {
}
function completeChallenge(layer, x) {
var x = player[layer].activeChallenge
if (!x) return
let completions = canCompleteChallenge(layer, x)
if (!completions){
Vue.set(player[layer], "activeChallenge", null)
run(layers[layer].challenges[x].onExit, layers[layer].challenges[x])
return
}
if (player[layer].challenges[x] < tmp[layer].challenges[x].completionLimit) {
needCanvasUpdate = true
player[layer].challenges[x] += completions
player[layer].challenges[x] = Math.min(player[layer].challenges[x], tmp[layer].challenges[x].completionLimit)
if (layers[layer].challenges[x].onComplete) run(layers[layer].challenges[x].onComplete, layers[layer].challenges[x])
}
Vue.set(player[layer], "activeChallenge", null)
run(layers[layer].challenges[x].onExit, layers[layer].challenges[x])
updateChallengeTemp(layer)
// You can change this if you have things that can be messed up by long tick lengths
function maxTickLength() {
return(3600) // Default is 1 hour which is just arbitrarily large
}
VERSION.withoutName = "v" + VERSION.num + (VERSION.pre ? " Pre-Release " + VERSION.pre : VERSION.pre ? " Beta " + VERSION.beta : "")
VERSION.withName = VERSION.withoutName + (VERSION.name ? ": " + VERSION.name : "")
function autobuyUpgrades(layer){
if (!tmp[layer].upgrades) return
for (id in tmp[layer].upgrades)
if (isPlainObject(tmp[layer].upgrades[id]) && (layers[layer].upgrades[id].canAfford === undefined || layers[layer].upgrades[id].canAfford() === true))
buyUpg(layer, id)
}
function gameLoop(diff) {
if (isEndgame() || tmp.gameEnded){
tmp.gameEnded = true
clearParticles()
}
if (isNaN(diff) || diff < 0) diff = 0
if (tmp.gameEnded && !player.keepGoing) {
diff = 0
//player.tab = "tmp.gameEnded"
clearParticles()
}
if (maxTickLength) {
let limit = maxTickLength()
if(diff > limit)
diff = limit
}
addTime(diff)
player.points = player.points.add(tmp.pointGen.times(diff)).max(0)
for (let x = 0; x <= maxRow; x++){
for (item in TREE_LAYERS[x]) {
let layer = TREE_LAYERS[x][item]
player[layer].resetTime += diff
if (tmp[layer].passiveGeneration) generatePoints(layer, diff*tmp[layer].passiveGeneration);
if (layers[layer].update) layers[layer].update(diff);
}
}
for (row in OTHER_LAYERS){
for (item in OTHER_LAYERS[row]) {
let layer = OTHER_LAYERS[row][item]
player[layer].resetTime += diff
if (tmp[layer].passiveGeneration) generatePoints(layer, diff*tmp[layer].passiveGeneration);
if (layers[layer].update) layers[layer].update(diff);
}
}
for (let x = maxRow; x >= 0; x--){
for (item in TREE_LAYERS[x]) {
let layer = TREE_LAYERS[x][item]
if (tmp[layer].autoPrestige && tmp[layer].canReset) doReset(layer);
if (layers[layer].automate) layers[layer].automate();
if (tmp[layer].autoUpgrade) autobuyUpgrades(layer)
}
}
for (row in OTHER_LAYERS){
for (item in OTHER_LAYERS[row]) {
let layer = OTHER_LAYERS[row][item]
if (tmp[layer].autoPrestige && tmp[layer].canReset) doReset(layer);
if (layers[layer].automate) layers[layer].automate();
player[layer].best = player[layer].best.max(player[layer].points)
if (tmp[layer].autoUpgrade) autobuyUpgrades(layer)
}
}
for (layer in layers){
if (layers[layer].milestones) updateMilestones(layer);
if (layers[layer].achievements) updateAchievements(layer)
}
}
function hardReset(resetOptions) {
if (!confirm("Are you sure you want to do this? You will lose all your progress!")) return
player = null
if(resetOptions) options = null
save(true);
window.location.reload();
}
var ticking = false
var interval = setInterval(function() {
if (player===undefined||tmp===undefined) return;
if (ticking) return;
if (tmp.gameEnded&&!player.keepGoing) return;
ticking = true
let now = Date.now()
let diff = (now - player.time) / 1e3
let trueDiff = diff
if (player.offTime !== undefined) {
if (player.offTime.remain > modInfo.offlineLimit * 3600) player.offTime.remain = modInfo.offlineLimit * 3600
if (player.offTime.remain > 0) {
let offlineDiff = Math.max(player.offTime.remain / 10, diff)
player.offTime.remain -= offlineDiff
diff += offlineDiff
}
if (!options.offlineProd || player.offTime.remain <= 0) player.offTime = undefined
}
if (player.devSpeed) diff *= player.devSpeed
player.time = now
if (needCanvasUpdate){ resizeCanvas();
needCanvasUpdate = false;
}
tmp.scrolled = document.getElementById('treeTab') && document.getElementById('treeTab').scrollTop > 30
updateTemp();
updateOomps(diff);
updateWidth()
updateTabFormats()
gameLoop(diff)
fixNaNs()
adjustPopupTime(trueDiff)
updateParticles(trueDiff)
ticking = false
}, 50)
setInterval(function() {needCanvasUpdate = true}, 500)
// Use this if you need to undo inflation from an older version. If the version is older than the version that fixed the issue,
// you can cap their current resources with this.
function fixOldSave(oldVersion){
}

430
js/incrementum.js Normal file
View file

@ -0,0 +1,430 @@
var player;
var needCanvasUpdate = true;
// Don't change this
const INC_VERSION = {
incNum: "2.6.6.2",
incName: "Fixed Reality"
}
function getResetGain(layer, useType = null) {
let type = useType
if (!useType){
type = tmp[layer].type
if (layers[layer].getResetGain !== undefined)
return layers[layer].getResetGain()
}
if(tmp[layer].type == "none")
return new Decimal (0)
if (tmp[layer].gainExp.eq(0)) return decimalZero
if (type=="static") {
if ((!tmp[layer].canBuyMax) || tmp[layer].baseAmount.lt(tmp[layer].requires)) return decimalOne
let gain = tmp[layer].baseAmount.div(tmp[layer].requires).div(tmp[layer].gainMult).max(1).log(tmp[layer].base).times(tmp[layer].gainExp).pow(Decimal.pow(tmp[layer].exponent, -1))
gain = gain.times(tmp[layer].directMult)
return gain.floor().sub(player[layer].points).add(1).max(1);
} else if (type=="normal"){
if (tmp[layer].baseAmount.lt(tmp[layer].requires)) return decimalZero
let gain = tmp[layer].baseAmount.div(tmp[layer].requires).pow(tmp[layer].exponent).times(tmp[layer].gainMult).pow(tmp[layer].gainExp)
if (gain.gte(tmp[layer].softcap)) gain = gain.pow(tmp[layer].softcapPower).times(tmp[layer].softcap.pow(decimalOne.sub(tmp[layer].softcapPower)))
gain = gain.times(tmp[layer].directMult)
return gain.floor().max(0);
} else if (type=="custom"){
return layers[layer].getResetGain()
} else {
return decimalZero
}
}
function getNextAt(layer, canMax=false, useType = null) {
let type = useType
if (!useType) {
type = tmp[layer].type
if (layers[layer].getNextAt !== undefined)
return layers[layer].getNextAt(canMax)
}
if(tmp[layer].type == "none")
return new Decimal (Infinity)
if (tmp[layer].gainMult.lte(0)) return new Decimal(Infinity)
if (tmp[layer].gainExp.lte(0)) return new Decimal(Infinity)
if (type=="static")
{
if (!tmp[layer].canBuyMax) canMax = false
let amt = player[layer].points.plus((canMax&&tmp[layer].baseAmount.gte(tmp[layer].nextAt))?tmp[layer].resetGain:0).div(tmp[layer].directMult)
let extraCost = Decimal.pow(tmp[layer].base, amt.pow(tmp[layer].exponent).div(tmp[layer].gainExp)).times(tmp[layer].gainMult)
let cost = extraCost.times(tmp[layer].requires).max(tmp[layer].requires)
if (tmp[layer].roundUpCost) cost = cost.ceil()
return cost;
} else if (type=="normal"){
let next = tmp[layer].resetGain.add(1).div(tmp[layer].directMult)
if (next.gte(tmp[layer].softcap)) next = next.div(tmp[layer].softcap.pow(decimalOne.sub(tmp[layer].softcapPower))).pow(decimalOne.div(tmp[layer].softcapPower))
next = next.root(tmp[layer].gainExp).div(tmp[layer].gainMult).root(tmp[layer].exponent).times(tmp[layer].requires).max(tmp[layer].requires)
if (tmp[layer].roundUpCost) next = next.ceil()
return next;
} else if (type=="custom"){
return layers[layer].getNextAt(canMax)
} else {
return decimalZero
}}
function softcap(value, cap, power = 0.5) {
if (value.lte(cap)) return value
else
return value.pow(power).times(cap.pow(decimalOne.sub(power)))
}
// Return true if the layer should be highlighted. By default checks for upgrades only.
function shouldNotify(layer){
for (id in tmp[layer].upgrades){
if (isPlainObject(layers[layer].upgrades[id])){
if (canAffordUpgrade(layer, id) && !hasUpgrade(layer, id) && tmp[layer].upgrades[id].unlocked){
return true
}
}
}
if (player[layer].activeChallenge && canCompleteChallenge(layer, player[layer].activeChallenge)) {
return true
}
if (tmp[layer].shouldNotify)
return true
if (isPlainObject(tmp[layer].tabFormat)) {
for (subtab in tmp[layer].tabFormat){
if (subtabShouldNotify(layer, 'mainTabs', subtab)) {
tmp[layer].trueGlowColor = tmp[layer].tabFormat[subtab].glowColor || defaultGlow
return true
}
}
}
for (family in tmp[layer].microtabs) {
for (subtab in tmp[layer].microtabs[family]){
if (subtabShouldNotify(layer, family, subtab)) {
tmp[layer].trueGlowColor = tmp[layer].microtabs[family][subtab].glowColor
return true
}
}
}
return false
}
function canReset(layer)
{
if (layers[layer].canReset!== undefined)
return run(layers[layer].canReset, layers[layer])
else if(tmp[layer].type == "normal")
return tmp[layer].baseAmount.gte(tmp[layer].requires)
else if(tmp[layer].type== "static")
return tmp[layer].baseAmount.gte(tmp[layer].nextAt)
else
return false
}
function rowReset(row, layer) {
for (lr in ROW_LAYERS[row]){
if(layers[lr].doReset) {
if (!isNaN(row)) Vue.set(player[lr], "activeChallenge", null) // Exit challenges on any row reset on an equal or higher row
run(layers[lr].doReset, layers[lr], layer)
}
else
if(tmp[layer].row > tmp[lr].row && !isNaN(row)) layerDataReset(lr)
}
}
function layerDataReset(layer, keep = []) {
let storedData = {unlocked: player[layer].unlocked, forceTooltip: player[layer].forceTooltip, noRespecConfirm: player[layer].noRespecConfirm, prevTab:player[layer].prevTab} // Always keep these
for (thing in keep) {
if (player[layer][keep[thing]] !== undefined)
storedData[keep[thing]] = player[layer][keep[thing]]
}
Vue.set(player[layer], "buyables", getStartBuyables(layer))
Vue.set(player[layer], "clickables", getStartClickables(layer))
Vue.set(player[layer], "challenges", getStartChallenges(layer))
Vue.set(player[layer], "grid", getStartGrid(layer))
layOver(player[layer], getStartLayerData(layer))
player[layer].upgrades = []
player[layer].milestones = []
player[layer].achievements = []
for (thing in storedData) {
player[layer][thing] =storedData[thing]
}
}
function addPoints(layer, gain) {
player[layer].points = player[layer].points.add(gain).max(0)
if (player[layer].best) player[layer].best = player[layer].best.max(player[layer].points)
if (player[layer].total) player[layer].total = player[layer].total.add(gain)
}
function generatePoints(layer, diff) {
addPoints(layer, tmp[layer].resetGain.times(diff))
}
function doReset(layer, force=false) {
if (tmp[layer].type == "none") return
let row = tmp[layer].row
if (!force) {
if (tmp[layer].canReset === false) return;
if (tmp[layer].baseAmount.lt(tmp[layer].requires)) return;
let gain = tmp[layer].resetGain
if (tmp[layer].type=="static") {
if (tmp[layer].baseAmount.lt(tmp[layer].nextAt)) return;
gain =(tmp[layer].canBuyMax ? gain : 1)
}
if (layers[layer].onPrestige)
run(layers[layer].onPrestige, layers[layer], gain)
addPoints(layer, gain)
updateMilestones(layer)
updateAchievements(layer)
if (!player[layer].unlocked) {
player[layer].unlocked = true;
needCanvasUpdate = true;
if (tmp[layer].increaseUnlockOrder){
lrs = tmp[layer].increaseUnlockOrder
for (lr in lrs)
if (!player[lrs[lr]].unlocked) player[lrs[lr]].unlockOrder++
}
}
}
if (run(layers[layer].resetsNothing, layers[layer])) return
tmp[layer].baseAmount = decimalZero // quick fix
for (layerResetting in layers) {
if (row >= layers[layerResetting].row && (!force || layerResetting != layer)) completeChallenge(layerResetting)
}
player.points = (row == 0 ? decimalZero : getStartPoints())
for (let x = row; x >= 0; x--) rowReset(x, layer)
for (r in OTHER_LAYERS){
rowReset(r, layer)
}
player[layer].resetTime = 0
updateTemp()
updateTemp()
}
function resetRow(row) {
if (prompt('Are you sure you want to reset this row? It is highly recommended that you wait until the end of your current run before doing this! Type "I WANT TO RESET THIS" to confirm')!="I WANT TO RESET THIS") return
let pre_layers = ROW_LAYERS[row-1]
let layers = ROW_LAYERS[row]
let post_layers = ROW_LAYERS[row+1]
rowReset(row+1, post_layers[0])
doReset(pre_layers[0], true)
for (let layer in layers) {
player[layer].unlocked = false
if (player[layer].unlockOrder) player[layer].unlockOrder = 0
}
player.points = getStartPoints()
updateTemp();
resizeCanvas();
}
function startChallenge(layer, x) {
let enter = false
if (!player[layer].unlocked || !tmp[layer].challenges[x].unlocked) return
if (player[layer].activeChallenge == x) {
completeChallenge(layer, x)
Vue.set(player[layer], "activeChallenge", null)
} else {
enter = true
}
doReset(layer, true)
if(enter) {
Vue.set(player[layer], "activeChallenge", x)
run(layers[layer].challenges[x].onEnter, layers[layer].challenges[x])
}
updateChallengeTemp(layer)
}
function canCompleteChallenge(layer, x)
{
if (x != player[layer].activeChallenge) return
let challenge = tmp[layer].challenges[x]
if (challenge.canComplete !== undefined) return challenge.canComplete
if (challenge.currencyInternalName){
let name = challenge.currencyInternalName
if (challenge.currencyLocation){
return !(challenge.currencyLocation[name].lt(challenge.goal))
}
else if (challenge.currencyLayer){
let lr = challenge.currencyLayer
return !(player[lr][name].lt(challenge.goal))
}
else {
return !(player[name].lt(challenge.goal))
}
}
else {
return !(player.points.lt(challenge.goal))
}
}
function completeChallenge(layer, x) {
var x = player[layer].activeChallenge
if (!x) return
let completions = canCompleteChallenge(layer, x)
if (!completions){
Vue.set(player[layer], "activeChallenge", null)
run(layers[layer].challenges[x].onExit, layers[layer].challenges[x])
return
}
if (player[layer].challenges[x] < tmp[layer].challenges[x].completionLimit) {
needCanvasUpdate = true
player[layer].challenges[x] += completions
player[layer].challenges[x] = Math.min(player[layer].challenges[x], tmp[layer].challenges[x].completionLimit)
if (layers[layer].challenges[x].onComplete) run(layers[layer].challenges[x].onComplete, layers[layer].challenges[x])
}
Vue.set(player[layer], "activeChallenge", null)
run(layers[layer].challenges[x].onExit, layers[layer].challenges[x])
updateChallengeTemp(layer)
}
VERSION.withoutName = "v" + VERSION.num + (VERSION.pre ? " Pre-Release " + VERSION.pre : VERSION.pre ? " Beta " + VERSION.beta : "")
VERSION.withName = VERSION.withoutName + (VERSION.name ? ": " + VERSION.name : "")
function autobuyUpgrades(layer){
if (!tmp[layer].upgrades) return
for (id in tmp[layer].upgrades)
if (isPlainObject(tmp[layer].upgrades[id]) && (layers[layer].upgrades[id].canAfford === undefined || layers[layer].upgrades[id].canAfford() === true))
buyUpg(layer, id)
}
function gameLoop(diff) {
if (isEndgame() || tmp.gameEnded){
tmp.gameEnded = true
clearParticles()
}
if (isNaN(diff) || diff < 0) diff = 0
if (tmp.gameEnded && !player.keepGoing) {
diff = 0
//player.tab = "tmp.gameEnded"
clearParticles()
}
if (maxTickLength) {
let limit = maxTickLength()
if(diff > limit)
diff = limit
}
addTime(diff)
player.points = player.points.add(tmp.pointGen.times(diff)).max(0)
for (let x = 0; x <= maxRow; x++){
for (item in TREE_LAYERS[x]) {
let layer = TREE_LAYERS[x][item]
player[layer].resetTime += diff
if (tmp[layer].passiveGeneration) generatePoints(layer, diff*tmp[layer].passiveGeneration);
if (layers[layer].update) layers[layer].update(diff);
}
}
for (row in OTHER_LAYERS){
for (item in OTHER_LAYERS[row]) {
let layer = OTHER_LAYERS[row][item]
player[layer].resetTime += diff
if (tmp[layer].passiveGeneration) generatePoints(layer, diff*tmp[layer].passiveGeneration);
if (layers[layer].update) layers[layer].update(diff);
}
}
for (let x = maxRow; x >= 0; x--){
for (item in TREE_LAYERS[x]) {
let layer = TREE_LAYERS[x][item]
if (tmp[layer].autoPrestige && tmp[layer].canReset) doReset(layer);
if (layers[layer].automate) layers[layer].automate();
if (tmp[layer].autoUpgrade) autobuyUpgrades(layer)
}
}
for (row in OTHER_LAYERS){
for (item in OTHER_LAYERS[row]) {
let layer = OTHER_LAYERS[row][item]
if (tmp[layer].autoPrestige && tmp[layer].canReset) doReset(layer);
if (layers[layer].automate) layers[layer].automate();
player[layer].best = player[layer].best.max(player[layer].points)
if (tmp[layer].autoUpgrade) autobuyUpgrades(layer)
}
}
for (layer in layers){
if (layers[layer].milestones) updateMilestones(layer);
if (layers[layer].achievements) updateAchievements(layer)
}
}
function hardReset(resetOptions) {
if (!confirm("Are you sure you want to do this? You will lose all your progress!")) return
player = null
if(resetOptions) options = null
save(true);
window.location.reload();
}
var ticking = false
var interval = setInterval(function() {
if (player===undefined||tmp===undefined) return;
if (ticking) return;
if (tmp.gameEnded&&!player.keepGoing) return;
ticking = true
let now = Date.now()
let diff = (now - player.time) / 1e3
let trueDiff = diff
if (player.offTime !== undefined) {
if (player.offTime.remain > gameInfo.offlineLimit * 3600) player.offTime.remain = gameInfo.offlineLimit * 3600
if (player.offTime.remain > 0) {
let offlineDiff = Math.max(player.offTime.remain / 10, diff)
player.offTime.remain -= offlineDiff
diff += offlineDiff
}
if (!options.offlineProd || player.offTime.remain <= 0) player.offTime = undefined
}
if (player.devSpeed) diff *= player.devSpeed
player.time = now
if (needCanvasUpdate){ resizeCanvas();
needCanvasUpdate = false;
}
tmp.scrolled = document.getElementById('treeTab') && document.getElementById('treeTab').scrollTop > 30
updateTemp();
updateOomps(diff);
updateWidth()
updateTabFormats()
gameLoop(diff)
fixNaNs()
adjustPopupTime(trueDiff)
updateParticles(trueDiff)
ticking = false
}, 50)
setInterval(function() {needCanvasUpdate = true}, 500)

View file

@ -1,79 +0,0 @@
let modInfo = {
name: "The ??? Tree",
id: "mymod",
author: "nobody",
pointsName: "points",
modFiles: ["layers.js", "tree.js"],
discordName: "",
discordLink: "",
initialStartPoints: new Decimal (10), // Used for hard resets and new players
offlineLimit: 1, // In hours
}
// Set your version in num and name
let VERSION = {
num: "0.0",
name: "Literally nothing",
}
let changelog = `<h1>Changelog:</h1><br>
<h3>v0.0</h3><br>
- Added things.<br>
- Added stuff.`
let winText = `Congratulations! You have reached the end and beaten this game, but for now...`
// If you add new functions anywhere inside of a layer, and those functions have an effect when called, add them here.
// (The ones here are examples, all official functions are already taken care of)
var doNotCallTheseFunctionsEveryTick = ["blowUpEverything"]
function getStartPoints(){
return new Decimal(modInfo.initialStartPoints)
}
// Determines if it should show points/sec
function canGenPoints(){
return true
}
// Calculate points/sec!
function getPointGen() {
if(!canGenPoints())
return new Decimal(0)
let gain = new Decimal(1)
return gain
}
// You can add non-layer related variables that should to into "player" and be saved here, along with default values
function addedPlayerData() { return {
}}
// Display extra things at the top of the page
var displayThings = [
]
// Determines when the game "ends"
function isEndgame() {
return player.points.gte(new Decimal("e280000000"))
}
// Less important things beyond this point!
// Style for the background, can be a function
var backgroundStyle = {
}
// You can change this if you have things that can be messed up by long tick lengths
function maxTickLength() {
return(3600) // Default is 1 hour which is just arbitrarily large
}
// Use this if you need to undo inflation from an older version. If the version is older than the version that fixed the issue,
// you can cap their current resources with this.
function fixOldSave(oldVersion){
}

View file

@ -289,6 +289,6 @@ addLayer("options-tab", {
})
addLayer("changelog-tab", {
tabFormat() {return ([["raw-html", modInfo.changelog]])},
tabFormat() {return ([["raw-html", gameInfo.changelog]])},
row: "otherside"
})

View file

@ -1,8 +1,8 @@
// Load files
for (file in modInfo.modFiles) {
for (file in gameInfo.gameFiles) {
let script = document.createElement("script");
script.setAttribute("src", "js/" + modInfo.modFiles[file]);
script.setAttribute("src", "js/" + gameInfo.gameFiles[file]);
script.setAttribute("async", "false");
document.head.insertBefore(script, document.getElementById("temp"));
}

View file

@ -114,7 +114,7 @@ var systemComponents = {
<br>
<span v-if="player.points.lt('1e1000')" class="overlayThing">You have </span>
<h2 class="overlayThing" id="points">{{format(player.points)}}</h2>
<span v-if="player.points.lt('1e1e6')" class="overlayThing"> {{modInfo.pointsName}}</span>
<span v-if="player.points.lt('1e1e6')" class="overlayThing"> {{gameInfo.pointsName}}</span>
<br>
<span v-if="canGenPoints()" class="overlayThing">({{tmp.other.oompsMag != 0 ? format(tmp.other.oomps) + " OOM" + (tmp.other.oompsMag < 0 ? "^OOM" : tmp.other.oompsMag > 1 ? "^" + tmp.other.oompsMag : "") + "s" : formatSmall(getPointGen())}}/sec)</span>
<div v-for="thing in tmp.displayThings" class="overlayThing"><span v-if="thing" v-html="thing"></span></div>
@ -125,21 +125,21 @@ var systemComponents = {
'info-tab': {
template: `
<div>
<h2>{{modInfo.name}}</h2>
<h2>{{gameInfo.name}}</h2>
<br>
<h3>{{VERSION.withName}}</h3>
<span v-if="modInfo.author">
<span v-if="gameInfo.author">
<br>
Made by {{modInfo.author}}
Made by {{gameInfo.author}}
</span>
<br>
The Modding Tree <a v-bind:href="'https://github.com/Acamaeda/The-Modding-Tree/blob/master/changelog.md'" target="_blank" class="link" v-bind:style = "{'font-size': '14px', 'display': 'inline'}" >{{TMT_VERSION.tmtNum}}</a> by Acamaeda
Incrementum <a v-bind:href="'https://github.com/Acamaeda/Incrementum/blob/master/changelog.md'" target="_blank" class="link" v-bind:style = "{'font-size': '14px', 'display': 'inline'}" >{{TMT_VERSION.tmtNum}}</a> by Acamaeda
<br>
The Prestige Tree made by Jacorb and Aarex
Based on The Prestige Tree by Jacorb and Aarex
<br><br>
<div class="link" onclick="showTab('changelog-tab')">Changelog</div><br>
<span v-if="modInfo.discordLink"><a class="link" v-bind:href="modInfo.discordLink" target="_blank">{{modInfo.discordName}}</a><br></span>
<a class="link" href="https://discord.gg/F3xveHV" target="_blank" v-bind:style="modInfo.discordLink ? {'font-size': '16px'} : {}">The Modding Tree Discord</a><br>
<span v-if="gameInfo.discordLink"><a class="link" v-bind:href="gameInfo.discordLink" target="_blank">{{gameInfo.discordName}}</a><br></span>
<a class="link" href="https://discord.gg/F3xveHV" target="_blank" v-bind:style="gameInfo.discordLink ? {'font-size': '16px'} : {}">Incrementum Discord</a><br>
<a class="link" href="http://discord.gg/wwQfgPa" target="_blank" v-bind:style="{'font-size': '16px'}">Main Prestige Tree server</a><br>
<br><br>
Time Played: {{ formatTime(player.timePlayed) }}<br><br>

View file

@ -340,7 +340,7 @@ function isPlainObject(obj) {
return (!!obj) && (obj.constructor === Object)
}
document.title = modInfo.name
document.title = gameInfo.name
// Converts a string value to whatever it's supposed to be
function toValue(value, oldValue) {

View file

@ -41,7 +41,7 @@ function sumValues(x) {
}
function format(decimal, precision = 2, small) {
small = small || modInfo.allowSmall
small = small || gameInfo.allowSmall
decimal = new Decimal(decimal)
if (isNaN(decimal.sign) || isNaN(decimal.layer) || isNaN(decimal.mag)) {
player.hasNaN = true;

View file

@ -2,8 +2,8 @@
function save(force) {
NaNcheck(player)
if (NaNalert && !force) return
localStorage.setItem(modInfo.id, btoa(unescape(encodeURIComponent(JSON.stringify(player)))));
localStorage.setItem(modInfo.id+"_options", btoa(unescape(encodeURIComponent(JSON.stringify(options)))));
localStorage.setItem(gameInfo.id, btoa(unescape(encodeURIComponent(JSON.stringify(player)))));
localStorage.setItem(gameInfo.id+"_options", btoa(unescape(encodeURIComponent(JSON.stringify(options)))));
}
function startPlayerBase() {
@ -12,14 +12,14 @@ function startPlayerBase() {
navTab: (layoutInfo.showTree ? layoutInfo.startNavTab : "none"),
time: Date.now(),
notify: {},
versionType: modInfo.id,
versionType: gameInfo.id,
version: VERSION.num,
beta: VERSION.beta,
timePlayed: 0,
keepGoing: false,
hasNaN: false,
points: modInfo.initialStartPoints,
points: gameInfo.initialStartPoints,
subtabs: {},
lastSafeTab: (readData(layoutInfo.showTree) ? "none" : layoutInfo.startTab)
};
@ -185,7 +185,7 @@ function fixData(defaultData, newData) {
}
}
function load() {
let get = localStorage.getItem(modInfo.id);
let get = localStorage.getItem(gameInfo.id);
if (get === null || get === undefined) {
player = getStartPlayer();
@ -207,7 +207,7 @@ function load() {
changeTheme();
changeTreeQuality();
updateLayers();
setupModInfo();
setupGameInfo();
setupTemp();
updateTemp();
@ -217,7 +217,7 @@ function load() {
}
function loadOptions() {
let get2 = localStorage.getItem(modInfo.id+"_options");
let get2 = localStorage.getItem(gameInfo.id+"_options");
if (get2)
options = Object.assign(getStartOptions(), JSON.parse(decodeURIComponent(escape(atob(get2)))));
else
@ -227,9 +227,9 @@ function loadOptions() {
}
function setupModInfo() {
modInfo.changelog = changelog;
modInfo.winText = winText ? winText : `Congratulations! You have reached the end and beaten this game, but for now...`;
function setupGameInfo() {
gameInfo.changelog = changelog;
gameInfo.winText = winText ? winText : `Congratulations! You have reached the end and beaten this game, but for now...`;
}
function fixNaNs() {
@ -246,7 +246,7 @@ function NaNcheck(data) {
if (!NaNalert) {
clearInterval(interval);
NaNalert = true;
alert("Invalid value found in player, named '" + item + "'. Please let the creator of this mod know! You can refresh the page, and you will be un-NaNed.")
alert("Invalid value found in player, named '" + item + "'. Please let the creator of this game know! You can refresh the page, and you will be un-NaNed.")
return
}
}
@ -274,10 +274,10 @@ function importSave(imported = undefined, forced = false) {
imported = prompt("Paste your save here");
try {
tempPlr = Object.assign(getStartPlayer(), JSON.parse(atob(imported)));
if (tempPlr.versionType != modInfo.id && !forced && !confirm("This save appears to be for a different mod! Are you sure you want to import?")) // Wrong save (use "Forced" to force it to accept.)
if (tempPlr.versionType != gameInfo.id && !forced && !confirm("This save appears to be for a different game! Are you sure you want to import?")) // Wrong save (use "Forced" to force it to accept.)
return;
player = tempPlr;
player.versionType = modInfo.id;
player.versionType = gameInfo.id;
fixSave();
versionCheck();
NaNcheck(save)
@ -291,12 +291,12 @@ function versionCheck() {
let setVersion = true;
if (player.versionType === undefined || player.version === undefined) {
player.versionType = modInfo.id;
player.versionType = gameInfo.id;
player.version = 0;
}
if (setVersion) {
if (player.versionType == modInfo.id && VERSION.num > player.version) {
if (player.versionType == gameInfo.id && VERSION.num > player.version) {
player.keepGoing = false;
if (fixOldSave)
fixOldSave(player.version);