Custom Importer API now available

  • In Construct 3 r76, we've added the first iteration of the Custom Importer API. The intent of this API is to allow plugins to import custom data formats in to C3 projects, in particular, skeletal animation formats. The API is designed to be general purpose, and it should allow the developers of these formats to maintain their own importers themselves, without having to go via Scirra.

    To get started, download the plugin SDK v1.2 and check out the customImporterPlugin sample. Download the Custom Importer API sample data further down the page too. If you then install the plugin, then drag-and-drop the sample data .zip to an empty layout, it should create and position three sprite instances based on the data in the zip. It's pretty basic but hopefully it's enough to demonstrate the principle of reading a custom data format.

    The current API is definitely a minimum-viable-product, and I expect we'll have to add many more API interfaces to fully support skeletal animation formats. So for that I'm interested to hear back from any other developers what kinds of other APIs that are needed. All currently available APIs in r76 are already documented - the starting point is SDK.UI.Util.AddDragDropFileHandler(). If it's not documented, we haven't added it yet, so please add it to your request list.

    Please let me know how this works out for you! Tagging some developers who may be interested: lucid badlogic kmoon11

  • Thanks Ashley - will take a look

  • Ashley - I have a couple of questions about the importer API. First in the example plugin.js, on line 70, you have: const imageEntry = zipFile.GetEntry(filename);

    [quote:3bzhpeq7] // Look for the given filename in the zip file.

    const imageEntry = zipFile.GetEntry(filename);

    if (!imageEntry)

    return; // referenced filename is missing in zip

    // If the file exists, read the referenced image file as a Blob.

    const imageBlob = await zipFile.ReadBlob(imageEntry);

    Is it possible to have it read from the folder of the dropped file, or does it have to be a zip file that contains the other files?

    Second question, how would I go about adding entries to the event sheet - In C2, dragging and dropping the scml file created the On Initialized event, and added the Associate actions. Is this possible with this API yet?

  • Is it possible to have it read from the folder of the dropped file, or does it have to be a zip file that contains the other files?

    Do you mean reading a different file on disk other than the one dropped in? No, that would be a security issue, so browsers block it at the moment. This is why everything's centered on a zip file, since you can get an entire folder of files.

    [quote:28hhiogr]Second question, how would I go about adding entries to the event sheet - In C2, dragging and dropping the scml file created the On Initialized event, and added the Associate actions. Is this possible with this API yet?

    It's not possible yet - best post a comment on the issue so it's not forgotten: https://github.com/Scirra/Construct-3-bugs/issues/836

  • Ashley - finally got around to trying this out on the Spriter plugin. I had a couple of questions. First, is this documented anywhere aside from the CustomImporterPlugin in the sdk?

    Could you please provide a link if so? I wasn't able to find it in the sdk documentation.

    If not, I had a few specific questions.

    1. How would I go about making a blank frame in a sprite of a specific size?

    2. How would I add additional frames to an animation?

    3. Is it possible to add events yet, and if so how?

    4. I'm getting a bunch of errors like this:

     main.js:63 Error loading texture: Error: no content set
     at n.ǃIkK (main.js:80)
     at window.ǃISB.ǃIkG (main.js:80)
     at n.map (main.js:80)
     at Array.map (<anonymous>)
     at window.ǃISB.ǃIky (main.js:80)
     at window.ǃISB.ǃIkN (main.js:80)
     at window.ǃISB.ǃIkR (main.js:80)
     at window.ǃISB.ǃIki (main.js:80)
     at window.ǃISB.ǃIgS (main.js:80)
     at n.ǃIgS (main.js:80)

    when attempting to load images from the Spriter json format. I've confirmed with console logs that it is correctly retrieving valid filenames that exist within the zip. Any ideas?

    Thank you.

  • It's all documented in the Editor API reference.

  • Ashley - thanks. I mistook that as edittime stuff similar to C2.

    I got almost everything working. The API is excellent and thorough. I did run into a few things I can't figure out:

    1. I can't find anything about creating families and adding object types to them. Is this supported yet?
    2. I'm getting TypeError: eventBlock.AddCondition is not a function. The same for AddAction. In fact, if I log an IEventBlock to the console, it looks like it doesn't contain any properties or functions not derived from its parent:
    3. I don't seem to be getting the 'promise'd IAnimationFrame from ReplaceBlobAndDecode. I need it to specify the pivot point on the first frame. I don't see an option to remove a frame either. This works: currentFrame = await firstAnim.AddFrame(imageBlob, fileWidth, fileHeight); But for this currentFrame is undefined: currentFrame = await currentFrame.ReplaceBlobAndDecode(imageBlob); I tried using a separate variable to hold the result just to be sure there wasn't anything strange happening, and it had the same result.
    4. I couldn't find a way to make the first blank frame of an animation a specific size. IObjectType.AddAnimation would let me specify the first frame size, but I don't see a RemoveAnimation. IAnimation.AddFrame is the same situation with no RemoveFrame.
    5. IWorldInstance has GetOpacity but no SetOpacity. Is there any way to set the opacity?
    6. I'm still getting a bunch of these errors, though everything seems to be working anyway. Is it safe to ignore or will it cause issues down the line?
    7. How would I get a blob from an entry to use with IProject.AddOrReplaceProjectFile(blob, filename, kind = "general") - say I started with: const entry = zipFile.GetEntry(fileName); Also, how would I create a subfolder in the project Files and place it in there?
    8. Any way to import sounds yet?
    1. It looks like families aren't supported yet, probably an oversight
    2. It looks like you're trying to call that method on an event group, or the root node of the event sheet, or some other class that doesn't actually support adding conditions and actions. Make sure it's really an EventBlock (i.e. something returned by AddEventBlock())
    3. The documentation does not say the promise resolves with anything. Why are you expecting a return value from 'await'?
    4. For an empty frame at a specific size, see the documentation: pass a null blob but provide a size.
    5. Looks like an oversight
    6. Those definitely need to be fixed but I can't tell why they're happening. I would guess you are trying to use an animation frame before waiting for a promise that loads content in to it to resolve. You must not use them before any promises affecting them resolve.
    7. Use ReadBlob
    8. Yes, AddOrReplaceProjectFile() takes a "sound" or "music" kind.

    For new SDK features, please collect a complete list of everything you need then post an issue to GitHub listing them all.

  • Thanks for the help.

    2) This is the code:

    const eventSheet = layoutView.GetLayout().GetEventSheet();
    const eventBlock = await eventSheet.GetRoot().AddEventBlock();		
    console.log(eventBlock);
    
    const systemType = eventSheet.GetProject().GetSystemType();
    eventBlock.AddCondition(systemType, null, "on-start-of-layout");

    which produces this output in the console:

    3) I misread the last sentence "Returns a promise that resolves when the image content" as "with the image content". I just re-fetched it from the array I got with IAnimation.GetFrames().

    There's a new issue though. I'll post it as a bug unless there's a step I'm missing. After changing the first frame with SetPivotX and SetPivotY, it shows up in the layout as if the pivot point is still in the center. If I double click the sprite, in the image editor the pivot point is in the place I had set. If I change the initial frame in the properties panel to something else and change it back, it corrects the pivot point placement.

    4) I meant specifically for the first frame. I can't find any way to remove an animation or a frame, and ReplaceBlobAndDecode only takes one parameter.

  • 2) I just realised there's a bug where these methods aren't minified correctly. It should be fixed in the next release (after r118).

    3) Every animation frame has its own origin, and the object itself separately has an origin. Sprites copy the animation frame origin to the object origin. It sounds like we need to make sure this happens when calling the SDK methods.

    4) I'm not really clear what you're trying to do? The SDK currently does not support removing animation frames, but why do you need to do that? Shouldn't you just add the correct sequence of frames?

  • 3) Just to be clear, you mean 'we' as in Scirra needs to make a change, or 'we' as in plugin developers using the SDK need to do an additional step to update the object to the animation frame pivot?

    4) I'm just trying to make the first frame of the first animation a blank frame of a specific size.

  • Well, you can use ReplaceBlobAndDecode(), and just pass the blob of an empty image at a certain size. You could make it from a canvas element.

  • Thanks Ashley . That worked. I haven't tested sound yet, so the last question for now is:

    3) Every animation frame has its own origin, and the object itself separately has an origin. Sprites copy the animation frame origin to the object origin. It sounds like we need to make sure this happens when calling the SDK methods.

    Just to make sure, you mean this is something you need to fix in the SDK? Or is there some way for me to set the animation frame origin to the object origin?

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • I'm not sure exactly what's going on with the origin there so it will probably take some investigation. I'd suggest filing a bug with a demo addon so I can figure out the sequence of calls and if any APIs need to be changed.

  • K. I had filed a bug report already. I'll update it with a demo addon.

    Edit: The bug report is updated with the demo addon.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)