Map (tm.map)
The glue between a map provider resource and the UIs that show a world map. The pictures, calibration and style are defined once by a provider (a worldmap resource), and every resource with a map in its UI (the kit's KMap, a phone, dispatch) asks for them the same way. The UI side is in the interface kit (KMap).
| Side | Calls |
|---|---|
| Shared | tm.map.expandTiles(cfg) |
| Server (provider) | tm.map.provide(fn), tm.map.setCalibration(cal, target?) |
| Client (UI host) | tm.map.bind(options), tm.map.getConfig(), tm.map.getLook(), tm.map.setLook(look) |
The contract between them has no resource names in it: the provider answers the server callback tm_lib:map:getConfig, and fires the client event tm_lib:map:calibrationUpdated when staff recalibrate.
Tile expander
tm.map.expandTiles(cfg) turns a tile config into the flat list of pictures every map draws. It has no natives, so it also runs in a plain Lua test. The result:
{ width, height, size = width, list = { { url | fill, fade?, bleed?, x, y, w, h, minZoom? }, ... } }Every rectangle is in atlas pixels (the space the calibration maps game coordinates into: px = x * sx + ox), so a picture can have any resolution of its own: it is stretched to its rectangle. A detailed island can sit next to a coarse overview. The list order is the draw order (later pictures are on top).
tm.map.expandTiles({
width = 8192, height = 8192,
sets = {
{ fill = '#10304c' }, -- flat sea behind everything
{ url = 'https://example.com/tile%03d.png', grid = 4 }, -- 16 pictures, tile000 to tile015
{ url = 'https://example.com/isle%03d.png', x = 6000, y = 6000, w = 1000, h = 1000, cols = 2, rows = 2, first = 20, bleed = 2, minZoom = 1.5 },
},
})| Set field | Meaning |
|---|---|
url | A picture address with one %d style number (%03d). The number is the picture's index. A set needs url or fill. |
fill | A flat color instead of pictures (no download). |
fade | With fill: 'down', 'up', 'left' or 'right', from clear to solid in that direction. |
x, y, w, h | The set's rectangle in atlas pixels. Defaults: the whole atlas. |
grid | Cut into grid x grid pictures. cols and rows set them separately. A count below 1 is 1. |
first | Added to each index in url (one naming scheme across several sets). Default 0. |
skip | Array of picture numbers to leave out, counted from 0 inside the set. |
bleed | Atlas pixels of the neighbors' picture each tile carries on its right and bottom edge, to hide seams. Ignored for fills. |
minZoom | Only draw once the map is shown this large. |
Each edge is rounded to a whole pixel once, so neighbors share their border exactly. The older shape { url, grid, size } (one square set) works too. Anything that is not a table gives the default 8192 pixel atlas with no pictures. A url that string.format rejects drops that set only.
Provider (server)
tm.map.provide(function(source)
return {
calibration = { sx = 0.6583, sy = 0.6583, ox = 3756, oy = 5523 },
tiles = tilesConfig, -- a tile config (expanded for you) or an already expanded atlas
style = 'night', -- 'night' or 'original': the look for players who have not chosen one
}
end)
tm.map.setCalibration({ sx = 0.66, sy = 0.66, ox = 3760, oy = 5520 }) -- everyone; pass a source for one playersetCalibration returns false and sends nothing when the calibration is not four numbers with positive scales.
UI host (client)
tm.map.bind({
commit = function(message, payload) SendNUIMessage({ action = message, data = payload }) end,
calibration = 'setMapCalibration', -- message name for { sx, sy, ox, oy } updates
look = 'setMapLook', -- message name for { preset, sea, land, roads } updates
})bind answers the UI's map:getConfig NUI callback with { calibration, tiles, style, look } (or false when no provider answers), and pushes later calibration and look changes through commit. Binding again replaces the options instead of stacking listeners.
The look
The look is { preset = 'original' | 'night' | 'custom', sea, land, roads } (colors are #rrggbb). It comes from, in order:
- The player's own look:
tm.map.setLook(look). It is kept onLocalPlayer.state.tmMapLook(not replicated), so every resource sees it, and announced on the local eventtm_lib:map:lookChanged. Saving it between sessions is up to the screen that edits it (a settings menu can keep it intm.kvpand callsetLookat start).setLook(nil)clears it. An invalid look is refused. - The server default, from the
tm_libsettings below, unless the preset isauto. - Nothing: the UI then uses the provider's
style.
Setting (tm_lib namespace) | Type | Default |
|---|---|---|
map.preset | select: auto, original, night, custom | auto |
map.sea | color | #10304c |
map.land | color | #1d2a3a |
map.roads | color | #8fa8c6 |
Changing a setting or calling setLook reaches an open map at once through the look message. Clearing the player's look switches open maps to the server default when there is one.