diff --git a/assets/index.md.14bdf584.js b/assets/index.md.14bdf584.js deleted file mode 100644 index ca3603db..00000000 --- a/assets/index.md.14bdf584.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,c as t,o}from"./app.829490d2.js";const u='{"title":"Home","description":"","frontmatter":{"home":true,"title":"Home","heroText":"Profectus","tagline":"A game engine that grows with you","actionText":"Get Started","actionLink":"/guide/setup","features":[{"title":"Easy to Use","details":"Everything is written to be as intuitive to use as possible"},{"title":"Well integrated","details":"Seamlessly deploy your project, get type hints in your IDE, etc."},{"title":"Incremental","details":"Designed to actively encourage you to become better at programming"}],"footer":"Copyright \xA9 2022 thepaperpilot"},"headers":[],"relativePath":"index.md"}',i={};function a(r,s,n,c,l,p){return o(),t("div")}var m=e(i,[["render",a]]);export{u as __pageData,m as default}; diff --git a/assets/index.md.14bdf584.lean.js b/assets/index.md.14bdf584.lean.js deleted file mode 100644 index ca3603db..00000000 --- a/assets/index.md.14bdf584.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,c as t,o}from"./app.829490d2.js";const u='{"title":"Home","description":"","frontmatter":{"home":true,"title":"Home","heroText":"Profectus","tagline":"A game engine that grows with you","actionText":"Get Started","actionLink":"/guide/setup","features":[{"title":"Easy to Use","details":"Everything is written to be as intuitive to use as possible"},{"title":"Well integrated","details":"Seamlessly deploy your project, get type hints in your IDE, etc."},{"title":"Incremental","details":"Designed to actively encourage you to become better at programming"}],"footer":"Copyright \xA9 2022 thepaperpilot"},"headers":[],"relativePath":"index.md"}',i={};function a(r,s,n,c,l,p){return o(),t("div")}var m=e(i,[["render",a]]);export{u as __pageData,m as default}; diff --git a/assets/index.md.4f35ffdc.js b/assets/index.md.4f35ffdc.js new file mode 100644 index 00000000..726a766d --- /dev/null +++ b/assets/index.md.4f35ffdc.js @@ -0,0 +1 @@ +import{_ as e,c as t,o}from"./app.829490d2.js";const u='{"title":"Home","description":"","frontmatter":{"home":true,"title":"Home","heroText":"Profectus","tagline":"A game engine that grows with you","actionText":"Get Started","actionLink":"/guide/setup","features":[{"title":"Easy to Use","details":"Everything is written to be as intuitive to use as possible"},{"title":"Helpful","details":"Seamlessly deploy your project, get type hints in your IDE, and more"},{"title":"Incremental","details":"Designed to actively encourage you to become better at programming"}]},"headers":[],"relativePath":"index.md"}',a={};function i(r,s,n,c,l,d){return o(),t("div")}var m=e(a,[["render",i]]);export{u as __pageData,m as default}; diff --git a/assets/index.md.4f35ffdc.lean.js b/assets/index.md.4f35ffdc.lean.js new file mode 100644 index 00000000..726a766d --- /dev/null +++ b/assets/index.md.4f35ffdc.lean.js @@ -0,0 +1 @@ +import{_ as e,c as t,o}from"./app.829490d2.js";const u='{"title":"Home","description":"","frontmatter":{"home":true,"title":"Home","heroText":"Profectus","tagline":"A game engine that grows with you","actionText":"Get Started","actionLink":"/guide/setup","features":[{"title":"Easy to Use","details":"Everything is written to be as intuitive to use as possible"},{"title":"Helpful","details":"Seamlessly deploy your project, get type hints in your IDE, and more"},{"title":"Incremental","details":"Designed to actively encourage you to become better at programming"}]},"headers":[],"relativePath":"index.md"}',a={};function i(r,s,n,c,l,d){return o(),t("div")}var m=e(a,[["render",i]]);export{u as __pageData,m as default}; diff --git a/guide/changelog.html b/guide/changelog.html index 810adb82..a7d6b91c 100644 --- a/guide/changelog.html +++ b/guide/changelog.html @@ -32,7 +32,7 @@ </ul> </details>

