Skip to main content

Overview

Entities are the fundamental game objects in Cub3D. Everything that exists in the game world - from walls and doors to players and enemies - is an entity. The entity system provides a flexible, type-based architecture for creating diverse game objects.

Entity Types

headers/cub3d.h
enum e_entity_type
{
	ENTITY,
	ENTITY_PLAYER,
	ENTITY_WALL,
	ENTITY_DOOR,
	ENTITY_BILLBOARD,
	ENTITY_DROP,
	ENTITY_CHARACTER,
	ENTITY_ELEVATOR
};

Base Entity Structure

All entities inherit from the base t_entity structure:
headers/cub3d.h
struct s_entity
{
	void			(*frame)(t_game *game, t_entity *entity, double delta_time);
	void			(*clear)(void *this);
	void			(*action)(t_entity *entity, t_character *actioner);
	void			(*shot)(t_entity *shooted, t_character *shooter);
	t_controller	controller;
	bool			targetable;
	bool			transparent;
	bool			ultra_mega_transparent;
	bool			no_transparency_for_bill;
	int				max_health;
	int				health;
	bool			invencible;
	bool			hard;
	bool			wall;
	bool			actionable;
	bool			billboard;
	bool			character;
	char			identifier;
	bool			active;
	t_coords		coords;
	t_dsize			size;
	t_entity_type	type;
	t_fta_audio		*collision_sound;
};
The entity system uses function pointers for polymorphic behavior - each entity type can override frame, action, shot, and clear methods.

Entity Properties

Core Properties

  • coords: Position (x, y) and facing angle (yaw) in the world
  • size: Width and height of the entity hitbox
  • identifier: Single character used in map files
  • active: Whether the entity is currently in the game
  • type: The specific entity type enum

Interaction Flags

  • targetable: Can be targeted by players (for shooting/interaction)
  • actionable: Can be interacted with (use key)
  • hard: Blocks movement (collision detection)

Visual Properties

  • transparent: Can be seen through (like windows)
  • ultra_mega_transparent: Always transparent, rays pass through
  • no_transparency_for_bill: Blocks billboards but not raycasts

Combat Properties

  • health: Current health points
  • max_health: Maximum health points
  • invencible: Cannot take damage

Wall Entities

Walls are the basic solid entities that define level geometry.
headers/cub3d.h
struct s_wall
{
	t_entity	entity;
	t_sprite	*north_sprite;
	t_sprite	*south_sprite;
	t_sprite	*west_sprite;
	t_sprite	*east_sprite;
};
  • Four directional textures (one for each cardinal direction)
  • Block movement and raycasts by default
  • Can be made transparent for windows
  • Foundation for door and elevator types

Wall Configuration

headers/cub3d.h
#define WALL_INTERACTION_DISTANCE 2.0
Players can interact with walls within 2.0 units.

Door Entities

Doors extend walls with opening/closing mechanics.
headers/cub3d.h
struct s_door
{
	t_wall		wall;
	t_direction	direction;
	t_sprite	*opening_sprite;
	t_sprite	*door_sprite;
	t_sprite	*door_sides_sprite;
	bool		opened;
	bool		cant_close;
	t_time		auto_close_delay;
	t_time		last_opened_at;
	int			last_animation_index;
	bool		closeable;
	t_time		animation_delay;
	int			animation_frames;
	t_fta_audio	*open_sound;
	t_fta_audio	*close_sound;
};

Door Configuration

headers/cub3d.h
#define DOOR_ANIMATION_FPS 6
Doors animate at 6 FPS by default. Custom animation speeds can be set per-door via the ANIMATION_DELAY property in map files.

Door States

  • opened: Current state (open/closed)
  • closeable: Can be closed after opening
  • cant_close: Stays open permanently once opened
  • auto_close_delay: Time before automatic closing (if set)

Billboard Entities

Billboards are 2D sprites that always face the camera (sprite rendering).
headers/cub3d.h
struct s_billboard
{
	t_entity		entity;
	bool			y_centered;
	t_sprite		**sprites;
};

