43 lines
22 KiB
JavaScript
43 lines
22 KiB
JavaScript
|
import{_ as s,c as a,o as n,N as e}from"./chunks/framework.0799945b.js";const d=JSON.parse('{"title":"Your First Layer","description":"","frontmatter":{},"headers":[],"relativePath":"guide/getting-started/first-layer.md","lastUpdated":1681878045000}'),o={name:"guide/getting-started/first-layer.md"},l=e(`<h1 id="your-first-layer" tabindex="-1">Your First Layer <a class="header-anchor" href="#your-first-layer" aria-label="Permalink to "Your First Layer""></a></h1><p>This page is a guide on where to start with creating your very first layer. It is intended for developers who are first learning to use the engine.</p><h2 id="creating-the-layer" tabindex="-1">Creating the layer <a class="header-anchor" href="#creating-the-layer" aria-label="Permalink to "Creating the layer""></a></h2><div class="info custom-block"><p class="custom-block-title">INFO</p><p>The template comes with a layer in <code>projEntry.tsx</code> and another in <code>prestige.tsx</code>. You can use those as a base instead of creating a new one from scratch.</p></div><p>To add a new layer, first create it via the <a href="./../../api/modules/game/layers#createlayer">createLayer</a> function. You typically create a single layer per file, the first being in <code>projEntry</code>. After it is created, you'll need to add it to the returned array in <a href="./../../api/modules/data/projEntry#getinitiallayers">getInitialLayers</a>.</p><p>The <code>createLayer</code> function will need a unique ID for your layer and a function that constructs the layer. At a minimum, it needs a <code>display</code> property so Profectus knows what to render. It will look something like this:</p><div class="language-ts"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> id </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">"</span><span style="color:#C3E88D;">p</span><span style="color:#89DDFF;">"</span><span style="color:#89DDFF;">;</span></span>
|
|||
|
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> layer </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createLayer</span><span style="color:#A6ACCD;">(id</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;font-style:italic;">this</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">BaseLayer</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
|||
|
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
|||
|
<span class="line"><span style="color:#F07178;"> display</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">jsx</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> <></span><span style="color:#A6ACCD;">My</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">layer</span><span style="color:#89DDFF;"></></span><span style="color:#F07178;">)</span></span>
|
|||
|
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">};</span></span>
|
|||
|
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span></span></code></pre></div><h2 id="adding-a-resource" tabindex="-1">Adding a resource <a class="header-anchor" href="#adding-a-resource" aria-label="Permalink to "Adding a resource""></a></h2><p>Game elements in Profectus are called "features". You'll create them inside the layer's constructor function and return them in the object at the end. Many features can also be rendered in the layer's display.</p><p>In the file tree, there's a folder called <code>src/features</code>, which contains all the different features that are included in Profectus (and any others you've created or downloaded from others!). You can browse the folder to see all the features and learn what each one does. Some features also have dedicated guide pages on how to use them.</p><p>Let's add one of these features to our layer: a Resource. As with most features, there's a <a href="./../../api/modules/features/resource#createresource">createResource</a> constructor for creating this feature. These constructors typically take a function that returns an object with all the options for that feature. However, resources are simple features, so they just take the options as parameters. Creating a resource will look like this:</p><div class="language-ts"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> points </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createResource</span><span style="color:#89DDFF;"><</span><span style="color:#FFCB6B;">DecimalSource</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">"</span><span style="color:#C3E88D;">prestige points</span><span style="color:#89DDFF;">"</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span></span></code></pre></div><p>In your IDE you'll be able to see the documentation for each parameter - in this case, the first one is the default value for this resource, and the second is the display name for the resource. Now we can make sure to add the points to our layer's object and display it using the <a href="./../../api/modules/features/resource#maindisplay-component">MainDisplay</a> Vue component. All in all, our layer should look like this now:</p><div class="language-ts"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> id </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">"</span><span style="color:#C3E88D;">p</span><span style="color:#89DDFF;">"</span><span style="color:#89DDFF;">;</span></span>
|
|||
|
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> layer </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createLayer</span><span style="color:#A6ACCD;">(id</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#89DDFF;font-style:italic;">this</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">BaseLayer</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
|||
|
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">points</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">createResource</span><span style="color:#89DDFF;"><</span><span style="color:#FFCB6B;">DecimalSource</span><span style="color:#89DDFF;">></span><span style="color:#F07178;">(</span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">"</span><span style="color:#C3E88D;">prestige points</span><span style="color:#89DDFF;">"</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
|
|||
|
<span class="line"></span>
|
|||
|
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
|||
|
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">points</span><span style="color:#89DDFF;">,</span></span>
|
|||
|
<span class="line"><span style="color:#F07178;"> display</span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">jsx</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> (</span></span>
|
|||
|
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><></span></span>
|
|||
|
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;"><</span><span style="color:#A6ACCD;">MainDisplay</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">resource</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">points</span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">/></span></span>
|
|||
|
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;"></></span></span>
|
|||
|
<span class="line"><span style="color:#F07178;"> ))</span></span>
|
|||
|
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">};</span></span>
|
|||
|
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span></span></code></pre></div><h2 id="update-loop" tabindex="-1">Update loop <a class="header-anchor" href="#update-loop" aria-label="Permalink to "Update loop""></a></h2><p>Some things happen every tick, such as passive resource generation. You can hook into the update loop using an event bus. There's a global one and one for each layer. For example, within the layer function, you can add this code to our example to increase our points at a rate of 1 per second:</p><div class="language-ts"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight has-diff"><code><span class="line"><span style="color:#89DDFF;">this.</span><span style="color:#82AAFF;">on</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">"</span><span style="color:#C3E88D;">update</span><span style="color:#89DDFF;">"</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">diff</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
|||
|
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">points</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">value</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">Decimal</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">add</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">points</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">value</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">diff</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
|
|||
|
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">;</span></span></code></pre></div><p>Note that within the <code>createLayer</code>'s function, <code>this</code> refers to the layer you're actively creating, and the <code>diff</code> parameter represents the seconds that have passed since the last update - which will typically be around 0.05 unless throttling is disabled in the settings. If we wanted to generate an amount other than 1/s, we could multiply diff by the per-second rate.</p><h2 id="adding-an-upgrade" tabindex="-1">Adding an upgrade <a class="header-anchor" href="#adding-an-upgrade" aria-label="Permalink to "Adding an upgrade""></a></h2><p>Let's add a more complex feature to the layer now - an upgrade. Upgrades represent one-time purchases. This time the <a href="./../../api/modules/features/upgrade#createupgrade">createUpgrade</a> function requires an options function. We can create a lambda that returns the options object. We'll need to give it a cost requirement and display. Afterwards, it should look like this:</p><div class="language-ts"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> myUpgrade </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createUpgrade</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">requirements</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createCostRequirement</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">resource</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">noPersist</span><span style="color:#A6ACCD;">(points)</span><span style="color:#89DDFF;">,</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">cost</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">))</span><span style="color:#89DDFF;">,</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">display</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">description</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">"</span><span style="color:#C3E88D;">Double points generation</span><span style="color:#89DDFF;">"</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span></span>
|
|||
|
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">))</span><span style="color:#89DDFF;">;</span></span></code></pre></div><p>We'll add this upgrade to our returned object and our display. Upgrades are a renderable feature, which means we can use the <a href="./../../api/modules/util/vue#render">render</a> function to display them. The returned layer object will now look like this:</p><div class="language-ts"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> points</span><span style="color:#89DDFF;">,</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> myUpgrade</span><span style="color:#89DDFF;">,</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">display</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">jsx</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><></span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"><</span><span style="color:#A6ACCD;">MainDisplay resource</span><span style="color:#89DDFF;">={</span><span style="color:#A6ACCD;">points</span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">/></span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;font-style:italic;">render</span><span style="color:#A6ACCD;">(</span><span style="color:#A6ACCD;font-style:italic;">myUpgrade</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">}</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;"></></span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> ))</span></span>
|
|||
|
<span class="line"><span style="color:#89DDFF;">}</span></span></code></pre></div><p>The last thing to do to implement our upgrade is to give it an effect! If <code>myUpgrade.bought.value</code> is true, then the points generation should double. We'll represent that by creating a points gain modifier, which will make it easy to handle many things affecting points gain. The modifier should look like this:</p><div class="language-ts"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> myModifier </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createSequentialModifier</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> [</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">createMultiplicativeModifier</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> (</span><span style="color:#89DDFF;">{</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">multiplier</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#89DDFF;">,</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">enabled</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> myUpgrade</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">bought</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">))</span></span>
|
|||
|
<span class="line"><span style="color:#A6ACCD;">])</span><span style="color:#89DDFF;">;</span></span></code></pre></div><p>Now to make the points gain use the modifier, we'll update the line that adds points to this:</p><div class="language-ts"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki material-theme-palenight has-diff"><code><span class="line"><span style="color:#A6ACCD;">points</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">value </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> Decimal</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">add</span><span style="color:#A6ACCD;">(points</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">value</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> Decimal</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">times</span><span style="color:#A6ACCD;">(myModifier</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">apply</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#A6ACCD;">)</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> diff))</span><span style="color:#89DDFF;">;</span></span></code></pre></div><p>You now have a functioning upgrade, and are prepared to create many more upgrades and other features!</p><h2 id="next-steps" tabindex="-1">Next Steps <a class="header-anchor" href="#next-steps" aria-label="Permalink to "Next Steps""></a></h2><p>Since Profectus is an engine, what to do with it is a fairly open-ended question. If you're not quite ready to go out on your own, there are more guides to help prepare you. A good next step would be the <a href="./../recipes/prestige">Prestige Mechanic</a> recipe page.</p><p>The "Important Concepts" section of the guide goes further into various parts of the engine that are prudent to understand. If any of those look interesting or like something you need help with, they can be a great help.</p><p>Beyond that, the best way to learn is to just continue using the engine and exploring its various features. Have fun!</p>`,32),p=[l];function t(r,c,i,y,D,F){return n(),a("div",null,p)}const C=s(o,[["render",t]]);export{d as __pageData,C as default};
|