The details and summary tags will create a section that can be collapsed and uncollapsed. While collapsed only the text in the summary tag will appear. By default sections are collapsed, although adding the open attribute to the details element will change that.

Within the details of the version, you can add a description and a list of changes for that version. CSS classes have been defined to automatically mark a change as a feature, fix, breaking change, or balancing tweak. You can of course add additional tags as you have full control over the entire component.

- + diff --git a/guide/coercable.html b/guide/coercable.html index 2e5a799e..159bb181 100644 --- a/guide/coercable.html +++ b/guide/coercable.html @@ -31,7 +31,7 @@ )), }

Components

This one might be the most obvious, but you can also just give it a Vue component to display outright. Keep in mind it will not be passed any props, so it should not depend on any. You can read more about creating Vue components on Components Basics.

- + diff --git a/guide/creating-features.html b/guide/creating-features.html index 1c551a97..fb4a7537 100644 --- a/guide/creating-features.html +++ b/guide/creating-features.html @@ -22,7 +22,7 @@

Creating Features

# TODO

Because typescript does not emit JS, if a value is supposed to be a function it is impossible to determine if a given function is the intended value or a function that returns the actual value. For this reason it is not recommended for any feature types to include properties that are Computable<Function>s, and all functions will be wrapped in computed. The notable exception to this is JSX, which uses a utility function to mark that a function should not be wrapped.

- + diff --git a/guide/features.html b/guide/features.html index 9f1bceec..3137f854 100644 --- a/guide/features.html +++ b/guide/features.html @@ -32,7 +32,7 @@

The result will be a lazy proxy of the feature being created. The feature can then be used throughout the rest of the layer. The main thing to keep in mind when creating features is that they should typically be included in the layer object that gets returned. If a feature has any persistent refs they must be included or else they will not have their values saved and loaded correctly.

While the structure of layers is intentionally left up to the creator, it is recommended to avoid storing them in arrays. If you ever remove an upgrade from an array, or add an upgrade in between others, then it will interfere with the save data of existing users. You can manually fix these issues in fixOldSave, but it's recommended to avoid the error entirely.

Since usually you want to access a specific feature, storing them in an object is much more reliable and makes the code easier to read. For things like checking number of upgrades bought, for example, you can still use Object.values to get an array of the objects instead.

Example

const upgrades = { addGainUpgrade, gainMultUpgrade, upgMultUpgrade };
 const numUpgrades = computed(() => Object.values(upgrades).length);
 

Tree Shaking

Since Profectus takes advantage of tree shaking, and type of feature that is not used will not be included in the output of the project. That means users have less code to download, a slight performance boost, and you don't need to worry about feature type-specific settings appearing (such as whether to show maxed challenges).

It should be noted that a couple features depend on each other, such as Buyables depending on Clickables. That means you may see features included in the output despite not directly using them. Some features, such as Links and Tooltips, are used by the engine itself and will always be included in the output.

- + diff --git a/guide/index.html b/guide/index.html index 46987199..92d8b1e7 100644 --- a/guide/index.html +++ b/guide/index.html @@ -22,7 +22,7 @@

Introduction

Profectus is a web-based game engine. You can write your content using many built in features, write your own features, and build up complex gameplay quickly and easily.

The purpose of creating profectus was to create an easy to use engine that does not create a ceiling for a programmer's personal growth. This engine will grow in complexity with you, empowering you to create increasingly complex designs and mechanics.

Design Philosophies

While absolute purity is impossible, design decisions have been and will continue to be made using these principles in mind.

  • An engine should be intuitive, and code readable without context
  • An engine should not constrain a creator
  • An engine should be consistent
  • An engine should be extensible, and those extensions sharable
  • An engine should be efficient
  • An engine should report issues early and thoroughly
  • Passing by reference is one honking great idea -- let's do more of that!