Billboard Configuration

headers/cub3d.h
#define BILLBOARD_WIDTH 0.23
#define BILLBOARD_HEIGHT 0.23
Default billboard size is 0.23x0.23 units.

8-Directional Sprites

Billboards support 8 directional sprites for viewing from different angles:
Sprite indices correspond to viewing angles:
1: Front-left
2: Front
3: Front-right
4: Right
5: Back-right
6: Back
7: Back-left
8: Left
The engine automatically selects the appropriate sprite based on the player’s viewing angle.

Character Entities

Characters extend billboards with health, inventory, and AI capabilities.
headers/cub3d.h
struct s_character
{
	t_billboard	billboard;
	t_sprite	**using_sprite;
	t_sprite	**death_sprite;
	t_sprite	**hit_sprite;
	t_sprite	**walking_sprite;
	t_sprite	**_sprite;
	t_time		last_hit;
	t_time		last_use;
	t_time		last_auto_use;
	t_fta_audio	*hit_sound;
	t_fta_audio	*death_sound;
	t_entity	*target_entity;
	t_character	*last_hit_by_character;
	t_direction	target_entity_direction;
	t_time		last_inventory_scroll;
	bool		cheating;
	t_item		*inventory[INVENTORY_SIZE];
	t_drop		*drop;
	bool		drop_items;
	double		fov;
	int			rays;
	int			inventory_index;
	char		last_used_item_identifier;
	int			ammo;
	int			score;
	t_time		died_at;
	bool		was_already_dead;
	bool		dead;
};

Character Configuration

headers/cub3d.h
#define CHARACTER_HIT_DELAY 100.0
#define CHARACTER_DEFAULT_MAX_HEALTH 100
#define INVENTORY_SIZE 9
#define INVENTORY_SCROLL_DELAY 0.5

Character Features

  • Inventory system: 9 item slots
  • Health and damage: 100 HP by default
  • Animation states: Walking, using items, hit, death
  • AI targeting: Can target and track other entities
  • Item drops: Drop items on death
  • Sound effects: Hit sounds and death screams
  • Combat cooldowns: 100ms delay between hits

Player Entities

Players are characters with additional rendering and control properties.
headers/cub3d.h
struct s_player
{
	t_character			character;
	t_ftm_image			*canvas;
	t_coords			last_canvas_pos;
	int					controller_id;
	bool				friendly_fire;
};

Player Configuration

headers/cub3d.h
#define PLAYER_FOV 66.0
#define PLAYER_MOUSE_LOOK_VELOCITY 20.0
#define PLAYER_KEY_LOOK_VELOCITY 180.0
#define PLAYER_WALK_VELOCITY 4.0
#define PLAYER_SPRINT_VELOCITY 6.0
#define PLAYER_MAX_TARGET_DISTANCE 1.2
#define PLAYER_WIDTH 0.23
#define PLAYER_HEIGHT 0.23
#define PLAYER_MAX 4
#define PLAYER_DEAD_RESET_DELAY 2000
Cub3D supports up to 4 simultaneous players with split-screen rendering.

Player Movement

  • Walk speed: 4.0 units/second
  • Sprint speed: 6.0 units/second
  • Rotation speed: 180°/second (keyboard), 20°/second (mouse)

Drop Entities

Drops are pickupable items placed in the world.
headers/cub3d.h
struct s_drop
{
	t_billboard	billboard;
	t_item		*item;
	t_item		*prev_item;
	bool		auto_use;
	bool		auto_pickup;
};
  • auto_pickup: Automatically picked up when touched
  • auto_use: Automatically used when picked up
  • Contains an t_item pointer for the actual item data

Elevator Entities

Elevators teleport players to different maps.
headers/cub3d.h
struct s_elevator
{
	t_wall		wall;
	char		*map_path;
};
When activated, the elevator loads the map specified in map_path.

Entity Controller

