Skip to content

Map editing proposes and the owning resource applies; maps are documents the core validates ​

Status: Accepted (2026-11-02)

Context ​

A map editor must work through the public SDK alone, like any other resource, while the edited entities stay server-owned: the client is hostile, yet it moves a gizmo locally. Lua has no file API, and a map made in the editor must be loadable by another resource on a server where the editor is not installed. Wire details are on the map editing page.

Decision ​

  • An edit is a proposal, not a write. In an edit session the client sends one EntityEdit when the player releases the gizmo. The core checks the session, that the entity belongs to the session's resource, that it is shown to the player and in their scope, the revision and the values; the resource applies the edit with the ordinary setters (set_position, set_rotation and the like). The resource therefore owns undo history, the document and the right to refuse. A refused or unapplied edit is answered with the entity's previous state.
  • Resources grant editing. The core has no notion of an admin: a resource opens a session with dlmp.begin_edit. The shipped map_editor opens one from the server console; another resource sets its own policy.
  • The map format is in the core, the file is the resource's. dlmp.list_maps, read_map, save_map and load_map work only with maps/<name>.toml of the calling resource. This is not a file API: the name is checked (a-z, 0-9, -, _, up to 64 bytes), the content can only be a map document, and a save replaces the file whole and atomically. A separate autosave draft exists for the editor; load_map never reads it.
  • Loading is all or nothing. The whole document is validated before the first entity is created; when the server has no room for everything, nothing is created and load_map fails.
  • A map point is data. The game mode gives meaning to a point's kind (a spawn, a flag base); the core knows only the shape of the record.
  • The camera position is a separate packet, only in a session.EditCamera makes the editing player's camera their stream center; ordinary player frames do not grow, and the packet is dropped outside a session.

Consequences ​

  • The map format is a public contract with a version number (currently 1). Sections the core does not know survive a resave, so tools can store their own data in a map.
  • A map reaches a game mode by copying its file into the game mode's resource; there is no other path.
  • A game mode must handle a refused load_map: a busy server may not have room for the map.
  • Picking is by the bounding boxes of shown entities, so it is imprecise in the empty parts of a box (an arch's opening); cycling the selection and box selection compensate.

Alternatives considered ​

  • Stream poses while dragging. Nobody else watches the drag, while the attack surface and the number of undo steps grow.
  • Let the core apply edits. The resource could not refuse one, contrary to ADR 0038.
  • A password typed in chat to open the editor. The beginning of an authorization system, and plain text over UDP.
  • A general file API with a loader written in Lua. Every game mode would invent its own format, and a map would need a dependency on the editor through dlmp.import.
  • A shared maps folder, or reading from the editor's folder. One resource overwrites another's maps, and a game mode stops being portable.
  • Partial loading. An arena with a hole in its floor is worse than an honest refusal.
  • Picking with a ray against the game's collision. It stops at world buildings and does not see models without collision.

Documentation licensed under CC BY 4.0. DarqlineMP is not affiliated with Rockstar Games or Take-Two Interactive. Grand Theft Auto is a trademark of Take-Two Interactive Software, Inc.