- + diff --git a/guide/layers.html b/guide/layers.html index 142374f8..d097767e 100644 --- a/guide/layers.html +++ b/guide/layers.html @@ -22,7 +22,7 @@

Layers

Profectus content is organized into units called "Layers". When display content to the user, it will be done so by having some number of layers appearing as sections on the screen. They are stored in /src/data/layers.

Each layer is ultimately a collection of different features, and a display function. While there are a couple reserved properties for layers, most of its structure is fully up to the creator.

Layers can be dynamically added or removed at any time, which also allows for effectively disabling or enabling content based on arbitrary conditions. Just make sure getInitialLayers can process the player save data object and determine which layers should be currently active.

Lazy Proxies

Layers (and features) are not actually created immediately. Instead, their options are gotten through a function which is then run the first time something inside the layer is accessed. This is a concept called lazy evaluation, which is also used for things like computed, and allows for features to reference each other without worrying about cyclical dependencies.

- + diff --git a/guide/project-entry.html b/guide/project-entry.html index 4524824e..018d06f3 100644 --- a/guide/project-entry.html +++ b/guide/project-entry.html @@ -23,7 +23,7 @@

Project Entry

This is a TypeScript file containing the non-static parts of your project, and acts as the entry point for it.

It is stored at /src/data/projEntry.jsx.

This file has 3 things it must export, but beyond that can export anything the creator wants it to. Typically in addition to the required 3, the initial/"main" layer will be exported. Typically utilites belong in common.tsx, which exists next to projEntry.tsx.

Required Exports

getInitialLayers

  • Type: (player: Partial<PlayerData>) => GenericLayer[]

A function that is given a player save data object currently being loaded, and returns a list of layers that should be active for that player. If a project does not have dynamic layers, this should always return a list of all layers.

hasWon

  • Type: ComputedRef<boolean>

A computed ref whose value is true whenever the game is over.

For example, in a game where the goal is to have a resource reach 10:

export const hasWon = computed(() => Decimal.gte(resource.value, 10));
 

fixOldSave

  • Type: (oldVersion: string | undefined, player: Partial<PlayerData>) => void

This function will be run whenever a save is loaded that has a different version than the one in project info. It will be given the old version number, and the player save data object currently being loaded.

The purpose of this function is to perform any necessary migrations, such as capping a resource that accidentally inflated in a previous version of the project. By default it will do nothing.

- + diff --git a/guide/project-info.html b/guide/project-info.html index 9aa76581..ca4ad141 100644 --- a/guide/project-info.html +++ b/guide/project-info.html @@ -22,7 +22,7 @@

Project Info

This is a JSON file containing information that describes your project and configures parts of how Profectus should represent it.

It is stored at /src/data/projInfo.json.

Basic Config

title

  • Type: string
  • Default: Profectus

The name of the project, which will appear in the info tab and in the header, if enabled. The page title will also be set to this value.

id

  • Type: string
  • Default: ""

This is a unique ID used when saving player data. Changing this will effectively erase all save data for all players.

WARNING

This ID MUST be unique to your project, and should not be left as the default value. Otherwise your project may use the save data from another project and cause issues for both projects.

author

  • Type: string
  • Default: ""

The author of the project, which will appear in the info tab.

discordName

  • Type: string
  • Default: The Paper Pilot Community

The text to display for the discord server to point user's to. This will appear when hovering over the discord icon, inside the info tab, the game over screen, as well as the NaN detected screen.

By default, this is The Paper Pilot Community, which can act as a catch-all for any Profectus projects without their own servers. If you change the discord server with your own, The Paper Pilot Community will still display underneath the custom server when hovering over the discord icon and within the info tab. Those places will also contain a link to the Modding Tree discord server.

  • Type: string
  • Default: https://discord.gg/WzejVAx

