Skip to main content

Map File Overview

Cub3D map files use the .cub extension and contain two main sections:
  1. Configuration section: Texture paths and colors
  2. Map grid section: The actual level layout
Map files are plain text files that you can create with any text editor.

Map File Format

A Cub3D map file follows this structure:
NO ./texture_north.xpm
SO ./texture_south.xpm
WE ./texture_west.xpm
EA ./texture_east.xpm

F 220,100,0
C 225,30,0

111111
100001
100N01
100001
111111
1

Texture definitions

Define paths to textures for all four wall directions (NO, SO, WE, EA)
2

Color definitions

Specify floor (F) and ceiling (C) colors in RGB format
3

Empty line separator

Leave at least one empty line between configuration and map grid
4

Map grid

Define the level layout using characters: 1 (wall), 0 (empty), N/S/E/W (player)

Configuration Section

Texture Paths

Four texture identifiers must be defined, each on its own line:
NO <path_to_north_texture>
SO <path_to_south_texture>
WE <path_to_west_texture>
EA <path_to_east_texture>
Texture paths can have flexible spacing, but must be on separate lines.

Texture Identifier Rules

From asignatributes.c:24-35, texture assignment validation:
if (!ft_strcmp(arr0, "NO") && !map->northtexture)
    return (map->northtexture = ft_strdup(noendline), 0);
if (!ft_strcmp(arr0, "SO") && !map->southtexture)
    return (map->southtexture = ft_strdup(noendline), 0);
if (!ft_strcmp(arr0, "WE") && !map->westtexture)
    return (map->westtexture = ft_strdup(noendline), 0);
if (!ft_strcmp(arr0, "EA") && !map->easttexture)
    return (map->easttexture = ft_strdup(noendline), 0);
return (msg(2, MAP_ARG_DUP), msg(2, arr0), msg(2, "\n"), 1);
Error: “Atribute is found more than once”Each texture identifier (NO, SO, WE, EA) can only be defined once in the map file.

Texture File Validation

From asignatributes.c:49-54:
fd = open(noendline, O_RDONLY);
if (fd > 0)
    close(fd);
else
    return (msg(2, IMG), 1);
Error: “The image of one of the directions was not found in the system”All texture files must exist and be readable before the map can be loaded.

Supported Texture Format

Cub3D uses the XPM (X PixMap) image format for textures.

XPM Format

XPM is a plain text image format native to X11 systems. Texture files must have the .xpm extension.
Textures are loaded using MiniLibX:
tex->img_ptr = mlx_xpm_file_to_image(mapa->mlx_ptr, path,
        &tex->width, &tex->height);

Color Configuration

Floor and ceiling colors are specified in RGB format:
F <R>,<G>,<B>
C <R>,<G>,<B>
  • F: Floor color
  • C: Ceiling color
  • RGB values: Each value must be between 0 and 255

Color Validation

From utils4.c:15-27, RGB range validation:
int isrgbable(char **arr2)
{
    int i = 0;
    while (arr2[i])
    {
        if (ft_atoi(arr2[i]) < 0 || ft_atoi(arr2[i]) > 255)
            return (msg(2, RGBERROR2), 1);
        i++;
    }
    return (0);
}
Error: “Some introduced number is not valid for rgb standard”RGB values must be integers between 0 and 255.

Color Format Validation

From utils4.c:29-54, the parser validates:
  1. Exactly 3 values: RGB format requires three comma-separated numbers
  2. All digits: Each value must be composed only of digit characters
  3. Valid range: Each value must be 0-255
if (i != 3)
    return (msg(2, RGBERROR), 1);
// Error: "There aren't three arguments after spliting"

if (!ft_isdigit(arr2[i][ii]))
    return (msg(2, FORMAT3), 1);
// Error: "There is some non digit character"

Color Parsing

