Prepare your next release

Upload scripts

Drop files anywhere or choose them below. Review each destination before uploading.

{preferredTarget ? `New version for ${scripts.find((s) => s.id === preferredTarget)?.name ?? 'script'}` : 'One file or a whole batch'} Existing filenames are recognized automatically. { void addFiles([...(event.currentTarget.files ?? [])]); event.currentTarget.value = ''; }} />
{#each queue as item (item.key)}
{item.file.name}{(item.file.size / 1024).toFixed(1)} KB
{#if item.result}

{item.result.reused ? 'Already uploaded' : 'Uploaded'} as {artifactVersionLabel( item.result, 'script' )} · View script →

{:else} (item.error = '')} /> {#if item.target === 'new'} {:else if item.target !== ''}{@const s = scripts.find( (s) => s.id === item.target )}

Keeps scope: {s ? scopeLabel(s) : '—'}. Target: {s?.target_rel_path}

{/if} {#if item.inspecting}

Checking file contents…

{:else if duplicate(item)}

Already uploaded as {artifactVersionLabel( duplicate(item), 'script' )}. We’ll reuse that version.

{:else if item.target !== 'new' && item.target !== ''}

New version for {scripts.find((s) => s.id === item.target)?.name}

{/if} {#if validation(item)}

{validation(item)}

{/if} {#if item.error} {#if !item.inspected}{/if}{/if} {/if}
{/each}
{#if pending.length}

Shared upload details

{#if hasNew} {#if scopeType !== 'none'} {#if scopeType === 'map'} {/if} {#if scopeValue}

{matches.length} matching servers: {matches .map((s) => s.name) .join(', ') || 'None'}

{/if} {#if scopeType === 'map' && scopeGame === 't6'}

Map scope includes every server using this engine map, including its Survival variants.

{/if} {:else}

Unscoped scripts deploy only to explicitly selected beta targets.

{/if}

Existing scripts keep their current scope.

{/if}
{/if} {#if message}

{message}

{/if}