Why does HOTP use such a complex truncate function? In the HOTP protocol after calculating a 20 byte hash it is truncated to 4 bytes.

For this first an offset is calculated (low-order 4 bits of the last byte) which determines the four bytes to be selected:


DT(String) // String = String[0]...String[19]
 Let OffsetBits be the low-order 4 bits of String[19]
 Offset = StToNum(OffsetBits) // 0 &lt;= OffSet &lt;= 15
 Let P = String[OffSet]...String[OffSet+3]
 Return the Last 31 bits of P



Why is this more 'secure' than simply always taking the first four bytes of the hash?
It looks to me that the original intent was to make sure that all bits of the hash digest have an equal chance to contribute to the truncated portion.  But one of the properties of a secure hash function is to ensure that a single bit change results in a cascade that yields changing bits across the entire digest.  If you don't trust this property in the hash algorithm, you either have a very weak hash algorithm or a weak understanding of the properties that make a hash algorithm strong.  

If any of the input bits to the hash differed originally, at least some of bits in the last four bytes will reflect it, with the expected reduction in collision resistance from $2^{80}$  to $2^{16}$.

So, given a good hash algorithm, it's not "more secure".  At best, it's equally secure.  In the real world, it's slightly more risky (and therefore less secure) because the added complexity offers the chance for a programmer to make an implementation mistake.