Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions source/contributing/implementation/debugging/faq.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
==========================
Frequently Asked Questions
==========================

.. note::

This page is not complete. If you feel like you can help, you can do so on `our GitHub repository
<https://github.com/spongepowered/spongedocs>`_. Also see the `related GitHub Issue
<https://github.com/SpongePowered/SpongeDocs/issues/356>`_ for more information on what is required.

Installing Sponge
-----------------


Configuring Sponge
------------------


GIT
---


IntelliJ
--------

- How do I fix my run configurations when a main class is not specified?

When in the ``Edit Configurations...`` window, select a module that has ``.main`` in its name in the ``Use classpath
of module:`` dropdown list. Click ``Apply``.

- Why does my SpongeVanilla workspace not have a ``genIntelliJRuns`` task?

This is by design. See `VanillaGradle doesn't have genIntelliJRuns
<https://forums.spongepowered.org/t/vanillagradle-doesnt-have-genintellijruns/19091/2>`_ in Sponge Forums for
details.

75 changes: 75 additions & 0 deletions source/contributing/implementation/debugging/git.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
===
Git
===

This article explains some useful features of Git which may assist you.

.. note::
See :doc:`../../howtogit` for more information about Git, branches, and using the rebase command. Please be sure
to follow the **Squashing with Rebase** section.

Rebase
======

There are times when the project you are working on takes longer to complete than planned, and your branch falls
behind the target branch and cannot get merged without further testing. To capture the other changes in your branch for
testing, use the ``git rebase`` command.

Before using the command, ensure your local repository has the changes with the ``git pull`` command or the ``git
fetch`` / ``git merge`` commands. Once your local repository is updated with the changes,

1. Ensure you are in the project's branch
#. Run ``git rebase`` *target branch*

For example, consider your project's branch name is ``feature`` and the target branch is ``bleeding``. After updating
your local repository with any changes to the ``bleeding`` branch, checkout branch ``feature`` and run ``git rebase
bleeding``. Your ``feature`` branch will now have the changes included and you can test your own changes with them to
ensure no issues are introduced.

Finding A Commit
================

Knowing a commit can sometimes help in debugging, and there are many ways to identify them. Below are some ways to
find a commit:

1. Git log

At a command prompt, run ``git log`` and Git will begin displaying changes made to the repository.

In an IDE, use the IDE's version control feature to display the log. Check your IDE's documentation to learn the
different ways to do this.

#. MANIFEST.MF file

If you have the Sponge jar file already, you can view the MANIFEST.MF file to obtain the last git-commit in the
file. The file is located in the META-INF directory and contains many key-value pairs. One is the ``Git-Commit`` key
and the value of this key is the last commit of the GitHub repository at the time the Sponge jar file was created.

#. Sponge `Downloads <https://www.spongepowered.org/downloads>`_ page.

Another method for determing the last commit in the file is to locate the build on the Sponge `Downloads`_ page.
Under the build's title, click on the first commit message. A new browser tab or window will open on GitHub with
the commit displayed on the right hand side along with other commit information.

.. tip::
For a summary of changes and a quick find for a commit, use ``git log --oneline -x``, where ``x`` can be any
numeric value representing the number of commits to display.

Checking Out a Branch
=====================

A good practice when preparing to debug is to create a new branch and give it a name related to the issue you are
working on. You will delete it after your changes are merged, but the name will help you remember the purpose of the
branch.

.. note::
It is important to create the new branch from the appropriate target branch. See :doc:`../../versioning` for more
information.

With a name picked out and the appropriate branch to create from checked out, you can now use ``git checkout
--recurse-submodules -B <new_branch>`` to create the new branch. Git creates the new branch and switches your
repository to it. Now, you are ready to make any necessary adjustments to settings in your workspace or IDE.

.. tip::
The ``--recurse-submodules`` parameter ensures SpongeCommon and SpongeAPI are changed to the proper commit as well.

27 changes: 27 additions & 0 deletions source/contributing/implementation/debugging/ide.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
===============================
Debugging Sponge Within the IDE
===============================

See the :ref:`runConfig` section and the following :ref:`usingDebugger` section on the Plugin Debugging page for
debugging information.

IntelliJ
--------

Now that your workspace is ready, you can open IntelliJ.

- At the Welcome screen, click on ``Import Project``.
- If IntelliJ is already open, click on ``File``, followed by ``Open Project``.

Navigate to the implementation's root directory and select ``build.gradle``. Click OK. IntelliJ loads your workspace
and builds the project. You can begin debugging the code.


Eclipse
-------

.. note::

This page is not complete. If you feel like you can help, you can do so on `our GitHub repository
<https://github.com/spongepowered/spongedocs>`_. Also see the `related GitHub Issue
<https://github.com/SpongePowered/SpongeDocs/issues/356>`_ for more information on what is required.
52 changes: 52 additions & 0 deletions source/contributing/implementation/debugging/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
================
Debugging Sponge
================

.. tip::
See :doc:`/plugin/debugging` for debugging a plugin and :ref:`usingDebugger` tips.

