Kingdom of the Lyre: Path Generation
Monday, 11th November 2019
In this series, Damian blogs about how the game works.
Having just submitted Kingdom of the Lyre to PROCJAM, I want to make a series of posts about how the game works, so that others can see an example of how to put together an interesting game in Tiny BASIC. I started development with the path generation, so I'll deal with that first. Here's the first subroutine.
REM --- Determine available paths from an location REM --- Get the terrain of a location REM --- Inputs: X - origin location REM --- Changes: C - counter REM --- D - short term direction calculation REM --- Y - latitude REM --- Z - random number seed REM --- Outputs: E - Exits as a combination of: REM --- 1 = east REM --- 2 = south REM --- 4 = west REM --- 8 = north 310 LET Z=4881 LET C=0 LET Y=X/80 LET X=X-80*Y IF X-X/2*2=Y-Y/2*2 THEN GOTO 312 REM --- Process squares independent of their surroundings 311 GOSUB 500 LET C=C+1 IF C<=X+80*Y THEN GOTO 311 IF Y=79 THEN LET R=R-R/8*8 IF X=0 THEN LET R=R-R/4*4+R/8*8 IF Y=0 THEN LET R=R-R/2*2+R/4*4 IF X=79 THEN LET R=R/2*2 LET E=R RETURN REM --- Process squares dependent on their surroundings 312 LET E=0 313 GOSUB 500 IF Y<79 THEN IF C=X+80*(Y+1) THEN LET E=E+8*((R-R/4*4)/2) IF X>0 THEN IF C=X-1+80*Y THEN LET E=E+4*(R-R/2*2) IF Y>0 THEN IF C=X+80*(Y-1) THEN LET E=E+2*(R/8) IF X<79 THEN IF C=X+1+80*Y THEN LET E=E+(R-R/8*8)/4 LET C=C+1 IF C<=X+80*(Y+1) THEN IF C<=80*80-1 THEN GOTO 313 RETURN
Line 990 just the Random Number Generator that you can download from the Subroutine Library, so I won't repeat it here. Another subroutine at line 500 is central to the algorithm, and is reproduced here:
REM --- Generate a random 3-way junction REM --- Changes: Z - random number seed REM --- Outputs: R - directional exits for a 3-way junction REM --- 07 - west, south, east REM --- 11 - north, south, east REM --- 13 - north, west, east REM --- 14 - north, west, south 500 GOSUB 990 LET R=Z-Z/4*4 LET R=15-(R+1+R/2+R/3*3) RETURN
The algorithm as a whole works by dividing up the entire NxN map into a chequerboard pattern. Every one of the "black" squares has a random 3-way junction, except the ones at the edge. Here the junctions are clipped to prevent routes leading off the map. The "white" squares in between are subservient, and simply connect the black ones together.
This generates a reasonably open set of paths that might suit a city plan. It's not difficult to find your way through, but there are occasional blockages and dead ends that provide interest. It's not perfect, and it's possible to find sections that are isolated. But Kingdoms of the Lyre has a map of 80x80 locations, and apart from a few isolated edge locations, disconnected parts of the map should be rare.
The routine returns only a single map location, but it counts through all the locations from the south-west corner generating a random number for each one in order to get the value for the current location. My first attempts took a seed from the coordinates and was much quicker, but the poor quality of the random number generator revealed easily-discernible patterns across the map. So I had to resort to this slower method and hope that nobody tries to run this game on an old 8-bit micro. The game should still be reasonably responsive, especially when compiled.
This counting-through-the-map approach is used for other parts of the procedural generation, including terrain generation, which I'll cover in the next blog post.
Comments