diff --git src/simutrans/builder/wegbauer.cc src/simutrans/builder/wegbauer.cc
index 762e861b3..f8a182c8f 100644
--- src/simutrans/builder/wegbauer.cc
+++ src/simutrans/builder/wegbauer.cc
@@ -1663,7 +1663,8 @@ DBG_DEBUG("way_builder_t::intern_calc_route()","steps=%i  (max %i) in route, ope
 
 
 
-void way_builder_t::intern_calc_straight_route(const koord3d start, const koord3d ziel)
+// If allow_empty_start, tunnels can start on an empty underground tile
+void way_builder_t::intern_calc_straight_route(const koord3d start, const koord3d ziel, const bool allow_empty_start)
 {
 	const koord3d koordup(0, 0, welt->get_settings().get_way_height_clearance());
 
@@ -1685,6 +1686,9 @@ void way_builder_t::intern_calc_straight_route(const koord3d start, const koord3
 			ok = true;
 		}
 	}
+	if (!test_bd  &&  (bautyp&tunnel_flag)  &&  allow_empty_start) {
+		ok = true;
+	}
 	if (!ok) {
 		//target is not suitable
 		return;
@@ -2261,9 +2265,10 @@ const char *way_builder_t::calc_straight_route(koord3d start, const koord3d ziel
 		intern_calc_route_runways(start, ziel);
 	}
 	else {
-		intern_calc_straight_route(start,ziel);
+		const bool allow_empty_start = tunnel_desc && tunnel_desc->can_empty_start();
+		intern_calc_straight_route(start, ziel, allow_empty_start);
 		if (route.empty()) {
-			intern_calc_straight_route(ziel,start);
+			intern_calc_straight_route(ziel, start, allow_empty_start);
 		}
 	}
 	return warn_fail;
diff --git src/simutrans/builder/wegbauer.h src/simutrans/builder/wegbauer.h
index f9ce1e6f8..1766e7a27 100644
--- src/simutrans/builder/wegbauer.h
+++ src/simutrans/builder/wegbauer.h
@@ -108,7 +108,7 @@ private:
 	/// Type of bridge to build (null => no bridges)
 	const bridge_desc_t *bridge_desc;
 
-	/// Type of tunnel to build (null => no bridges)
+	/// Type of tunnel to build (null => no tunnels)
 	const tunnel_desc_t *tunnel_desc;
 
 	/**
@@ -151,7 +151,7 @@ private:
 	void check_for_bridge(const grund_t* parent_from, const grund_t* from, const vector_tpl<koord3d> &ziel);
 
 	sint32 intern_calc_route(const vector_tpl<koord3d> &start, const vector_tpl<koord3d> &ziel);
-	void intern_calc_straight_route(const koord3d start, const koord3d ziel);
+	void intern_calc_straight_route(const koord3d start, const koord3d ziel, const bool allow_empty_start);
 
 	sint32 intern_calc_route_elevated(const koord3d start, const koord3d ziel);
 
diff --git src/simutrans/descriptor/reader/tunnel_reader.cc src/simutrans/descriptor/reader/tunnel_reader.cc
index 0573776ce..e0af98ce8 100644
--- src/simutrans/descriptor/reader/tunnel_reader.cc
+++ src/simutrans/descriptor/reader/tunnel_reader.cc
@@ -77,7 +77,21 @@ obj_desc_t * tunnel_reader_t::read_node(FILE *fp, obj_node_info_t &node)
 	const uint16 v = decode_uint16(p);
 	const uint16 version = v & 0x8000 ? v & 0x7FFF : 0;
 
-	if (version == 6) {
+	if (version == 7) {
+		// allow some tunnels to be built anywhere undeground
+		desc->topspeed          = decode_uint32(p);
+		desc->price             = decode_sint64(p);
+		desc->maintenance       = decode_sint64(p);
+		desc->wtyp              = decode_uint8(p);
+		desc->intro_date        = decode_uint16(p);
+		desc->retire_date       = decode_uint16(p);
+		desc->axle_load         = decode_uint16(p);
+		desc->number_of_seasons = decode_uint8(p);
+		desc->empty_start       = decode_uint8(p);
+		desc->has_way           = decode_uint8(p);
+		desc->broad_portals     = decode_uint8(p);
+	}
+	else if (version == 6) {
 		// cost/maintenance as sint64
 		desc->topspeed          = decode_uint32(p);
 		desc->price             = decode_sint64(p);
@@ -158,8 +172,12 @@ obj_desc_t * tunnel_reader_t::read_node(FILE *fp, obj_node_info_t &node)
 		desc->axle_load = 9999;
 	}
 
+	if(  version < 7  ) {
+		desc->empty_start = 0;
+	}
+
 	PAKSET_INFO("tunnel_reader_t::read_node()",
-		"version=%d, waytype=%d, price=%" PRId64 ", maintenance=%" PRId64 ", topspeed=%d, intro=%d/%d, retire=%d/%d, axle_load=%d, has_way=%i, seasons=%i, b_portals=%i",
+		"version=%d, waytype=%d, price=%" PRId64 ", maintenance=%" PRId64 ", topspeed=%d, intro=%d/%d, retire=%d/%d, axle_load=%d, empty_start=%d, has_way=%i, seasons=%i, b_portals=%i",
 		version,
 		desc->wtyp,
 		desc->price,
@@ -168,6 +186,7 @@ obj_desc_t * tunnel_reader_t::read_node(FILE *fp, obj_node_info_t &node)
 		(desc->intro_date %12)+1, desc->intro_date /12,
 		(desc->retire_date%12)+1, desc->retire_date/12,
 		desc->axle_load,
+		desc->empty_start,
 		desc->has_way,
 		desc->number_of_seasons,
 		desc->broad_portals
diff --git src/simutrans/descriptor/tunnel_desc.h src/simutrans/descriptor/tunnel_desc.h
index d650ffba3..974867657 100644
--- src/simutrans/descriptor/tunnel_desc.h
+++ src/simutrans/descriptor/tunnel_desc.h
@@ -44,6 +44,10 @@ private:
 	 */
 	uint8 broad_portals;
 
+	/* Can be built anywhere underground (no portals needed)?
+	 */
+	uint8 empty_start;
+
 public:
 	const image_t *get_background(slope_t::type slope, uint8 season, uint8 type ) const
 	{
@@ -82,6 +86,8 @@ public:
 	}
 
 	bool has_broad_portals() const { return (broad_portals != 0); }
+
+	bool can_empty_start() const { return (empty_start != 0); }
 };
 
 #endif
diff --git src/simutrans/descriptor/writer/tunnel_writer.cc src/simutrans/descriptor/writer/tunnel_writer.cc
index 03f75a635..8d55f3f9a 100644
--- src/simutrans/descriptor/writer/tunnel_writer.cc
+++ src/simutrans/descriptor/writer/tunnel_writer.cc
@@ -24,6 +24,7 @@ void tunnel_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj)
 	const sint64 maintenance = obj.get_int64("maintenance", 1000);
 	const uint8  wtyp        = get_waytype(obj.get("waytype"));
 	const uint16 axle_load   = obj.get_int("axle_load",   9999);
