# ymap or script: how a custom FiveM sign is built

> Why a baked map animation beats a client script for anything that just has to look good — frame time, sync, restarts and what each approach can and cannot do.

Source: https://fam-tools.com/guides/ymap-vs-script-signs · FAM Tools · published 2026-10-12 · updated 2026-10-12 · about 9 min

**Short answer.** A script sign recolours objects from client Lua every frame; a map sign stores the colour cycle in a texture and scrolls across it with a clip dictionary, which is how the base game animates its own signage. The map version costs no frame time, survives restarts and stays in sync for everyone.

## Key points

- Script animation costs frame time on every client, forever.
- Map animation is a texture plus a clip dictionary, and the engine does it for free.
- A baked sign keeps running when your scripts stop, crash or get restarted.
- Every player sees the same phase of the loop, because there is no per-client timer.

There are two ways to make a sign move on a FiveM server, and they are not variations on the same idea. One runs code on every client, every frame. The other puts the movement inside the asset and never runs at all. The difference shows up in your profiler, in how it behaves when something restarts, and in whether two players standing next to each other see the same thing.

## Two ways to animate a sign

A script sign spawns objects and changes them from client Lua. Usually that means a loop that recolours a material, swaps a texture variation or moves a prop a little each frame. It is quick to write and easy to break: it costs frame time, it stops when the resource stops, and every player sees a slightly different phase because every client started its own timer at a different moment.

A map sign puts the animation inside the asset. The colour cycle lives in a texture, and a clip dictionary scrolls the UV coordinates across it. That is not a trick — it is exactly the mechanism the base game uses for its own moving signage and screens. Once the asset is streamed, the engine animates it with no help from anybody.

|  | Script sign | Map sign |
| --- | --- | --- |
| Per-frame cost | One loop per client, forever | None |
| Survives a resource restart | No | Yes |
| Same phase for every player | No | Yes |
| Works with no framework | Depends how it was written | Always |
| Can react to events | Yes | No |
| Breaks when you break your Lua | Yes | No |

## What the baked version actually contains

The colour ramp is rendered to a narrow strip texture — one pixel column per step of the loop. The drawable's UVs are laid out so that each letter, or each slice of a logo, reads from a particular point along that strip.

The clip dictionary then animates the UV offset over the length of the loop. Scrolling the strip past the geometry is what makes the colours travel across the sign. Because the loop is a property of the clip and not of a timer, two clients who joined an hour apart are looking at the same frame of it.

- A .ytd holding the colour strip for the loop.
- A .ycd clip dictionary that scrolls the UV offset, named so the engine binds it to the drawable automatically.
- Drawables whose shader is set up for animated UVs and emissive output.
- Archetype flags that tell the game the model carries its own animation.

> **Why this matters for a hill sign** — A Vinewood sign is visible from most of the map. If it cost one Lua loop per client, that loop would run whether anybody was looking at it or not. A baked sign that nobody can see costs exactly nothing.

## What a baked sign cannot do

It cannot react. If you want the sign to change colour when a gang takes a turf, or spell out the name of the last player who joined, you need a script — the asset has no way to know about any of that.

Everything that is purely visual, though, belongs in the map. A loop, a sweep, a breathing glow, a gradient travelling across the letters: all of that is decided when the asset is built, and after that it is the engine's problem rather than yours.

## Why we only export maps

The banner creator has no script export, on purpose. A script version would be easier for us to generate and worse for you to run — and the day someone restarts the wrong resource, the sign your server is named after goes dark.

It also makes the resource portable in a way a script never is. Hand the folder to another admin, drop it on a fresh server, move hosts: nothing has to be matched up, because there is nothing to match.

## Questions

### Is an animated Vinewood sign bad for performance?

Not when the animation is baked into the map. There is no script, no NUI and no per-frame work — the only ongoing cost is drawing a handful of small objects you can already see.

### Can the sign change based on something in game?

No. A baked map animation has no access to game state. If you need the sign to react to events, that needs a script — but then you take on the frame cost and the sync problem that come with it.

### Do all players see the same colours at the same time?

Yes. The loop lives in the clip dictionary rather than in a client timer, so there is nothing to drift.

## Related

- https://fam-tools.com/guides/install-a-custom-vinewood-sign
- https://fam-tools.com/guides/fivem-sign-performance
- https://fam-tools.com/guides/fivem-ymap-guide
- https://fam-tools.com/guides/codewalker-map-editing
- https://fam-tools.com/guides/fivem-client-fps-optimization
