• Hi Guest!

    We are extremely excited to announce the release of our first Beta for VaM2, the next generation of Virt-A-Mate which is currently in development.
    To participate in the Beta, a subscription to the Entertainer or Creator Tier is required. Once subscribed, download instructions can be found here.

    Click here for information and guides regarding the VaM2 beta. Join our Discord server for more announcements and community discussion about VaM2.

Solved This is a question about posting similar plugins

bqbq

Well-known member
Joined
Apr 29, 2024
Messages
131
Solutions
1
Reactions
453
I have improved the existing 'OrificeAligner' plugin.
Since I don't have much knowledge about coding, I asked ChatGPT to assist me with the work.
I specifically requested that it rewrite the code in a different way, excluding the basic logic that is not subject to copyright.

But to be honest, I can't really say that I have a solid understanding of code.
As far as I can tell, most of the structure and wording have been changed, but this is just a beginner’s observation.

Could you please review it and determine whether there are any remaining copyright issues regarding the code?

Additionally, if there are no copyright problems, I would like to know whether it would be permissible to publish a similar plugin.
The original 'OrificeAligner' plugin is licensed under CC BY-NC-SA, so I’m not sure if I would be allowed to release mine under a CC BY license.





C#:
using UnityEngine;
using SimpleJSON;
using System.Collections.Generic;
using System.Linq;

namespace AutoAlign
{
    public class AutoAlignController : MVRScript
    {
        private Atom targetAtom;
        private FreeControllerV3 thisControl;

        private JSONStorableStringChooser atomChooser;
        private JSONStorableStringChooser bodyPartChooser;
        private JSONStorableStringChooser alignModeChooser;

        private JSONStorableBool alignPositionJSON;
        private JSONStorableBool alignRotationJSON;

        private JSONStorableFloat posOffsetXJSON;
        private JSONStorableFloat posOffsetYJSON;
        private JSONStorableFloat posOffsetZJSON;

        private JSONStorableFloat rotOffsetXJSON;
        private JSONStorableFloat rotOffsetYJSON;
        private JSONStorableFloat rotOffsetZJSON;

        private JSONStorableBool oscillatePosXJSON;
        private JSONStorableBool oscillatePosYJSON;
        private JSONStorableBool oscillatePosZJSON;
        private JSONStorableBool oscillateRotXJSON;
        private JSONStorableBool oscillateRotYJSON;
        private JSONStorableBool oscillateRotZJSON;

        private JSONStorableFloat oscillationSpeedJSON;
        private JSONStorableFloat oscillationAmplitudeJSON;

        private Rigidbody targetRigidbody;

        private float oscillationTime;

        private readonly List<string> bodyParts = new List<string> { "Mouth", "Vagina", "Anus" };
        private readonly List<string> alignModes = new List<string> { "Sync Rotation", "Look At" };

        public override void Init()
        {
            if (containingAtom == null)
            {
                SuperController.LogError("AutoAlignController: Must be attached to an atom.");
                return;
            }

            thisControl = containingAtom.freeControllers.FirstOrDefault(fc => fc.name == "control");
            if (thisControl == null)
            {
                SuperController.LogError("AutoAlignController: No control found.");
                return;
            }

            atomChooser = new JSONStorableStringChooser("Target Atom", SuperController.singleton.GetAtomUIDsWithRigidbodies(), "", "Target Atom", SyncTargetAtom);
            RegisterStringChooser(atomChooser);
            CreateFilterablePopup(atomChooser, false);

            bodyPartChooser = new JSONStorableStringChooser("Body Part", bodyParts, "Mouth", "Body Part", SyncBodyPart);
            RegisterStringChooser(bodyPartChooser);
            CreateFilterablePopup(bodyPartChooser, false);

            alignModeChooser = new JSONStorableStringChooser("Align Mode", alignModes, "Sync Rotation", "Align Mode");
            RegisterStringChooser(alignModeChooser);
            CreateFilterablePopup(alignModeChooser, false);

            alignPositionJSON = new JSONStorableBool("Align Position", true);
            RegisterBool(alignPositionJSON);
            CreateToggle(alignPositionJSON);

            alignRotationJSON = new JSONStorableBool("Align Rotation", true);
            RegisterBool(alignRotationJSON);
            CreateToggle(alignRotationJSON);

            oscillatePosXJSON = CreateToggleWithLabel("Oscillate Position X", false);
            oscillatePosYJSON = CreateToggleWithLabel("Oscillate Position Y", false);
            oscillatePosZJSON = CreateToggleWithLabel("Oscillate Position Z", false);
            oscillateRotXJSON = CreateToggleWithLabel("Oscillate Rotation X", false);
            oscillateRotYJSON = CreateToggleWithLabel("Oscillate Rotation Y", false);
            oscillateRotZJSON = CreateToggleWithLabel("Oscillate Rotation Z", false);

            oscillationSpeedJSON = new JSONStorableFloat("Oscillation Speed", 1f, 0.1f, 25f);
            RegisterFloat(oscillationSpeedJSON);
            CreateSlider(oscillationSpeedJSON);

            oscillationAmplitudeJSON = new JSONStorableFloat("Oscillation Amplitude", 0.1f, 0.01f, 1f);
            RegisterFloat(oscillationAmplitudeJSON);
            CreateSlider(oscillationAmplitudeJSON);

            posOffsetXJSON = CreateOffsetSlider("Position Offset X", -1f, 1f);
            posOffsetYJSON = CreateOffsetSlider("Position Offset Y", -1f, 1f);
            posOffsetZJSON = CreateOffsetSlider("Position Offset Z", -1f, 1f);

            rotOffsetXJSON = CreateOffsetSlider("Rotation Offset X", -180f, 180f);
            rotOffsetYJSON = CreateOffsetSlider("Rotation Offset Y", -180f, 180f);
            rotOffsetZJSON = CreateOffsetSlider("Rotation Offset Z", -180f, 180f);
        }

