Og det er faktisk litt gøy.
Hvert år holdes det en konkurranse på nettet, der deltakerne må lage dataspill i programmeringsspråket BASIC. Man kan bruke alle slags BASIC-varianter, så lenge de fungerer på en 8-bits-datamaskin, og det er bare én begrensning man må holde seg innenfor: Koden kan ikke overskride ti linjer. Dette krever litt forklaring: Gamle versjoner av BASIC hadde linjenummer, der hver linje kunne inneholde en rekke separate kommandoer. På plattformer som Commodore 64 er en slik linje begrenset til 80 tegn, altså to fysiske linjer på skjermen.
Hvorfor ikke?
I år tenkte jeg å delta, ikke fordi jeg føler jeg har noen vinnersjanser, men fordi jeg syntes det virker som en gøy utfordring. Jeg har sagt det tusen ganger før, men for meg er programmering litt som et hjernetrimspill. Jeg har et sett med instruksjoner som kan settes sammen på spesifikke måter innenfor visse rammer, og må prøve å finne en måte å gjøre dette som på nærmest magisk vis oversetter ideene mine til noe fysisk som fungerer på skjermen.
Hvis du har kost deg med et spill fra Zachtronics, som Spacechem, Infinifactory, Shenzhen I/O eller Opus Magnum, så har du en overraskende god idé om hvordan det føles i praksis. Kort sagt: Det er kjempegøy, og utrolig tilfredsstillende når jeg lykkes med det jeg prøver på.
Jeg har laget ett bidrag, og har to spill til som jeg ikke er helt sikker på hva jeg skal gjøre med – det ene er kanskje litt for simpelt, når alt kommer til alt, og med det andre gapte jeg nok over litt for mye. Jeg har valgt å jobbe med Sharp MZ-80A, en plattform jeg tidligere har skrevet litt om her på nettstedet, men om du for eksempel er vant med BASIC-programmering på Commodore 64, vil mye fremstå likt. Det store flertallet av kommandoer er like, og brukes omtrent (om ikke alltid helt) likt.
Naturligvis er minneadressene jeg bruker med kommandoene PEEK og POKE annerledes, og MZ-80A har to kilobytes med skjermminne, i stedet for bare én som på Commodore 64.
Akkurat det siste der var noe jeg fant ut at jeg skulle utnytte meg av i mitt bidrag. Det jeg har laget er nemlig et ganske enkelt spill der du styrer en liten strekmann (eller -dame, jeg legger ikke føringer) rundt for å samle kuer (strengt tatt pi-tegn) og unngå UFO-er. Det dukker gradvis opp nye kuer og UFO-er på spillbrettet, og siden UFO-ene aldri forsvinner igjen gjør de navigasjon vanskeligere. Men i utgangspunktet er dette et ganske kjedelig konsept, så derfor har jeg lagt spillarealet over to «skjermer», og skjermbildet skroller automatisk opp og ned mellom de to. Det vil også skrolle gradvis fortere, frem til det når en viss hastighet, noe som også gjør spillet mer utfordrende underveis.
Alt i alt er jeg faktisk rimelig fornøyd med det vesle spillet mitt. Her kan du se koden:
Og her kan du se hvordan det fungerer i praksis:
Begrenset plass
Sharp MZ-80A har en solid BASIC-implementering, men den mangler ting som forkortelser og slikt, som du kanskje tar for gitt om du bruker for eksempel Commodore 64. Den store utfordringen er uansett at når du skal bruke IF-setninger for å teste kondisjoner ender du fort opp med å miste mye plass. Ta en titt på følgende (fiktive) linje:
7 IF A=0 THEN GOTO 4
I dette tilfellet bruker linjen kun 20 tegn (mellomrom telles også, men du trenger ikke ha dem om du ikke bryr deg om lesbarhet). De resterende 60 vil jeg typisk ikke kunne få brukt, fordi enten er variabelen A lik 0, og instruksjonen om å hoppe til linje 4 følges, eller så er den noe annet og BASIC vil automatisk hoppe til neste linje med en gang systemet registrerer at A ikke er 0. Hvis jeg er begrenset til 10 linjer med 80 tegn hver, har jeg altså kun 800 tegn for hele programmet mitt, og da bør jeg helst bruke de 60 tegnene jeg «mister» her til noe fornuftig. Med andre ord handler mye av utfordringen om å strukturere koden på en slik måte at jeg ikke kaster bort plass, og finne alternativer til IF som kan brukes i ulike situasjoner.
Det er selvsagt verd å påpeke at en IF-setning ikke trenger å følges av en GOTO-kommando, så det er mulig å putte inn en hel linje med kommandoer som kun vil kjøres om kondisjonen i IF-setningen er møtt. Man kan også ha flere IF-setninger etter hverandre om man først ønsker å teste en kondisjon og så, hvis denne er sann, ønsker å teste en annen.
Hvordan fungerer det?
I utgangspunktet tenkte jeg at det kunne vært artig å gå gjennom hver linje med kode og forklare hva den gjør, men jeg prøvde og ga opp. Spillet er så komprimert at det ikke nytter, spesielt når jeg samtidig må forklare hvordan de ulike kommandoene fungerer. Det ville sikkert også være en kilde til irritasjon for meg selv, da jeg gjennom de to neste prosjektene jeg har jobbet med har lært mye som jeg kunne brukt for å gjøre dette spillet bedre. Det er nemlig mye av greia med dette ti-linjers-prosjektet; den rimelig ekstreme plassbegrensningen tinger meg til å tenke utenfor de vante banene og søke nye løsninger, noe som så skaper nyttige erfaringer for fremtidige prosjekter.
Men jeg kan gi et kjapt overblikk. De første to linjene setter opp spillarealet, og gjør samtidig klar ulike variabler og slikt for spillet. Selve spill-sløyfen går fra linje tre til linje ni. I linje tre leses spillerens tastetrykk, og avhengig av hva det er vil den neste posisjonen for spillfiguren sjekkes for eksisterende innhold, og spillet vil avgjøre hvilken av de fire figur-karakteren som skal brukes. I tillegg blankes den eksisterende posisjonen til spillfiguren. I neste linje tegnes spillfiguren opp igjen, og avhengig av hva som befant seg i den nye posisjonen velger spillet om det skal fortsette, eller gå til «game over» (om det var en UFO der).
I linjene fem og seks legger spillet inn nye UFO-er og kuer, og de neste linjene er ansvarlige for skrollingen (som altså skal veksle mellom å gå opp og ned, og dessuten øke i hastighet gradvis – hastigheten går opp hver gang skjermen når toppen av arenaen). Linje ni sender starter spillsløyfen på nytt, samtidig som den er brukt til å lagre data (DATA-kommandoen leses aldri av direkte, i stedet leses den påfølgende dataen av READ-kommandoen som jeg har helt i starten – derfor kan DATA ligge etter en GOTO-kommando). Linje ti gir spilleren mulighet til å starte på nytt etter å ha fått «game over».
Det var det! Som sagt, dette er et simpelt spill, men det er jo begrenset hva man får til på ti linjer uten forkortelser og slikt. Samtidig er det jo ganske moro at man faktisk kan få til å lage et fungerende spill ved hjelp av så lite programmering. En av tingene jeg syntes er fascinerende er å prøve å finne ut hvor lite som egentlig skal til for at et dataspill skal være gøy å spille, og det jeg har laget er faktisk litt artig (og ganske hektisk, etter hvert).
Konkurransen er åpen frem til 21. mars, så hvis du var en racer på BASIC på åttitallet og har lyst til å børste støv av de gamle kunnskapene dine, er det bare å hive seg på!
Wow. Imponerende, og veldig kult!