NEON ARENA / SPRITEPILOT
49 original code-drawn assets. 531 frames at each of two resolutions.

Every asset folder contains 1x.png and 2x.png horizontal strips, a lossless RGBA preview.apng, and the SVG source of frame 0. No font files or third-party artwork.

SIZES AND TIMING
Ships, enemies, projectiles, effects and pickups: 128 and 256 px square frames. Health pips: 64/128. Digits: 40x48 / 80x96. Buttons: 256x64 / 512x128. Logo: 512x160 / 1024x320. Grid and stars: 256/512 square. Border: 512x288 / 1024x576. Panel: 256x128 / 512x256.
pack.json lists each frame size, fps, loop flag, paths and normalized anchor. All anchors are centered except digits (top-left). Ships and bolts face right (+X). Gameplay collision bounds should ignore the glow and transparent padding.
Loops sample t=i/N; one-shots sample t=i/(N-1). One-shots end with a faint tail, so no frame is empty; hide on animation completion. fps=0 means static artwork or indexed states, never automatic playback: digits 0-9; buttons normal/hover/pressed. APNG previews cycle these indexed states for inspection.

IMPORT
For the Phaser examples, copy the extracted kit contents (the folder containing pack.json) into a served folder named pack/.
Phaser 3: this.load.multiatlas('neon','pack/atlas-1x.json','pack/'); use frame 'player-idle/000'. Create animations from pack.json; repeat=-1 only when loop=true. Both atlas JSON files use TexturePacker multiatlas format: each existing strip PNG is a page, with untrimmed, unrotated frames. This preserves every original pixel without duplicating artwork in the download. Load 1x or 2x with the matching JSON. See every asset working in the playable demo: https://spritepilot.com/game-kits/neon-arena
Godot 4: import per-asset strips, create SpriteFrames with Add frames from sprite sheet, horizontal count=frames, vertical count=1; set speed=fps and Loop from pack.json. Use a CanvasItemMaterial light mode Unshaded.
Unity: import strips as Sprite (2D and UI), Multiple; Sprite Editor > Slice > Grid By Cell Size using the manifest frame dimensions; pivot Center (digits Top Left). Create clips at the listed fps; enable Loop Time only for loops. Disable texture compression for best neon edges.
Digits: digits.json gives glyph rectangles and advance at 1x; double coordinates for 2x. No external font required.

ALPHA
PNG data is straight RGBA. Glow uses soft (partially transparent) edges → premultiplied alpha / linear filtering recommended. Let your engine premultiply on upload; do not premultiply PNGs twice. Normal alpha blending preserves mechanical bodies; additive blending is best for effects and projectiles. Disable mipmaps for the strip atlas pages; for smaller mipmapped art use standalone strips with engine padding.
Grid and both star layers tile seamlessly. Border is a full-screen overlay, not a tile.

Every sprite is vector art drawn in code. Every sound effect is synthesized in code.

LICENSE
Free use in personal and commercial projects; standalone redistribution is prohibited. See LICENSE.txt.

SOUND EFFECTS
Every sound is synthesized in code.
31 sound families / 48 recordings. WAV: mono, 44.1 kHz, signed 16-bit PCM. OGG: Opus 96 kbps. MP3: 192 kbps. sfx/sfx.json lists files, durations, loop flags, suggested relative gain, concurrency and variants. EBU R128 integrated loudness, silence padded to 500 ms only for events shorter than 500 ms; target -20 LUFS (+/- 3 LU), source true peak <= -2.5 dBTP and all delivery codecs <= -1 dBTP.
The one-second shield-hum WAV has an exact periodic boundary. Loop shield-hum.wav for a seamless hum (Phaser: { loop: true }). Use WAV for sample-accurate loops (MP3 encoder padding and engine decoding can disrupt looping).
Phaser 3: with Phaser loaded and the kit contents served from pack/, this complete example plays player-laser on click or tap:
new Phaser.Game({
  type: Phaser.AUTO,
  width: 320,
  height: 180,
  scene: {
    preload() {
      this.load.audio('player-laser', ['pack/sfx/player-laser.ogg', 'pack/sfx/player-laser.mp3', 'pack/sfx/player-laser.wav']);
    },
    create() {
      this.add.text(20, 70, 'Click or tap to play');
      const cue = this.sound.add('player-laser', { volume: 0.48 });
      this.input.on('pointerdown', () => {
        if (!cue.isPlaying) cue.play();
      });
    }
  }
});
Start audio after the first click/tap so the browser can unlock it. Cap simultaneous copies of each sound using the concurrency value in sfx/sfx.json; this example allows one copy at a time.
Godot 4: import WAV as AudioStreamWAV, use AudioStreamPlayer, volume_db = linear_to_db(suggestedVolume). Enable forward loop only on shield-hum.wav, loop begin=0/end=44100; keep one-shots nonlooping.
Unity: import WAV as AudioClip (Decompress On Load for short cues); AudioSource.PlayOneShot(clip, suggestedVolume); use a dedicated AudioSource with loop=true for shield hum. Start/stop with a short volume ramp.
Gem levels 1/2/3 rise in pitch; variants stay close to each base pitch. Use suggestedVolume for quieter UI and weapon cues; the files themselves are level matched.

Music
-----
Three original tracks performed with software instruments, supplied as stereo OGG and MP3.
Arena Menu Loop: menu, 73.846 seconds, 104 BPM, A minor, loop.
Arena Battle Loop: gameplay, 105.000 seconds, 128 BPM, A minor, loop.
Arena Game Over Sting: sting, 5.000 seconds, 104 BPM, A minor, one-shot.
music/music.json lists exact sample counts, loop points in seconds and suggested volumes.
OGG files are Ogg Vorbis — Godot, Unity and Phaser import them directly; use OGG for seamless loops. Some browsers need the MP3 fallback; some engines ignore MP3 gapless headers.
Phaser: use Web Audio (noAudio is false, disableWebAudio is false); supply OGG first and MP3 as a browser fallback, then play with loop: true. For explicit loop points, decode into an AudioBufferSourceNode, set loopStart = 0 and loopEnd from music.json, then loop = true. Never restart from an ended callback.
Godot: import the OGG directly as AudioStreamOggVorbis, enable loop with loop_offset = 0 for the two full-clip loops, and play through AudioStreamPlayer. Leave loop disabled for the sting.
Unity: import the OGG directly as AudioClip with Decompress On Load, disable Load In Background and enable Preload Audio Data. Use AudioSource.loop for the two full-clip loops; leave it off for the sting.
Keep a separate music volume, fade between menu and gameplay over about 0.8 seconds, and stop or duck gameplay for the one-shot sting.
