LegacyShell WikiLegacyShell Wiki
Back to LegacyShell
Home
Wiki
Plugins
Docs
Back to LegacyShell
Home
Wiki
Plugins
Docs
  • Documentation

    • Getting Started

      • What is LegacyShell?
      • Speed Setup
      • Requirements
      • Installation
      • First Run
      • Config Files
      • Making an Account
      • Troubleshooting (Getting Started)
    • Running a Server

      • Architecture Overview
      • The Database
      • Users and Ranks
      • Adding Game Servers
      • Client Mirrors
      • Perpetual
      • Backups
      • Rate Limiting
      • Moderation
      • Closed Mode
      • Deployment
      • Troubleshooting (Running a Server)
      • Hosting for Someone Else's Instance
    • Content Creation

      • Maps
      • Dealing with Babylon Models
      • Map Blocks
      • Items and Skins
      • Hats and Stamps
      • Sounds
      • Gamemodes
      • Seasonal Events
    • Plugin Development

      • Quickstart
      • I Want To...
      • Anatomy of a Plugin
      • Lifecycle
      • Dependencies
      • Events (Concept)
      • Event Reference

        • services: events
        • game: events — shared logic (src/shell/)
        • game: events — main-thread server process
        • game: events — per-connection client object
        • game: events — room lifecycle & tick loop
        • game: events — in-browser gameplay
        • client: events — client server & build pipeline
      • Commands
      • Client-Side Code
      • Static Assets
      • Content Packs
      • Networking
      • Workers and State
      • Prediction and Authority
      • Recipes

        • Recipe: Killstreaks
        • Recipe: New Pickup Item
        • Recipe: New Gamemode
        • Recipe: Custom Weapon
        • Recipe: UI Modification
        • Recipe: Discord Integration
        • Recipe: Replacing Core Behaviour
        • Recipe: Persistent Plugin Storage
        • Recipe: Rewarding Players with Currency
        • Recipe: Custom Per-Player Data
        • Recipe: Custom Theme
      • Publishing
      • Pitfalls
      • Modifiers
      • Sound and Apollo
    • Codebase Reference

      • Repo Layout
      • Shared Shell Layer
      • Server-Only Markers
      • The ss Object
      • Build Pipeline
      • Stamps and Babylons
      • Game Loop
      • Rooms and Workers
      • Wire Protocol
      • Generated

        • Wire Protocol Opcodes
        • Enums & Lookup Tables
        • Database Schema
        • Config Reference
        • Slash Command Reference
      • Services Internals
      • Catalog and Items
      • Permissions Internals
      • Physics and Collision
      • Known Quirks
      • Codebase Anecdotes
      • Development Timeline
    • Contributing

      • Documentation Style Guide
      • Generators
      • For AI Agents

Maps

Audience: Map makers · Prereqs: Getting Started

Canonical source: server-services/src/maps/*.json, server-services/src/data_management/recordsManagement.js (insertMaps)

Building and installing a custom map - no coding required, using the in-game map editor.

The editor

Open /editor on any client server (e.g. http://localhost:13370/editor) - it's a full 3D block-placement editor running in the browser, built on the same rendering pipeline as the game itself. Place blocks from a palette of models, set spawn points (the SPECIAL.spawn-blue.none/SPECIAL.spawn-red.none block types), test your map directly in the editor before exporting.

This isn't a LegacyShell-specific format - it's the same map editor and file format the original Shell Shockers game used, which is why the root README notes map JSON files are "directly compatible with those exported from the Shell Shockers map editor." If you've ever made a Shell Shockers map before, nothing here is new.

The file format

An exported map is a single JSON file:

{
    "fileVersion": 1,
    "data": {
        "generic.grass.full": [{ "x": 0, "y": 0, "z": 0, "ry": 2 }, ...],
        "town.shop1.full": [{ "x": 5, "y": 0, "z": 3 }, ...]
    },
    "palette": ["SPECIAL.spawn-blue.none", "SPECIAL.spawn-red.none", "town.shop1.full", ...],
    "width": 20,
    "height": 6,
    "depth": 20,
    "name": "Blue",
    "surfaceArea": 482
}

data is keyed by mesh name (matching a model in map.babylon - see Dealing with Babylon Models and Map Blocks if you need a block type that doesn't already exist), each holding an array of placements (x/y/z grid position, optional ry rotation). You won't typically hand-edit this - the editor produces it - but it's a plain, readable format if you ever need to script a change across many maps.

Installing a map

Once exported, a map becomes playable by placing its JSON file where services reads maps from and restarting:

cp YourMap.json server-services/src/maps/

Then restart the services server - initTablesMaps unconditionally wipes and reloads the entire maps table from this directory on every boot (see The Database), so a new file just needs to be present at the next restart, no separate "install" step.

If you're distributing a map pack as a plugin instead of editing the base game directly (the preferred approach per this project's "could this be a plugin?" philosophy - see the root README), see Content Packs instead, which covers the equivalent services:initTablesMaps + ss.recs.insertMaps(...) hook for shipping your own maps directory from a plugin folder.

Fields set outside the editor

A few map properties aren't part of the editor export and instead come from the database row's own defaults (or need setting directly) - sun, fog (unused), skybox, modes (which gamemodes the map is valid for, e.g. {"FFA":true,"Teams":true}), availability (public/private/both), and numPlayers (spawn-count hint). See the generated database schema for the full column list and current defaults - editing these means editing the database row directly (or the plugin-side map object before calling insertMaps) rather than through the in-game editor.

Common Issues

My map doesn't show up after restarting services. Confirm the file actually landed in server-services/src/maps/ (not a client or game server's own directory - only services reads this path) and that it's valid JSON - a parse error here fails that one file's insert silently rather than crashing the whole boot.

Blocks I placed aren't rendering / show as missing geometry. The mesh name in your placement doesn't exist in the currently-loaded map.babylon - see Map Blocks for adding new block types, or double check you're using a block from the standard palette if you didn't intend to add anything custom.

Next: Map Blocks.


This page was drafted with AI assistance and reviewed for accuracy. If something looks wrong, please open a PR or flag it.

Edit this page on GitHub
Next
Dealing with Babylon Models