Primeiro de tudo, existem muitas maneiras de gerar geração procedural e nenhuma delas é fácil, farei um tipo de abordagem de como você pode fazê-lo funcionar, depende de você aceitá-lo, modificá-lo ou descartá-lo.
Será pseudo-código em JS, pois é mais fácil de entender.
1º defina um ponto de entrada, como você quer construir uma cidade medieval, vamos começar com um quadrado, então digamos que sua cidade terá 300 unidades quadradas e a praça estará no meio dela (representada por um X).
300
________________
| |
| |
| | 300
| X |
| |
| |
|_______________|
const square = [ 150, 150 ];
2º agora vamos às avenidas, haverá um número aleatório delas, serão retas e começarão da praça do meio ou de outras avenidas
let avenues = [] // will contain start and end [[sx,sy],[ex,ey]]
const n_avenues = RANDOM(4, 8); // number of avenues
const n_av_from_square = RANDOM(0, avenues); // starting in the square
for av in av_from_square
avenues.push(square, [RANDOM(0, 200) + 100, RANDOM(0, 200) + 100])
// we want avenues to have, at least 100 units length, thats why we randomize just te last 200 units of the whole town size
Isso deve lhe dar uma praça e algumas ruas principais
300
________________
| \\ |
| \\ |
| \\ | 300
| X===== |
| |
| |
|_______________|
Agora temos que definir as avenidas que não começam na praça principal, elas cruzarão as outras avenidas
for av in (n_avenues - av_from_square){
const av_to_intersect = avenues[RANDOM(0,avenues.length)];
//check av_to... and get a perpendicular vector (explained bellow)
av[0] = [ av_to_intersect[0][1], - av_to_intersect[0][0] ];
av[1] = [ av_to_intersect[1][1], - av_to_intersect[1][0] ];
}
Para obter vetores perpendiculares, você deve trocar os cabos x, y e negar o novo y:
swiped == x: noswiped.y, y: -1 * (noswiped.x)
Agora você deve ter algo parecido com isso, não parece uma cidade? : P
300
________________
| \\ // |
| \\// || |
| \\ || | 300
| //\X===== |
| // || |
| || |
|_______________|
3º agora você só precisa interconectar as avenidas com ruas curtas, além disso, você pode gerar quadrados aleatórios por toda a cidade e fazer o mesmo que acima para todos eles, ou apenas gerar pequenas ruas de algumas praças secundárias, depende de você.
Lembre-se, quanto mais curtas forem as ruas, mais caótica será a cidade.