4ian / GDevelop

🎮 Open-source, cross-platform 2D/3D/multiplayer game engine designed for everyone.
https://gdevelop.io
Other
9.14k stars 790 forks source link

Create a copy of images when duplicating a sprite #2749

Open tristanbob opened 3 years ago

tristanbob commented 3 years ago

Description

The user duplicates a sprite object. They edit the new object in Piskel.
They soon find out that they were editing the exact same image files used by the original object.
They expected their changes to only impact the new object.

Solution suggested

Alternatives considered

cool-nick-the-ditto commented 3 years ago

i think the prompt is the best one to do

arthuro555 commented 3 years ago

We can also try to make this a preference: always ask, copy image or reuse image.

Bouh commented 3 years ago

A duplicated object shouldn't reuse resources. If we duplicate an object we should duplicate the resources too.

cool-nick-the-ditto commented 3 years ago

The current process is bad because it's not intuitive and it's explains nowhere in the documentation, normal it's because this process sucks. We don't need a preference or worst a prompt... (prompt=evil=easy bad solution)

A duplicated object shouldn't reuse resources, if we duplicate it the resources should be duplicated too. Otherwise, the interest of the duplication is non-existing because all objects are unique, if we keep a link on resources between two objects it will be certainly useful for rare cases but here the majority of the time the current process is a misunderstand point for users. And that why this Issue is open.

I dont like the choice thing eather but i can deal with it eather way it should have not reused it FROM THE START. And i 100% agree with your message. and Acually the op of this issue made it for me Also i wanted this changed bc i wanted to make gender counterparts of a carrecter and redrawing sprites for my level would look sloppy and weird. and also an unintentonal workaround was pached out unintentonally

arthuro555 commented 3 years ago

While I agree that for some users it might be confusing, I do not agree that this is the only good way and should be the default.To me, it always was more intuitive and clear that the same resources are used, the same way the same animations/behavior/all object properties are the same, and that if i modify that image it is modified for all objects using that image. I also believe that duplicating images automatically like this by default can be annoying, especially if you are for example duplicating a player object with many frames and animations for the shadow clone extension, having everything duplicates, making it harder to change the sprite as it either needs 2 edits per frame or to remove the copies and add back manually all files (or to create a script to automate that but we can't really expect that from all GDevelop users), and having multiple duplicate images comes also with unnecessarily higher game loading times and file size.

Bouh commented 3 years ago

You raise an important part of the duplication, it must be a smart duplication when it's needed.

If the images on the duplicated object are not affected/edited then it is good to keep the link on the resource 👍

If the image comes to be edited by Piskel, then there you have to duplicate the image, add the resource name in the animation list and then draw on it. Or the other way, we open Piskel with the texture, we modify it, then we create a new file with this texture and we integrate it as a new resource in the object.

arthuro555 commented 3 years ago

If the image comes to be edited by Piskel, then there you have to duplicate the image, add the resource name in the animation list and then draw on it.

Well that sounds even more confusing than not copying to be frank. Users would wonder "why is this image duplicating but not that one?". And this sounds worse, as GDevelop may duplicate more often than necessary resources, making a mess in the folder with different version of the image and all objects using different ones where they could use the same. I can't think of a way to make GDevelop "smart" about this, as GDevelop cannot know when editing the file what the goal of the user is, and it will always do something wrong for the user.

If you are not talking about copying all resources when duplicating an object, then I would simply add a "save as" button, to use a new resource pointing to the newly created modified file i stead of trying to get GDevelop to automatically guess when to duplicate.

Bouh commented 3 years ago

Well that sounds even more confusing than not copying to be frank. Users would wonder "why is this image duplicating but not that one?". And this sounds worse

No it's better. In this situation the current system is kept, we keep the link on resources by default. And when an edit is done on a resource used in multiple objects the resource is duplicated and the new file is used for the object we started to edit.

Or if needed on the resources e.g a sprite in an animation a choice is added in context menu for "make the sprite unique".

As I said on Discord: About the current system, we stayed too long on a bad practice that we have integrated how to bypass this wrong behavior from duplication overtime... Each people have a way to duplicate objects and reuse or not the textures. People starting in GD don't understand that weird process, why images are all linked to images from the original object, and I agree with people, it's just wtf.

We learned (experimented users) to live with a broken system (yes it is) but it's not a reason for keeping it. Duplicate means is a reproduction in double of something, there is no need to link to anything else, a copy is unique by nature. Based on an existing element yes, but never linked, and I told again, it's a new unique object copied from another one.

You take a book you copy it, you have two similar books, you draw a cat on the cover of the first book, the cat isn't replicated on the second one. It's the same for objects, the object is the book, the cover is the texture.

I'm not against an option that adds both possibilities, I'm just trying to convince that the existing functionality sucks and causes misunderstood, so I don't understand how we can keep this solution for long term. If I can convince people the option become useless.

arthuro555 commented 3 years ago

Well, that didn't answer my concerns, which were that while we sometimes indeed wish to have the resources copied, we also sometimes need to not do so. Saying that one is better is in my opinion simply not true. Having GDevelop automagically chose when to duplicate files is not a good idea because GDevelop cannot predict what the user intends to do, and therefore it WILL do something the user doesn't want if we let GDevelop chose.

We learned (experimented users) to live with a broken system (yes it is) but it's not a reason for keeping it.

As I said on discord, I think that this is on the contrary the biased statement, as you only experienced frustration with that system, but having tons of unnecessarily duplicated files would frustrate you as well when using it for a longer time.

You take a book you copy it, you have two similar books, you draw a cat on the cover of the first book, the cat isn't replicated on the second one. It's the same for objects, the object is the book, the cover is the texture.

That is not an accurate representation though. A resource is simply put a path to a file, so a more accurate way would be to see the book cover as an URL to an image, as the image is stored on a common place (in a file on the filesystem) and not inside the object. If you modify the image behind the "URL", then obviously all books that have that URL will now display the modified image when accessing the link. If you want to change it only for your book, you have to make a new URL with the changed image, and change the URL written on your book.


Again, I think that a better solution than making GDevelop select one option depending on previous action would simply be a "Save as new resource" button in piskel. This would provide a way for users to say "hey I want to keep that changed scoped to that object", while still not preventing objects to share resources/to be edited on objects that share them intentionally if the user wants to.

cool-nick-the-ditto commented 3 years ago

I think the “save as new resorce” button seems good becuse it lets people duplicate animatoin and its easy to understand what the button means they may still not understand why to do it on their first duplicatoin but they will find out and that would also do more things as well

Bouh commented 3 years ago

Again, I think that a better solution than making GDevelop select one option depending on previous action would simply be a "Save as new resource" button in piskel. This would provide a way for users to say "hey I want to keep that changed scoped to that object", while still not preventing objects to share resources/to be edited on objects that share them intentionally if the user wants to.

We have suggested different things, and we join on that solution, what you said, is what I've said earlier. https://github.com/4ian/GDevelop/issues/2749#issuecomment-863351718

tristanbob commented 3 years ago

I just ran into a highly related problem:

When you add the same object from the asset store multiple times, they all reference the same file. When users edit one of those images, they don't realize they are changing all of them.

4ian commented 3 years ago

Similar problem indeed (though in this case, it was considered as a feature: if you had multiple times the same object, it's not duplicating the resources). We might have to go with a solution of giving the choice to the user to duplicate an object and its resources (though only applicable when you have a filesystem, i.e: on desktop, not on the web-app).

LuniMoon commented 1 year ago

Adding the Topic from the forum that reports this issue (for use case reference): https://forum.gdevelop.io/t/global-object-instances-not-independent-in-scenes/28366/9