        private JSONStorableFloat CreateOffsetSlider(string name, float min, float max)
        {
            var slider = new JSONStorableFloat(name, 0f, min, max);
            RegisterFloat(slider);
            CreateSlider(slider);
            return slider;
        }

        private JSONStorableBool CreateToggleWithLabel(string label, bool defaultValue)
        {
            var toggle = new JSONStorableBool(label, defaultValue);
            RegisterBool(toggle);
            CreateToggle(toggle);
            return toggle;
        }

        private void SyncTargetAtom(string uid)
        {
            targetAtom = SuperController.singleton.GetAtomByUid(uid);
            SyncBodyPart(bodyPartChooser.val);
        }

        private void SyncBodyPart(string part)
        {
            if (targetAtom == null) return;

            string triggerName = "MouthTrigger";
            if (part == "Mouth")
            {
                triggerName = "MouthTrigger";
            }
            else if (part == "Vagina")
            {
                triggerName = "VaginaTrigger";
            }
            else if (part == "Anus")
            {
                triggerName = "LabiaTrigger";
            }

            targetRigidbody = targetAtom.rigidbodies.FirstOrDefault(rb => rb.name == triggerName);

            if (targetRigidbody == null)
            {
                SuperController.LogError("AutoAlignController: Target Rigidbody not found.");
            }
        }

        void FixedUpdate()
        {
            if (targetRigidbody == null || thisControl == null) return;

            oscillationTime += Time.deltaTime * oscillationSpeedJSON.val;
            float oscValue = Mathf.Sin(oscillationTime) * oscillationAmplitudeJSON.val;

            Vector3 targetPos = targetRigidbody.transform.position;
            Vector3 targetUp = targetRigidbody.transform.up;

            if (alignPositionJSON.val)
            {
                Vector3 posOffset = new Vector3(posOffsetXJSON.val, posOffsetYJSON.val, posOffsetZJSON.val);

                Vector3 oscOffset = Vector3.zero;
                if (oscillatePosXJSON.val) oscOffset.x = oscValue;
                if (oscillatePosYJSON.val) oscOffset.y = oscValue;
                if (oscillatePosZJSON.val) oscOffset.z = oscValue;

                thisControl.transform.position = targetPos + thisControl.transform.rotation * (posOffset + oscOffset);
            }

            if (alignRotationJSON.val)
            {
                Quaternion rotation;

                if (alignModeChooser.val == "Sync Rotation")
                {
                    rotation = targetRigidbody.transform.rotation;
                }
                else
                {
                    rotation = Quaternion.LookRotation(targetUp, Vector3.up);
                }

                Vector3 eulerOffset = new Vector3(rotOffsetXJSON.val, rotOffsetYJSON.val, rotOffsetZJSON.val);

                if (oscillateRotXJSON.val) eulerOffset.x += oscValue * 10f;
                if (oscillateRotYJSON.val) eulerOffset.y += oscValue * 10f;
                if (oscillateRotZJSON.val) eulerOffset.z += oscValue * 10f;

                thisControl.transform.rotation = rotation * Quaternion.Euler(eulerOffset);
            }
        }
    }
}
 
