I'm working on a rudimentary roguelike game and thought i would share what i've done so far with this community.
It's a realtime strategy game in which the user needs to manage resources in order to grow a planetary colony and explore the planet before moving onto the the next planet. My aim is to make something super responsive and a little addictive, while allowing an interesting narrative emerge out of the gameplay. I have a playable version except for a few bugs and unfinished "launch" and "power managment" sections.
Eventually I want to code this completely in assembly in order to fit in more detail, graphics and sound. I currently have a BASIC framework of the game.
If you try running the BASIC code, note that you might need to press the keys a couple of times before the program registers it.
I think this is because my game loop is so long that it misses it, even though I try to capture the key press with peek 197 a few times during the loop. I need to buffer any input of the key somehow during the loop, and need to figure out how to do that as I think peek 197 just looks for if a key is pressed down at that moment?
So, my immediate tasks are in order of priority:
1. Capture key presses properly.
2. Create asm routines to draw the guages as i think this will capture the most time from game loop.
3. ASM routines for background processes i.e building things and calculating drain on vitals
4. once planet colonised, add series of planets as progressing "levels" using Fibonacci sequence
5. add complexity to random events and exploration
6. add graphics "monitor" which will display growing base, exploration animation and spaceship launch animation
I've been learning assembly, and I think I'm just about ready, and learning the CBM prg IDE however I'm stuck on CBM prg for a simple hello world tutorial! I've attached that code too, and cannot seem to see what is going wrong?
If anyone here has any feedback on the project, I would love your input.
Code: Select all
10 rem COLONY: A realtime roguelike game for the vic 20 8k+
20 rem by eoghan kidney
30 rem (c)2019
100 gosub 10000:goto 810
105 rem returning from exploration
110 if xp=1 OR xc=1 then return
120 on sc goto 1140,2005,2105,2215,2225
810 ?"{clear}":POKE 36878,10: poke 36879,10: rem start game with a sound
820 FOR T=210 TO 254
830 POKE 36874,T
850 FOR D=1 TO 2
860 NEXT D:NEXT T
870 POKE 36878,0
880 POKE 36874,0
900 rem (d)ay tp:temp (c)olonists (h)ab (l)food (lc)launch count (ox)ygen (fu)el
905 rem (w)ater (w)water ice (p)ower (s)ci-labs (r)overs (m)aterials (te)ch(micros) dr(o)nes
910 rem sol(a)r (b)atteries (g)ardens (f)orge sabat(i)er or(e) (mm)ars mapped
1000 D=234: tp=-20: C=1132: lc=0: X = RND(-TI) :ox=50: fu=50 : fl=0
1002 H=40+INT(RND(1)*60): L=40+INT(RND(1)*60): W=40+INT(RND(1)*60): P=40+INT(RND(1)*60): S=3: R=1
1005 M=34: te=12: O=3: A=23: B=32: G=10: F=4: I=5: e=0: mm=1
1006 hr=1:lr=1:wr=1:pt=-2:cr=25: rem hab rate, food rate, water, powerloss rate, colonist
1008 rem pl = hab power ps = food power pu = water power q=daytime mt=maxtime la=launchbool?
1010 pl=25:ps=25:pu=50:sc=1:uc=200:q=0:mt=100:la=0:pw=1:dn$="day": rem pw=power state dn=day/night mt=time rate(increase 4 difficulty)
1015 n$ = "welcome commander":pz=p: rem n$ = newsfeed
1025 gosub 1138
1050 rem update loop
1060 kb=peek(197): ?"{home}{space*3}{left*3}";kb;" ";q: rem buffer input state
1065 gosub 1125: gosub 1090: rem buffer vitals = power/water/food/habitat
1070 gosub 2500 : rem process changes
1080 gosub 1090: gosub 2600: gosub 1090: rem check for input, BG tasks, input check
1081 gosub 1110: rem update vital graph if changed
1083 gosub 1090
1085 goto 1050
1090 kc = peek(197):if kb<>kc then POKE36878,15: POKE36876,230: POKE36876,0: gosub 2260: rem key was pressed, goto input
1100 return
1110 if int(p)<>qp OR int(h)<>qh OR int(w)<>qw OR int(l)<>ql then gosub 2130
1120 return
1125 qp=int(p):qh=int(h):qw=int(w):ql=int(l): return
1138 sc=1: rem 1. monitor
1140 print"{clear}{white}{141} m a r s gov.81{141} systems online{141}{141} "C*10"colonists "
1150 print"{141} i:inventory{141}{141} a:activities"
1160 gosub 2130
1180 return
1999 rem /2.activities menu
2000 sc=2
2005 print"{clear}{white}{141}activities{141}{141}{reverse on}1{reverse off} mine for ore & ice{141}{reverse on}2{reverse off} repair habitat{141}{reverse on}3{reverse off} process ore{141}{reverse on}4{reverse off} harvest food{141}"
2010 print"{reverse on}5{reverse off} launch{141}{reverse on}6{reverse off} build{141}{reverse on}7{reverse off} divert power{141}{reverse on}8{reverse off} monitor{141}{reverse on}{blue}9{reverse off} explore{white}{141}"
2020 gosub 2130: return
2100 sc=3: rem /3. build menu
2105 print"{clear} resin";TAB(15);"{cm +}";m;"{141} tech";TAB(15);"X";te;"{141}"
2106 print" {purple}cost";TAB(15);"{cm +} X"
2107 for zx=0 to 8: print"{white}{141}{reverse on}"zx+1"{reverse off}"b$(zx+10);TAB(14);"{purple}"b%(zx*2);TAB(18);b%((zx*2)+1)"{white}";
2110 next zx
2115 print"{141}"
2120 rem display newsfeed
2130 print"{home}{down*15}{yellow}habi ";:na=qh:gosub2150:?"{141}{green}food ";:na=ql:gosub2150:?"{141}{blue}water";:na=qw:gosub2150:?"{141}{cyan}power";:na=qp:gosub2150
2135 print"{141}{white}"dn$;D"{141} {left*20}{red}"n$"{white}"
2138 if sc=4 then ?"{home}{down*3}{right*7}fff";fl
2140 return
2150 t=INT(na/8):tb=INT(((na/8)-t)*8):?" {left*12}";
2160 for xq=1 to t:?"{reverse on}{space}{reverse off}";:next xq:?ba$(tb);:return
2210 rem /4. power menu
2215 sc=4
2216 print"{clear}{141}sabatier plant{141}{141}";"fuel:";fl;"{141}produce:{141}1.rocket fuel:"fu"%{141}2.oxygen:"ox"%"
2217 print"{141}hit 1 to change{141}power state"pw
2218 gosub 2130
2219 return
2220 rem /5. inventory
2225 ?"{clear}{141} materials";TAB(15);"{cm +}";m;"{141} tech";TAB(16);"X";t;"{141}"
2230 for jj=0 to 8:?b$(10+jj);tab(16);ws(jj*4): next jj
2240 gosub 2130: return
2260 rem /intepret input
2275 a$=str$(sc)+str$(kc):rem combine sc number and input
2280 if a$=" 1 0" then gosub 2000
2282 if a$=" 2 0" then gosub 3000
2285 if a$=" 2 56" then gosub 3300
2288 if a$=" 2 1" then gosub 3600
2290 if a$=" 2 57" then gosub 3700
2300 if a$=" 2 2" then gosub 4000
2310 if a$=" 2 58" then gosub 2100
2320 if a$=" 2 3" then gosub 2210
2325 if a$=" 2 59" then gosub 1138
2328 if a$=" 2 4" then gosub 4200
2338 if a$=" 3 0" then bm = 0: gosub 5000
2348 if a$=" 3 56" then bm = 1: gosub 5000
2358 if a$=" 3 1" then bm = 2: gosub 5000
2364 if a$=" 3 57" then bm = 3: gosub 5000
2367 if a$=" 3 2" then bm = 4: gosub 5000
2368 if a$=" 3 58" then bm = 5: gosub 5000
2370 if a$=" 3 3" then bm = 6: gosub 5000
2380 if a$=" 3 59" then bm = 7: gosub 5000
2390 if a$=" 3 4" then bm = 8: gosub 5000
2395 if a$=" 4 0" then gosub 5500
2400 if kc=17 then gosub 2000
2410 if kc=12 then gosub 2220
2490 return
2500 rem process changes
2510 q=q+1: if q>mt then gosub 2530
2511 rem ?"{home}{right*16}"q:rem daytimer
2512 if dn$="day" AND q>(mt/2) then dn$="night": poke 36879,8: gosub 2120
2514 if dn$="night" AND q<(mt/2) then dn$="day" : poke 36879,10: gosub 2120
2515 if h<1 OR l<1 OR w<1 OR p<1 then gosub 11000: rem death by zero
2518 ifRND(1)<.001 then gosub 9000: rem check for random event
2520 if p>100 then p=100: gosub 2120
2521 if h>100 then h=100: gosub 2120
2522 if l>100 then l=100: gosub 2120
2523 if w>100 then w=100: gosub 2120
2526 pz=(pz+(pt/50)):h=h-ABS(hr*(pl/(250-ox))):w=w-ABS(wr*(pu/250)):l=l-ABS(lr*(ps/250)): rem update monitors INT(pt/500): CHECK INT LOGIC!!!!
2527 fl=fl+(1*(fu/25))
2529 return
2530 rem add a day
2540 tp=tp+INT(RND(1)*6)-3: rem change temp
2544 c=(c-cr)+INT(RND(1)*50): rem kill and birth colonists
2545 d=d+1: q=0 :p=p+INT((a+b)*0.03)
2552 if h<10 OR l<10 OR w<10 OR p<10 then n$="vitals low!":gosub 2120
2560 return
2600 rem process background activity i.e building things
2610 for x=0 to 7:xq=x*4: rem cycle through all items to check
2620 if ws(xq+3)=1 then ws(xq+2)=(ws(xq+2))-1:gosub2700: rem if item is building, remove time ledt
2630 nextx
2640 return
2700 if ws(xq+2)=0 AND ws(xq+3)=1 then ws(xq)=ws(xq)+1:ws(xq+3)=0: gosub 2800
2710 return
2800 n$="built "+b$(10+x):gosub 7000
2810 gosub 120:return
3000 rem mine
3005 if r<2 then n$="2 rovers needed": goto 3018
3010 q=q+10:w=w-2:p=p-5:x=INT(RND(1)*6)
3012 if RND(1)<0.5 then e=e+x:n$=str$(x)+"t ore mined":goto 3018
3015 n$=str$(x)+"t ice mined":w=w+(x*10)
3018 gosub 2120
3020 return
3300 rem repair
3310 q=q+20:w=w-2:p=p-5:x=INT(RND(1)*10):h=h+x:ifh>100thenh=100
3320 n$="hab now"+str$(h)+"%"
3325 gosub 2120
3330 return
3600 rem process
3605 if e<1 then goto 3645
3610 q=q+10:w=w-3:p=p-5:m=m+INT(e/2):e=0
3620 n$=str$(m)+"x new resin"
3625 gosub 2120
3635 return
3645 n$="no ore to process":goto 3625
3700 rem harvest
3710 q=q+10:w=w-5:x=INT(RND(1)*10):l=l+x
3715 n$="food now"+str$(l)+"%"
3718 gosub 2120
3720 return
4000 rem launch
4010 if la=0 then GOTO 4180
4015 if p>50 then n$="need more power"
4020 n$="launching..."
4030 gosub 7000: gosub 120
4170 return
4180 n$="no ship!":gosub 2120
4190 return
4200 rem explore
4201 tt=mt: mt=20: xp=0:xc=1: fx=1:sx=15
4202 poke 36878,10:poke36877,180
4205 ex$="setting out"
4210 ?"{clear}exploring...{141}{141}"mm"% mars mapped{141}{141}";ex$;"!{return}{return}press any key to{return}return to base"
4225 b=peek(197)
4228 gosub 1125
4230 gosub 2500
4235 gosub 2120
4236 gosub 4500: rem do sfx
4238 if xp=1 then xp=0: goto 4202
4240 if rnd(1)<0.05 then mm=mm+0.2: on INT(RND(1)*10) goto 4310, 4320, 4330, 4340, 4350, 4360, 4370, 4380, 4390, 4400
4250 a=peek(197)
4255 if a<>b then mt=tt:gosub 2000:poke 36877,0: xp=0: xc=0: return
4265 gosub 1110
4300 goto 4225
4310 ex$="found water": w=w+10: goto 4210
4320 ex$="colony established": c=c+100: goto 4210
4330 ex$="beautiful caves": goto 4210
4340 ex$="ancient structure": goto 4210
4350 ex$="invasive species": c=c-20: goto 4210
4360 ex$="curious dust": goto 4210
4370 ex$="more rocks": goto 4210
4380 ex$="mountain": goto 4210
4390 ex$="endless plain": goto 4210
4400 ex$="unpassable ridge": goto 4210
4500 if fx=0 then sx=sx+1
4510 if fx=1 then sx=sx-1
4520 if sx = 13 and fx=0 then fx=1
4530 if sx = 4 and fx=1 then fx=0
4540 poke 36878, sx
4550 return
5000 rem building (bm= item to build)
5015 mc=b%(bm*2):tc=b%((bm*2)+1)
5018 if ws((bm*4)+3)=1 then n$="in progress":goto 5034
5020 if mc>m AND tc>t THEN n$="under resourced"
5025 if mc>m THEN n$="need more mat."
5028 if tc>te THEN n$="need more tech"
5029 if mc<=m AND tc<=te THEN gosub 5040: rem if enough resources, then build
5034 gosub 2120: return
5040 n$="building "+b$(10+bm)+str$(bm)
5050 m=m-mc: te=te-tc
5051 gosub 5200: REM GO TO EXPERIMENTAL BUILDING
5052 ON bm+1 GOSUB 5070,5080,5090,5100,5110,5120,5130,5140,5150: rem build the thing
5055 gosub 2520: gosub 2100
5060 return
5070 o=o+1: return
5080 r=r+1: return
5090 a=a+1: return
5100 b=b+1: return
5110 g=g+1: return
5120 f=f+1: return
5130 i=i+1: return
5140 te=te+1: return
5150 H=H+20: return
5200 ws((bm*4)+1)=ws((bm*4)+1)+1
5205 ws((bm*4)+3)=1
5210 ws((bm*4)+2)=20: rem timeTaken 20 for all objects (temp)
5220 return
5500 rem sabatier (unfinished)
5510 pw=pw+1
5520 if pw>5 then pw=1
5530 if pw=1 then fu=100:ox=0: hr=hr+2
5540 if pw=2 then fu=75:ox=25: hr=hr+1
5550 if pw=3 then fu=25:ox=75
5560 if pw=4 then fu=0:ox=100: hr=hr-1
5562 if pw=5 then fu=0:ox=0: hr=hr-2
5565 gosub 2210
5570 return
6000 rem SFX for BAD
6010 ?"{clear}"
6060 FOR xx=15 TO 0 STEP -1
6070 gosub 6130: ? "{red}"n$
6080 NEXT
6090 POKE 36865,38: POKE 36864,12: POKE 36878,0
6100 POKE 36874,0: POKE 36875,0: POKE 36877,0
6105 poke 36879,10: FOR mx=0 TO 1000: NEXT
6110 gosub 120: return
6130 POKE 36878,xx: POKE 36877,200+xx*RND(1)
6140 POKE 36874,129: POKE 36875,190+xx
6150 POKE36865,38+4*(4*RND(l)-2)
6160 POKE36864,12+2*(2*RND(l)-2)
6170 IF xx=15 THEN POKE 36879,112: FOR mx=0 TO 100: NEXT
6180 POKE 36879,27
6190 return
7000 rem poke 36879,10:rem SFX for GOOD
7005 ?"{clear}"
7015 ? "{white}really "n$
7020 POKE36878,15
7030 FORfx=4TO0STEP-1:POKE36878,fx
7040 FORfy=1TO100:NEXT
7050 FORfz=220TO240:POKE36876,fz:NEXT:NEXT
7060 poke 36876,0
7070 poke 36878,0
7100 return
9000 rem random events
9010 x = INT(RND(1)*10)
9015 if x=0 then hr=hr+3: h=h-1: c=c-20: a=a-2: b=b-2
9025 if x=1 then wr=wr+3: g=g-1: cr=cr+20
9035 if x=2 then pt=pt+3
9045 if x=3 then pt=pt-1: c=c-5
9055 if x=4 then wr=wr-3: c=c+100: cr=cr-20
9065 if x=5 then hr=hr-3: cr=cr-10
9075 if x=6 then c=c-20
9085 if x=7 then c=c-5: p=p-2: r=r-1
9095 if x=8 then c=c-20
9098 if x=9 AND la>1 then return
9102 if x=9 then m=m+20:w=w+20:t=t+20:c=c+100:la=la+1
9110 n$=b$(x)
9115 if x>5 then gosub 7000:goto 9120
9118 gosub 6000
9120 gosub110:q=q+1000:xp=1:return
9999 end
10000 DATA "meteor hit!","disease!","dust storm!","riot","disappearances","rover crash!"
10010 DATA "med. discovery!","tech discovery!","celebration!","supply ship!"
10020 DATA "drone","rover","solar panels","batteries"
10030 DATA "growspace","forge","sab plant","tech","habitat"
10035 DIM b$(19)
10036 rem first 10 are random events, rest are buildable objects
10037 for x=0 to 18: read b$(x): next x
10038 rem below for each buildable item [(begin amount, material cost, tech cost),(),.]
10040 DATA 2,1,1,5,5,1,1,1,1,2,0,0,0,2,1,0,30,3,0,2,1,0,1,1
10045 DIM b%(23)
10050 for x=0 to 23: read b%(x): next x
10052 rem below for each buildable item [(number of, time remaining ,isBuilding?),(),.]
10055 DATA 3,0,0,0,0,0,0,0,23,0,0,0,32,0,0,0,10,0,0,0,4,0,0,0,5,0,0,0,12,0,0,0,2,0,0,0
10060 DIM ws(35)
10070 for x=0 to 35: read ws(x): NEXT X
10080 DIM ba$(7)
10085 rem below are characters for guages
10090 DATA " ","{cm g}","{cm h}","{cm j}","{cm k}","{reverse on}{cm l}{reverse off}","{reverse on}{cm n}{reverse off}","{reverse on}{cm m}{reverse off}"
10110 return
10500 rem end state
11000 poke 36877,0:?"{clear}the colony survived{141}"d-234"days of your{141}leadership."
11002 ?"yet without ";
11005 if p<1 then ? "power";
11006 if w<1 then ? "water";
11007 if l<1 then ? "food";
11008 if h<1 then ? "habitat"
11010 ?:?c*10;"perished"
11015 ?:?"{141}hit a key to try again"
11020 a=peek(197)
11025 if peek(197)<>a then clr: goto 100
11030 goto 11025
+++++++++++++++++++++++++++++++++++++++++++++++++++++
And here's the asm that i cant figure out why isnt working
+++++++++++++++++++++++++++++++++++++++++++++++++++++
Code: Select all
; 10 SYS (4864)
*=$1201
BYTE $0E, $12, $0A, $00, $9E, $20, $28, $34, $38, $36, $34, $29, $00, $00, $00
*=$1300
start LDX #$0
cycle LDA hworld,X
CMP #0
BEQ exit
JSR $FFD2
INX
JMP cycle
exit RTS
hworld text 'HELLO WORLD!',0
byte 0