The link for the discord server to point user's to. See discordName for more details.

Version Config

versionNumber

  • Type: string
  • Default: 0.0

The current version of the project loaded. If the player data was last saved in a different version of the project, fixOldSave will be run, so you can perform any save migrations necessary. This will also appear in the nav, the info tab, and the game over screen.

versionTitle

  • Type: string
  • Default: Initial Commit

The display name for the current version of the project loaded. This will also appear in the nav, the info tab, and the game over screen, unless set to an empty string.

Display Config

allowGoBack

  • Type: boolean
  • Default: true

Whether or not to allow tabs (besides the first) to display a "back" button to close them (and any other tabs to the right of them).

defaultShowSmall

  • Type: boolean
  • Default: false

Whether or not to allow resources to display small values (<.001). If false they'll just display as 0. Individual resources can also be configured to override this value.

defaultDecimalsShown

  • Type: number
  • Default: 2

Default precision to display numbers at when passed into format. Individual format calls can override this value, and resources can be configured with a custom precision as well.

useHeader

  • Type: boolean
  • Default: true

Whether or not to display the nav as a header at the top of the screen. If disabled, the nav will appear on the left side of the screen laid over the first tab.

  • Type: string | null
  • Default: null

A path to an image file to display as the logo of the app. If null, the title will be shown instead. This will appear in the nav when useHeader is true.

  • Type: string
  • Default: ""

A path to an image file to display as the logo of the app within the info tab. If left blank no logo will be shown.

initialTabs

  • Type: string[]
  • Default: ["main"]

The list of initial tabs to display on new saves. This value must have at least one element. Each element should be the ID of the layer to display in that tab.

Advanced Config

maxTickLength

  • Type: number
  • Default: 3600

The longest duration a single tick can be, in seconds. When calculating things like offline time, a single tick will be forced to be this amount or lower. This will make calculating offline time spread out across many ticks as necessary. The default value is 1 hour.

offlineLimit

  • Type: number
  • Default: 1

The max amount of time that can be stored as offline time, in hours.

- + diff --git a/guide/reactivity.html b/guide/reactivity.html index 40828a6f..fbfc3b6b 100644 --- a/guide/reactivity.html +++ b/guide/reactivity.html @@ -22,7 +22,7 @@

Reactivity

Profectus takes large advantage of Vue's reactivity system. It's recommended to read up on how refs and computed refs work. Ultimately this means that sometimes you'll need to type .value to get the actual value of something, but also you are able to pass things around by reference instead of by value. Indeed, it is recommended to only unwrap the actual value when you actually need it. .value is guaranteed to be correct and up to date only on the exact moment it is accessed.

With a proper IDE, such as Visual Studio Code, you should be able to see whether or not something is a ref or not from type hints. If in doubt, you can always wrap the property in an unref call.

Vue's reactivity is probably the "quirkiest" part of Profectus, and not even the documentation makes all of those quirks clear. It is recommend to read this thread of common misconceptions around Vue reactivity.

Persistent

Some refs are "persistent" refs. Most notably, any time you use the persistent() function it will be a persistent ref. You access these the same way you would any other ref, but keep in mind its value will be saved and loaded automatically.

All persistent refs must be included in a layer object in order for persistence to work. Since many features will create persistent refs internally its recommended to include all of them just to be safe.

Computable

Most properties on features will accept Computable values. Computable values can either be a raw value, a ref to the value, or a function that returns the value. In the lattermost case it will be wrapped in computed, turning it into a ref. The feature type will handle it being a ref or a raw value by using unref when accessing those values. With type hints, your IDE should correctly identify these values as refs or raw values so you can treat them as the types they actually are.

Because functions are automatically wrapped in computed for many properties, it might be expected to happen to custom properties you add to a feature that isn't defined by the feature type. These functions will not be wrapped, and if you want it cached you should wrap it in a computed yourself. This does, however, allow you to include custom methods on a feature without worry.

