• Runtimes
  • Unable to load spine fils using Spine Web Player

Using https://en.esotericsoftware.com/spine-player, I am unable to load the attached file with the following code. Please let me know how to fix it, thanks!

new SpinePlayer(target.current, {
      preserveDrawingBuffer: false,
      skeleton: 'move.skel',
      atlasUrl: 'move.atlas',
    })

Additionally, I would like to know:

  1. How to obtain the animation names of the animation
  2. How to scale the animation

For 2, pixi-spine has something like the following to allow scaling. Thanks!

spine.scale.x = scale;
spine.scale.y = scale;
Related Discussions
...

To address your issue with loading files using the Spine Web Player, it seems there might be a few adjustments needed in your code. Here is a revised version of your code snippet:

new spine.SpinePlayer(target.current, {
    jsonUrl: 'move.json', // Ensure you are using the correct file extension
    atlasUrl: 'move.atlas',
    success: function (player) {
        console.log("Spine animation loaded successfully");
    },
    error: function (player, reason) {
        console.error("Failed to load Spine animation:", reason);
    }
});

Make sure that your move.json and move.atlas files are correctly formatted and accessible from the specified URLs.

1. Obtaining Animation Names

To obtain the animation names, you can access the skeleton instance after the player has successfully loaded. Here is an example:

new spine.SpinePlayer(target.current, {
    jsonUrl: 'move.json',
    atlasUrl: 'move.atlas',
    success: function (player) {
        const animations = player.skeleton.data.animations;
        animations.forEach(animation => {
            console.log(animation.name);
        });
    },
    error: function (player, reason) {
        console.error("Failed to load Spine animation:", reason);
    }
});

2. Scaling the Animation

To scale the animation, you can directly manipulate the scaleX and scaleY properties of the skeleton. Here is an example:

new spine.SpinePlayer(target.current, {
    jsonUrl: 'move.json',
    atlasUrl: 'move.atlas',
    success: function (player) {
        player.skeleton.scaleX = 1.5; // Adjust the scale as needed
        player.skeleton.scaleY = 1.5; // Adjust the scale as needed
    },
    error: function (player, reason) {
        console.error("Failed to load Spine animation:", reason);
    }
});

Ensure that you replace 'move.json' and 'move.atlas' with the correct paths to your files.

Hello and thanks for reaching us 🙂

Since this is a continuation of an issue you opened on github, you should have mentioned that, and the details that brought you to the issue.

I've provided the solution on the github issue and closed it.

