- Reporting bugs
- Requesting features
- Contributing code
- Setting up a development installation
- Setting up a development environment
- Keeping your fork up to date
- Last Epoch Planner development tutorials
- Using the inbuilt profiler
- Check that the bug hasn't been reported in an existing issue. View similar issues to the left of the submit button.
- Make sure you are running the latest version of the program. Click "Check for Update" in the bottom left corner.
- If you've found an issue with offence or defence calculations, make sure you check the breakdown for that calculation in the Calcs tab to see how it is being performed, as this may help you find the cause.
- Select the "Bug Report" issue template and fill out all fields.
- Please provide detailed instructions on how to reproduce the bug, if possible.
- Provide a build share code for a build that is affected by the bug, if possible. In the "Import/Export Build" tab, click "Generate", then "Share" and add the link to your post.
Build share codes allow us to reproduce bugs much more quickly.
Feature requests are always welcome. Note that not all requests will receive an immediate response.
- Check that the feature hasn't already been requested. Look at all issues with titles that might be related to the feature.
- Make sure you are running the latest version of the program, as the feature may already have been added. Click "Check for Update" in the bottom left corner.
- Select the "Feature Request" issue template and fill out all fields.
- Be specific! The more details, the better.
- Small requests are fine, even if it's just adding support for a minor modifier on a rarely-used unique.
- Familiarise yourself with the code base here(Outdated) to get you started.
- Pull requests must be created against the
devbranch, as all changes to the code are staged there before merging tomaster. - Make sure that the changes have been thoroughly tested!
- There are many files in the
./src/Datadirectory that are automatically generated. This is indicated by the header-- This file is automatically generated, do not edit!. To change these, instead change the scripts in the./src/Exportdirectory and rerun the exporter. For your PR, please include all relevant changes to both the scripts and data files.
Note: This tutorial assumes that you are already familiar with Git.
The easiest way to make and test changes is by setting up a development installation, in which the program runs directly from a local copy of the repository:
-
Clone the repository using this command:
git clone -b dev https://github.com/Musholic/LastEpochPlanner.git -
Go to the actual folder on your computer where you cloned Last Epoch Planner. (e.g. C:/XX/GitHub/LastEpochPlanner/runtime/)
cd LastEpochPlanner -
Start Last Epoch Planner from the repository by running
./runtime/Path{space}of{space}Building.exe.
You can now use the shortcut to run the program from the repository. Running the program in this manner automatically enables "Dev Mode", which has some handy debugging feature:
F5restarts the program in-place (this is what usually happens when an update is applied).Ctrl+~toggles the console (Note that this does not work with all keyboard layouts. US layout is a safe bet though).ConPrintf()can be used to output to the console. Search for "===" in the project files if you want to get rid of the default debugging strings.- Holding
Altadds additional debugging information to tooltips:- Items and passives show all internal modifiers that they are granting.
- Stats that aren't parsed correctly will show any unrecognised parts of the stat description.
- Passives also show node ID and node power values.
- Conditional options in the Configuration tab show the list of dependent modifiers.
- While in the Tree tab, holding
Altalso highlights nodes that have unrecognised modifiers. - Holding
Ctrlwhile launching the program will rebuild the mod cache.- If this does not work, you can start the program with
REGENERATE_MOD_CACHE="1"as env variable, e.g.$env:REGENERATE_MOD_CACHE="1"; & ".\runtime\Last Epoch Planner.exe"
- If this does not work, you can start the program with
Note that automatic updates are disabled in Dev Mode.
Sometimes you may need to force Dev mode OFF when running from the dev branch to debug a specific part of Last Epoch Planner (e.g. the update system).
To do so comment out Line 54 to line 58 of the Launch.lua file:
--if localManXML and not self.versionBranch and not self.versionPlatform then
-- -- Looks like a remote manifest, so we're probably running from a repository
-- -- Enable dev mode to disable updates and set user path to be the script path
-- self.devMode = true
--end
and create a valid manifest.xml file in the ./src directory. Then run the ./runtime/Path{space}of{space}Building.exe as usual. You should get the typical update popup in the bottom left corner.
The manifest.xml file deserves its own in depth document, but usually copying from release and editing accordingly works well enough.
Note: This tutorial assumes that you are already familiar with Git and basic command line tools.
Note: If you've configured a remote already, you can skip ahead to step 3.
-
Add a new remote repository and name it
upstream.git remote add upstream https://github.com/Musholic/LastEpochPlanner.git -
Verify that adding the remote worked.
git remote -v -
Fetch all branches and their commits from upstream.
git fetch upstream -
Check out your local
devbranch if you haven't already.git checkout dev -
Merge all changes from
upstream/devinto your localdevbranch.git rebase upstream/dev -
Push your updated branch to GitHub.
git push -f origin dev
Note: This tutorial assumes that you are already familiar with the development tool of your choice.
If you want to use a text editor, Visual Studio Code (proprietary) is recommended. If you want to use an IDE instead, PyCharm Community or IntelliJ Idea Community (open source) are recommended. They are all free and support EmmyLua, a Lua plugin that comes with a language server, debugger and many pleasant features. It is recommended to use it over the built-in Lua plugins.
Please note that EmmyLua is not available for other editors based on Visual Studio Code, such as VSCodium or Eclipse Theia but can be built from source if needed.
Note that you will need to have Java installed to use emmyLua, and have either the JAVA_HOME environment variable correctly set up or have the path to java added to the settings.json file. Example:
"emmylua.java.home": "C:/Program Files (x86)/Java/jre1.8.0_201/"
To do this in VSCode find the Java installation folder on your computer as displayed above.
- Navigate to extensions inside VSCode
- Click the cog icon next to EmmyLua -> Extension Settings
- Find "Java: Home" -> Edit settings
- Place the directory address between the quotes
- File -> Save
- Create a new "Debug Configuration" of type "EmmyLua New Debug"
- Open the Visual Studio Code extensions folder. On Windows, this defaults to
%USERPROFILE%/.vscode/extensions. - Find the sub-folder that contains
emmy_core.dll. You should find both x86 and x64; pick x86. For example,C:/Users/someuser/.vscode/extensions/tangzx.emmylua-0.3.28/debugger/emmy/windows/x86. - Paste the following code snippet directly below
function launch:OnInit()in./src/Launch.lua:
-- This is the path to emmy_core.dll. The ?.dll at the end is intentional.
package.cpath = package.cpath .. ";C:/Users/someuser/.vscode/extensions/tangzx.emmylua-0.3.28/debugger/emmy/windows/x86/?.dll"
local dbg = require("emmy_core")
-- This port must match the Visual Studio Code configuration. Default is 9966.
dbg.tcpListen("localhost", 9966)
-- Uncomment the next line if you want Last Epoch Planner to block until the debugger is attached
--dbg.waitIDE()- Start Last Epoch Planner Community
- Attach the debugger
Depending on the amount of system ram you have available and the amount that gets assigned to the jvm running the emmylua language server you might run into issues when trying to debug Last Epoch Planner.
Files in /Data /Export and /TreeData can be massive and cause the emmyLua language server to use a significant amount of memory. Sometimes causing the language server to crash. To avoid this and speed up initialization consider adding an emmy.config.json file to the .vscode folder in the root of the Last Epoch Planner repository with the following content:
{
"source": [
{
"dir": "../",
"exclude": [
"src/Export/**.lua",
"src/Data/**.lua",
"src/TreeData/**.lua"
]
}
]
}
- Create a new "Debug Configuration" of type "Emmy Debugger(NEW)".
- Select "x86" version.
- Select if you want the program to block (checkbox) until you attached the debugger (useful if you have to debug the startup process).
- Copy the generated code snippet directly below
function launch:OnInit()in./src/Launch.lua. - Start Last Epoch Planner Community
- Attach the debugger
If you're on windows, consider downloading git for windows and installing git bash. Git bash comes with a variety of typical linux tools such as grep that can make navigating the code base much easier.
If you're using linux you can run the ./runtime/Path{space}of{space}Building.exe executable with wine. You will need to provide a valid wine path to the emmy lua debugger directory.
LEP uses the Busted framework to run its tests. Tests are stored under spec/System and run automatically when a PR is modified.
More tests can be added to this folder to test specific functionality, or new test builds can be added to ensure nothing changed that wasn't intended.
- Install LuaRocks
- Run
luarocks install busted - Run
busted --lua=luajitfrom the command line. You may need to addluajitto your PATH
Docker alternative:
- Install Docker
- Run
docker-compose upfrom the command line
Sometimes a change will be made that intends to change the stats garnered by LEP, which will break our tests.
- Add the new build XML (if applicable) to the
TestBuildsfolder - Run
busted --lua=luajit -r generateto generate a LUA file that contains the current stats of that build - Run
busted --lua=luajitand the tests should pass
Docker alternative:
- Add the new build XML (if applicable) to the
TestBuildsfolder - Run
docker-compose up -dto generate a LUA file that contains the current stats of that build and run the tests
The profiler is found at https://github.com/charlesmallah/lua-profiler and is written entirely in lua under a MIT license.
Pressing pause will start and stop the profiler depending upon if profiling is active. This isn't very precise and has very wide scope so if you want to profile a certain section of code you can also call profiler.start() and profiler.stop() at the start and end of code block you want to profile. Then calling profile.report(fileName) will generate a file in the src folder with the profiling data. This file is called the name given to function or if none are given it is called "profiler.log".
This file contains:
- Total time spent executing
- A table containing information about the profiling
- File, function and line are the file that a given function was executed in and the line of the function definition
- Time and % are the time spent executing code within a function and its percentage relative to the total time spent
- # Is the number of times the function was called
- ~ is displayed if function execution time is less than 0.0001
Here is an example table that could be generated
> Total time: 0.510000 s
-------------------------------------------------------------------------------------------------------------------------------------
| FILE : FUNCTION : LINE : TIME : % : # |
-------------------------------------------------------------------------------------------------------------------------------------
| ...ers\*****\Documents\GitHub\: Anon : 104 : 0.4770 : 93.5 : 2 |
| Modules/Main : Anon : 263 : 0.4770 : 93.5 : 2 |
| Modules/Build : CallMode : 906 : 0.4730 : 92.7 : 2 |
| Classes/TreeTab : Draw : 178 : 0.4360 : 85.5 : 2 |
| Classes/PassiveTreeView : Draw : 97 : 0.4240 : 83.1 : 2 |
| Classes/Control : IsMouseInBounds : 91 : 0.4150 : 81.4 : 5 |
| Classes/Control : GetProperty : 83 : 0.4080 : 80.0 : 26 |
| Classes/PassiveTreeView : renderConnector : 378 : 0.2400 : 47.1 : 5256 |
| Classes/PassiveTreeView : DrawAsset : 751 : 0.0720 : 14.1 : 9532 |
| Classes/PassiveTreeView : treeToScreen : 178 : 0.0550 : 10.8 : 27020 |
| Classes/ControlHost : DrawControls : 85 : 0.0260 : 5.1 : 12 |
| Classes/Control : GetSize : 79 : 0.0230 : 4.5 : 1624 |
| Classes/PassiveTreeView : setConnectorColor : 363 : 0.0210 : 4.1 : 5884 |
| Classes/PassiveTreeView : renderGroup : 333 : 0.0160 : 3.1 : 1222 |
| Classes/Control : IsShown : 83 : 0.0120 : 2.4 : 201 |
| Classes/PassiveTreeView : getState : 366 : 0.0100 : 2.0 : 5256 |
| Classes/ControlHost : ProcessControlsInput : 32 : 0.0100 : 2.0 : 6 |
| Classes/ControlHost : GetMouseOverControl : 24 : 0.0090 : 1.8 : 22 |
| Classes/Control : GetProperty : 34 : 0.0070 : 1.4 : 3794 |
| Classes/EditControl : IsMouseOver : 114 : 0.0060 : 1.2 : 8 |
| Classes/DropDownControl : IsMouseOver : 160 : 0.0050 : 1.0 : 18 |
| Classes/CheckBoxControl : IsMouseOver : 14 : 0.0030 : 0.6 : 6 |
| Classes/ScrollBarControl : IsMouseOver : 70 : 0.0030 : 0.6 : 27 |
| Modules/Build : GetProperty : 141 : 0.0020 : 0.4 : 99 |
| Classes/DropDownControl : CheckDroppedWidth : 467 : 0.0020 : 0.4 : 10 |
| Modules/Common : __index : 77 : 0.0010 : 0.2 : 306 |
| Modules/Build : GetProperty : 596 : 0.0010 : 0.2 : 18 |
| Classes/TextListControl : IsMouseOver : 18 : 0.0010 : 0.2 : 1 |
-------------------------------------------------------------------------------------------------------------------------------------
| Modules/Main : GetProperty : 111 : ~ : ~ : 16 |
| Classes/TextListControl : GetProperty : 10 : ~ : ~ : 10 |
| Classes/PassiveSpec : CountAllocNodes : 468 : ~ : ~ : 99 |
| Modules/Build : GetProperty : 133 : ~ : ~ : 33 |
| Modules/Build : GetProperty : 532 : ~ : ~ : 26 |
| Modules/Build : GetProperty : 499 : ~ : ~ : 2 |
| Classes/SearchHost : IsSearchActive : 68 : ~ : ~ : 32 |
| Classes/DropDownControl : GetDropCount : 92 : ~ : ~ : 16 |
| Modules/Main : DrawArrow : 921 : ~ : ~ : 12 |
| Modules/Build : GetProperty : 483 : ~ : ~ : 2 |
| Modules/Main : GetProperty : 154 : ~ : ~ : 3 |
| Modules/Main : Anon : 405 : ~ : ~ : 1 |
| Classes/TradeQuery : onFrameFunc : 42 : ~ : ~ : 2 |
| Classes/TradeQueryRequests : ProcessQueue : 21 : ~ : ~ : 2 |
| Classes/LabelControl : GetProperty : 9 : ~ : ~ : 37 |
| Modules/Main : GetProperty : 143 : ~ : ~ : 4 |
| Modules/Build : GetProperty : 503 : ~ : ~ : 2 |
| Modules/Main : GetProperty : 139 : ~ : ~ : 4 |
| Modules/Build : GetProperty : 544 : ~ : ~ : 26 |
| Modules/Build : GetProperty : 491 : ~ : ~ : 2 |
| ...ers\*****\Documents\GitHub\: Anon : 166 : ~ : ~ : 1 |
| Modules/Build : IsEnabled : 120 : ~ : ~ : 2 |
| Classes/EditControl : GetProperty : 62 : ~ : ~ : 84 |
| Modules/Build : GetProperty : 487 : ~ : ~ : 2 |
| Modules/Build : GetProperty : 495 : ~ : ~ : 2 |
| Modules/Build : GetProperty : 479 : ~ : ~ : 2 |
| Modules/Build : IsEnabled : 126 : ~ : ~ : 2 |
| Classes/ButtonControl : IsMouseOver : 30 : ~ : ~ : 64 |
| Classes/Control : SetAnchor : 42 : ~ : ~ : 2 |
| Classes/PassiveTreeView : screenToTree : 182 : ~ : ~ : 2 |
| Modules/Build : RefreshSkillSelectControls : 1174 : ~ : ~ : 2 |
| ...ers\*****\Documents\GitHub\: Anon : 134 : ~ : ~ : 1 |
| Modules/Common : wipeTable : 420 : ~ : ~ : 16 |
| Modules/Main : CallMode : 418 : ~ : ~ : 2 |
| Classes/DropDownControl : SelByValue : 122 : ~ : ~ : 2 |
| Classes/ItemsTab : GetSocketAndJewelForNodeID : 1248 : ~ : ~ : 84 |
| Classes/Control : IsEnabled : 34 : ~ : ~ : 54 |
| Classes/Control : IsEnabled : 87 : ~ : ~ : 54 |
| Classes/ScrollBarControl : SetContentDimension : 24 : ~ : ~ : 14 |
| Classes/EditControl : UpdateScrollBars : 201 : ~ : ~ : 4 |
| Classes/UndoHandler : ResetUndo : 19 : ~ : ~ : 2 |
| Classes/DropDownControl : SetList : 458 : ~ : ~ : 6 |
| Classes/EditControl : CreateUndoState : 737 : ~ : ~ : 2 |
| Classes/EditControl : SetText : 90 : ~ : ~ : 2 |
| Modules/Common : copyTable : 351 : ~ : ~ : 2 |
-------------------------------------------------------------------------------------------------------------------------------------