Solution
I'm a former mod of the Hub, so i have a pretty good understanding of Hub policy.

Running a plugin through ChatGPT to rewrite it absolutely, positively, does not remove any copyright issues. What you have produced is a derivative of the original plugin. As the original plugin was published as "CC BY-NC-SA", you MUST publish it with the same license (because of the SA term) , say it's a modification of the original plugin, and credit the author of that plugin (because of the BY term).

If you hadn't mentioned running the thing through chatGPT, and instead lied (or lied by omission by not saying anything at all) and published it as an original creation, you probably would have gotten away with it. But that wouldn't mean you didn't...
I think you should release it under the same license (...SA). There are plugins changing existing plugins, ie. https://hub.virtamate.com/resources/jointcorrectee.25933/
The core of my question is whether I can distribute this plugin under a CC BY license.
I find it difficult to clearly understand the rules regarding this.


If the code is different enough to avoid copyright issues and only the functionality is similar, would it still be necessary to apply the same license?

If that is the case, for example, in the case of 'JointCorrect' that you linked, wouldn’t all plugins that modify morphs based on movement need to have the same license as well?

This area is a bit difficult for me to fully understand.


However, by looking at this note on 'JointCorrect EE':


'License / Permission
CC BY-NC-SA. Despite the Non-Commercial part, you may use JointCorrectEE var as a dependency in your own paid content releases by referencing it. (The same license and permission apply to the original Joint Correct plugin.)'


I was able to understand at least one thing — even if the 'AutoAlign' plugin I created is distributed under CC BY-NC-SA, it can still be used as a dependency in paid content releases, since it does not use 'OrificeAligner' as a dependency.

Is that correct?
 
Upvote 0
Feeding the code to ChatGPT to rebuild is basically reverse engineering. Now if you didn't say that you used chat gpt to rewrite the code structure then you could have just gone ahead and license it to whatever you wanted.

This is not a matter of it being referenced as a dependency. As long as it's a derivative or based of the original code it has to carry the same license as you basically still made a modified version using the base structure even if you rewrote it from the ground up you still worked from the original. The "SA" means share alike so the license needs to be the same.

If you want to have a different license you would have to use the Idea and build your plugin from there. It's like you know what the plugin does and from that you said to chat gpt to create a plugin that does this or that, then that can work, tho, you can still be accused of using the original if it comes out the same.

I think you can still rebuild from the idea and submit it under whatever license you want.🤔
 
Upvote 0
understand that point.
I could have simply published it without mentioning that I had referred to ChatGPT.
I must admit, I was somewhat tempted, but it didn't feel right to me morally. Still, if that’s not acceptable, it’s not a problem — there are other reference plugins available.
I can simply try again by referring to another 'Aligner' plugin that is released under a CC BY license.
It’s just that the thought of starting all over again feels a bit exhausting.
Feeding the code to ChatGPT to rebuild is basically reverse engineering. Now if you didn't say that you used chat gpt to rewrite the code structure then you could have just gone ahead and license it to whatever you wanted.

This is not a matter of it being referenced as a dependency. As long as it's a derivative or based of the original code it has to carry the same license as you basically still made a modified version using the base structure even if you rewrote it from the ground up you still worked from the original. The "SA" means share alike so the license needs to be the same.

If you want to have a different license you would have to use the Idea and build your plugin from there. It's like you know what the plugin does and from that you said to chat gpt to create a plugin that does this or that, then that can work, tho, you can still be accused of using the original if it comes out the same.

I think you can still rebuild from the idea and submit it under whatever license you want.🤔
 
Upvote 0
Feeding the code to ChatGPT to rebuild is basically reverse engineering. Now if you didn't say that you used chat gpt to rewrite the code structure then you could have just gone ahead and license it to whatever you wanted.

This is not a matter of it being referenced as a dependency. As long as it's a derivative or based of the original code it has to carry the same license as you basically still made a modified version using the base structure even if you rewrote it from the ground up you still worked from the original. The "SA" means share alike so the license needs to be the same.

If you want to have a different license you would have to use the Idea and build your plugin from there. It's like you know what the plugin does and from that you said to chat gpt to create a plugin that does this or that, then that can work, tho, you can still be accused of using the original if it comes out the same.

I think you can still rebuild from the idea and submit it under whatever license you want.🤔
Anyway, would it be correct to understand that as long as there’s no issue with referencing the code, it’s fine to publish a plugin with the same functionality?
 