These sections provide information for debugging Sponge itself. Whether you need to debug SpongeForge, SpongeVanilla,
SpongeCommon, or SpongeAPI, set up your workspace for a SpongeForge or SpongeVanilla implementation. SpongeCommon and
SpongeAPI are debugged within the implementation setup.

See :doc:`../../../about/structure` for more information.

.. note::
Be sure to read and understand :doc:`/contributing/howtogit` and :doc:`/contributing/versioning` as well as the
entirety of the :doc:`../index` sections before proceeding.

Setup the Workspace
===================

Here are the steps to setup your workspace if you do not have one already:

1. Clone the implementation.
2. Make changes to the local repository (e.g. create new branch if you will make changes).
3. Setup the implementation.
4. Build the implementation.
5. Run the implementation.

With these instructions successfully completed, you are ready to import the project into your IDE.

.. note::
This is an outline of the steps necessary to setup the workspace. See the `SpongeForge
<https://github.com/SpongePowered/SpongeForge>`_ or
`SpongeVanilla <https://github.com/SpongePowered/SpongeVanilla>`_ GitHub pages for complete instructions on
cloning, setup, building, and running the implementation.

Contents
========

.. toctree::
:maxdepth: 2
:titlesonly:

git
ide
testing
issues
mixin
tools
more
faq

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
===============================
Debugging Sponge Within the IDE
===============================
============================
Common Issues When Debugging
============================

.. note::

Expand Down
184 changes: 184 additions & 0 deletions source/contributing/implementation/debugging/mixin.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
===============
Debugging Mixin
===============

.. tip::
The **Mixins** section of :doc:`../../../plugin/practices/best` has a discussion on mixins, coremods, and other
low-level definitions.

`Spongepowered Mixin <https://github.com/SpongePowered/Mixin>`_ is the subsystem that allows SpongeAPI and other
programs to interface with Minecraft. This article is not to provide a comprehensive explanation of Mixin. Please see
`Mixin's wiki <https://github.com/SpongePowered/Mixin/wiki>`_ for its documentation and support options.

.. note::
Mixin has its own repository which you can clone and import into IntelliJ to find error messages and research
problems. Alternatively, you can specify your local clone of the Mixin repository as a Module in the Project
Settings of your Sponge implementation and debug Mixin.

Output
======

By default, a directory named ``.mixin.out`` is created in the ``run`` directory. The directory contains a sub-directory
named ``audit`` with empty reports in text and comma-separated-values formatted files. These files are used if the
``mixin.checks.interfaces`` option is enabled.

However, Mixin supports *Java System Properties* to enable various debugging and auditing features. There are times
when you may need or want to see the results of the process. You can see the mixin output by supplying **one** of the
following VM options:

+-------------------------------+---------------------------------------------------------+
| ``-Dmixin.debug=true`` | Turns on all debugging features |
+-------------------------------+---------------------------------------------------------+
| ``-Dmixin.debug.export=true`` | Turns on only the feature that sends the output to disk |
+-------------------------------+---------------------------------------------------------+

In IntelliJ, open the ``Run/Debug Configurations`` window by clicking on ``Run`` -> ``Edit Configurations...``. Be sure
to add the options to the appropriate application (``Minecraft Client``, ``Minecraft Server``, or both).

A new directory named ``classes`` is created in the ``.mixin.out`` directory when one of these options is used. This
directory contains the new class content from the mixin process in a standard package/class structure.

.. note::
These options are not contingent upon having cloned the Mixin repository, adding Mixin as a module, or using the
Minecraft Development for IntelliJ plugin by DemonWav.

.. tip::
See `Mixin Java System Properties <https://github.com/SpongePowered/Mixin/wiki/Mixin-Java-System-Properties>`_
for more mixin VM options with explanations for each option.

Decompiling
===========

There are a several ways to view the class files from the mixin process.

* IDE

Opening the file in your IDE will decompile it and display the source code

* Fernflower

Having the fernflower jar on your runtime classpath will cause the class files to be decompiled as they are created.

* `JD-Gui <http://jd.benow.ca/>`_ is a standalone graphical utility that displays Java source codes of class files.

Phases And Environments
=======================

Important to understanding Mixin is knowing that game execution is split into two distinct phases: ``pre-init`` and
``default``. The ``pre-init`` phase occurs between starting the game (running a command, script, double-clicking a
shortcut, clicking a "launch" button or whatever method you use to tell your computer to run Minecraft) and launching
the game (all modifications are complete and the game starts up and enters its main loop). The ``default`` phase begins
when the game is in its "ready to be loaded" state and is the same as simply launching Minecraft.

Changes occur to infrastructure classes (loader, transformers, etc.) during the ``pre-init`` phase. Mixin also gathers
information pertaining to all other mixins during the ``pre-init`` phase and applies them during the ``default`` phase.

Phases are handled by separating them into environments, where the ``pre-init`` **phase** is the ``PREINIT``
**environment** and the ``default`` **phase** is the ``DEFAULT`` **environment**.

.. tip::
Environments are among the properties specified in mixin configuration files. Examples of how they are specified
are ``"target": "@env(PREINIT)"`` and ``"target": "@env(DEFAULT)"``

Configurations
==============

