Making a Text RPG can be very easy. You need to know exactly what you want it to do though. Things like is it real time or turn based. Can you shoot, can the player pick up things, are you going to have a map editor. These effect what kind of map data you use. Some are easyer then others because they allow less code to move around, and are easier to understand. Some are alittle difficult to use and have more code. I have programmed as many possible types of maps that can be used. These can be combined to make use of different features. They all hold the same practical idea. I will start with a simple one. If you copy the code and paste it in a new text file and name it "textrpg.bas". then open it in QBasic it should work unless you screwed it somehow, If you didn't it could have been me. -=**************************************> Start of Code <**************************************=- CLS 'gets map ready DIM map(100, 100) FOR y = 1 TO 10 FOR x = 1 TO 10 READ map(x, y) IF map(x, y) = 0 THEN LOCATE y, x: COLOR 2: PRINT CHR$(176) IF map(x, y) = 2 THEN LOCATE y, x: COLOR 6: PRINT CHR$(176) IF map(x, y) = 10 THEN LOCATE y, x: COLOR 10: PRINT CHR$(6) IF map(x, y) = 11 THEN LOCATE y, x: COLOR 7: PRINT CHR$(111) NEXT x NEXT y 'sets player x and player y px = 2 py = 9 'start of big loop top: 'gets what is behind player bg = SCREEN(py, px) bgc = SCREEN(py, px, 1) 'puts player on the screen LOCATE py, px: COLOR 15: PRINT CHR$(2) 'checks to see if a key is pressed DO: P$ = INKEY$: LOOP UNTIL P$ <> "" 'clears player off screen and replaces with background LOCATE py, px: COLOR bgc: PRINT CHR$(bg) 'checks to see if a certian key was pressed so that the player x or player y 'can be moved to a new location. IF P$ = "8" AND map(px, py - 1) <= 9 THEN py = py - 1 IF P$ = "5" AND map(px, py + 1) <= 9 THEN py = py + 1 IF P$ = "6" AND map(px + 1, py) <= 9 THEN px = px + 1 IF P$ = "4" AND map(px - 1, py) <= 9 THEN px = px - 1 'goes back to the top GOTO top 'map data DATA 10,10,10,10,10,10,10,10,10,10 DATA 10,00,00,00,00,00,00,00,02,10 DATA 10,00,00,00,00,00,11,02,02,10 DATA 10,00,00,00,02,02,02,02,10,10 DATA 10,00,00,00,02,10,00,00,00,10 DATA 10,00,00,02,02,00,00,00,00,10 DATA 10,00,02,02,00,10,00,00,10,10 DATA 10,00,02,00,10,10,10,00,00,10 DATA 10,02,02,00,00,00,00,00,00,10 DATA 10,10,10,10,10,10,10,10,10,10 -=***************************************> End of Code <***************************************=- Simple huh? Most of this makes sense. The only thing you might be confused about is why I use 00,02,10,11 in the data instead of using 1,2,3,4. Well if you look at my code in the keys part you will notice it checks the map for something. "map(px, py - 1) <= 9" This checks to see if the position it wants to move to is a walkable tile or a wall. I have used 00-09 as walkable tiles and 10-99 as wall tiles. This way I'm setup for when I add more walkable tiles. If you really want to be safe you can have 0-50 as walkables and 50-whatever as walls. If you wanted to make items laying around then you should use a fake and chck when the player ontop of it by using -=> Start code <=- IF map(px, py) = 3 THEN map(px, py) = 0: bg = 176 : bgc = 2: score = score + 1 -=> End of Code <=- Put it after the keys so it happens as soon as you move onto it. It checks to see if the place where the player is a 3 on the map and if it is then it sets that part of the map to a normal walkable tile. Now that you have taken all that code in you are ready to see the next map type. -=**************************************> Start of Code <**************************************=- CLS 'gets map ready DIM map(100, 100), tiles(100) 'reads tiles data READ amount FOR i = 1 TO amount * 4 READ tiles(i) NEXT i 'reads map FOR y = 1 TO 10 FOR x = 1 TO 10 READ map(x, y) LOCATE y, x 'Prints right tile in right place FOR i = 1 TO 100 STEP 4 IF map(x, y) = tiles(i) THEN COLOR tiles(i + 2) PRINT CHR$(tiles(i + 1)) EXIT FOR END IF NEXT i NEXT x NEXT y 'sets player x and player y px = 2 py = 9 'start of big loop top: 'gets what is behind player bg = SCREEN(py, px) bgc = SCREEN(py, px, 1) 'puts player on the screen LOCATE py, px: COLOR 15: PRINT CHR$(2) 'checks to see if a key is pressed DO: P$ = INKEY$: LOOP UNTIL P$ <> "" 'clears player off screen and replaces with background LOCATE py, px: COLOR bgc: PRINT CHR$(bg) 'checks to see if a certian key was pressed so that the player x or player y 'can be moved to a new location. IF P$ = "8" AND tiles((map(px, py - 1) * 4)) = 0 THEN py = py - 1 IF P$ = "5" AND tiles((map(px, py + 1) * 4)) = 0 THEN py = py + 1 IF P$ = "6" AND tiles((map(px + 1, py) * 4)) = 0 THEN px = px + 1 IF P$ = "4" AND tiles((map(px - 1, py) * 4)) = 0 THEN px = px - 1 IF P$ = CHR$(27) THEN END 'goes back to the top GOTO top 'map data 'Tile data DATA 5 'tiles (Tile number, ASCII Character, Color, 0=walkable 1=wall) DATA 1,176,2,0 DATA 2,6,10,1 DATA 3,177,6,0 DATA 4,176,9,1 DATA 5,111,7,1 'The map DATA 04,04,04,04,04,04,02,02,02,02 DATA 04,04,04,04,04,01,01,02,01,02 DATA 04,04,04,04,04,01,01,01,02,02 DATA 04,04,04,04,01,02,01,01,01,02 DATA 02,01,04,04,02,01,01,02,01,02 DATA 02,01,02,01,01,03,03,03,03,02 DATA 02,01,03,03,03,03,05,01,02,02 DATA 02,03,03,01,01,01,02,01,01,02 DATA 02,03,01,01,05,01,01,01,02,02 DATA 02,02,02,02,02,02,02,02,02,02 -=***************************************> End of Code <***************************************=- This one is a little more complex. I only just came up with it. This one makes it easier to make a new tile. The tile can be any number and it doesn't effect the where the player moves. The 0 and the 1 change that. DATA 1,176,2,0 The 0 at the end tells the player that he can move onto it, if it was a 1 then the player could not walk on it. This is the code it uses to check if it can go somewhere. IF P$ = "8" AND tiles((map(px, py - 1) * 4)) = 0 THEN py = py - 1 Looks the same as the the code in the 1st program. It really is very much the same. It goes and sees what tile number is in the position and then if the tile has a 0, if so then the player moves. Those two are pretty good but I still have more. Heres the 3rd one. It is kind similar to the one above. -=**************************************> Start of Code <**************************************=- CLS 'gets map ready DIM map(100, 100), walls(100, 100) FOR y = 1 TO 10 FOR x = 1 TO 10 READ map(x, y) LOCATE y, x COLOR VAL(MID$(STR$(map(x, y)), 1, 2)) PRINT CHR$(VAL(MID$(STR$(map(x, y)), 3, 6))) NEXT x NEXT y FOR y = 1 TO 10 FOR x = 1 TO 10 READ walls(x, y) NEXT x NEXT y 'sets player x and player y px = 2 py = 9 'start of big loop top: 'gets what is behind player bg = SCREEN(py, px) bgc = SCREEN(py, px, 1) 'puts player on the screen LOCATE py, px: COLOR 15: PRINT CHR$(2) 'checks to see if a key is pressed DO: P$ = INKEY$: LOOP UNTIL P$ <> "" 'clears player off screen and replaces with background LOCATE py, px: COLOR bgc: PRINT CHR$(bg) 'checks to see if a certian key was pressed so that the player x or player y 'can be moved to a new location. IF P$ = "8" AND walls(px, py - 1) = 0 THEN py = py - 1 IF P$ = "5" AND walls(px, py + 1) = 0 THEN py = py + 1 IF P$ = "6" AND walls(px + 1, py) = 0 THEN px = px + 1 IF P$ = "4" AND walls(px - 1, py) = 0 THEN px = px - 1 IF P$ = CHR$(27) THEN END 'goes back to the top GOTO top 'map data (color + ASCII character) DATA 01176,02176,03176,04176,05176,01176,02176,03176,04176,05176 DATA 02176,00000,00000,00000,00000,00000,00000,00000,00000,04176 DATA 03176,00000,00000,00000,00000,00000,00000,00000,00000,03176 DATA 04176,00000,00000,06176,06176,06176,00000,00000,00000,02176 DATA 05176,00000,06176,06177,06177,06177,06176,00000,00000,01176 DATA 06173,00000,06176,06177,05178,06177,06176,00000,00000,00176 DATA 07176,00000,06176,06177,06177,06177,06176,00000,00000,01176 DATA 08176,00000,00000,06176,05178,06176,00000,00000,00000,02176 DATA 09179,00000,00000,00000,00000,00000,00000,00000,00000,03176 DATA 10176,09166,08156,07176,06136,05176,04176,03176,02124,01176 'wall data DATA 1,1,1,1,1,1,1,1,1,1 DATA 1,0,0,0,0,0,0,0,0,1 DATA 1,0,0,0,0,0,0,0,0,1 DATA 1,0,0,0,0,0,0,0,0,1 DATA 1,0,0,0,0,0,0,0,0,1 DATA 1,0,0,0,1,0,0,0,0,1 DATA 1,0,0,0,0,0,0,0,0,1 DATA 1,0,0,0,0,0,0,0,0,1 DATA 1,0,0,0,0,0,0,0,0,1 DATA 1,1,1,1,1,1,1,1,1,1 -=***************************************> End of Code <***************************************=- Nice eh? This makes use of moulding information together. This has saved space. I could have blended then wall data into the map data by changing the data in the map to "101760" which breaks up into color: 10 character: 176 wall 1/0: 0 As a challenge you might want to do that and also make an editor to make maps. I recconmend that you make an editor for that data, because it aint all that much fun to put in. If I get enough e-mails(lets say 1) I will wright a tut on editors and make one just for this. This code is a little different for when it displays it. it first has a look at the first two digits of the number COLOR VAL(MID$(STR$(map(x, y)), 1, 2)) this tells it what color it will be. The next line finds out what the last 3 digits are and uses them with CHR$() PRINT CHR$(VAL(MID$(STR$(map(x, y)), 3, 6))) When the player moves it checks the 2nd map to see if there is a 0 on the position it wants to move too. If it is a 1 it won't move there, thus acting like a wall. Simple huh? I'll give one last example of a map and then show you how to link up a couple of maps and store the data of each map in a tidy easy to use way. -=**************************************> Start of Code <**************************************=- CLS 'gets map ready DIM map(100, 100) FOR y = 1 TO 10 FOR x = 1 TO 10 READ map(x, y) IF map(x, y) = 0 THEN LOCATE y, x: COLOR 2: PRINT CHR$(176) IF map(x, y) = 2 THEN LOCATE y, x: COLOR 6: PRINT CHR$(176) IF map(x, y) = 10 THEN LOCATE y, x: COLOR 10: PRINT CHR$(6) IF map(x, y) = 11 THEN LOCATE y, x: COLOR 7: PRINT CHR$(111) NEXT x NEXT y 'sets player x and player y px = 2 py = 9 'start of big loop top: 'gets what is behind player bg = SCREEN(py, px) bgc = SCREEN(py, px, 1) 'puts player on the screen LOCATE py, px: COLOR 15: PRINT CHR$(2) 'checks to see if a key is pressed DO: P$ = INKEY$: LOOP UNTIL P$ <> "" 'clears player off screen and replaces with background LOCATE py, px: COLOR bgc: PRINT CHR$(bg) 'checks to see if a certian key was pressed so that the player x or player y 'can be moved to a new location. IF P$ = "8" AND SCREEN(py - 1, px) <> 6 THEN py = py - 1 IF P$ = "5" AND SCREEN(py + 1, px) <> 6 THEN py = py + 1 IF P$ = "6" AND SCREEN(py, px + 1) <> 6 THEN px = px + 1 IF P$ = "4" AND SCREEN(py, px - 1) <> 6 THEN px = px - 1 IF P$ = CHR$(27) THEN END 'goes back to the top GOTO top 'map data DATA 10,10,10,10,10,10,10,10,10,10 DATA 10,00,00,00,00,00,00,00,02,10 DATA 10,00,00,00,00,00,11,02,02,10 DATA 10,00,00,00,02,02,02,02,10,10 DATA 10,00,00,00,02,10,00,00,00,10 DATA 10,00,00,02,02,00,00,00,00,10 DATA 10,00,02,02,00,10,00,00,10,10 DATA 10,00,02,00,10,10,10,00,00,10 DATA 10,02,02,00,00,00,00,00,00,10 DATA 10,10,10,10,10,10,10,10,10,10 -=***************************************> End of Code <***************************************=- Now this one is almost the same as the 1st program. The only difference is that instead of check the map to see if it can move it checks the screen. This can useful sometimes but others useless. If you printed character 006 randomly over the screen and did not have a map for it then this is useful. It would create a forest type type effect also. You could put any other character on the screen and you would be able to walk over it because it is not character 6. To change that just change the sixs in the keys part to anothe character, for example 219 IF P$ = "8" AND SCREEN(py - 1, px) <> 219 THEN py = py - 1 IF P$ = "5" AND SCREEN(py + 1, px) <> 219 THEN py = py + 1 IF P$ = "6" AND SCREEN(py, px + 1) <> 219 THEN px = px + 1 IF P$ = "4" AND SCREEN(py, px - 1) <> 219 THEN px = px - 1 Instead of checking the character yo could check the color. to do that all you have to do is add a 1. Like this SCREEN(py - 1, px,1) <> 4 If you use that instead you will not be able to walk on anything that is dark red. Now for the end of this. I will show you a program that can change to different maps easily. After all it would be stupid not to show this in a RPG tut, because thats one of the main features. -=**************************************> Start of Code <**************************************=- CLS 'gets map ready DIM map(10, 11, 11) FOR m = 1 TO 3 FOR y = 1 TO 10 FOR x = 1 TO 10 READ map(m, x, y) NEXT x NEXT y NEXT m 'sets player x and player y px = 2 py = 9 'sets the map you start on m = 1 'draws the current map you are on redraw: FOR y = 1 TO 10 FOR x = 1 TO 10 IF map(m, x, y) = 0 THEN LOCATE y, x: COLOR 2: PRINT CHR$(176) IF map(m, x, y) = 2 THEN LOCATE y, x: COLOR 6: PRINT CHR$(176) IF map(m, x, y) = 10 THEN LOCATE y, x: COLOR 10: PRINT CHR$(6) IF map(m, x, y) = 11 THEN LOCATE y, x: COLOR 7: PRINT CHR$(111) NEXT x NEXT y 'start of big loop top: 'gets what is behind player bg = SCREEN(py, px) bgc = SCREEN(py, px, 1) 'puts player on the screen LOCATE py, px: COLOR 15: PRINT CHR$(2) 'checks to see if a key is pressed DO: P$ = INKEY$: LOOP UNTIL P$ <> "" 'clears player off screen and replaces with background LOCATE py, px: COLOR bgc: PRINT CHR$(bg) 'checks to see if a certian key was pressed so that the player x or player y 'can be moved to a new location. IF P$ = "8" AND map(m, px, py - 1) <= 9 THEN py = py - 1 IF P$ = "5" AND map(m, px, py + 1) <= 9 THEN py = py + 1 IF P$ = "6" AND map(m, px + 1, py) <= 9 THEN px = px + 1 IF P$ = "4" AND map(m, px - 1, py) <= 9 THEN px = px - 1 IF P$ = CHR$(27) THEN END IF px = 11 THEN px = 1 IF m = 1 THEN m = 2: GOTO redraw END IF IF px = 0 THEN px = 10 IF m = 2 THEN m = 1: GOTO redraw END IF IF py = 11 THEN py = 1 IF m = 2 THEN m = 3: GOTO redraw END IF IF py = 0 THEN py = 10 IF m = 3 THEN m = 2: GOTO redraw END IF 'goes back to the top GOTO top 'map data DATA 10,10,10,10,10,10,10,10,10,10 DATA 10,00,00,00,00,00,00,00,00,10 DATA 10,11,00,00,00,00,11,00,00,10 DATA 10,00,00,00,02,02,02,02,10,00 DATA 10,00,00,00,02,10,00,02,02,02 DATA 10,00,00,02,02,00,00,00,00,00 DATA 10,00,02,02,00,10,00,00,10,10 DATA 10,00,02,00,10,10,10,00,00,10 DATA 10,02,02,00,00,00,00,00,11,10 DATA 10,10,10,10,10,10,10,10,10,10 DATA 10,10,10,10,10,10,10,10,10,10 DATA 10,00,00,00,00,00,10,00,10,10 DATA 10,00,00,00,11,00,00,00,00,10 DATA 00,00,00,00,00,00,00,00,10,10 DATA 02,02,02,02,00,00,10,00,00,10 DATA 00,00,00,02,00,10,00,00,00,10 DATA 10,00,00,02,00,00,00,00,00,10 DATA 10,10,00,02,02,02,00,10,00,10 DATA 10,00,00,11,00,02,00,00,00,10 DATA 10,10,10,10,00,02,00,10,10,10 DATA 10,10,10,10,00,02,00,10,10,10 DATA 10,00,00,00,00,00,00,00,00,10 DATA 10,00,00,00,00,00,00,00,00,10 DATA 10,00,00,00,00,00,00,00,00,10 DATA 10,00,00,00,00,00,00,00,00,10 DATA 10,00,00,00,00,00,00,00,00,10 DATA 10,00,00,00,00,00,00,00,00,10 DATA 10,00,00,00,00,00,00,00,00,10 DATA 10,00,00,00,00,00,00,00,00,10 DATA 10,10,10,10,10,10,10,10,10,10 -=***************************************> End of Code <***************************************=- The big difference in this program is the 3 different maps. To switch from map to map all I had to do was change m to the desired map number so that that map data was used. When you reach the end of the map it checks to see what map you are on and then send you to the map that you need to goto. You can have many more levels and to change to a different map you can change what m equals. eg instead of going to map 2 you could change the IF m = 1 THEN m = 2: GOTO redraw to IF m = 1 THEN m = 3: GOTO redraw This would take you to map 3 and put you ontop of a wall because map 3 was not designed to link to map 1. All ya have to do is change the map data to make it look like you can. Experiment with all of these and mix and match the map data use. This way you will be able to understand the code better and make better things. Try adding extra features to the programs like in the last one, try adding more maps. Make more tiles. Even try to make NPC's, people or monsters walk around on the map as well. I hope this has inspired you, or at the least made you consider making a text RPG, or anyother text game. I hope to release another tutorial on Editors or AI's next month. I can't believe I wrote all this in one afternoon. If you have any problems e-mail me at cant.get.nixon@gmail.com or vist Pure Text and post on the forum www.Pure-Text.com -Nixon