diff --git src/simutrans/descriptor/roadsign_desc.h src/simutrans/descriptor/roadsign_desc.h
index f20c9ebf0..b30b5f3b2 100644
--- src/simutrans/descriptor/roadsign_desc.h
+++ src/simutrans/descriptor/roadsign_desc.h
@@ -44,7 +44,8 @@ public:
 		ONLY_BACKIMAGE        = 1U << 5,
 		SIGN_LONGBLOCK_SIGNAL = 1U << 6,
 		END_OF_CHOOSE_AREA    = 1U << 7,
-		SIGN_PRIORITY_SIGNAL  = 1U << 8
+		SIGN_PRIORITY_SIGNAL  = 1U << 8,
+		SIGN_TWO_WAYS         = 1U << 9
 	};
 
 	image_id get_image_id(ribi_t::dir dir) const
@@ -65,6 +66,8 @@ public:
 
 	bool is_choose_sign() const { return (flags & CHOOSE_SIGN) != 0; }
 
+	bool is_two_ways() const { return (flags & SIGN_TWO_WAYS) != 0; }
+
 	//  return true for signal
 	bool is_simple_signal() const { return (flags & (
 		SIGN_SIGNAL |
diff --git src/simutrans/descriptor/writer/roadsign_writer.cc src/simutrans/descriptor/writer/roadsign_writer.cc
index 55e5502c4..aaab7f989 100644
--- src/simutrans/descriptor/writer/roadsign_writer.cc
+++ src/simutrans/descriptor/writer/roadsign_writer.cc
@@ -111,6 +111,9 @@ void roadsign_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& ob
 			(obj.get_int("no_foreground",      0) > 0 ? roadsign_desc_t::ONLY_BACKIMAGE        : roadsign_desc_t::NONE) |
 			(obj.get_int("end_of_choose",      0) > 0 ? roadsign_desc_t::END_OF_CHOOSE_AREA    : roadsign_desc_t::NONE);
 	}
+	if(  obj.get_int("two_ways", 0)   ) {
+		flags |= roadsign_desc_t::SIGN_TWO_WAYS;
+	}
 	// this causes unused entries to give a warning that they are ignored
 
 	obj_node_t node(this, 28, &parent);
diff --git src/simutrans/ground/grund.cc src/simutrans/ground/grund.cc
index ac11a81bf..3921b0891 100644
--- src/simutrans/ground/grund.cc
+++ src/simutrans/ground/grund.cc
@@ -1774,6 +1774,10 @@ void grund_t::display_overlay(const sint16 xpos, const sint16 ypos)
 				}
 
 				if( signal_t* sig = find<signal_t>() ) {
+					if (sig->get_desc()->is_two_ways()) {
+						// Display only one arrow if needed
+						mask = sig->get_dir();
+					}
 					if( sig->get_state()==roadsign_t::signalstate::STATE_RED ) {
 						c1 = gfx->palette_lookup( COL_ORANGE+2 );
 						c2 = gfx->palette_lookup( COL_ORANGE );
diff --git src/simutrans/obj/roadsign.cc src/simutrans/obj/roadsign.cc
index c18f899de..6ef67e207 100644
--- src/simutrans/obj/roadsign.cc
+++ src/simutrans/obj/roadsign.cc
@@ -112,7 +112,7 @@ roadsign_t::~roadsign_t()
 				finance_waytype = weg->get_waytype();
 
 				if (!preview) {
-					if (desc->is_single_way()  ||  desc->is_signal_type()) {
+					if (desc->is_single_way()  ||  (desc->is_signal_type() && !desc->is_two_ways())) {
 						// signal removed, remove direction mask
 						weg->set_ribi_maske(ribi_t::none);
 					}
@@ -143,7 +143,7 @@ void roadsign_t::set_dir(ribi_t::ribi dir)
 		if(  desc->get_wtyp()!=track_wt  &&  desc->get_wtyp()!=monorail_wt  &&  desc->get_wtyp()!=maglev_wt  &&  desc->get_wtyp()!=narrowgauge_wt  ) {
 			weg->count_sign();
 		}
-		if(desc->is_single_way()  ||  desc->is_signal_type()) {
+		if(desc->is_single_way()  ||  (desc->is_signal_type() && !desc->is_two_ways())) {
 			// set mask, if it is a single way ...
 			weg->count_sign();
 			weg->set_ribi_maske(calc_mask());
diff --git src/simutrans/obj/roadsign.h src/simutrans/obj/roadsign.h
index ce73637f1..6c13c72ec 100644
--- src/simutrans/obj/roadsign.h
+++ src/simutrans/obj/roadsign.h
@@ -28,7 +28,7 @@ protected:
 	image_id foreground_image;
 
 	enum {
-		SHOW_FONT        = 1,
+		SHOW_FRONT       = 1,
 		SHOW_BACK        = 2,
 		SWITCH_AUTOMATIC = 16
 	};
diff --git src/simutrans/vehicle/rail_vehicle.cc src/simutrans/vehicle/rail_vehicle.cc
index 3d88546e3..0ea87ab34 100644
--- src/simutrans/vehicle/rail_vehicle.cc
+++ src/simutrans/vehicle/rail_vehicle.cc
@@ -755,11 +755,15 @@ bool rail_vehicle_t::block_reserver(const route_t *route, route_t::index_t start
 #endif
 		if(reserve) {
 			if(  sch1->has_signal()  &&  i<route->get_count()-1  ) {
-				if(count) {
-					signs.append(gr);
+				signal_t* signal = gr->find<signal_t>();
+				// Ignore signals if we come the wrong way
+				if ( !(signal->get_desc()->is_two_ways() && i>start_index && !(ribi_type(pos, route->at(i-1)) & signal->get_dir()) )) {
+					if(count) {
+						signs.append(gr);
+					}
+					count --;
+					next_signal_index = i;
 				}
-				count --;
-				next_signal_index = i;
 			}
 			if (!sch1->reserve(cnv->self, ribi_type(route->at(max(1u, i) - 1u), route->at(min(route->get_count() - 1u, i + 1u))))) {
 				success = false;