The primary resource Mixin requires is the configuration file(s). Each configuration file defines a mixin set - the
mixins to be applied with that configuration. Any mixin not specified by a configuration is not applied even though the
mixin may exist in the code. An application may have one to many sets; however, each set **must** contain mixins for
only **one** environment. Another reason to separate configurations into multiple files is for organizational purposes.

Each mixin set (configuration file) is subdivided into three discrete areas: common, client, and server. The common
mixins are mixed first followed by client **or** server, depending on the detected *side*.

Who Started It?
===============

The Mixin subsystem interacts with all programs through a single instance of the subsystem, regardless of file, author,
or organization. Yet, only one **starts** the subsystem, and it determines which version of Mixin is used. A problem
occurs many times because an older version of Mixin is started. So, the order in which files are launched is important.
Ideally, Sponge should launch first after Forge and before other tweakers and coremods.

A Broken Mixin
==============

The game will crash when a class cannot be loaded, and this condition is known as a broken mixin. A broken mixin
generally means a problem exists with the annotations and/or signature. For example, consider the following log
snippet:

.. code-block:: text

MixinSpongeSmeltingRecipe.java:41: error: No obfuscation mapping for @Overwrite method
default String getId() {
^

This error was corrected by changing the ``@Overwrite`` annotation to ``@Overwrite(remap = false)``. The
remap element set to *false* causes the annotation processor to skip this annotation when attempting to build the
obfuscation table for the mixin.

Analysis of the source code might lead one to think the ``default`` keyword in the method declaration is the problem.
Changing the keyword to ``static`` results in the following log snippet:

.. code-block:: text

MixinSpongeSmeltingRecipe.java:41: error: getId() in MixinSpongeSmeltingRecipe clashes with getId() in
static String getId() {
^
overriding method is static

MixinSpongeSmeltingRecipe.java:40: error: method does not override or implement a method from a supertype
@Override
^

MixinSpongeSmeltingRecipe.java:42: error: non-static variable this cannot be referenced from a static context
return CustomSmeltingRecipeIds.getDefaultId((SmeltingRecipe) this);
^

As you can see, three different errors occurred instead of the one error. The correct fix was adding the ``remap``
element as described above. Keep in mind, though, the point of this example is not to show how to solve this problem,
but to demonstrate what a broken mixin looks like and to point out that most broken mixins are the result of incorrect
annotations or signatures.

.. note::
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't really wanna duplicate the mixin wiki, but maybe some useful stuff like the java arguments to export mixin in production https://github.com/SpongePowered/Mixin/wiki/Mixin-Java-System-Properties

not sure what this page could contain otherwise, maybe some coredevs have any other pointers what they use commonly to debug mixins that isnt documented already

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My idea for this page is to address ST-DDT's comments:

Debugging options such as the post mixin class content output (I forgot the command line option for that)
Tools for decompiling the post mixing code (jd-gui or similar ones)
Common issues you might encounter (Broken mixin, NPEs, PhaseErrors with suggestions how to fix them or a link to their respective documentation)
Help with finding the error in your mixin based on the stacktrace (The only help you get is the line number)

and the link you mentioned.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise, if you use MinecraftDev plugin for IntelliJ, you can debug and step through mixin code without having to deal with outputted class files from the mixin class loader.

I can do a demonstration gif of sorts stepping through sponges changes with both SpongeCommon and SpongeForge intersecting each other.

See the Mixin Wiki for a description on `methods' signatures
<https://github.com/SpongePowered/Mixin/wiki/Introduction-to-Mixins---Understanding-Mixin-Architecture#2-through-the-looking-glass>`_

This section will be expanded in the future to list common causes of broken mixins and the solutions to fix them.
If you feel like you can help, you can do so on `our GitHub repository
<https://github.com/spongepowered/spongedocs>`_.

Minecraft Development for IntelliJ
==================================

A useful tool for working with Mixin is the `Minecraft Development <https://github.com/minecraft-dev/MinecraftDev>`_
plugin for IntelliJ. You can debug and step through mixin code without having to deal with outputted class files from
the mixin class loader.

.. note::
The plugin's `website <https://minecraftdev.org/>`_ provides information about installing and support options. A
link to its GitHub repository is also provided where you can contribute and/or learn more about the project.

Installing
----------

To use the plugin without cloning the source:

1. Open ``File -> Settings -> Plugins`` and select ``Marketplace``.
#. Search for *minecraft* in the search bar and select ``Minecraft Development by DemonWav``.
#. Click the ``Install`` button (do **not** restart IntelliJ *yet*).
#. Go to https://github.com/minecraft-dev/MinecraftDev and download a ZIP file of the repository.
#. Do **one** of the following:

* Open your program of choice for extracting zip files. Navigate to the ``idea-configs`` directory and copy/extract
**the contents** of that directory to the ``.idea`` directory of your Sponge workspace.
* Extract the zip file to a location on your drive. Navigate to the ``idea-configs`` directory and copy **the
contents** of that directory to the ``.idea`` directory of your Sponge workspace.
#. Restart IntelliJ

The plugin will now be active and your project will have useful configurations and copyright settings.

Using
-----

Coming soon!

Loading