From utils7.c:15-29, colors are parsed into hex format:
int parse_color(const char *line)
{
    int r, g, b;
    
    while (*line && (*line == 'F' || *line == ' '))
        line++;
    r = ft_atoi(line);
    line = ft_strchr(line, ',') + 1;
    g = ft_atoi(line);
    line = ft_strchr(line, ',') + 1;
    b = ft_atoi(line);
    return ((r << 16) | (g << 8) | b);
}
The RGB values are combined into a single integer: 0xRRGGBB

Configuration Order

From parselineutils.c:55-62, all configuration attributes must be present:
static int all_atributes_asigned(t_map *map)
{
    if (map->northtexture && map->southtexture && map->easttexture
        && map->westtexture && map->floorcolor && map->ceilingcolor)
        return (1);
    else
        return (0);
}
All six configuration attributes (NO, SO, WE, EA, F, C) must be defined before the map grid begins.

Map Grid Section

Valid Map Characters

From utils4.c:56-62, the allowed characters are:
int ft_is_nswe(char c)
{
    if (c == 'N' || c == 'S' || c == 'W' || c == 'E' || c == '1'
        || c == '0' || c == ' ' || c == '\t' || c == '\n')
        return (1);
    return (0);
}

1

WallSolid wall block

0

Empty SpaceWalkable floor

N

Player NorthStarting position facing north

S

Player SouthStarting position facing south

E

Player EastStarting position facing east

W

Player WestStarting position facing west

(space)

VoidEmpty space outside map

(tab)

WhitespaceTreated as void
Any character not in this list will cause the map to fail validation.

Player Position

From utils3.c:30-53, player validation:
int checkns(t_map *map, int count, int i, int ii)
{
    while (map->toflood_map[i])
    {
        ii = 0;
        while (map->toflood_map[i][ii])
        {
            if (ft_is_nswe(map->toflood_map[i][ii]) != 1)
                return (0);
            if (map->toflood_map[i][ii] == 'N' || map->toflood_map[i][ii] == 'S'
                || map->toflood_map[i][ii] == 'E'
                || map->toflood_map[i][ii] == 'W')
            {
                if (count == 0)
                    add_values(map, i, ii);
                know_starting_angle(map, i, ii);
                count++;
            }
            ii++;
        }
        i++;
    }
    return (count);
}
Error: “Should have only one player and map with only 0 and 1”The map must contain exactly one player character (N, S, E, or W). No more, no less.

Map Closure Validation

The most critical rule: the map must be completely enclosed by walls. From utils4.c:64-84, flood fill validation:
void flood_fill(t_map *mapa, char **map, int x, int y)
{
    if (x < 0)
        return (msg(2, MAPERROR4), freeall(mapa), exit(1));
    if (x == mapa->row)
        return (msg(2, MAPERROR4), freeall(mapa), exit(1));
    if (map[x][y] == ' ' || map[x][y] == '\n' || map[x][y] == '\t'
        || map[x][y] == '\0')
        return (msg(2, MAPERROR4), freeall(mapa), exit(1));
    if (!map[x][y])
        return (msg(2, MAPERROR4), freeall(mapa), exit(1));
    if (map[x][y] && map[x][y] != '1')
    {
        if (map[x][y] != 1)
            map[x][y] = '1';
        flood_fill(mapa, map, x + 1, y);
        flood_fill(mapa, map, x - 1, y);
        flood_fill(mapa, map, x, y + 1);
        flood_fill(mapa, map, x, y - 1);
    }
}
Error: “Map is not closed”This flood fill algorithm starts from the player position and explores all walkable spaces. If it encounters a space, tab, newline, or map boundary, the map is not properly closed.

Map Closure Rules

1

Wall boundaries

All edges of the map must be walls (1)
111111  ✓ Correct
100001
100001
111111
111111  ✗ Incorrect - right edge open
100000
100000
111111
2

No holes in walls

Walkable spaces cannot be adjacent to void spaces
11111
10001
10 01  ✗ Incorrect - space creates hole
10001
11111
3

Handle irregular shapes

Maps can be non-rectangular, but all exposed edges must be walls
    111
    101
111111
100001
111111
This is valid because all walkable spaces are surrounded by walls.