Regarding the other questions, spinebot answered correctly 👍

    Continue from EsotericSoftware/spine-runtimes2616 regarding React initialization.
    If I place a log right above new SpinePlayer(), it now renders once, but still failing. I am not seeing any other new SpinePlayer() calls.

    Besides, with strict mode, it will render twice, which would have Too many active WebGL contexts... printed twice, matching what's expected with strict mode.
    I do call dispose() on the initialized SpinePlayer instance tho, so it shouldn't be a problem? Otherwise I would've see 2 canvas then immediately know something is wrong.

    Thanks for catching that it rendered 3 times and I have fixed it by the way!

    Davide
    Hi, thanks for responding yet again!
    So I followed what Spine bot responded, but one issue is that the skel / json file I provided seems to be binary instead of json. I noticed that there's an binaryUrl option, but I am not sure how to use that. At least my file with *.skel is not getting consumed. My bad of not attaching the file, didn't realize it never got uploaded.

    move.zip
    51kB

    First of all, your asset is a 4.0 exported asset, you need a 4.0 spine player to load that asset.
    In that case the API the property to specify in the config are binaryUrl and atlasUrl.

    I tried your skeleton with a 4.0 spine player and works fine.
    Remember that major.minor of your exported assets must match the major.minor of your runtime.

    Regarding the errors, if you are sure you are instantiating the player once, that's clearly something wrong on your side.
    What is that Removing unpermitted intrinsics? Seems caused by a plugin. Can you try to load the page in a window without any broswer plugin?

      Davide
      Hi,
      So I did the following but still having error:

      1. I changed the dependency to "@esotericsoftware/spine-player": "4.0.28",.
      2. Changed the code to the following:
        const hrefOfSkeleton = '/actions/pokemon/regular/194/action/move.skel';
        
        const targetRef = React.useRef<HTMLDivElement>(null);
        const playerRef = React.useRef<SpinePlayer>();
        
        React.useEffect(() => {
          if (!hrefOfSkeleton || !targetRef.current) {
            return;
          }
        
          console.log('SpinePlayer creation', hrefOfSkeleton);
          const playerLocal = new SpinePlayer(targetRef.current, {
            binaryUrl: hrefOfSkeleton,
            atlasUrl: hrefOfSkeleton.replaceAll('.skel', '.atlas'),
          });
        
          playerRef.current = playerLocal;
        
           return () => playerRef.current?.dispose();
        }, [hrefOfSkeleton, targetRef.current]);
        
        return <div ref={targetRef}/>;
      3. Disabled the plugin causing Removing unpermitted intrinsics, this is caused by MetaMask.
      4. Close out every other pages of the same app to resolve context disposal issue. It seems like it's simply because I opened too many pages.

      Then, I tried with both .json and .skel extension, but no luck on my end. This is with strict mode disabled already.

      If your code works fine and happen to be React-usable, may I test with your code?

      Also, v4.0.28 in TypeScript seems to have some typing issue as simply supplying binaryUrl and atlasUrl gives me the following typing error, and if I check the typing, every property of SpinePlayerConfig is marked as required.

      As a side note, pixi-spine works fine with the same set of files, but missing some parts in the animation.

      Somehow I can't edit the previous reply. Please delete it. This is my current progress and questions:

      Davide
      Hi,
      So I did the following but still having error:

      1. I changed the dependency to "@esotericsoftware/spine-player": "4.0.28", as well as "@esotericsoftware/spine-core": "4.0.28",. Without specifying spine-core and previous history of installing 4.2, it will stuck at 4.2 causing read error.
      2. Changed the code to the following:
        const hrefOfSkeleton = '/actions/pokemon/regular/194/action/move.skel';
        
        const targetRef = React.useRef<HTMLDivElement>(null);
        const playerRef = React.useRef<SpinePlayer>();
        
        React.useEffect(() => {
          if (!hrefOfSkeleton || !targetRef.current) {
            return;
          }
        
          console.log('SpinePlayer creation', hrefOfSkeleton);
          const playerLocal = new SpinePlayer(targetRef.current, {
            binaryUrl: hrefOfSkeleton,
            atlasUrl: hrefOfSkeleton.replaceAll('.skel', '.atlas'),
            success: () => console.log('success'),
            error: () => console.log('error'),
            loading: (_, delta) => console.log('loading', delta),
          });
        
          playerRef.current = playerLocal;
        
           return () => playerRef.current?.dispose();
        }, [hrefOfSkeleton, targetRef.current]);
        
        return <div ref={targetRef}/>;
      3. Disabled the plugin causing Removing unpermitted intrinsics, this is caused by MetaMask.
      4. Close out every other pages of the same app to resolve context disposal issue. It seems like it's simply because I opened too many pages of the same app.

      Then, it somehow stuck permanently at the loading stage.

      Also, v4.0.28 in TypeScript seems to have some typing issue as simply supplying binaryUrl and atlasUrl gives me the following typing error, and if I check the typing, every property of SpinePlayerConfig is marked as required.

      Can't edit my previous response again, so I have to post it separately, sorry.

      One other issue is that if I install dependency like "@esotericsoftware/spine-player": "~4.0",, it will install 4.2 spine-core and spine-webgl for me, which seems to be why it's causing the error. I am using yarn for package manager, if it matters.

      I think dependencies should be ~4.0 as well, instead of ^4.0.28, so it stick to major.minor versioning regarding runtime, in spine-player and spine-webgl.


      Sorry again, I wish I could delete all my previous responses but it doesn't seem like I am able to do so.

      The only issue left is the dependency issue - I currently set my package.json to have the following to force the version:

      "resolutions": {
        "@esotericsoftware/spine-core": "~4.0",
        "@esotericsoftware/spine-webgl": "~4.0"
      }

      Once set, I can finally load the animation! Thanks for the help. I still got a few questions though:

      1. With React strict mode on, it will load the player quite quickly then dispose it before it even ends. If it's possible to keep this on without doing some hacks to not running the useEffect() twice, it'll be great.
      2. Is there any anti-aliasing going on? Left side is using pixi-spine and right side is using spine-player. There's an obvious difference on the head of the character. Left side should be how it looks like.
      3. Based on what actually renders in the game and what's inside the png file, there should be an antenna-like object to render. But neither pixi-spine nor spine-player have been able to render it. I thought Spine Web Player would be able to render it, that's why I am giving Spine Web Player a try. May I know what am I missing here?
      4. Is there anyway to remove that large "Spine" marking? Even if reducing it to the size to about 20px tall at the right bottom is fine...It's just too big and the demo website with controls doesn't even have it, if the control is not shown.

      Thanks for answering all these questions!

        RaenonX

        First of all thanks for noticing the version mismatch! We're going to release a 4.0.29 version without this problem.

        1. With React strict mode on, it will load the player quite quickly then dispose it before it even ends. If it's possible to keep this on without doing some hacks to not running the useEffect() twice, it'll be great.

        That's a deliberate behaviour of react in development mode to make developers aware of possible risks due to effects running twice. If you care about the possibility that the effect is called twice (that might happen also in production for any reason!), you should react to your effect called twice to avoid it to make side effects twice.
        It's something we cannot solve on our side since you are basically calling twice the player constructor. That's something legitimate to do.

        1. Is there any anti-aliasing going on? Left side is using pixi-spine and right side is using spine-player. There's an obvious difference on the head of the character. Left side should be how it looks like.

        That seems to me a pma problem. Do you have premultipliedAlpha set to false?

        1. Based on what actually renders in the game and what's inside the png file, there should be an antenna-like object to render. But neither pixi-spine nor spine-player have been able to render it. I thought Spine Web Player would be able to render it, that's why I am giving Spine Web Player a try. May I know what am I missing here?

        I guess you did not make the animation. The asset you provide has two skins male and female.
        Set the player config skin to the skin you want to activate to make the antennas appear.
        The antennas are part of the skin.

        1. Is there anyway to remove that large "Spine" marking? Even if reducing it to the size to about 20px tall at the right bottom is fine...It's just too big and the demo website with controls doesn't even have it, if the control is not shown.

        There should not be any marking, if you imported correctly the css within the package. I guess that logo is shown because a css class that sizes and hides it is not found.

        We have just published the 4.0.29 version that fixes the version mismatch issue 🙂

        Hi,
        Thanks for the quick action on fixing the version mismatch!
        Regarding 1., I am aware of strict mode calling useEffect() getting called twice and know that it's intentional. My point was that since it's quickly doing construct -> dispose -> construct under strict mode, it seems like the error was because when dispose() was called, the loading mark wasn't even loaded, eventually causing dispose() getting called on a null object. I know that calling the constructor twice is completely possible (making 2 animations showing on the same page is one of the cases), but allowing quick construct -> dispose -> construct might be something worth addressing?

        You should react to your effect called twice to avoid it to make side effects twice.

        I have a hacky custom useEffect hook that would do so, but I feel like allowing disposal even before loading mark shows up shouldn't cause any error. It's fine if you think it should still give error though! I can just use my own custom useEffect so it only trigger the effect once in strict mode.

        pma problem (...)

        I didn't supply any value so it should be whatever value (likely true) by default. Specifying false gives me roundy head of the character. Thanks!

        I guess you did not make the animation.

        Yes, I am not the maker of the animation. Didn't know that there's a "skin" setting exists. Thanks! On top of that, Calling player.skeleton.data.skins gives me what skins are available.

        css within the package

        That's exactly the missing piece, thanks!


        Hopefully last (batch of) question(s)

        1. Is the typing of SpinePlayerConfig for v4.0 is correct? All config options are marked as required, so something like this fails the TypeScript check.
        2. How to automatically starts playing the animation when showControls is false? The following code snippet doesn't start the animation automatically, only if showControls of the player config is false:
          success: (player) => player.play()

        I want to express the gratitude of your responsiveness, thank you for being so responsive!

        Sorry again. I really wish I could delete my response after finding the issue.
        Typing issue, and the behavior under strict mode are the only things left!

          9 jours plus tard

          RaenonX

          Sorry for the late reply, I was in a one week vacation. I read again your previous messagges about the problem on strict mode. The error you mention on the on dispose() failing due to the LoadingScreen not yet initialized was solved from 4.1 version of the runtime.

          The same happens for the ts definition of the player configuration. From 4.1, we defined optional configuration parameters as optional.

          I highly recommend you to upgrade your animation to at least 4.1. 4.0 is more than 2 years old and we don't port all fixes to previous versions.

          Hi Davide,
          Hope you had a great vacation and thanks for responding as always!

          Is it fine if I submit PR instead so you guys can patch it? I understand that due to the maintenance effort needed, it's not possible port all fixes to old versions.

            RaenonX

            Thanks, vacation was great in the center of Italy 🙂

            Sure, PR are always welcome!
            Just try to make it as similar as possible to the latest version.

              Great, thank you for this.
              I'll merge it and make a release later today. 👍

              No problem and thanks!