- + diff --git a/guide/setup.html b/guide/setup.html index 1af4be2e..41e58c5e 100644 --- a/guide/setup.html +++ b/guide/setup.html @@ -22,7 +22,7 @@

Setting Up

Profectus requires a node development environment in order to work on a project. If you are comfortable with the command line, it is recommended to use a local development environment.

Local Development

You will require the following tools for local development:

Create a new project from the Profectus repository via the "Use this template" button. You can then copy the link for the repository to clone it locally.

INFO

Since the repository is a template repository, you can easily create multiple projects from one repository. However, it does make updating an existing project to a newer version of Profectus more difficult.

It's recommended to create a new git branch for development, so you can push your changes without it affecting the live build. This allows you to continue working with smaller commits, and only release new versions when you're actually ready to. The github workflow will automatically rebuild the page whenever you push to the main branch.

The next step is to install Profectus' dependencies. This is as simple as running npm install.

You can now run npm serve to start a local server that will host your project so you can work on it. As you change files the site will automatically reload them.

Deploying

If you're using git, deploying is as easy as pushing your changes to the main branch. In a couple minutes the site will be updated fully automatically. If you'd like to see progress on it, or look at any errors that happened, you can do so from the actions tab on your repository.

Before github knows to actually host the generated site, you'll have to enable github pages in the repo settings. This just means selecting the branch to use - gh-pages. You will only need to perform this step once. This will automatically start another github action to deploy the website.

Once the action completes, your project should be available at https://<YOUR_GITHUB_USERNAME>.github.io/<YOUR_REPO_NAME>/. For example, the TMT Demo project hosted at https://github.com/profectus-engine/TMT-Demo is available at https://profectus-engine.github.io/TMT-Demo/.

Visual Studio Code Setup

If you don't already have a preferred IDE, Profectus is currently developed in Visual Studio Code and is known to work well with that IDE in particular. It's recommend to use Take Over Mode for proper type analysis, and consider turning off .value autocomplete by running the Preferences: Open Settings command and setting volar.autoCompleteRefs to false.

Replit

As an alternative to local development, you may use replit, which will automatically set up your development environment for you and also host your project itself.

However, on the free plan you will be limited by the amount of resources you can use, and the program will need to start up occasionally.

To create a Profectus project on replit, all you have to do is click this button:

You can then start the developing by clicking the "Run" button at the top of the screen. This will also make the project run publicly, so you could consider it as automatically deployed. This does mean you cannot have a separate development environment from your production environment, however.

Glitch

Glitch is a site similar to replit, with much the same pros and cons. To create a projectus project on glitch, select "New Project", "Import from GitHub", and then type in profectus-engine/Profectus. The new project will be created and should be automatically configured and ready to go.

- + diff --git a/guide/themes.html b/guide/themes.html index 20cb9f0c..61314b30 100644 --- a/guide/themes.html +++ b/guide/themes.html @@ -22,7 +22,7 @@

Themes

Themes are objects that change how the project's interface should look. This is done mostly by changing the values of various CSS variables. You can look at the existing themes as a reference for the kind of values these CSS variables expect. They can also set various theme options that change how parts of the screen are laid out, which are described below.

They are stored in /src/data/themes.ts.

Modifying Themes

You can add a theme by adding a property to the Themes enum and then including the theme in the exported object. It's recommended to use the spread operator if you'd like to have a theme look like another, but override specific options / CSS variables.

Themes added in this way will be automatically included in the Themes dropdown in the Options tab. Removing themes from the enum and exported object will similarly hide them from the dropdown.

If you'd like to change which theme is the default, you may modify the initial player settings object in the /src/game/settings.ts file. Keep in mind you'll also want to change it in the hardResetSettings function in the same file.

Theme Options

floatingTabs

  • Type: boolean

Toggles whether to display tab buttons in a tab list, similar to how a browser displays tabs; or to display them as floating buttons, similar to how TMT displays buttons.