Example Maps

Let’s examine real example maps from the repository:

Simple Map: COME.cub

From maps/COME.cub:
                                        NO ./pizza.xpm
SO ./doom2.xpm      
WE              ./doom3.xpm
EA ./eagle.xpm

F 220,100,0
C 225,30,0






111
1N1
111
Configuration:
  • North texture: ./pizza.xpm
  • South texture: ./doom2.xpm
  • West texture: ./doom3.xpm
  • East texture: ./eagle.xpm
  • Floor: Orange (RGB: 220, 100, 0)
  • Ceiling: Red-orange (RGB: 225, 30, 0)
  • Note: Flexible spacing is allowed before texture identifiers
Map Grid:
  • Minimal 3x3 map
  • Player starts in center facing North
  • Completely enclosed by walls
  • Perfect for testing basic functionality

Medium Map: DOOMGUY.cub

From maps/DOOMGUY.cub:
NO ./doom4.xpm
SO ./doom3.xpm
WE ./doom2.xpm
EA ./doom.xpm

F 220,100,0
C 225,30,0

111111111111111111111111
  110000000000000000001111
    1000000000000000111
    10000000000000000001111
     110000000000000000111111
     111110000000000000000111111
      111100000N0000011111111111   
111111111111110011111100111111111111111
1111111111111111111111000111111111111111110
111111111111111111111111111111111111111111111
Configuration:
  • DOOM-themed textures
  • Same floor/ceiling colors as COME.cub
Map Grid:
  • Irregular shape with indented sections
  • Leading spaces create interesting geometry
  • Player in middle area facing North
  • Multiple corridor widths
  • Demonstrates complex but valid map structure
  • Notice how walkable areas never touch void spaces

Complex Map: Dommed.cub

From maps/Dommed.cub:
NO ./tex1.xpm
SO ./tex2.xpm
WE ./tex3.xpm
EA ./tex4.xpm

F 220,100,0
C 225,30,0

1111111111111111111111111
1000000000110000000000001
1011000001110000000000001
100100000000000000000000111111111
111111111011000001110000000000001
100000000011000001110111111111111
11110111111111011100000010001
 11110111111111011101010010001111
  11000000110101011100000010001111
    10000000000000001100000010001
    10000000000000001101010010001
     11000001 1010101 111011110N0111
     11110111 1110101 101111010000001
      11111111111111111111111111 11111     111   
Configuration:
  • Generic texture names (tex1-4)
  • Standard floor/ceiling colors
Map Grid:
  • Highly irregular shape
  • Multiple room-like areas
  • Internal spaces in walls (see row 12: spaces between numbers)
  • Player at right edge facing North
  • Demonstrates that spaces inside walls are valid
  • Trailing spaces/empty areas are allowed
  • Shows complex but properly enclosed structure

Step-by-Step Map Creation

Let’s create a simple custom map from scratch:
1

Create a new .cub file

touch maps/my_first_map.cub
2

Add texture paths

Choose four textures (or reuse existing ones):
NO ./greystone.xpm
SO ./greystone.xpm
WE ./purplestone.xpm
EA ./purplestone.xpm
3

Add floor and ceiling colors

Pick RGB values for floor and ceiling:
F 64,64,64
C 135,206,235
This creates a gray floor and sky blue ceiling.
4

Add empty line

Separate configuration from map grid:
5

Design your map layout

Start with a simple rectangular room:
1111111111
1000000001
1000000001
1000N00001
1000000001
1000000001
1111111111
6

Add complexity (optional)

Add corridors and rooms:
1111111111111111
1000000001000001
1000000001000001
1000N00001000001
1000000000000001
1000000001000001
1111111111111111
7

Test your map

Run Cub3D with your new map:
./cub3d maps/my_first_map.cub

Complete Map Template

Here’s a complete template you can use as a starting point:
NO ./greystone.xpm
SO ./greystone.xpm
WE ./purplestone.xpm
EA ./purplestone.xpm

