DEV Community

Hiroshi TK
Hiroshi TK

Posted on

Put a compatibility gate between your particle export and your game

This article was prepared with AI assistance. The code below is an original application-side check. The helper was checked with synthetic inputs; the cross-backend rendering steps below are a proposed integration procedure, not a completed visual benchmark.

A particle effect can look right in an editor and still be the wrong export for a game scene. The practical question is not whether the editor supports a setting somewhere. It is whether the selected runtime can represent the effect the team is shipping.

This tutorial adds a small compatibility gate to a proposed PixiJS and Three.js comparison. The purpose is to make unsupported behavior visible before someone evaluates the screenshots.

Choose one effect and a narrow comparison

Create an original short burst with a simple unlit particle appearance. Use a portable target, disable looping, and avoid imported meshes for the first comparison. Keep the same authored source and random seed for both hosts.

The comparison should answer three separate questions: does the export declare support, does each host load the required files, and does the effect look acceptable in the intended scene? Passing the first check does not answer the other two.

The NixieFX runtime documentation describes the export and renderer boundaries for this 2D and 3D particle editor. PixiJS and Three.js should not be treated as visually interchangeable: PixiJS lacks mesh-surface emission and lit shading, and editor preview bloom is not exported.

Make a strict review policy explicit

The helper below consumes the documented per-backend status fields. Its deliberately strict policy accepts only an explicit supported status. A partial report may be usable after a human reviews its approximations, but this particular comparison should stop there until that decision is recorded.

export function inspectTargets(compiledEffect, targets) {
  if (!Array.isArray(targets) || targets.length === 0) {
    throw new Error("Choose at least one target");
  }
  const reports = compiledEffect?.support?.backends ?? {};
  return targets.map(target => {
    const status = reports[target]?.status ?? "missing";
    return { target, status, allowed: status === "supported" };
  });
}

const sample = {
  support: { backends: {
    pixi2d: { status: "partial" },
    three3d: { status: "supported" }
  }}
};
console.table(inspectTargets(sample, ["pixi2d", "three3d"]));
Enter fullscreen mode Exit fullscreen mode

The sample is synthetic. It demonstrates the helper's decision and makes no claim about an actual exported effect. Local checks confirmed that a partial report is rejected, a supported report is allowed, a missing report is rejected, and an empty target list throws. These checks exercise the helper only, not particle rendering. Do not manufacture a report object in the real integration: read it from the compiled export and retain the original warnings for review.

Implementation steps for a reproducible render

  1. Record the installed NixieFX and renderer versions in the project lockfile. Keep the authored effect in source control.
  2. Validate and export that project. Save the generated manifest, compiled effect, referenced assets, and diagnostics together.
  3. Run the helper on the compiled effect with pixi2d and three3d as the target list. Stop if either result is missing, partial, or blocked under this tutorial's strict policy.
  4. Build one minimal PixiJS host and one minimal Three.js host using the installed package's integration examples. Load the export through the official bundle loader; the helper does not replace its validation.
  5. Use the same fixed seed. Choose a documented scene scale for each host and a fixed camera for Three.js. Advance each renderer once per host frame using elapsed seconds.
  6. Capture the burst at a recorded simulation time, then let it finish. Remove finished instances and destroy the owning renderer on scene teardown.

For a UI burst, the PixiJS host can place the effect beside a stationary marker. The Three.js host can place it at a stationary world point. Those are different coordinate spaces; equal numeric positions do not establish an equivalent composition.

Record evidence without claiming parity

The review record should include the source revision, package versions, export status, seed, scene scale, camera, capture time, and cleanup observation. Keep loading failures in the record rather than replacing them with an editor screenshot.

When implementing the comparison, capture one frame from each actual runtime at the same recorded simulation time. Label each capture with the backend, viewport, seed, and export revision. No cross-backend runtime captures are presented here.

The expected reproducible result is a compatibility decision followed by two independently inspected renders. The images need not be pixel-identical. Different cameras, scaling, material representation, and scene composition can change their appearance even when the shared effect data is valid.

What this gate does not prove

The helper does not parse assets, benchmark rendering, validate the complete export schema, or inspect visual quality. It only makes a team's acceptance policy for backend status explicit. Keep the official loader, actual screenshots, and human review in the workflow.

The useful failure is an early, readable stop: this effect needs a compatibility decision before it becomes a runtime claim in a tutorial or a shipped scene.

Top comments (0)