I’m an artist now! There I said it, so it’s true! Who woulda thought it? Having spent almost my entire adult life so far, as a software engineer, I decided I needed a change. Actually, it’s not quite that cut and dry, and in fact my current artistic distraction began as a tech project. Essentially, I was exploring neural networks and deep learning, and I stumbled into the whole art side of NNs. My deep learning sandbox inexorably became an art tool set, and now I spend my days making strange, abstract art. I am what is called, a Generative Artist, and I make abstract art using all sorts of cool software I’m actively programming and developing. You can see some examples of the art I make below. I also have an Instagram account for all this stuff, so feel free to check it out.
I come from a family of artists and creativity runs deep in the genes, but being the “technical” one in the family, my work and interests were always considered not so much artistic, but still creative. This new art thing is a perfect mix of skills and interests, and my programming chops have enabled me to understand and make some nice tools and tech that allows me to express myself in a cool and unique way. It just goes to show that life is unpredictable, and how ironic it can be too. I am legally blind, and I decide to be an artist and make visual art. It’s fucking hilarious really!
After my lazy weekend working on the high score stuff, which I ultimately shit-canned trying to keep the game in scope, I got my head down to finish up the pick-ups and power-ups in the game. I’ve been working on in-game pick-ups the past couple of days. Pick-ups are bonus items like secondary weapons, power-ups, and points, that various enemies drop or get spawned by the game arena.
I don’t have an artist for this project, so I’m doing all the art myself. When I say “art”, I use the term very loosely indeed. If you knew me better, you’d understand why this is actually hilarious. There are a few special people out there who can do multiple things well. All singing, all dancing, plus juggling too.. “Triple-threats” or those unique one man bands who can draw and code and design in equal measure. I hate them all, because I can only do one thing well, and that’s code. I used to say that I pissed code when I was younger, because it flowed out of me so well, I guess. Now I’m old and things are slower and more mellow, I like to say I can code til the cows come home.
Anyway, what the hell has any of that go to do with pick-ups and power-ups, I hear you ask? Well not much actually, so lets get back to the point.
The game has a primary weapon, which is upgraded through power-up that the actual game arena will spawn. The player can rush to collect these, increasing the utility and power of their primary weapon each time.
There are collectible secondary weapons that are dropped by enemies the player kills during the game. These include a shield, homing missiles, gravity well, slow-mo, and “Death Blossom”. There are an equal number of offensive and defensive (CC) secondary weapons and they’re upgraded by collecting the “Power Crystals” that enemies drop when they’re killed. For example, each time the homing missile is upgraded, the number of missiles fired increases by one (up to a maximum of 4), with the final upgrade making the missile’s explosion have a blast radius that will kill multiple enemies, rather than just the one it hits. Additionally, there are pick-ups that will clear the warp and weapons cooldowns, bonus points, and “Super Power Crystals”, that give a big boost to your secondary weapon.
All of this work is complete (99%), and is ready to go into the game, and so the rest of this week is all about secondary weapons, because I need to code the weapons that the power-ups give you 😀 I’ve been looking forward to coding these for a couple of weeks because I think they’ll be fun to do and to tweak to get right. So next up is the “Wingman” weapon, which gives you a number of semi-intelligent helpers that protect you and help kill stuff too. A “Slow-mo” weapon that, well, slows everything down for a time. A “Gravity Well” weapon that bends bullet trajectories and swallows unwary enemies. And a “Death Blossom” weapon that is a weapon of last resort, and can only be used if you’re about to die. Obviously an homage to The Last Starfighter.
As part of this new game, I’m planning on having a global high score system where players from anywhere can post their initials and have them displayed across all game instances, and on the game website. Technically, doing that is pretty straight forward. You have some code running on a web server that receives and processes HTTP requests, and depending on what the service does, it’ll stash data in a database or maybe produce an image or whatever, and return some response to the requester. Simple in concept, but to build and architect a service that can scale and handle abuse, is nuanced and not at all simple.
I’m not going to get into architecture or scaling here, because at the end of the day, how I solve that is really based on the resources I have available and my personal framework or scripting language preferences for the back end. And that stuff is ideology and whatever I use there will be someone with a man-bun telling me I should use the latest new Google framework. Meh! The actual web service I am building is very, very simple and a regular LAMP stack will work just fine for my requirements. So that stuff aside, this leaves security and abuse. How do I stop some malicious asshole from spamming the service, trying to break it for the lulz, or maybe, more innocently trying to cheat the high score system?
There is no simple answer or solution to this, certainly not with the resources I have available. Even if my service requires strong authentication, where the user is registered, and uses a token, etc., the nature of a web service is its availability and ease to hit with requests. Any script-kiddie could write a script to send requests at a high frequency. Anyone could sniff the request being sent by the game and figure out how to form their own requests and spam or cheat the service. Shit, they can just send any old stream of garbage to the service, and it would need to handle it. So there’s no way to stop someone from spamming your service, but you can mitigate some of this by using mature and readily available software packages that most hosting providers have available. Something like Fail2ban, that scans logs looking for unusual and potentially malicious activity and bans IPs. This is already installed and working on my web server, but has a potential issue for a game related web service, where people may be behind proxies used by multiple people, meaning if there’s one bad actor who decided to get themselves banned, all people on that proxy will also get banned. Not ideal! If there’s no way to stop spamming, how do we stop the spamming from breaking or bringing the service to its knees? A server IP ban at the firewall (Fail2ban), will stop any blocked traffic from ever reaching and hitting the service, so that will be in place. My hosting service have their own rules and layers of protection on their networks and can help mitigate persistent attacks if needed. Basically this is too big a problem for me to solve well given my resources, so I’ll have to make do as best I can.
Then there’s cheating and just people trying to break shit. That is guaranteed to happen, as there are a lot of twats out there, so it’s important to make sure the web service is as bulletproof as possible. It must be able to handle with grace, any data that’s thrown at it. This just comes down to best practices and carefully scrubbing and cleaning any data the service will ultimately use. Requests must be authenticated to make sure they are coming from the actual game rather than a stand alone script. Tracking abusive or cheater IPs in another database and soft banning them. A possible option here, to take the validation load off the main DB, would be to hide the actual service behind another layer that uses a NoSQL DB to stash requests while some code chews on it in the background, and sorts the good from the bad, eventually sending good data to the actual service to be stashed as a purely internal, hidden operation. This approach could also provide a simple mechanism for metering traffic allowed into the service.
Tracking and catching cheats is more of an algorithm problem than anything else. The first thing would be to define what cheating or suspicious activity would look like. Knowing the rules of the game, it’s fairly easy to come up with a set of criteria that describes a valid high score. Is it impossibly high? Is it impossibly high for the length of time played or the wave/level reached? Are there too many requests from the same IP or user in a short period of time? Etc. Etc. There are all sorts of ways to break the problem down, and simply requires some thoughtful consideration and careful implementation.
Another thing that can be done to deter the casual or wannabe hacker, is to obfuscate the request to the web service, with encryption or misdirection, and protect it from manipulation with a checksum. This just makes it harder and more time consuming for someone to figure out, and because most griefers are lazy little oiks, they won’t bother. I don’t think this game or web service will be worth expending real energy on to hack.. LOL, who am I kidding!? When has that ever stopped someone from trying to break shit just because.
So there you have it. There’s a lot about web services that needs to be considered. If I was building this in a corporate or studio environment, I would definitely be more meticulous and “enterprise” in my approach, especially with the additional resources that would be available. I’m a one man band, building a silly little twin stick shooter on zero budget, so it’ll be as good as I can manage. Additionally, none of this is written in stone. I may just shit-can the global high scores idea completely if it proves too hard/risky, and I can’t come up with something reasonable, or it fails hard in test.
Of course if I was smart, there’s always a service like PlayFab where ALL that unpleasant crap is just done and handled for you. This is a very real option, provided you can justify the expense. As a small, one-man-band, hobbyist game developer, without a budget or any real hope the game will make any significant money, committing to a recurring expense is a tough pill to swallow. Also, because I’m a bit weird, I like to program stuff like this. I even used to do it for money at one time.
Anyway, I got super bored over the weekend working on this stuff, so have basically pushed the remaining tasks on the high score system (namely the in game GUI stuff), to the “back lot”. I got a big chunk of it out the way, and I’m looking forward to some fun coding next week making game pickups.
Honestly, I didn’t get much done today. It’s Saturday and there are a ton of distractions all vying for my attention. I was supposed to be working on my high scores web service (which is mostly done), and the in-game UI and high score table functionality (which is NOT mostly done), but I ended up messing with camera code, playing in the back yard in the sunshine, and watching Davie504 and The Proper People videos on Youtube. Bah!
But wait, there’s an important lesson to be had here. A learning opportunity, if you will.
First, be realistic about working weekends, especially after a long, busy week where all you really want to do is veg out and put your feet up. Rest is really important!
Second, don’t be hard on yourself if this kind of thing happens. If it happens a lot, then yeah give yourself a good kicking or something, but once in a while is OK. It’s not like any of this is actually important or anything, so just enjoy your choices and get back to it ASAP.
Because the world needs another grumpy old game developer blogging about his game dev escapades, and because I happen to be developing a game right now, AND because I’m stuck in my house hiding from COVID-19, I’ve decided to do a dev blog. Hooray! Over the next few months, you can follow along as I slowly lose my sanity trying to build and release my latest game, “Enemy Wave”.
The game is a twin stick shooter, in the old-school arcade coin-op vein. Basically a no-fuss, fast-paced, bullet-hell, survival shooter, full of crazy enemies and weapons. I’ve no clue if it’ll turn out any good or not, but either way, I’ll have a good time making it. And at my age, that’s really all that matters. I’ll share some video when I have somethng to show, and as soon as I have something playable, I’ll post a demo so you can make up your own mind.
You may be wondering who the hell I am, and why you should care about what I’m doing. First off, you absolutely shouldn’t care about what I’m doing, because I’m not solving hunger or poverty or anything important like that. As far as who I am, I’m Chris (obviously), and I’m a really old games programmer. I’m so old, I learned about “Ferrite Core Memory”, and “Punch Cards” at college, and had my first game published in 1983! Crazy huh?! I’ve done tons of games over the years, and I’ll probably talk about some of that silliness too at some point.
This is possibly the most boring post ever, but I wanted to preserve this silliness for posterity.
This is the listing for the first commercially published game I ever made. It’s called “Pub Quest”, it’s 100% BASIC, and I wrote it in 1983. The game was published by a Dream Software based in Basingstoke. They were a nice bunch and I met them once at ECTS way-back-when. I wrote another text adventure called “Mad House”, that used a disk based database (very swish) and was massive with 100s of locations. Sadly Dream Software when bust before it got published and the game was lost forever.
Looking through the listing, all I can say is, it’s pretty crap code. Enjoy!
1 rem "tttttt ***** (c) c.p.shrigley 1983 ***** 2 rem "tttttt 3 rem "tttttt 5 poke 774,248: poke 775,252: poke 808,230 7 poke 53272,21: poke 53280,5: poke 53281,11: print chr$(8): gosub 8000: ss=1: bc=15 9 poke 650,128: print"“": poke 53281,1: poke 53280,15: dim co$(13): sc=0: nn=30: t=0 10 poke 53272,22: print chr$(8): r=1: dim r$(87),ob$(32),o$(32),o(32),de$(87): gosub 5000 20 print"“" 30 if (r=32 or (r>=23 and r<=30) or r>38) and t=0 then kk=1: goto 50 40 kk=0 50 if kk=1 then print"£qqGosh isn't it dark in here.": goto 155 90 if f2=1 then 155 100 print"You're "; r$(r) 101 gosub 16010 110 print"‘qYou can see : q" 120 for i=1 to nn: if o(i)=r then print ob$(i): f1=1 130 next: if f1=1 then f1=0: goto 150 140 print"Nothing of any use to you here.": goto 151 150 print"qhere.": f1=0 151 print"•qExits are : "; 152 gosub 2900 155 if r=31 then print"qYou have failed. Thanks for playing.": goto 2408 156 if du>2 then poke 198,0: gosub 4600 158 if ti$>tl$ then tl=1 159 if tl=1 then tl=0: gosub 3300 160 print"£qqWhat shall I do ?": print">–"; 165 in$="": bb$="" 170 gosub 20000 175 if rt=1 then rt=0: goto 159 180 for i=1 to len(in$): if mid$(in$,i,1)=" " then ch=i: l1=1 190 next: if l1=0 then 196 195 bb$=mid$(in$,ch+1,(len(in$)-ch+1)): l1=0: in$=left$(in$,(len(in$)-len(bb$))-1) 196 gosub 22000 200 if in$="n" or in$="north" then a=1: gosub 1000: goto 999 210 if in$="s" or in$="south" then a=3: gosub 1000: goto 999 220 if in$="e" or in$="east" then a=5: gosub 1000: goto 999 230 if in$="w" or in$="west" then a=7: gosub 1000: goto 999 240 if in$="take" or in$="get" then gosub 1100: goto 999 241 if in$="eat" then gosub 4900: goto 999 242 if in$="drive" then gosub 10020: goto 999 243 if in$="pay" then gosub 10700: goto 999 244 if in$="steal" then print"I'm no thief!": f2=1: goto 999 245 if left$(bb$,3)="cup" then gosub 4650: goto 999 246 if bb$="car" then gosub 4700: goto 999 247 if left$(bb$,3)="com" then gosub 4710: goto 999 248 if in$="climb" then gosub 4800: goto 999 249 if in$="jump" then gosub 4850: goto 999 250 if in$="i" or in$="inv" or in$="inventory" then gosub 1200: goto 999 251 if (in$="walk" and r=6) and pb=1 then r=7: un=0: f2=0: sc=sc+100: goto 999 260 if in$="look" or in$="l" then f2=0: goto 999 270 if in$="push" or in$="press" then gosub 1300: goto 999 280 if in$="throw" then gosub 1400: goto 999 290 if in$="open" then gosub 1500: goto 999 300 if in$="exam" or in$="examine" then gosub 1600: goto 999: 310 if left$(in$,3)="unl" then gosub 1700: goto 999 320 if in$="drop" then gosub 1800: goto 999 330 if bb$="torch" then gosub 1900: goto 999 380 if bb$="n" or bb$="north" then a=1: gosub 1000: goto 999 390 if bb$="s" or bb$="south" then a=3: gosub 1000: goto 999 400 if bb$="e" or bb$="east" then a=5: gosub 1000: goto 999 410 if bb$="w" or bb$="west" then a=7: gosub 1000: goto 999 420 if in$="buy" then print"£qWhat wiv' ? Buttons ?": f2=1: goto 999 430 if in$="time" then gosub 2000: goto 999 440 if bb$="glove" then gosub 2100: goto 999 450 if bb$="something" or in$="something" then gosub 2130: goto 999 460 if bb$="bed" then gosub 2200: goto 999 470 if in$="read" then gosub 2300: goto 999 480 if in$="quit" then gosub 2400: goto 999 490 if in$="help" then gosub 2600: goto 999 500 if in$="rub" then gosub 2700: goto 999 510 if in$="light" then gosub 3500: goto 999 520 if in$="tie" then gosub 3600: goto 999 530 if in$="fill" then gosub 3700: goto 999 550 if in$="wear" then gosub 3800: goto 999 560 if in$="save" then gosub 4000: goto 999 570 if in$="load" then gosub 4100: goto 999 580 if in$="list" then gosub 4300: goto 999 590 if in$="function" or in$="func" then gosub 4400: goto 999 600 if in$="border" then gosub 7500: goto 999 610 if in$="screen" then gosub 7530: goto 999 620 if in$="command" then gosub 7550: goto 999 630 if in$="smash" or in$="break" or in$="kill" then gosub 7800: goto 999 650 if in$="score" then gosub 7950: goto 999 670 if in$="freeze" then gosub 10500: goto 999 998 print"I'm afraid I didn't understand that": du=du+1: f2=1: goto 90 999 du=0: goto 30 1000 a$=mid$(de$(r),a,2): ct=ct+1: if lf=1 then 1002 1001 if ct>25 and t=1 then tc=1: t=0: ct=0: print"£qYour light source has run out.": f2=1: return 1002 if val(a$)=0 then p=1: goto 1027 1003 if (r=6 and hh=1) and a=3 then un=0: goto 1022 1004 if (r=6 and hh<>1) and a=3 then 1027 1005 if (r=2 or r=20) and a=7 then gosub 6020: goto 1013 1006 if ((r=2 or r=20) and un=1) and a=7 then goto1022 1007 cc=0 1008 if t=0 then ct=0 1009 if r=3 and a=7 then gosub 6000: goto 1013 1010 if (r=3 and un=1) and a=7 then goto1022 1011 gosub 3000: if bo=1 then bo=0: goto 1027 1012 cc=0 1013 if cc=1 then cc=0: goto 1022 1014 if cc=2 then cc=0: goto 1022 1015 if cc=3 then cc=0: if un<>1 then 1030 1016 if (r=61 and a=5) and pe=0 then print"q£You've fallen down the crevasse.": r=31: goto 155 1017 if (r=73 and so=0) and a>2 then print"£qYou've been asphixiated by the gas.": r=31: goto 155 1018 if (o(12)=0 and r=39) and a=7 then gosub 3900 1019 if (r=32 or (r>=23 and r<=30) or r>38) and t=0 then mo=mo+1: print"q£It's dark,you might fall" 1020 if mo>4 then mo=0: print"£qOh dear,It looks as though you've fallen": r=31: goto 155 1022 if un=1 and r=3 then sc=sc+50 1023 r=val(a$) 1024 f2=0: return 1027 if p=1 then p=0: print"—qI'm afraid you can't go that way": f2=1: return 1028 if r=6 then print"£That's to dangerous.You might get splattered.": f2=1: return 1029 if r=19 then f2=1: return 1030 print"—qYou've just walked into a locked door": f2=1: return 1100 if bb$="spider" and r=62 then gosub 3080: f2=1: return 1110 for p=1 to nn: if o$(p)=bb$ and o(p)=r then dd=p: goto 1160 1130 next 1131 for p=1 to nn: if o$(p)=bb$ and o(p)<>r then print"—I don't see one here.": f2=1: return 1132 next 1135 if bb$="" then bb$="thingy" 1140 print"—To ";in$;" a ";chr$(34);bb$;chr$(34);" is beyond my power.": f2=1: return 1160 if no>5 then print"—I can't carry anything else.": f2=1: return 1161 if o$(dd)=bb$ and no<=5 then print"O.K.": ok=1: no=no+1 1163 if ok=1 then ok=0: o(dd)=0: f2=1: return 1165 print"—qWhat's a ";chr$(34);bb$;chr$(34): f2=1: return 1200 ff=0: print"—“You're carrying : q" 1210 for i=1 to nn: if o(i)=0 then print ob$(i): ff=1 1220 next 1230 if ff=0 then print"nothing at all.": f2=1: return 1240 if ff=1 then ff=0: f2=1: return 1300 if bb$="button" then 1320 1310 print"£Wow, that really helped.": f2=1: return 1320 if (o(9)=0 and r=6) and wg=1 then goto 1360 1325 if r=6 then goto 1330 1326 print"£qI don't see a button here.": f2=1: return 1330 print"£“You press the red button and a nasty poison spike sticks into" 1340 print"your thumb.You fall to the floor unconsious." 1350 r=31: goto 155 1355 hh=0: f2=1: return 1360 print"you press the red button and a little sign lights up above your head 1370 print"It says ‘r'WALK NOW'’" 1380 pb=1: hh=1: f2=1: sc=sc+500: return 1400 if bb$="" then print"£qThrow what ";: input"]]]*";bb$: print 1401 rn=8+(int(rnd(1)*8)+1) 1402 if bb$="slab" and (r<>18 and r<>33) and o(3)=0 then o(3)=rn: print"O.K.": f2=1: return 1403 if (r=44 or r=72) and bb$="canister" then gosub 3090 1404 if ca=1 then ca=0: f2=1: return 1405 if r=18 and bb$="slab" and o(3)=0 and cv=0 then goto 1470 1407 if r=33 and bb$="slab" and o(3)=0 and cj=0 then goto 1490 1415 for i=1 to nn: if bb$=o$(i) and o(i)=0 then bb=i: s=1 1420 next 1425 if s<>1 then 1440 1430 s=0: gosub 1492: o(bb)=r: print"O.K.": no=no-1 1431 if bb=4 then t=0 1432 if bb=5 then t=0 1433 if bb=26 then so=0 1439 f2=1: return 1440 print"£I can't throw something I haven't got.": f2=1: return 1470 print"£“The paving slab lands in the mine field. There is a deafening "; 1480 print"explosion and rubble showers down all around.": o(16)=r: et=1: cv=1 1485 if et=1 then et=0: sc=sc+500: f2=1: return 1490 print"“The paving slab rips into the side of the shed leaving a gaping hole" 1491 o(15)=r: de$(33)="22350000": sc=sc+500: cj=1: f2=1: return 1492 if bb$="hook" or bb$="rope" then 1494 1493 f2=1: return 1494 if ((o(19)=0 and o(11)=0) and pe=1) and r=61 then 1496 1495 o(19)=r: o(11)=r: pe=0: f2=1: return 1496 print"£qThe hook and rope sails through the air and catches on an outcrop "; 1497 print"of rock on the far side of the cravass." 1498 print"qIt looks safe to cross." 1499 sc=sc+200: f2=1: return 1500 if bb$<>"door" then 1520 1501 if un=1 then goto 1700 1502 if bb$="door" and o(1)=0 or o(2)=0 then print"£qTry unlocking it first.": gg=1 1505 if gg=1 then gg=0: f2=1: return 1510 if bb$="door" and o(1)<>0 or o(2)<>0 then print"£qYou could unlock it IF you had a KEY" 1515 f2=1: return 1520 if bb$<>"book" then print"£You can't open a ";bb$;".": f2=1: return 1521 if bb$="book" and o(8)=0 then z=1: print"£qThe book falls open and you see the word" 1522 if z=1 then print" rTOILET’ IS A RELIEVING WORD.": sc=sc+100: f2=1: return 1530 print"£qYou don't have a book.": f2=1: return: 1540 f2=1: return 1600 if bb$="self" or bb$="yourself" or bb$="you" then 1620 1601 if bb$="me" then print"œI seem to be a COMMODORE 64.": f2=1: return 1602 if bb$="card" then 1692 1604 if bb$="button" then 1651 1605 if bb$="bar" then 1680 1607 for i=1 to nn 1608 if o$(i)=bb$ and o(i)<>0 then print"œYou haven't got a ";bb$: f2=1: return 1609 next 1610 for i=1 to nn 1611 if o$(i)=bb$ and o(i)=0 then print"œThe ";bb$;" looks normal to me.": f2=1: return 1612 next 1613 for i=1 to nn 1614 if o$(i)=bb$ and o(i)<>r then ew=1 1615 if ew=1 then ew=0: print"œI can't examine something I havn't got": f2=1: return 1616 next: 1617 if bb$="" then print"œEverything looks very normal to me.": f2=1: return 1618 print"The ";bb$;" looks rather like a ": print bb$;" to me.": f2=1: return 1620 if pp=0 then print"qYou begin to rummage through your q pockets, "; 1630 if pp=0 then print"'WHAT'S THIS' you cry, q 'A KEY ?'" 1632 if pp=1 then print"qœYou rummage through your pockets and find nothing.": po=1 1633 if po=1 then f2=1: po=0: return 1640 o(2)=0: sc=sc+300: pp=1 1645 f2=1: return 1650 if lc=1 then print"šIt's already unlocked.": f2=1: return 1651 if r<>6 then print"I don't see a button here.": f2=1: return 1660 print"A torn note hangs from the button.It reads : 'FOR SAFE CROSSING "; 1670 print"WEAR ....' The rest of the note is missing.": f2=1: return 1680 if r<>2 then print"œqThere isn't a bar here.": f2=1: return 1681 if r=2 then print"£qThere's a sign on the bar that says : ": br=1 1682 if br=1 then br=0: goto 1690 1690 print"œq]]]]]]]r'WE TAKE AMERICAN EXPRESS'’": sc=sc+100: f2=1: return 1692 if o(13)=0 then print"£qThe word r'BARCLAYCARD'’ is written across it": cr=1 1694 if cr=1 then cr=0: f2=1: return: 1695 if cr=0 then print"You haven't got a card.": f2=1: return 1696 gosub 1684: return 1700 if un=1 then 1705 1701 if r=2 and o(1)=0 then un=1: goto 1720 1702 if r=20 and o(2)=0 then un=1: goto 1730 1703 if r=2 or r=20 then 1710 1704 if r<>2 or r<>20 then print"šDon't be silly.": f2=1: return 1705 print"œIt has already been ";in$;"ed.": f2=1: return 1710 print"œYou don't have the key.": f2=1: return 1720 print"—The door swings open to reveal the gentstoilets": sc=sc+200: f2=1: return 1730 print"—The door swings open to reveal a large hallway": f2=1: return 1800 if bb$="" then print"£qDrop what ";: input"]]]*";bb$: print 1801 if (r=44 or r=72) and bb$="canister" then gosub 3120 1802 if cx=1 then cx=0: f2=1: goto 155 1804 if (bb$="bottle" and r=25) and o(7)=0 then gosub 2140 1805 if bb$="glove" then wg=0: goto 1810 1807 if bb$="all" then gosub 4950: f2=1: no=0: return 1810 for i=1 to nn: if o$(i)=bb$ and o(i)=0 then dd=i: jp=1 1814 next: 1816 if jp=1 then jp=0: goto 1840 1818 print"£I can't drop something I haven't got.": f2=1: return 1840 o(dd)=r: f2=1: print"O.K.": no=no-1 1845 if r=84 then f2=1: return 1850 if dd=4 then t=0 1851 if dd=5 then t=0 1852 if dd=26 then so=0 1853 if r>38 and r<86 then print"£The ";o$(dd);" is carried away ": et=1 1854 if et=1 then et=0: print"into the depths of the sewer system by the ";: et=1 1855 if et=1 then et=0: print"strong flow of sewage.": o(dd)=38+int(rnd(1)*45)+1 1856 if r=86 then print"£The ";o$(dd);" is lost in the ": et=1 1857 if et=1 then et=0: print"thick branches.": o(dd)=85 1860 return 1900 if tc=1 then print"£qYou can't do that with a melted torch.": f2=1: return 1905 if (in$="on" and o(4)=0) and t=1 then 1992 1906 if in$="on" and o(4)=0 then 1950 1910 if (in$="off" and o(4)=0) and t=0 then 1995 1912 if in$="off" and o(4)=0 then 1970 1920 if in$="light" and o(4)=0 then 1990 1930 if (in$="on" or in$="off" or in$="light") and o(4)<>0 then tu=1 1932 if tu=1 then tu=0: print"£qYou don't have the torch.": f2=1: return 1940 print"£qYou can't do that with a torch": f2=1: return 1950 print"£qO.K. the torch is now on.": t=1: f2=1: return: 1970 print"£qO.K. the torch is now off.": t=0: f2=1: ct=0: return 1990 print"£qYou hear a strange sizzleing noise and your torch melts in your hands." 1991 tc=1: t=0: f2=1: ct=0: ob$(4)="a melted torch": return 1992 print"£qThe torch is already on.": f2=1: return 1995 print"£qThe torch is already off.": f2=1: return 2000 print"œqqYou've been playing : " 2010 ho=val(mid$(ti$,1,2)) 2020 mi=val(mid$(ti$,3,2)) 2030 print"—q";ho;" HOURS & ";mi;" MINUTES.": f2=1: return 2100 if wg=1 and in$="wear" then print"ŸYou're already wearing it.": f2=1: return 2102 if in$="wear" and o(9)=0 then wg=1: print"£qYou are now wearing the glove.": ww=1 2105 if ww=1 then ww=0: sc=sc+200: f2=1: return 2110 gosub 9000: return 2130 if r=25 then print"The tramp smiles and asks for a drink.": so=1: sc=sc+200: f2=1: return 2140 if so=1 then print"The tramp is very happy and lets you pass.": r=36: sc=sc+200: return 2150 print"The tramp doesn't want a drink YET.": f2=1: return: 2200 if in$="enter" and r=30 then 2240 2210 if in$<>"exit" then gosub 9000: f2=1: return 2215 if ob=1 then print"£qYou're not in bed.": f2=1: return 2220 if ib=1 and r=30 or r=84 then ob=1: print"You leave the bed after a refreshing sleep." 2222 sc=sc+200: o(21)=30: r=30 2230 f2=1: return: 2240 if ib=1 then print"£qYou lasy thingy ! You're not sleeping again.": f2=1: return 2250 if o(8)=0 then ib=1: print"You get into bed and settle down to sleep": r=84: f6=1 2255 if f6=1 then f2=1: sc=sc+50: f6=0: return 2260 print"£qYou get into the bed only to find a hugesnake keeping you company." 2270 print"The snake strikes and you pass out.": r=31: goto 155 2300 if bb$="book" then gosub 1500: f2=1: return 2310 gosub 9000: f2=1: return 2400 print"“œqARE YOU SURE YOU WANT TO QUIT ?" 2402 input qu$ 2404 if left$(qu$,1)="y" then 2408 2406 if left$(qu$,1)="n" then f2=1: return 2408 print"qqœr <ANY KEY TO CONTINUE> ’" 2409 get a$: if a$="" then 2409 2410 print"“" 2420 gosub 7950: 2450 gosub 2000: goto 4500 2500 if th<>1 then p=1: return 2600 if r=61 then print"œqrTry for the long shot.’": f2=1: return 2610 if r=44 or r=72 then print"œqrBandit to rid the sewer.’": f2=1: return 2620 print"œqrWho's playing this game,me or you ?’": f2=1: return 2700 print"—Nothing happened.": f2=1: return 2900 g=1: for i=1 to 8 step 2: qw$=mid$(de$(r),i,2) 2910 if val(qw$)<>0 then print d$(g);",";: f7=1 2920 g=g+1 2930 next: if f7=0 then print"none "; 2940 f7=0: print".": f2=1: return 3000 if r=33 and o(15)<>33 and a=3 then bo=1: return 3001 if r=18 and o(16)<>18 and a=3 then x=1: print"“£qYou enter the mine field detonating a" 3002 if x=1 then x=0: goto 3004 3003 goto 3006 3004 print"mine.You explode into little bits and make a terrible mess." 3005 r=31: goto 155 3006 if r=25 and (so=0 or o(7)<>r) and a=7 then print"£qThe tramp won't let you.": goto 999 3007 for i=1 to nn: if o(i)=0 then ci=ci+1 3010 next 3020 if (r=19 and a=5) and ci>3 then print"“q£A little man dressed in a boiler suit";: ws=1 3025 if ws=1 then ws=0: ci=0: goto 3030 3026 sc=sc+100: ci=0: goto 3064 3030 print" jumps out of the hole and says : ": 3040 print"q'YOU CAN'T ENTER HERE WITH MORE THAN THREE OBJECTS'" 3050 print"qthen he jumps back in muttering" 3060 print"something about safety precautions.": f2=1: bo=1: return 3064 if (r=44 or r=72) and pc=0 then print"£qYou're attacked by savage rats": r=31: goto 155 3070 f2=1: return: 3080 print"£qYou try to ";in$;" the spider,but it ";in$;"s you instead.": r=31: return 3090 if o(21)=0 then f=1: print"£qYou throw the smoke canister into the mass of rats,"; 3095 if f=0 then return 3100 print"it explodes into a cloud ofsmoke and the rats flee in all " 3110 print"directions.They are still here but it's safe to pass.": ca=1: pc=1 3115 o(21)=85: f2=1: f=0: return 3120 print"£qYou drop the canister and it envelopes you in choking smoke.": r=31 3130 cx=1: return 3300 print"£“I'm afraid your time is up.The debt collectors are here to take"; 3310 print" you away.Youhave failed.Bad luck.": r=31: dh=1: goto 155 3500 if nm=1 and bb$="lamp" then print"£qYou have nowt to light it with.": f2=1: return 3510 if ((bb$="lamp" and o(5)=0) and o(6)=0) and r>=39 then 3590: 3515 if (bb$="lamp" and o(5)=0) and o(6)=0 then 3550 3520 if (bb$="matches" and o(6)=0) and nm=0 then 3580 3530 print"£qI'm no arsonist.": f2=1: return 3550 if t=1 then print"£qThe lamp is already lit.": f2=1: return 3560 print"£qO.K. The lamp is now lit.": t=1: sc=sc+100: f2=1 3580 print"£qA blaze of light and no matches left.": nm=1: f2=1: o(6)=85: return 3590 print"£qAs you light the lamp you ignite a cloudof smelly gas." 3592 print"£You explode into little bits.": r=31: goto 155 3600 if (bb$="rope" and o(11)=0) and o(19)=0 then 3650 3610 if (bb$="hook" and o(11)=0) and o(19)=0 then 3670 3620 print"£qI see nothing to tie the ";bb$;" to.": f2=1: return 3650 if pe=1 then gosub 9050: return 3660 print"£qThe rope is now securely tied to the hook.": pe=1: sc=sc+200: f2=1: return 3670 if pe=1 then gosub 9050: return 3680 print"£qThe hook is now securely tied to the rope.": pe=1: f2=1: return 3700 if lf=1 then print"£qThe lamp is already full.": f2=1: return 3705 if o(22)=0 and o(5)=0 then 3750: 3710 if o(22)=0 then print"£qYou can't fill something you haven't got": f2=1: return 3720 if o(5)=0 then print"£qYou've got nowt to fill it with.": f2=1: return 3730 print"£qFill what ?": f2=1: return 3750 print"£qThe lamp is now full of oil."jf=1: lf=1: sc=sc+500: f2=1: ct=0: return 3800 if in$="wear" then 3830 3810 gosub 9000: return 3830 if o(26)=0 then so=1: print"£qO.K. You're now wearing the suit.": sc=sc+200: f2=1: return 3840 print"£qYou don't have a ";bb$;".": f2=1: return 3900 for i=1 to nn: if o(i)=0 then df=df+1 3901 next 3902 if df>1 then f4=1: df=0 3903 if f4=1 then f4=0: goto 3905 3904 df=0: f2=1: return 3905 print"“œqAnother little man jumps out from behind a wall an says : " 3910 print"q£'Ahhh ! It's you again,I'm afraid you can only take one object "; 3920 print"out of the sewers with you'œq" 3930 print" then he jumps back and dissapears.": f2=1: df=0: goto 999 4000 print"“Do you want to save current game (Y/N)" 4010 input yn$: if yn$="y" then 4026: 4015 if yn$="n" and dh=1 then 4095 4020 if yn$="n" then f2=0: return 4025 goto 4000 4026 print"qInsert game tape into the tape & press r*’" 4027 get sp$: if sp$="" then 4027 4028 if sp$<>"*" then 4027 4030 print"Please type in name of current game : " 4035 in$="" 4040 gosub 20000 4041 print"q£Is ";chr$(34);in$;chr$(34);" the correct title (Y/N) ?" 4042 get yn$: if yn$="" then 4042 4043 if yn$="y" then 4050 4044 if yn$="n" then in$="": print"‘ ‘‘‘‘‘";: goto 4030 4045 if yn$<>"y" or yn$<>"n" then 4042: 4050 open 1,1,1,in$ 4060 gosub 30050 4065 for i=1 to 8: print#1,f$(i): print#1,f(i): next 4070 for i=1 to nn 4080 print#1,o(i) 4090 next: print#1,"stop": close1 4093 print"qqqq]]]]]]]]]O.K. GAME ";chr$(34);in$;chr$(34);" SAVED" 4094 gosub 17000 4095 if dh=1 then print"qq]]]]]]]]]]]]]]]goodbye!!": poke808,237: end: rem poke115,96 4096 gosub 17100 4099 f2=1: return: 4100 print"“Do you want to load a game (Y/N)" 4110 input yn$: if yn$="y" then 4126 4120 if yn$="n" then f2=0: return 4125 goto 4100 4126 print"qInsert game tape into the tape & press r*’" 4127 getsp$: if sp$="" then 4127 4128 if sp$<>"*" then 4127 4130 print"Please type in name of game to load : " 4135 in$="" 4140 gosub 20000 4141 print"q£Is ";chr$(34);in$;chr$(34);" the correct title (Y/N) ?" 4142 get yn$: if yn$="" then 4142 4143 if yn$="y" then 4150 4144 if yn$="n" then in$="": print"‘ ‘‘‘‘‘";: goto 4130 4145 if yn$<>"y" or yn$<>"n" then 4142 4150 open 1,1,0,in$ 4160 gosub 30000 4165 for i=1 to 8: input#1,f$(i): input#1,f(i): next 4170 for i=1 to nn 4180 input#1,o(i) 4190 next: input#1,a$: if a$="stop" then close1 4191 gosub 17000 4195 print: print"qqqq]]]]]]]]O.K. GAME ";chr$(34);in$;chr$(34);" LOADED" 4196 gosub 17100 4199 f2=1: return 4230 return 4300 for i=1 to 8: if f(i)=1 then print"‘<R> ";: gb=1 4304 if gb=0 then print" "; 4305 print rm$(i);f$(i) 4310 if gb=0 then print; 4315 if gb=1 then gb=0 4320 next 4330 f2=1: return 4400 print"“" 4405 input"œDefine function key (1-8)";a 4410 if a>8 or a<1 then print"q£function keys 1 to 8 only please.q": goto 4405 4420 input"œqType in required function ";f$(a) 4430 input"qDo you want auto-return (Y/N) ";yn$ 4440 if left$(yn$,1)="y" then f(a)=1: f2=1: return 4450 f$(a)=f$(a)+" ": f(a)=0: f2=1: return 4500 input"qDo you want to play again ]]]*";pl$ 4510 if pl$="y" then 4530: 4520 if pl$="n" then dh=1: goto 4000 4530 clr: restore: goto 1 4600 print"qLook mate,either you're being very silly,or you haven't "; 4605 print"got the slightest idea of how to play an adventure game." 4610 print"q‘Now which is it (rS’illy - rN’o idea) ?" 4615 in$="": gosub 20000 4620 if left$(in$,1)="s" then gosub 20500: f2=1: du=0: return 4630 if left$(in$,1)="n" then gosub 21000: f2=1: du=0: return 4640 print"£q So you are being silly.": in$="s": goto 4620 4650 if lc=1 then 1705 4651 if r<>3 then print"—I don't see a cupboard.": f2=1: return 4652 if in$="open" then print"—The cupboard door won't move.": f2=1: return 4654 if in$="unlock" and o(2)=0 then 4670 4656 if in$="unlock" and o(2)<>0 and o(1)<>0 then print"—You don't have the key.": f2=1: return 4657 if in$="unlock" and o(1)=0 then print"—The key doesn't fit.": f2=1: return 4658 if left$(in$,4)="exam" then et=1 4660 if et=1 then et=0: print"—The cupboard seems to be locked.": f2=1: return: 4662 gosub 9000: f2=1: return 4670 de$(3)="00000232": r$(3)=r$(3)+".The cupboard isopen.": sc=sc+100 4675 print"—O.K. The cupboard is now unlocked.": sc=sc+500: f2=1: lc=1: return 4700 if r<>5 and r<>4 then print"—I don't see a car here.": f2=1: return 4701 if r=4 and left$(in$,4)="exam" then print"—The car is big,black and shiny.": f2=1: return 4702 if left$(in$,4)="exam" then print"—There is a glove compartment here.": f2=1: et=1 4704 if et=1 then et=0: o(27)=r: f2=1: return 4706 gosub 9000: f2=1: return 4710 if o(27)<>r then print"—I can't see a compartment here.": f2=1: return 4712 if in$="open" and tf=0 then print"—A torch falls out.": f2=1: tf=1: o(4)=r: sc=sc+200: return 4714 if left$(in$,4)="exam" and tf=0 then print"—There's something in there.": f2=1: return 4715 if left$(in$,4)="exam" and tf=1 then print"—There's nothing in there.": f2=1: return 4716 if in$="break" or in$="smash" then print"—You little vandal !": f2=1: return 4717 if in$="open" and tf=1 then print"—The glove compartment is already open.": f2=1: return 4718 gosub 9000: f2=1: return: 4800 if r=38 and bb$="tree" then print"O.K.": r=86: sc=sc+300: f2=1: return 4848 print"—My name is not Spider man !": f2=1: return 4850 if r=86 and o(30)=38 then print"—You sail through the air and land safely";: et=1 4852 if et=1 then et=0: print"on the mattress.": r=38: f2=1: return 4854 if r=86 and o(30)<>38 then print"—You sail through the air and land SPLATT";: et=1 4856 if et=1 then et=0: print"on the ground below.": r=31: goto 155 4858 if r>38 then print"—œDon't you think that's a bit dangerous.": f2=1: return 4859 print"I don't see anything to jump.": f2=1: return 4900 if bb$="apple" and o(29)=0 and r=86 then et=1: jm=0 4902 if et=1 then et=0: print"—You take a big,greedy byte from the apple";: et=1 4904 if et=1 then et=0: print" but you suddenly notice from the corner of your";: et=1 4906 if et=1 then et=0: print" eye something that must have come from a horror";: et=1 4908 if et=1 then et=0: print" film...ARGHHH !!You scream as the worm";: et=1: 4910 if et=1 then et=0: print" crawls towards you.Your stomach suddenly ";: et=1 4911 if et=1 then et=0: print"decides to come up for a drop of fresh air.";: et=1 4912 if et=1 then et=0: print"You release another agonizing scream as you crash ";: et=1 4915 if jm=1 then jm=0: print"to the floor clutching your throat.": jm=1 4916 if jm=1 then jm=0: r=31: goto 155 4917 if et=1 then et=0: print"Through the branches of the tree. The ";: et=1 4918 if et=1 then et=0: print"very,very hard ground rushes towardsyou ";: et=1 4919 if et=1 then et=0: print"at a very,very alarming rate.You hitthe ";: et=1 4920 if et=1 then et=0: print"ground with a bone crunchin' THUD!!!‘‘": r=31: goto 155 4930 if bb$="apple" and o(29)=0 then et=1: jm=1: goto 4900 4940 print"œYou'll surely break your teeth!": f2=1: return 4950 et=0: for i=1 to nn: if o(i)=0 then o(i)=r: et=1 4952 next: 4953 if r>38 and r<77 and et=1 then goto4956 4954 if et=1 then et=0: print"œO.K. "; 4955 goto4970 4956 if et=1 then et=0: print"q—All your objects are carried off by the ";: et=1 4958 if et=1 then et=0: print"strong flow of sewage,into the depths ofthe";: et=1 4960 if et=1 then et=0: print" sewer system.": et=1 4962 if et=1 then et=0: for i=1 to nn: if o(i)=r then o(i)=38+int(rnd(1)*38)+1: et=1 4964 next 4966 if et=1 then et=0: f2=1: return 4970 if et=0 then print"—You're not carrying anything.": f2=1: return 4999 5000 r$(1)="standing on a pavement running east-west along a busy main road." 5002 r$(1)=r$(1)+"To the north there is a pub which looks very welcoming" 5004 r$(2)="standing inside the pub next to the bar,there's a door to the west" 5005 r$(2)=r$(2)+" and asign above the bar that says: "+chr$(13) 5006 r$(2)=r$(2)+"r'WELCOME TO THE CHEQUERED FLAG INN'’" 5007 r$(3)="in the gents toilets,on the west wall there is a cupboard" 5008 r$(4)="standing next to a parked car ": 5010 r$(5)="inside the parked car.The car is very expensive looking" 5012 r$(6)="standing in front of a pelican crossing there is a red button " 5014 r$(7)="on the other side of the busy main road" 5016 r$(8)="standing on a very rough piece of pavement": 5018 r$(9)="on a desolate waste ground, all about is horrid, bleak wilderness" 5020 r$(10)=r$(9): r$(11)=r$(9): r$(12)=r$(9): r$(13)=r$(9): r$(14)=r$(9) 5022 r$(15)=r$(9): r$(16)=r$(9): r$(17)=r$(9) 5024 r$(18)="next to a sign which says : " 5025 r$(18)=r$(18)+" qr'DANGER MINE FIELD'’": 5026 r$(19)="standing next to a huge bomb crater all about there is rubble" 5028 r$(20)="standing in front of an old, dirty, derelict house" 5029 r$(20)=r$(20)+".A huge doorway looms ominously before you." 5030 r$(21)="standing in the front garden. (Gosh what a mess)" 5032 r$(22)="standing in the back garden, to the south there is an old shed" 5034 r$(23)="inside the house standing in a grotty hallway." 5036 r$(24)="in a big living room there are cobwebs everywhere (Yuk)" 5038 r$(25)="nearly in a huge kitchen. There is a tramp sitting here, he says" 5040 r$(25)=r$(25)+" 'Hello,say something to me and I'll let you pass'" 5042 r$(26)="standing at the bottom of a small flight of stairs" 5044 r$(27)="on a small landing at the top of the flight of stairs you've just " 5046 r$(27)=r$(27)+"come up": 5048 r$(28)="inside a big white bathroom " 5050 r$(29)="standing in a small,pokey,little bedroom there is a bed " 5052 r$(29)=r$(29)+"in the middle,youmust be feeling very,very tired" 5054 r$(30)=r$(29) 5056 r$(31)="lying in the middle of the busy main road " 5058 r$(31)=r$(31)+"There seem to be strange marks across your body " 5060 r$(32)="standing inside a big cupboard " 5062 r$(33)="standing outside the shed, there doesn't seem to be an entrance" 5064 r$(34)="looking inside a deep, dark pocket" 5065 r$(38)="standing in the pub's car park" 5066 r$(35)="inside the old garden shed" 5068 r$(36)="in the big kitchen, the tramp is smiling" 5070 ob$(1)="a shiny brass key": o$(1)="key": o(1)=86 5080 ob$(2)="a dull brass key": o$(2)="key": o(2)=34: 5090 ob$(3)="a piece of broken paving slab": o$(3)="slab": o(3)=8 5100 ob$(4)="a torch": o$(4)="torch": o(4)=85 5110 ob$(5)="an old lamp": o$(5)="lamp": o(5)=35 5120 ob$(6)="a box of matches": o$(6)="matches": o(6)=11 5130 ob$(7)="a bottle wrapped in brown paper": o$(7)="bottle": o(7)=19: 5140 ob$(8)="a book called : 'BEDTIME STORIES'": o$(8)="book": o(8)=36 5145 ob$(9)="a strong leather glove": o$(9)="glove": o(9)=32 5146 d$(1)="north": d$(2)="south": d$(3)="east": d$(4)="west": 5150 de$(1)="02310406" 5160 de$(2)="00010003" 5170 de$(3)="00000200" 5180 de$(4)="00050001": 5190 de$(5)="04000000" 5200 de$(6)="00070138" 5210 de$(7)="06090800" 5220 de$(8)="31000007" 5230 de$(9)="07121000" 5240 de$(10)="00131109" 5250 de$(11)="00140010" 5260 de$(12)="09151300": 5270 de$(13)="10161412" 5280 de$(14)="11170013" 5290 de$(15)="12001620" 5300 de$(16)="13001715" 5310 de$(17)="14180016" 5320 de$(18)="17190000" 5330 de$(19)="18003900": 5340 de$(20)="21221523" 5350 de$(21)="00200000" 5360 de$(22)="20330000" 5370 de$(23)="24262025" 5380 de$(24)="00230000": 5390 de$(25)="00222336" 5400 de$(26)="23000027" 5410 de$(27)="29302628" 5420 de$(28)="00002700" 5430 de$(29)="00270000" 5435 de$(30)="27000000": 5440 de$(31)="00000000" 5450 de$(32)="00000300" 5460 de$(33)="22000000" 5470 de$(34)="00000000" 5480 de$(35)="33000000" 5490 de$(36)="00002500" 5500 de$(37)="00000000" 5510 de$(38)="00000600": 5520 r$(39)="in the smelly,horrid,dark sewers" 5530 for i=40 to 80: r$(i)=r$(39): next 5540 ob$(10)="a crisp new fifty pound note": o$(10)="note": o(10)=67 5550 ob$(11)="an old oily rope": o$(11)="rope": o(11)=76 5560 ob$(12)="a cheque": o$(12)="cheque": o(12)=64: 5570 ob$(13)="a credit card": o$(13)="card": o(13)=65 5580 ob$(14)="a huge diamond": o$(14)="diamond": o(14)=59 5582 ob$(15)="a hole in the shed": o$(15)="shriggles": o(15)=85 5584 ob$(16)="a broken sign": o$(16)="shriggles": o(16)=85 5585 ob$(17)="a diamond studded bracelet": o$(17)="bracelet": o(17)=26 5586 ob$(18)="a Swiss-army combination knif e": o$(18)="knif e": o(18)=21 5587 ob$(19)="a grappling hook": o$(19)="hook": o(19)=80: 5588 ob$(20)="an old rusty shovel": o$(20)="shovel": o(20)=29: 5589 ob$(21)="a smoke canister": o$(21)="canister": o(21)=85 5600 de$(39)="41004019" 5602 de$(40)="42000039" 5604 de$(41)="43394200": 5606 de$(42)="00400041" 5608 de$(43)="45004441" 5610 de$(44)="46006543" 5611 de$(45)="66434600" 5612 de$(46)="00444845": 5614 de$(47)="49464800" 5616 de$(48)="50000047" 5618 de$(49)="51475000" 5620 de$(50)="51480049" 5622 de$(51)="53005249" 5624 de$(52)="54736851" 5626 de$(53)="00515400" 5628 de$(54)="00525653": 5630 de$(55)="57545600" 5632 de$(56)="58540055" 5634 de$(57)="00555800" 5636 de$(58)="40565957" 5638 de$(59)="00600058": 5640 de$(60)="59006100" 5642 de$(61)="00626360" 5644 de$(62)="61000000" 5646 de$(63)="64636361": 5648 de$(64)="00630000" 5650 de$(65)="00000044" 5652 de$(66)="00450067" 5654 de$(67)="00006600" 5656 de$(68)="00006952": 5658 de$(69)="00007068" 5660 de$(70)="00717469" 5662 de$(71)="70000072" 5664 de$(72)="00777173" 5666 de$(73)="52007200" 5668 de$(74)="74757470": 5670 de$(75)="76757574" 5672 de$(76)="76007675" 5674 de$(77)="72000078" 5676 de$(78)="00797700" 5678 de$(79)="78008000" 5680 de$(80)="00000079": 5685 gosub 8200 5690 print"–“Please type in your time limit qq (r 1 2 OR 3 HOURS ’ "; 5695 print" Default = 1 hour) " 5700 in$="": q$="": print"q]? ";: gosub 20000 5710 if left$(in$,1)="1" then ti$="000000": tl$="010000": return 5720 if left$(in$,1)="2" then ti$="000000": tl$="020000": return 5730 if left$(in$,1)="3" then ti$="000000": tl$="030000": return 5740 ti$="000000": tl$="010000": return 5999 end 6000 if o(2)=0 then cc=1: return 6010 cc=3: return 6020 if o(1)=0 and un=1 then cc=2: return 6030 cc=3: return: 7000 print"“]]]]]]]]]]]r CONGRATULATIONS ’" 7010 print"‘qq]]]]You've managed to solve my first" 7015 print"q adventure 'PUB QUEST'" 7020 print: print"q You have done very well to have solved" 7030 print"q this adventure,if not a little lucky" 7040 print"q We will meet again and next time I " 7050 print"q won't be so friendly" 7060 sc=15000: goto 2408 7400 print"“sqqqqqqqqqq]]] who's a naughty pirate then ?": poke115,96: end 7500 print"—New border colour (0 - 15) ";: input"]]]*";bc 7510 poke 53280,bc: f2=1: return 7530 print"—New screen colour (0 - 15) ";: input"]]]*";ss 7535 poke 53281,ss: f2=1: return 7550 for i=1 to 13: print co$(i): next 7560 f2=1: return 7800 if bb$="" then bb$="thingy" 7805 print in$;"ing a ";bb$;" is a symptom of madness": mp=mp+1: bb$="" 7810 if mp>2 then mp=0: goto 7830 7820 f2=1: return 7830 print"£It seems you are being taken somewhere rather unpleasant by a "; 7840 print"group of men dressed in white coats..." 7850 print"‘You're feeling very dqiq]]zqzq]y." 7860 r=31: goto 155 7950 print"qYour score is ";sc;" out of 15000.": 7952 if sc>15000 then print"—qHey thats an amazing score...": et=1 7954 if et=1 then et=0: print"qšHave you been cheating ?": f2=1: return 7960 print"q‘Your rating is : q" 7962 if sc<=5000 then print"10th..I'd take up crochet if I were you": f2=1: return 7964 if sc<=6000 and sc>5000 then print"9th..Terrible - very amature.": f2=1: return 7966 if sc<=7000 and sc>6000 then print"8th..Very bad - are you being silly ?": f2=1: return 7968 if sc<=8000 and sc>7000 then print"7th..bad - You're getting better.": f2=1: return 7970 if sc<=9000 and sc>8000 then print"6th..not bad - You're getting better.": f2=1: 7972 if sc<=10000 and sc>9000 then print"5th..slightly good - very slightly.": f2=1: return 7974 if sc<=11000 and sc>10000 then print"4th..pretty good - well played.": f2=1: return 7976 if sc<=12000 and sc>11000 then print"3rd..very good - well played.": f2=1: return 7978 if sc<=13000 and sc>12000 then print"2nd..excellent - You're nearly there": f2=1: return 7980 if sc<=15000 and sc>13000 then print"1st..Super - I take back the crochet bit": f2=1: return 7990 f2=1: return 8000 gosub 9100: if in=1 then in=0: return 8001 print"“eq]]]]]]]]]rwelcome to 'pub quest'’qqž": 8002 yu$="deep in the bowels of the local sewer": gosub 8100 8004 yu$="system lies the ultimate challenge": gosub 8100 8006 yu$="it is your job to find the means": gosub 8100 8008 yu$="to pay off your debt at your local": gosub 8100 8010 yu$="pub (pause for fanfare)...i wish": gosub 8100 8011 yu$="you good speed and much luck.": gosub 8100 8012 print"qq]]]]]]]]]]]‘renjoy yourself!!!’" 8020 print"šqqr just tickle the <space bar> to play "; 8030 get im$: if im$="" then 8030 8040 if im$<>" " then 8030 8050 return 8100 lx=len(yu$): if lx/2<>int(lx/2) then yu$=yu$+" ": lx=lx+1 8110 for i=1 to lx/2: print tab(20-i)mid$(yu$,lx/2+1-i,1)chr$(145) 8120 print tab(19+i)mid$(yu$,lx/2+i,1)chr$(145): next: print"q": return 8200 r$(61)="standing on the edge of a huge crevasse.You can just make out the" 8205 r$(61)=r$(61)+" dim outline of an archway on the far side. There doesn't" 8210 r$(61)=r$(61)+" seem to be any way across." 8215 r$(44)="in a cavernous chamber.All about there are red eyes and white " 8220 r$(44)=r$(44)+"fangs.I'm afraid you're slightly surrounded by rats." 8225 r$(72)=r$(44)+" again.": 8230 r$(77)="in the sewer workers rest station" 8232 r$(84)="lying in a nice comfortable bed." 8335 for i=78 to 80: r$(i)=r$(77): next 8340 ob$(22)="a rusty old oil can": o$(22)="can": o(22)=50 8345 ob$(23)="a cloud of obnoxious gas": o$(23)="shriggles": o(23)=73 8350 ob$(24)="a smoke canister": o$(24)="canister": o(24)=71 8355 ob$(25)="a massive,big hairy spider": o$(25)="spider": o(25)=62 8360 ob$(26)="a Sewer-Protect-o-Suit.": o$(26)="suit": o(26)=57 8370 f$(1)="north": f(1)=1: rm$(1)="f1 - " 8380 f$(3)="south": f(3)=1: rm$(3)="f3 - " 8390 f$(5)="east": f(5)=1: rm$(5)="f5 - " 8400 f$(7)="west": f(7)=1: rm$(7)="f7 - " 8410 f$(2)="look": f(2)=1: rm$(2)="f2 - " 8420 f$(4)="take ": f(4)=0: rm$(4)="f4 - ": 8430 f$(6)="drop ": f(6)=0: rm$(6)="f6 - " 8440 f$(8)="inventory": f(8)=1: rm$(8)="f8 - " 8450 is$(0)="piss": is$(1)="fuck": is$(2)="sod": is$(3)="bollocks" 8460 is$(4)="shit" 8470 co$(1)="help - computer might give a tip." 8475 co$(2)="quit - terminate adventure." 8485 co$(3)="examine - localised search." 8490 co$(4)="screen - change screen colour." 8495 co$(5)="border - change border colour." 8500 co$(6)="command - list out these commands." 8505 co$(7)="list - list out function keys." 8510 co$(8)="function - define a function key.": rem* 8515 co$(9)="load - load saved game off tape." 8520 co$(10)="save - save game to tape." 8525 co$(11)="inventory - list objects you have." 8530 co$(12)="time - prints time elapsed." 8535 co$(13)="freeze - stops game." 8540 ob$(27)="a glove compartment": o$(27)="shriggles": o(27)=85: 8542 ob$(28)="a big apple tree": o$(28)="shriggles": o(28)=38 8544 ob$(29)="a big juicy apple": o$(29)="apple": o(29)=86 8546 r$(86)="at the top of a huge apple tree." 8548 ob$(30)="an old mattress": o$(30)="mattress": o(30)=5 8999 return 9000 print"£qHow do you ";in$;" a ";bb$" ?": f2=1: return 9050 print"£qIt's already tied.": f2=1: return 9100 rem * * * * * * * * * * * 9104 poke 53281,11 9105 print"“qqqqq]]]]]]]]]]]]]]]r‘pub quest’Ÿ" 9110 print"qq]]]]]]]]written & programmed by" 9115 print"q]]]]]]]]]]]c.p.shrigley 1984" 9117 print"q]]]]]]]]]]] for " 9120 print"eq ²`I U`® 9122 print" } }reamJ`Ioftware 9124 print" ±`K``````K``````` 9125 print"ž ················· 9130 a$="instructions (y/n) ? ": po$="esqqqqqqqqqqqqqqqqqqqq]]]]]]" 9135 for i=1 to len(a$): get i$ 9140 print po$right$(a$,len(a$)-i)left$(a$,i): 9145 if i$="y" then return 9150 if i$="n" then in=1: return 9151 if i$="" then 9155 9155 for t=1 to 70: next t,i: goto 9135 10020 if bb$="car" and r=5 then print"‘You haven't got the ignition key.": f2=1: return 10022 if r<>5 then print"—I don't see a ";bb$;" here.": f2=1: return 10024 print"—That's beyond even me!": f2=1: return 10500 print"£O.K. Game frozen - press a key to cont.": tt$=ti$ 10510 get a$ 10520 ti$=tt$: if a$="" then 10510 10530 f2=1: return 10700 if r<>2 then print"‘I see nobody to pay.": f2=1: return 10702 in$="": print"œqWhat with ? ";: gosub 20000 10704 bb$=in$ 10706 if bb$="cheque" and o(12)=0 then goto 10750 10708 if bb$="card" and o(13)=0 then goto 10800 10709 if bb$="note" and o(10)=0 then goto 10850 10710 if bb$="cheque" or bb$="card" or bb$="note" or bb$="money" then et=1 10720 if et=1 then et=0: print"You don't possess any ";bb$: f2=1: return 10740 if et=0 then print"£The barman doesn't trade in trinkets.": f2=1: return 10750 print"œThe barman grabs the cheque and says : ": 10755 print"q—";chr$(34);"That'll do nicely!";chr$(34) 10760 gosub 15000 10765 print"‘r <ANY KEY TO CONTINUE> ’" 10770 get a$: if a$="" then 10770 10775 goto 7000 10800 print"œThe barman looks at the card and says : " 10805 print"q—";chr$(34);"Sorry mate,this is a Barclay card.";chr$(34) 10808 gosub 15000 10810 f2=1: return 10850 print"œThe barman looks at the note and says : ": 10855 print"q—";chr$(34);"Sorry mate,this note's a forgery.";chr$(34) 10860 gosub 15000 10865 f2=1: return 15000 print"œqHe rushes off to serve another customer.": return 16000 poke 850,asc("("): poke 680,111: poke 186,1: return 16010 if jf=1 then return 16020 if ct>20 and t=1 then tc=1: t=0: lf=0: ct=0: print"q£Your light source just ran out" 16030 return 17000 poke 680,111: poke 850,asc("("): return 17100 print"qqr PRESS <SPACE BAR> TO RESUME GAME ’" 17110 get sp$: if sp$="" then 17110 17120 if sp$<>" " then 17110 17130 return: 20000 get q$: if q$="" then q$="–" 20020 if cf=1 then print"r¦’"; 20030 if cf>2 then cf=0: print"¦";: goto 20045 20040 cf=cf+1 20045 if in$="" and q$=" " then 20000 20050 qq=asc(q$): ll=len(in$) 20060 if pos(io)>39 then print" œqHey! You'll blow my memory capacity": rt=1: return 20070 if qq=32 then 20195 20080 if qq=20 and ll>0 then in$=left$(in$,ll-1): print q$;: goto 20000 20090 if qq=20 and ll<1 then 20000 20100 if qq=13 and ll<1 then 20000 20110 if qq=13 and ll>0 then print".";q$: return 20120 if q$="…" then print f$(1);: in$=f$(1): q$="": if f(1)=1 then print chr$(13): return 20130 if q$="†" then print f$(3);: in$=f$(3): q$="": if f(3)=1 then print chr$(13): return 20140 if q$="‡" then print f$(5);: in$=f$(5): q$="": if f(5)=1 then print chr$(13): return 20150 if q$="ˆ" then print f$(7);: in$=f$(7): q$="": if f(7)=1 then print chr$(13): return 20160 if q$="‰" then print f$(2);: in$=f$(2): q$="": if f(2)=1 then print chr$(13): return 20170 if q$="Š" then print f$(4);: in$=f$(4): q$="": if f(4)=1 then print chr$(13): return: 20180 if q$="‹" then print f$(6);: in$=f$(6): q$="": if f(6)=1 then print chr$(13): return 20190 if q$="Œ" then print f$(8);: in$=f$(8): q$="": if f(8)=1 then print chr$(13): return 20192 if qq<48 or qq>90 then 20000 20195 if ch$=" "andq$=" " then 20000 20200 if q$<>"" then print q$;: in$=in$+q$: ch$=q$ 20210 goto 20000 20500 print"]qqœLook I can be silly to......": 20510 poke 53270,3 20520 for i=1 to 2000: next i 20530 poke 53281,6: poke 53280,14: poke 53270,8 20540 print"š“sq **** COMMODORE 64 BASIC V2 ****" 20550 print"q 64K RAM SYSTEM 38911 BASIC BYTES FREE "; 20560 du=0: print"qREADY.": poke 198,0 20570 get rr$ 20580 if cf=4 then print"r ’"; 20590 if cf>8 then print" ";: cf=0: goto 20600 20595 cf=cf+1 20600 if rr$<>"" then print"qqr‘Fooled you!’": poke 53281,ss: poke 53280,bc: return 20610 goto 20570 21000 print"I understand commands of two words. The first has to be a verb"; 21010 print" and the second a noun.": print"qE.g. GO WEST or TAKE BUCKET etc." 21020 print"q‘I also know special word such as : ": 21030 print"œqLOOK,INVENTORY,TIME,FUNCTION,LIST,LOAD, SAVE,HELP and COMMAND." 21040 print"qTRY THEM!!!" 21050 print"qAlso try to examine objects." 21060 poke 198,0: print"qqrš PRESS <SPACE> TO CONTINUE GAME ’" 21070 get a$: if a$="" then 21070 21080 if a$<>" " then 21070 21090 return 22000 for i=0 to 4: if is$(i)=in$ then goto 22020 22010 next 22015 return 22020 print"—You mucky beast! Wash your mouth out!" 22030 goto 159: 30000 input#1,r: input#1,t: input#1,so: input#1,ti$: input#1,tl$: input#1,no: input#1,un: input#1,sc 30010 input#1,ct: input#1,tc: input#1,wg: input#1,pe: input#1,ib: input#1,ob: input#1,pc: input#1,ca 30020 input#1,cx: input#1,dh: input#1,nm: input#1,lf: input#1,bo: 30030 return 30050 print#1,r: print#1,t: print#1,so: print#1,ti$: print#1,tl$: print#1,no: print#1,un: print#1,sc 30060 print#1,ct: print#1,tc: print#1,wg: print#1,pe: print#1,ib: print#1,ob: print#1,pc: print#1,ca 30070 print#1,cx: print#1,dh: print#1,nm: print#1,lf: print#1,bo 30080 return
Following on from my previous post about hacking the dark theme on VS 2017, I thought I’d share another useful trick for making the WordPress Admin Dashboard nice and dark and easy on the eyes. There are various addons for Chrome that will let you invert the screen (Deluminate), or modify a page’s CSS (Stylebot), but none really fully work the WordPress Dashboard for various reasons.
So, enter Stylish, a really cool addon that allows you to wholesale replace the CSS for a site or page or domain. There are tons of user made themes being shared, and you can get dark versions of most of the major sites. It’s easy to create your own styles for your own needs too.
This is how to turn all your WordPress dashboards into a beautiful, restful and dark experience.
I run a high contrast Windows theme because I have crappy eyesight. I also program for a living and use Microsoft Visual Studio. Visual Studio has a rather lovely “Dark” theme that suits my tired old eyes very well. Unfortunately, Microsoft won’t let me use their nice “Dark” theme, because someone at Microsoft thinks they know what I want, better than I know myself. Instead, Microsoft forces Visual Studio to use their special “High Contrast” theme. The theme dropdown in the options is disabled and font/color styling is limited to a handful of colors.
So what’s the problem with that, you ask? I mean,I’m happy to use the high contrast theme elsewhere in Windows, so what’s the big deal? For starters, their “High Contrast” theme is terrible. There is no syntax coloring or styling. It is plain, white text on a black background. It is a goddamn travesty. But the thing that bugs me most is, someone made a decision to take this choice away from me, making my work harder, and forcing me to endure a sub-optimal experience, reserved only for visually impaired users. Bravo Microsoft. Your good intentions kinda suck.
It’s not just me. Lots of people have the same problem, and not just VI users either. Here’s Microsoft’s official stance on this long existing problem..
Thank you for your feedback! The Visual Studio team has determined that this issue will not be addressed in the upcoming release. We understand the desire to have VS use a different theme from the system. To support customers who rely on high contrast and give them a single experience, we believe the the accessibility for visual Studio is paramount in this instance. We will continue to evaluate it for future releases. Thank you for helping us build a better Visual Studio!
So basically they’re saying “tough shit”.
So what is a programmer to do? Well there is a registry hack that I’ve used for a few generations of Visual Studio (like I said this is not a new issue). The hack essentially overwrites the crap “High Contrast” theme with the lovely “Dark” theme in the registry.
UPDATED – Confirmed working on VS 2019 Community and others..
Simplified instructions (old instructions below)
Close Visual Studio (if open).
Press Windows + R, and type regedit in the text box and click OK. This will run RegEdit!
Click on HKEY_USERS, and select File -> Load Hive.
Navigate to this location; C:\Users\<username>\AppData\Local\Microsoft\VisualStudio\16.0_????????
Select “privateregistry.bin”, and give the new Hive a nice name, like “VS2018PrivateRegistry” (without quotes).
You will now see the loaded Hive under HKEY_USERS node, and you can navigate to the key here; HKEY_USERS\VS2019PrivateRegistry\Software\Microsoft\VisualStudio\16.0_????????_Config\Themes\
Right click and export this key; HKEY_USERS\VS2019PrivateRegistry\Software\Microsoft\VisualStudio\16.0_????????_Config\Themes\{1ded0138-47ce-435e-84ef-9ec1f439b749}
Open the new, exported .reg file in your favorite text editor.
Find and replace the GUID of the “Dark” theme, with the GUID of the “High Contrast” theme. Find: ({1ded0138-47ce-435e-84ef-9ec1f439b749}) and Replace with: ({a5c004b4-2d4b-494e-bf01-45fc492522c7})
Save the edited .reg file and double click it to import back into the registry.
Unload the Hive; File -> Unload Hive. Important otherwise VS won’t run.
Fire up Visual Studio and you should now have the Dark Theme activated. Note: The theme selector in preference will still be disabled.
Export this registry key: HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0_Config\Themes{1ded0138-47ce-435e-84ef-9ec1f439b749} (this should the key of the Dark theme)
In the exported file replace the GUID of the Dark Theme ({1ded0138-47ce-435e-84ef-9ec1f439b749}) with the GUID of the High Contrast theme ({a5c004b4-2d4b-494e-bf01-45fc492522c7}):
Import the reg file
This worked like a charm up until Visual Studio 2017, but they have moved the config settings out of the registry and into %AppData%. The config is stored in a private registry that can be loaded and edited in RegEdit. The themes are stored in the private registry and can be edited the same way as the old, working hack.
Fortunately, you can use regedit.exe to load a private hive. You need to select the HKEY_USERS node, and click the File > Load Hive… menu. You select the privateregistry.bin file [Editors note: located in; C:\Users\<username>\AppData\Local\Microsoft\VisualStudio\15.0_????????\] , give a name to the hive (I entered “VS2017PrivateRegistry”) and now you can see the 15.0_Config key populated as usual.
Once you have the Hive loaded into RegEdit, you can navigate to the key here;
Export te “Dark” theme registry key: HKEY_USERS\VS2017PrivateRegistry\Software\Microsoft\VisualStudio\15.0_????????_Config\Themes\{1ded0138-47ce-435e-84ef-9ec1f439b749}
Replace the GUID of the “Dark” theme ({1ded0138-47ce-435e-84ef-9ec1f439b749}) with the GUID of the “High Contrast” theme ({a5c004b4-2d4b-494e-bf01-45fc492522c7})
Import the reg file
Note: Be sure to UNLOAD the Hive once you’ve applied the registry hack. Otherwise, Visual Studio wont run.
Meanwhile, Microsoft continues to see this as a non-issue.
I don’t update this site often, and I always get a kick out of reading the last few posts, sometimes years old, and having a laugh at my sincere naivety. It also makes me cringe a little, to read about stuff that just never panned out for one reason or another. Oh well, such is life.
Take my post about being a “Born Again Indie”. All very true, no dispute there, but shortly after that, things changed yet again, and then again and god knows how many times after that. Opportunities arose, and distractions tugged at me from every direction. Shiny, interesting things that all demanded little pieces of my mind, to greater and lesser extents.
The game I mentioned in that post was a top down, 2D, Egyptian themed dungeon crawler, RPG. It was actually going quite well, and then I had some problems with the artist I had teamed up with, and the whole thing just sucked all the wind out my sails. I sulked for a bit, and then, despite myself, I dipped my toe back into iOS and mobile for a few months, finally releasing one of my shelved iOS games. And then the game got swallowed by the App Store, and I got sad about mobile again and went back to the drawing board.
Then, about 8 months ago, I was having coffee with my good friend, and we were talking about the games we’d like to make. We do this regularly. We sit and torture ourselves with fantastical ideas and fantasies of RPGs and Dungeon Crawlers, and we always say we need to make something, but circumstances are always against us.
This time was different. This time, we were both in a position to commit some real time to a long project. We kicked around ideas and we toyed with making a small, quick game, and even a mobile game. But we kept coming back to our favorite things. Playing D&D, RPGs and Dungeon Crawlers. So we started to define our ultimate dungeon crawler game, constrained by the limitations of our dev resources (just 2 of us). We came up with something we both got excited about. By the end of our coffee, we were totally into the idea and decided to proceed by making a fully playable, polished prototype, to prove out the game’s viability as a full project.
We chose Unity to make the game, and we spent the next 3 months on the prototype. Quite a long time for a prototype, but our mandate was for all the system created would be production ready and usable in the actual project. No cutting corners and no temp or bought code and art. We developed a custom toolset around the Unity editor, and I built a number of highly flexible systems and game mechanics, that allowed Damon to do his thing, and put all his energy into making art and building dungeons and enemies and puzzles.
We quickly realized that Unity was a fantastic choice, and our strategy for simplicity with massive flexibility, was the correct one. Things came together quickly and easily, and we were both having a blast. Once the prototype was ready, we enrolled a bunch of people in a play test. We set up a SurveyMonkey questionnaire for our testers to fill out, rating everything we could think of and offering the chance to give us real, honest feedback. The play test went very well and the data we got back was incredibly valuable. We got some excellent insight into some of our best and worse mistakes and assumptions. Based on the feedback we got, we decided to move ahead with the full project, and spent a few weeks making adjustments to the design and laying out story and detailed design for the entire game.
We kicked off the project officially at the beginning of August. We’re coming up to 2 months in and the project is going really, really well. We’re both still excited about the project, which for a couple of cynical old gits like us, is something new. We meet for coffee and plan and design and figure out problems. We’re heads down right now, building and testing and refining our tools and systems. In a month or so, I’ll be putting a website together for the game, and I’ll be doing some sort of regular game blog update thing. If you’re a real person, and not a bot or an Eastern European or Korean spammer, I hope you’ll join us and follow along. I’ll let you know when things kick off.
Meanwhile, here’s a couple of videos from the prototype.
I finally found the source code to the Batman Returns project on Sega CD. Yay! I know I’ve been teasing you with the dead link on the archive page for so long, and I’m sorry. The package is now live and ready to download for you delight and amusement.
Please link to the page and not the file. For educational purposes only. Yadda, yadda, yadda.