F 64,64,64
C 135,206,235

11111111111111111111
10000000000000000001
10000000000000000001
10000000111100000001
10000000100100000001
10000000100100000001
10000000111100000001
10000000000000000001
10000000000N00000001
10000000000000000001
11111111111111111111

Common Errors and Solutions

Cause: Walkable space touches a void space or map edge.Solution:
  1. Ensure all edges of your map are walls (1)
  2. Check for spaces adjacent to 0 or player characters
  3. Verify irregular shapes have walls on all exposed edges
Example fix:
# Before (broken):
11111
10001
10 01
11111

# After (fixed):
11111
10001
10101
11111
Cause: Zero or multiple player characters (N/S/E/W).Solution:
  • Ensure exactly one N, S, E, or W character exists
  • Check for accidentally duplicated player positions
  • Verify you haven’t forgotten to place a player
# Broken - no player:
11111
10001
10001
11111

# Broken - two players:
11111
1N0E1
10001
11111

# Fixed:
11111
10N01
10001
11111
Cause: Texture file path is incorrect or file doesn’t exist.Solution:
  1. Verify all texture files exist:
    ls -la *.xpm
    
  2. Check paths are correct (relative or absolute)
  3. Ensure file permissions allow reading
  4. Use paths relative to where you run cub3d
Cause: RGB values outside 0-255 range.Solution:
  • Check all RGB values are between 0 and 255
  • Verify no negative values
  • Ensure no decimal points (must be integers)
# Broken:
F 256,100,0
C -10,30,0

# Fixed:
F 255,100,0
C 10,30,0
Cause: Floor or ceiling color doesn’t have exactly 3 RGB values.Solution:
  • Ensure colors have format: R,G,B
  • Use exactly two commas
  • No spaces between values
# Broken:
F 220,100
C 225,30,0,255

# Fixed:
F 220,100,0
C 225,30,0
Cause: Duplicate configuration identifiers.Solution:
  • Remove duplicate NO, SO, WE, EA, F, or C lines
  • Keep only one of each identifier
# Broken:
NO ./tex1.xpm
NO ./tex2.xpm

# Fixed:
NO ./tex1.xpm

Advanced Map Techniques

Creating Rooms and Corridors

111111111111111111111111111
100000001000000001000000001
100000001000000001000000001
100000001000000001000000001
100000000000000000000000001
100000001000000001000000001
100000001000N00001000000001
111111111111111111111111111
This creates three rooms connected by corridors.

Irregular Shapes

        1111111
        1000001
        1000001
    111110000111111
    100000000000001
    100000N00000001
    100000000000001
    111111111111111
Use leading spaces to create interesting geometries.

Large Open Areas

1111111111111111111111111
1000000000000000000000001
1000000000000000000000001
1000000000000000000000001
1000000000000000000000001
1000000000000N00000000001
1000000000000000000000001
1000000000000000000000001
1000000000000000000000001
1000000000000000000000001
1111111111111111111111111
Large open spaces showcase the raycasting engine.

Map Size Considerations

From cub3.h:89, the map buffer size:
char map[500][500];
Maps can be up to 500x500 cells. However, practical sizes are much smaller for performance and playability.
  • Small maps: 10x10 to 20x20 cells
  • Medium maps: 20x20 to 40x40 cells
  • Large maps: 40x40 to 100x100 cells
Remember: Each cell is 30x30 pixels in the game world (defined by SIZE in cub3.h:33).

Testing Your Map

1

Visual inspection

Check your map file in a text editor - does it look closed?
2

Run Cub3D

./cub3d maps/your_map.cub
3

Test navigation

Walk around using WASD - can you reach all areas?
4

Check textures

Rotate and verify all four wall textures appear correctly.
5

Verify colors

Look up and down (in your mind) - floor and ceiling colors correct?

Next Steps

You’re now ready to create complex, interesting maps for Cub3D!

Building

Review the build process

Running

Test your maps

Controls

Navigate your creations

Architecture

Understand the rendering engine