Upvote 0
That I can't fully say as I don't know the hub's policy of cloned plugins. You may have to reach out to the original creator first or not, I honestly don't know. So you can open a support ticket or wait here for help from staff on clarifying that. A support ticket should be faster.
 
Upvote 0
I'm a former mod of the Hub, so i have a pretty good understanding of Hub policy.

Running a plugin through ChatGPT to rewrite it absolutely, positively, does not remove any copyright issues. What you have produced is a derivative of the original plugin. As the original plugin was published as "CC BY-NC-SA", you MUST publish it with the same license (because of the SA term) , say it's a modification of the original plugin, and credit the author of that plugin (because of the BY term).

If you hadn't mentioned running the thing through chatGPT, and instead lied (or lied by omission by not saying anything at all) and published it as an original creation, you probably would have gotten away with it. But that wouldn't mean you didn't break copyright, it would just mean you got away with breaking copyright. If the hub moderators found out what you did, you'd be severely reprimanded and possibly banned, not just for the violation, but for the deception.

If you want to use chatGPT to recreate the functionality of existing plugins and claim it as original work, the only legal way to do it is to describe the function of the plugin, but not give chatGPT the original code to work with. I wouldn't even tell chatGPT the name of the original plugin, or it might go download the thing itself and use its code. The idea for the plugins function is not copyrightable, but the code is.

The use of chatGPT in this way opens up a whole can of worms about what people can get away with, and if/how wrongdoing can be proved, but legally and morally it's clear: if you build off someone else's work, not matter how you did it, it's a modification of that work, not an original work.

By asking the question here, you make it clear you have no bad intent. You just misunderstood the situation. So no worries. But now you know!
 
Last edited:
Upvote 1
Solution
Quite apart from any copyright issues, it occurs to me that if your goal is to provide service to the Vam community, the best course would be to offer your improved version to the original author to publish as an update. That way everybody using the original can update to the improved version. And new users will get the updated version instead of finding and downloading the old one. Having two plugins with pretty much the same function just adds to the bloat that plagues everybody's AddonPackages directory's.
 
Upvote 0
Confirming everything that @DJ has stated above.

Additionally, we do occasionally scan plugin code for evidence of copyright infringement. An AI, at this time, would not be enough to "hide" the evidence, especially if you are unfamiliar with coding yourself.
 
Upvote 0
I'm a former mod of the Hub, so i have a pretty good understanding of Hub policy.

Running a plugin through ChatGPT to rewrite it absolutely, positively, does not remove any copyright issues. What you have produced is a derivative of the original plugin. As the original plugin was published as "CC BY-NC-SA", you MUST publish it with the same license (because of the SA term) , say it's a modification of the original plugin, and credit the author of that plugin (because of the BY term).

If you hadn't mentioned running the thing through chatGPT, and instead lied (or lied by omission by not saying anything at all) and published it as an original creation, you probably would have gotten away with it. But that wouldn't mean you didn't break copyright, it would just mean you got away with breaking copyright. If the hub moderators found out what you did, you'd be severely reprimanded and possibly banned, not just for the violation, but for the deception.

If you want to use chatGPT to recreate the functionality of existing plugins and claim it as original work, the only legal way to do it is to describe the function of the plugin, but not give chatGPT the original code to work with. I wouldn't even tell chatGPT the name of the original plugin, or it might go download the thing itself and use its code. The idea for the plugins function is not copyrightable, but the code is.

The use of chatGPT in this way opens up a whole can of worms about what people can get away with, and if/how wrongdoing can be proved, but legally and morally it's clear: if you build off someone else's work, not matter how you did it, it's a modification of that work, not an original work.

By asking the question here, you make it clear you have no bad intent. You just misunderstood the situation. So no worries. But now you know!
Thank you for the clear answer. It's really difficult to fully understand copyright matters through searching alone. In any case, I’ve deleted the plugin. If I find the time later, I’m thinking of rebuilding it by referencing a similar plugin released under a CC BY license.
 
Upvote 0
Confirming everything that @DJ has stated above.

Additionally, we do occasionally scan plugin code for evidence of copyright infringement. An AI, at this time, would not be enough to "hide" the evidence, especially if you are unfamiliar with coding yourself.
I do my best to follow the Hub's policies.
 
Upvote 0
I'm not too disheartened when I think about the hard work of the people who created the plugin. Anyway, thank you for providing a clear guide. It really helped prevent confusion.
Don't get discouraged. But, as you did this time, when in doubt, ask!
 
Upvote 0
Back
Top Bottom