The controller handles entity input and AI behavior.
headers/cub3d.h
struct s_controller
{
	void		(*key)(t_game *game, t_entity *entity, t_ftm_key_hook_values);
	void		(*frame)(t_game *game, t_entity *entity, double delta_time);
	t_time		last_shot;
	t_time		last_strafe;
	t_time		last_seen_target;
	t_coords	last_target_position;
	t_entity	*prev_target;
	int			prev_key;
	double		prev_angle;
	double		moving_to_angle;
	double		time_accumulator;
	double		optimal_proximity;
	bool		walking_forward;
	bool		walking_left;
	bool		walking_backward;
	bool		walking_right;
	bool		looking_right;
	bool		looking_left;
	bool		sprinting;
	bool		action;
	bool		keyboard_only;
	bool		already_actioned;
	double		mouse_moviment;
	double		mouse_look_velocity;
	double		key_look_velocity;
	double		walk_velocity;
	double		sprint_velocity;
};
Controllers can be used for both player input and AI behavior. The same controller structure handles keyboard/mouse input for players and decision-making for NPCs.

Entity Management

Entities are stored and managed by the game:
headers/cub3d.h
struct s_game
{
	// ...
	t_list			*entities;        // Linked list of all entities
	t_entity		***walls;          // 2D grid for raycasting
	t_entity		**billboards;      // Array of billboard entities
	// ...
};

Entity Frame Updates

Every frame, all entities are updated:
src/utils/loop/loop.c
call_entity_frames(cub3d()->game, &cub3d()->game->fps);
update_walls_matrix(cub3d()->game);
update_billboards_vec(cub3d()->game);
  1. call_entity_frames: Calls the frame() function for each entity
  2. update_walls_matrix: Updates the 2D wall grid for raycasting
  3. update_billboards_vec: Updates the billboard array for rendering

Entity Creation

Entities are created via factory functions:
headers/cub3d.h
t_player		*player_new(t_game *game, t_ftm_window *window, char identifier);
t_wall			*wall_new(t_game *game, t_ftm_window *window, char identifier);
t_door			*door_new_e(t_game *game, t_ftm_window *window, char identifier);
t_billboard		*billboard_new(t_game *game, t_ftm_window *window, char identifier);
t_character		*character_new(t_game *game, t_ftm_window *window, char identifier);
t_drop			*drop_new(t_game *game, t_ftm_window *window, char identifier);
t_elevator		*elevator_new(t_game *game, t_ftm_window *window, char identifier);
Each function:
  1. Allocates memory for the entity
  2. Initializes base entity properties
  3. Loads configuration from map identifiers
  4. Sets up sprites, sounds, and other assets
  5. Returns the configured entity

Entity Lifecycle

  1. Creation: Entity is created from map data
  2. Initialization: Properties loaded from identifier configuration
  3. Frame Updates: frame() called every game tick
  4. Interactions: action() or shot() called when interacted with
  5. Cleanup: clear() frees resources, entity removed from game

Transparency System

Cub3D supports multiple levels of transparency:
headers/cub3d.h
bool transparent;                // Texture-based transparency
bool ultra_mega_transparent;     // Always transparent
bool no_transparency_for_bill;   // Blocks billboards only
  • transparent: Rays check texture alpha channel at hit point
  • ultra_mega_transparent: Rays always pass through, useful for thin decorative walls
  • no_transparency_for_bill: Walls that block billboards but not raycasts (optimization)
Transparency is checked during raycasting:
src/utils/render/camera/walls/render.c
if (((t_entity *)ray.hit)->ultra_mega_transparent
	|| (((t_entity *)ray.hit)->transparent
		&& entity_x_is_transparent(ray.hit, ray.hit_direction, ray.hit_x)))
{
	// Continue ray through transparent entity
	draw_ray(drc);  // Recursive call
}

Collision Detection

Entities with hard = true block movement. Collision is checked using entity size:
headers/cub3d.h
t_dsize		size;  // Width and height
Entity hitboxes are axis-aligned bounding boxes (AABB) for efficient collision detection.

Build docs developers (and LLMs) love