> ## Documentation Index
> Fetch the complete documentation index at: https://v5.rpgjs.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# provideLoadMap

> Guide for provideLoadMap in RPGJS.

# provideLoadMap

The `provideLoadMap` function allows you to customize how maps are loaded and displayed on the client side. It enables you to provide a custom map component and define how map data is processed before rendering.

## Overview

`provideLoadMap` is a client-side function that takes a callback function which receives a map ID and returns map data along with a custom component for rendering. This is particularly useful when you want to:

* Use custom map formats (like Tiled TMX files)
* Display maps with custom rendering components
* Process map data before rendering
* Add custom layers or effects to your maps

## Basic Usage

```ts theme={null}
import { provideLoadMap } from '@rpgjs/client'
import { createModule } from '@rpgjs/common'
import MyMapComponent from './MyMapComponent.ce'

export function provideCustomMap() {
  return createModule("CustomMap", [
    provideLoadMap(async (mapId) => {
      // Load your map data
      const response = await fetch(`/maps/${mapId}.json`)
      const mapData = await response.json()
      
      return {
        data: mapData,           // Raw map data
        component: MyMapComponent, // CanvasEngine component
        width: mapData.width,    // Map width in pixels
        height: mapData.height,  // Map height in pixels
        events: mapData.events   // Optional: map events
      }
    })
  ])
}
```

## Return Object Properties

The callback function must return an object with the following properties:

### Required Properties

* **`data`** - The raw map data that will be passed to your component
* **`component`** - A CanvasEngine component that will render the map

### Optional Properties

* **`width`** - Map width in pixels (used for viewport calculations)
* **`height`** - Map height in pixels (used for viewport calculations)
* **`events`** - Map events data
* **`id`** - Map identifier (defaults to the mapId parameter)
* **`hitboxes`** - Array of collision hitboxes for the map
* **`positions`** - Named positions, used by `player.changeMap("map", "name")`

## Creating a Map Component

Your map component should be a CanvasEngine component that receives the map data through props:

```html theme={null}
<Container>
    <TileMap tiles={mapTiles} />
    <EventLayerComponent />
</Container>

<script>
    import { EventLayerComponent } from "@rpgjs/client"
    import { signal } from "canvasengine"

    // Get the map data from props
    const { data } = defineProps()
    
    // Access the data using data()
    const mapData = data()
    const mapTiles = signal(mapData.tiles)
</script>
```

### Accessing Props Data

In your component, use `defineProps()` to access the map data:

```ts theme={null}
const { data } = defineProps()

// The data is a signal, call it to get the actual value
const mapData = data()
```

## Event Layer Integration

To display game events (NPCs, interactive objects, etc.), include the `EventLayerComponent` in your map component:

```html theme={null}
<Container>
    <!-- Your map rendering -->
    <MyTileRenderer tiles={tiles} />
    
    <!-- Event layer for NPCs, players, interactive objects -->
    <EventLayerComponent />
</Container>

<script>
    import { EventLayerComponent } from "@rpgjs/client"
    
    const { data } = defineProps()
    const mapData = data()
    const tiles = signal(mapData.layers)
</script>
```

The `EventLayerComponent` automatically handles:

* Player character rendering
* NPC and event rendering
* Character animations and interactions
* Proper layering and sorting

## Composing the SceneMap

If you want to add scene-level components without changing each map renderer, define a client `sceneMap.component` and wrap the built-in `SceneMap` component:

```ts theme={null}
import { RpgClient, defineModule } from '@rpgjs/client'
import MyScene from './my-scene.ce'

export default defineModule<RpgClient>({
  sceneMap: {
    component: MyScene
  }
})
```

```html theme={null}
<!-- my-scene.ce -->
<SceneMap>
  <MyComponent />
</SceneMap>

<script>
  import { SceneMap } from '@rpgjs/client'
  import MyComponent from './my-component.ce'
</script>
```

Use `SceneMap` children for overlays or scene systems that should be mounted around the current map renderer. Use `EventLayerComponent` children when the custom elements must be sorted by `zIndex` with players and events.

### Adding Custom Elements to EventLayerComponent

You can add custom elements inside `EventLayerComponent` that will be automatically sorted by zIndex with the rest of the elements:

```html theme={null}
<Container>
    <MyTileRenderer tiles={tiles} />
    
    <EventLayerComponent>
        <!-- Custom elements will be auto-sorted by zIndex -->
        <Text text="Hello World" x={100} y={100} zIndex={5} />
        <Sprite image="custom-effect.png" x={200} y={150} zIndex={10} />
        <Container x={300} y={200} zIndex={1}>
            <Circle radius={20} color="red" />
        </Container>
    </EventLayerComponent>
</Container>

<script>
    import { EventLayerComponent } from "@rpgjs/client"
    import { Text, Sprite, Circle } from "canvasengine"
    
    const { data } = defineProps()
    const mapData = data()
    const tiles = signal(mapData.layers)
</script>
```

## Hitboxes Configuration

The `hitboxes` property allows you to define collision areas for the map. Each hitbox can be either rectangular or polygonal:

### Rectangular Hitboxes

```ts theme={null}
return {
  data: mapData,
  component: MyMapComponent,
  width: 2048,
  height: 1536,
  hitboxes: [
    {
      id: "wall1",           // Optional: unique identifier
      x: 100,                // X position in pixels
      y: 50,                 // Y position in pixels
      width: 32,             // Width in pixels
      height: 128            // Height in pixels
    },
    {
      id: "obstacle1",
      x: 300,
      y: 200,
      width: 64,
      height: 64
    }
  ]
}
```

### Polygonal Hitboxes

```ts theme={null}
return {
  data: mapData,
  component: MyMapComponent,
  width: 2048,
  height: 1536,
  hitboxes: [
    {
      id: "triangle1",       // Optional: unique identifier
      points: [              // Array of [x, y] coordinates
        [100, 100],
        [150, 50],
        [200, 100]
      ]
    },
    {
      id: "complex-shape",
      points: [
        [400, 300],
        [450, 250],
        [500, 300],
        [450, 350]
      ]
    }
  ]
}
```

### Mixed Hitboxes

You can combine both rectangular and polygonal hitboxes in the same array:

```ts theme={null}
return {
  data: mapData,
  component: MyMapComponent,
  width: 2048,
  height: 1536,
  hitboxes: [
    // Rectangular hitbox
    {
      id: "wall1",
      x: 100,
      y: 50,
      width: 32,
      height: 128
    },
    // Polygonal hitbox
    {
      id: "triangle1",
      points: [
        [100, 100],
        [150, 50],
        [200, 100]
      ]
    }
  ]
}
```

**Note:** If no `id` is provided, a unique identifier will be automatically generated for each hitbox.