mergeAdjacent

  • Type: boolean

If true, elements in a row or column will have their margins removed and border radiuses set to 0 between elements. This will cause the elements to appear as segments in a single object.

Currently, this can only merge in a single dimension. Rows of columns or columns of rows will not merge into a single rectangular object.

- + diff --git a/guide/updating.html b/guide/updating.html index f1009b46..0eaeebac 100644 --- a/guide/updating.html +++ b/guide/updating.html @@ -25,7 +25,7 @@ git fetch --all git merge template/main --allow-unrelated-histories

The first command only has to be performed once. The third command may require you to merge conflicts between code both you and Profectus have changed - however, due to the modularity of Profectus, this should be fairly rare. Unfortunately, due to the unrelated histories the first time you do this every change will be marked as a conflict, and you'll need to accept each one.

Replit

The sidebar has a tab labelled "Version Control", which you can use to merge all changes made to Profectus into your project. Unfortunately, replit does not have a merge tool so this process may irrecoverably erase changes you've made - I'd recommend making a backup first.

Glitch

Unfortunately glitch does not provide any method by which to update a project from a github repository. If you've only changed things in the data folder you may consider creating a new project, importing the current version of Profectus, and then placing your data folder in the new project.

- + diff --git a/guide/utils.html b/guide/utils.html index 8171e9eb..d7e0af31 100644 --- a/guide/utils.html +++ b/guide/utils.html @@ -22,7 +22,7 @@

Utilities

There are often concepts that aren't inherent to a single feature, but rather work with joining different features together. For example, a reset clickable that activates a conversion and resets a tree, which happens to be a common use case but isn't inherent to clickables, conversions, or trees.

These are perfect situations for utilities, and so to encourage creators to learn to identify and take advantage of these situations, a file called src/data/common.tsx has been created to demo some of the more common utility functions a project might use. Adding new utilities to this file is encouraged, as is creating utils in general. It also works as a good stepping stone to creating your own features.

- + diff --git a/hashmap.json b/hashmap.json index a317e2b3..313d20a4 100644 --- a/hashmap.json +++ b/hashmap.json @@ -1 +1 @@ -{"guide_changelog.md":"6e2ff1db","guide_coercable.md":"c51dac2d","guide_creating-features.md":"54db17fd","guide_features.md":"b232f081","guide_index.md":"c6435a7c","guide_layers.md":"53ce88f3","guide_project-entry.md":"f84e9cd9","guide_project-info.md":"d4181672","guide_reactivity.md":"d72f6023","guide_setup.md":"85d3d48c","guide_themes.md":"4332fe54","guide_updating.md":"6435679a","guide_utils.md":"86676041","index.md":"14bdf584"} +{"guide_changelog.md":"6e2ff1db","guide_coercable.md":"c51dac2d","guide_creating-features.md":"54db17fd","guide_features.md":"b232f081","guide_index.md":"c6435a7c","guide_layers.md":"53ce88f3","guide_project-entry.md":"f84e9cd9","guide_project-info.md":"d4181672","guide_reactivity.md":"d72f6023","guide_setup.md":"85d3d48c","guide_themes.md":"4332fe54","guide_updating.md":"6435679a","guide_utils.md":"86676041","index.md":"4f35ffdc"} diff --git a/index.html b/index.html index 5ffc13b3..d354ee9f 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@ - + @@ -21,8 +21,8 @@ -

Profectus

A game engine that grows with you

Easy to Use

Everything is written to be as intuitive to use as possible

Well integrated

Seamlessly deploy your project, get type hints in your IDE, etc.

Incremental

Designed to actively encourage you to become better at programming

Copyright © 2022 thepaperpilot

- +

Profectus

A game engine that grows with you

Easy to Use

Everything is written to be as intuitive to use as possible

Helpful

Seamlessly deploy your project, get type hints in your IDE, and more

Incremental

Designed to actively encourage you to become better at programming

+