+	const uint8  empty_start = obj.get_int("allow_empty_start", 0);
 
 	// timeline
 	uint16 intro_date  = obj.get_int("intro_year", DEFAULT_INTRO_YEAR) * 12;
@@ -59,9 +60,9 @@ void tunnel_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj)
 		number_portals = 4;
 	}
 
-	obj_node_t node(this, 32, &parent);
+	obj_node_t node(this, 36, &parent);
 
-	node.write_version(fp, 6);
+	node.write_version(fp, 7);
 	node.write_sint32(fp, topspeed);
 	node.write_sint64(fp, price);
 	node.write_sint64(fp, maintenance);
@@ -70,6 +71,7 @@ void tunnel_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj)
 	node.write_uint16(fp, retire_date);
 	node.write_uint16(fp, axle_load);
 	node.write_sint8 (fp, number_of_seasons);
+	node.write_sint8 (fp, empty_start);
 
 	write_name_and_copyright(fp, node, obj);
 
diff --git src/simutrans/tool/simtool.cc src/simutrans/tool/simtool.cc
index ff7a5fa3e..9c381437b 100644
--- src/simutrans/tool/simtool.cc
+++ src/simutrans/tool/simtool.cc
@@ -3139,6 +3139,7 @@ bool tool_build_tunnel_t::init( player_t *player )
 
 const char *tool_build_tunnel_t::check_pos( player_t *player, koord3d pos)
 {
+	win_set_static_tooltip("");
 	if (grund_t::underground_mode == grund_t::ugm_all) {
 		return NULL;
 	}
@@ -3186,6 +3187,10 @@ const char *tool_build_tunnel_t::check_pos( player_t *player, koord3d pos)
 				return NULL;
 			}
 		}
+		if( tunnel_builder_t::get_desc(default_param)->can_empty_start() ) {
+			// The tunnel can still be built from here
+			return NULL;
+		}
 		return two_click_tool_t::check_pos(player, pos);
 	}
 }
@@ -3204,7 +3209,7 @@ void tool_build_tunnel_t::calc_route( way_builder_t &bauigel, const koord3d &sta
 	bauigel.init_builder(bt | way_builder_t::tunnel_flag, wb, desc);
 	bauigel.set_keep_existing_faster_ways( !is_ctrl_pressed() );
 	// wegbauer (way builder) tries to find route to 3d coordinate if no ground at end exists or is not kartenboden (map ground)
-	bauigel.calc_straight_route(start,end);
+	bauigel.calc_straight_route(start, end);
 }
 
 const char *tool_build_tunnel_t::do_work( player_t *player, const koord3d &start, const koord3d &end )
@@ -3278,6 +3283,9 @@ uint8 tool_build_tunnel_t::is_valid_pos(  player_t *player, const koord3d &pos,
 			}
 		}
 	}
+	else if( tunnel_builder_t::get_desc(default_param)->can_empty_start() ) {
+		return 2;
+	}
 	else {
 		error = NOTICE_UNSUITABLE_GROUND;
 		return 0;
