Canon
Dus heb ik een spel voor haar gemaakt waarin ze spellen kan maken: een multiplayer-wereld bestaande uit tekst, afbeeldingen en een kleine, nieuwe scripttaal, waarin ze alles uit elkaar kan halen om te zien hoe het werkt. Ik leerde zelf coderen in de tijd dat 'View Source' (broncode bekijken) een betrouwbare leraar was, en ik vind dat zij hetzelfde verdient.
Het spel heeft veel beperkingen. De taal, Cant, is geen heel goede taal, en dat is bewust. Maar het bleek ook erg leuk te zijn. Ik noem het: Canon.
Canon is een moderne, webgebaseerde interpretatie van de klassieke MUD's uit het oude internet. Voor de niet-ingewijden: voordat World of Warcraft de MMORPG tot een genre voor grote studio's maakte, hadden we tekstgebaseerde MUD's (en MUCK's en MUSHes), waarin spelers konden avontureren en socialiseren in uitgestrekte rijken die volledig uit geschreven woorden bestonden.
Ik heb talloze uren besteed aan het verkennen van deze imaginaire plaatsen. Ik wilde iets maken in diezelfde geest, maar dat natuurlijker aanvoelt voor een modern publiek. Canon heeft sterke meningen over wat een goede MU* maakt en wat een goede leeromgeving is. Elke kamer, elk object en elke interactie in Canon is door spelers gemaakt, en alles kan worden geïnspecteerd, gekopieerd en gewijzigd.
Mijn dochter is er dol op. Als je een volwassene bent die houdt van rollenspellen, tekstavonturen, of nostalgie heeft naar het tijdperk van telnet en het vroege web, dan vind je het misschien ook leuk. Maar eerst, in de stijl van een receptenblog, leg ik uit hoe we hier zijn gekomen.
Steunwielen voor de fiets van de geest
Herinner je je HyperCard nog? Zo niet, herinner je je Myst? (Zo niet, gefeliciteerd dat je jong bent. Draag me dan even bij.) Bill Atkinson bedacht HyperCard in 1985 na een LSD-trip. Ik kwam er voor het eerst mee in aanraking in 1989, in mijn computerlokaal van groep 6, en mijn geest werd daar ebenfalls door uitgebreid.
HyperCard werkt als volgt: er zijn kaarten. Dat is eigenlijk alles; dat is het genie ervan. Er zijn kaarten, en daarop kun je computerdingen plaatsen: knoppen, tekst, plaatjes en video. Kaarten worden op elkaar gestapeld. Een HyperCard-app wordt een "stack" (stapel) genoemd.
En al die knoppen en plaatjes kun je klikbaar maken. Je kunt ze opdracht geven om tussen kaarten in de stapel te bewegen. Het is een "choose your own adventure"-boek als gebruikersinterface (UX). (Als dit klinkt als een website, dan klopt dat. HyperCard was een van de eerste echt bruikbare instanties van HyperMedia en beïnvloedde Tim Berners-Lee bij de ontwikkeling van het World Wide Web.)
on mouseUp
go to card id 123
end mouseUp
Dat is geldige HyperTalk, de programmeertaal achter HyperCard. Maar voor de meest basisinteracties — op een knop klikken, naar een kaart gaan — hoef je HyperTalk niet eens te kennen. Je kunt dingen koppelen via een eenvoudige GUI-editor.
Als je op een knop kunt klikken, kun je HyperCard gebruiken. En als je HyperCard kunt gebruiken, kun je HyperCard programmeren. HyperCard was magisch, maar tegelijkertijd was het ook beperkt.
Magie en tekortkomingen
In veel opzichten waren HyperCard-stacks geen goede apps. Ze waren zwaar beperkt door de kaartmetafoor. Ze gebruikten invoerelementen uit de MacOS-visuele taal, maar ze voelden niet aan als normale native MacOS-applicaties. HyperTalk maakte dezelfde fout die later door AppleScript werd herhaald: proberen een programmeertaal meer op natuurlijke taal te laten lijken, waardoor het in beide gevallen niet echt goed lukte.
Voor elke echte programmeur was het een frustrerende, ondermaatse omgeving. Maar juist die gebreken en beperkingen maakten het magisch toegankelijk voor twee hongerige groepen: niet-programmeurs en nieuwsgierige kinderen.
De eerste groep produceerde een enorme hoeveelheid materiaal. Het Internet Archive heeft een speelbare collectie van duizenden stacks: games, zines, fandoms, manifesten en zelfs pornografie. Voor het web ruilden mensen met een Mac en iets te vertellen stacks uit op diskettes.
Ik viel in de tweede categorie. Op negenjarige leeftijd vond ik HyperCard op de Macintosh SE van mijn basisschool en ontdekte ik snel dat, in tegenstelling tot de meeste computerprogramma's, alles in HyperCard bewerkbaar was. Ik begon met het eerste wat in mijn opwelling opkwam: een vechtspel in de stijl van Street Fighter met twee grof getekende spelers.
(Artistieke reconstructie. Helaas is de originele stack verloren gegaan in de loop der tijd, in de doos met dode diskettes op de zolder van mijn ouders.)
Ik wist niets van programmeren, laat staan van geavanceerde game-concepten zoals sprites. Maar ik wist dat ik knoppen aan kaarten kon koppelen. Met de vastberadenheid die alleen een hypergefocust kind kan opbrengen, begon ik individuele kaarten te tekenen voor elke mogelijke combinatie van spelersbewegingen en posities, met knoppen als "bediening" om ertussen te schakelen.
Ik was een hamer tegengekomen, en ik zag hoe ik een spel kon maken van niets anders dan spijkers.
Je bent op kaart 154. Speler 1 is in kwadrant 2, in rust. Speler 2 is in kwadrant 3, in verdediging. Als speler 1 op de knop "aanval" drukt, ga dan naar kaart...
Het kostte me weken dat ik na school bleef. Maar het werkte. Ik had een spel gemaakt. Ik kon mijn eigen creatie spelen. Ik heb mijn hele carrière die kick nagejaagd.
Maar dat was pas het begin. Een van de slimme dingen die Bill Atkinson deed, was dat wanneer je HyperCard-gedragingen via de GUI bewerkte, het programma simpelweg de bijbehorende code voor je schreef. Halverwege mijn moeizame klik- en koppelproject merkte ik de knop 'Script...' in de editor op, begreep de implicaties en begon een copy-paste HyperTalk-fragment en een systematisch naamgevingsschema voor al mijn honderden kaarten te gebruiken om de ontwikkeling te versnellen.
Aan het einde merkte de computerdocent op wat ik aan het doen was en haalde hij de HyperCard-referentiehandleiding uit een lade voor me. Dit was mijn eerste ervaring met het lezen van een technische handleiding van kaft tot kaft.
Veel jaar later...
Ik ga mijn dochter niet leren werken met HyperCard. Ik ben een beetje een 'Troll Dad', maar niet zó gemeen. Maar ik wilde wel de magische combinatie van creatieve vrijheid en mechanische beperkingen reproduceren die HyperCard zo openschurend maakte voor de jonge Nick. Canon had het volgende nodig:
- Direct resultaat: Zodra je iets op het scherm plaatst, is het al onderdeel van het spel.
- View Source: Alles in het spel moet gebouwd zijn met de eigen tools van het spel en vrij bewerkbaar, kopieerbaar en uit elkaar te halen zijn.
- Een GUI voor de simpelste interacties.
- Een soepele leercurve van GUI naar het schrijven van ruwe code.
- Net genoeg kracht in die code om een breed scala aan leuke game-mechanics te bouwen en om basisconcepten van programmeren aan te leren, maar beperkt genoeg zodat een beginner de hele set primitives kan begrijpen.
Direct resultaat
Het geweldige aan een tekstgebaseerde wereld is dat je alles kunt toevoegen door simpelweg te typen: "hier is een [ding]". Je bent beperkt in hoe je bouwt — geen fancy 3D-visualisaties of indrukwekkend realistische physics-engines — maar je hebt onbeperkte vrijheid in wat je bouwt.
Canon bestaat uit drie dingen:
- Spelers
- Kamers
- Items
Spelers en Kamers zijn beide simpelweg tekstbeschrijvingen en, optioneel, afbeeldingen. Om een van beide te maken, beantwoord je gewoon een vraag: hoe ziet dit eruit?
De broncode inzien
Items zijn alles wat overblijft. Ze zijn ook tekstbeschrijvingen en afbeeldingen, dus je kunt een item vormgeven als wat je maar wilt: een levenloos object, een huisdier, een NPC, een spreukeffect, een voertuig, een deuropening, een quest-marker, een bericht, etc.
Maar naast tekst en afbeeldingen bestaan items ook uit acties en status, via Cant. Het ziet er zo uit:
item "Lantaarn met kap" {
describe "Een ijzeren lantaarn met een scharnierende kap."
on "aansteken" {
narrate "De {item} van {player} zwaait open en warm licht stroomt naar buiten."
}
}
Dat is genoeg om een lantaarn te produceren die de speler kan aansteken. Hier is een iets ingewikkelder item, een Magic 8-Ball:
item "Magic 8-Ball" {
describe "Een profetische biljartbal. Schud je hem?"
or "Schud hem om je toekomst te zien."
or "Durf je hem te schudden?"
on "schudden" {
say
"Het is zeker."
or "Vooruitzichten zijn goed."
or "Tekens wijzen op ja."
or "Reken er niet op."
or "Mijn bronnen zeggen nee."
or "Antwoord is wazig, probeer opnieuw."
or "Vraag later opnieuw."
}
}
Het trefwoord or werkt overal waar Cant een tekststring accepteert. Het kiest elke keer dat de string wordt gebruikt willekeurig een variant: wanneer een speler naar een item kijkt, of een actie activeert. Ik wilde dit op het laagste niveau in Canon inbouwen.
Er is iets speciaal verrukkelijks voor een nieuwe programmeur aan een RNG (Random Number Generator). Je vertelt de computer wat hij moet doen, en hij doet het. Maar je hebt hem ook verteld om een klein beetje van zijn eigen autonomie te gebruiken. Het is zowel verrassend als niet verrassend. Je hebt elke reactie geprogrammeerd, je kent alle dingen die hij kan zeggen, en toch weet je niet precies wat hij zal zeggen wanneer je op de toets drukt of op de knop klikt. Het is alsof je jezelf plotseling kunt kietelen.
Merk op dat dit item, naast schudden, ook een clone-knop heeft. Elk item in Canon kan worden gekloond. Items die je bezit (waaronder alles wat je hebt gekloond) kunnen worden bewerkt. Elk spel, speelgoed of quest die door een andere speler is gemaakt, is dus ook een tutorial.
Een GUI voor de simpelste interacties
De 8-ball is een van de eerste speeltjes die ik maakte om de kleine te lokken. Ik liet hem in de startzone liggen. Zelfs als je niets weet van conditionele logica, en zelfs als je niet naar de code kijkt, is het eenvoudig om na een paar minuten spelen te zien hoe het werkt. En het is makkelijk om je voor te stellen hoe je het zou kunnen aanpassen tot een muntje dat je opgooit, of een NPC die willekeurige grappen vertelt.
Of, zeg maar, een D20:
(Ik meen dit volledig.)
Als je een programmeur bent, zul je merken dat dit verschrikkelijk is. Dit is een inefficiënte manier om iets te schrijven dat overduidelijk randInt(1,20) zou kunnen zijn. Maar het is extreem toegankelijk. Cant is een taal die is ontworpen om op een educatieve manier "slecht" te zijn. Het is geoptimaliseerd voor begrijpelijkheid in plaats van schrijfsnelheid. Het is het tegenovergestelde van DRY (Don't Repeat Yourself).
Een vloeiende overgang van GUI naar code
Laten we dat editor-venster iets uitbreiden:
Een ervaren programmeur zal merken dat deze code een one-liner had kunnen zijn. Maar een beginner zal merken dat de code al veel minder werk is dan het klikken op 20 knoppen en het invullen van 20 tekstvelden.
De code en de gestructureerde editor zijn gesynchroniseerd. Elke geldige expressie in de een werkt direct door in de ander. Ik wilde dit de kleine lokken, op dezelfde manier als de knop 'Script...' van HyperCard mij lokte.
Precies genoeg kracht
Oké, willekeurige strings uitspreken is leuk, maar het is niet echt een spel. Wat kan dit ding nog meer? Een paar voorbeelden:
item "Dueltoverstaf" {
describe """
Een hazelaar {item} omwikkeld met koperdraad, die zachtjes gonst.
{when item vigor <= 0}Het licht is uit. De staf van een verslagen duelist, tot iemand hem herstelt.{end}
"""
borne "Een hazelaar {item} {when item vigor <= 0}hangt donker en stil{else}knettert van ongeduld{end} in de greep van {player}."
afield "Een hazelaar {item} ligt hier, {when item vigor <= 0}met gedimd licht{else}knetterend van magisch potentieel{end}."
state {
vigor 30
}
on "vuurbal" {
when item vigor > 0 {
when target vigor > 0 {
subtract target vigor 1d20
narrate "De {item} van {player} brult! Een vuurbal raakt {target}."
when target vigor <= 0 {
narrate "De staf van {target} wordt donker. {player} staat als overwinnaar."
}
}
otherwise {
narrate "De {item} van {player} vindt niemand om te raken."
}
}
otherwise {
narrate "{player} probeert een spreuk te werpen, maar hun {item} is donker tot hij hersteld is."
}
}
on "herstellen" {
when target vigor >= 30 {
narrate "De staf van {player} gonst, vindt niets om te herstellen op {target}, en weigert de charme te verspillen."
}
otherwise {
add target vigor 1d10
narrate "Groen licht van de {item} van {player} weeft zich over {target}."
when target vigor > 30 {
narrate "{target} sprankelt kortstondig van overtollige kracht."
set target vigor 30
}
}
}
}
Dit is een PVP-ontmoeting. Twee of meer spelers kunnen Dueltoverstaven oppakken en tegen elkaar vechten. Het belangrijkste om hier op te merken is:
state {
vigor 30
}
Items in Canon kunnen twee soorten status (state) vasthouden: marks en numbers.
- Marks zijn boolean vlaggen. Een lantaarn kan AAN (
LIT) zijn, een NPC kan VERDACHT (SUSPICIOUS) zijn, een deur kan VERGRENDELD (LOCKED) zijn. - Numbers zijn wat ze laten klinken. Een kampvuur kan
warmth 10hebben, een NPC kanhealth 20hebben, een slot dat gekraakt kan worden kanattempts 5hebben.
Marks zijn altijd in HOOFDLETTERS, numbers altijd in kleine letters. De hoofdlettergrootte bepaalt het type.
Let ook op dat vigor hier op de staf zit, niet op de speler. Spelers hebben zelf geen status, alleen op de items die ze dragen. Wanneer je een speler target met een vuurbal, target je hun staf. Of liever gezegd, je target elk item dat ze dragen dat reageert op de status vigor.
Op deze manier zijn alle ontmoetingen en mini-games in Canon consensueel en optioneel. Wil je niet duelen? Pak dan simpelweg de staf niet op. Statusnamen zijn volledig willekeurig. Deze staf heeft vigor, maar een andere set wapens zou life of health of stamina kunnen hebben. Je kunt een set items bouwen die allemaal reageren op dezelfde status en met elkaar interageren, of unieke namen kiezen voor unieke ontmoetingen.
Hier is een NPC die zowel marks als dialogen gebruikt:
item "De Dialoogboom" {
describe "Een pratende boom, die maar al te graag vertelt over de vreugden van een plant zijn."
remembers
state {
PLEASED false
}
on "chatten met de boom" {
dialog
"Welkom, welkom, neem plaats…"
or "Hallo daar, klein diertje…"
{
choice "Hoe is het om een boom te zijn?" {
dialog "Oh, het allerbeste! Je moet echt eens fotosynthese proberen."
mark item PLEASED
}
choice "Uh, excuseer me, ik was net aan het bladeren…" {
narrate "{item} ziet er een beetje verslagen... eh, tak-verslagen uit."
unmark item PLEASED
}
}
}
}
Dit creëert het klassieke RPG-dialoogvenster. Dialogen kunnen willekeurig diep genest zijn en elke andere Cant-effect bevatten als resultaat van een dialoogkeuze, of verschillende keuzes presenteren op basis van number- en mark-status. Merk op dat de stemming van de boom verandert afhankelijk van je antwoord, bijgehouden door de PLEASED mark.
Het trefwoord remembers vertelt een item dat het zijn status moet behouden wanneer het alleen in een lege kamer wordt achtergelaten. Zonder dit wordt de status gereset wanneer er geen spelers in de buurt zijn, zodat ontmoetingen fris zijn voor nieuwe bezoekers. In het geval van de Dialoogboom willen we dat hij zijn stemming behoudt van degene die als laatst met hem sprak.
Als je goed kijkt, zie je ook dat de afbeelding van de Dialoogboom verandert. Item-afbeeldingen kunnen reageren op marks en numbers. Cant draait om tekst, dus afbeeldingen worden apart behandeld in de item-editor.
Hetzelfde geldt voor Spelers. Je kunt de afbeelding van je personage veranderen op basis van de status van de items die ze dragen. Hier is een simpel "papieren pop"-item dat geen actie heeft, maar wel een status instelt:
item " Chique Rode Piratenjas" {
describe "Een chique rode jas, passend voor een piratenkapitein."
state {
OVERCOATED true
}
}
En hier is een speler waarbij zowel de tekstbeschrijving als de actieve afbeelding reageren op de aanwezigheid of afwezigheid van de jas. In plaats van (of in aanvulling op) het wijzigen van de beschrijvende tekst van een speler, kunnen we items ook een optionele borne-beschrijving geven, die wordt toegevoegd aan de beschrijving van de speler.
item "Chique Rode Piratenjas" {
describe "Een chique rode jas, passend voor een piratenkapitein."
borne "{player} is modieus gehuld in een {item}."
state {
OVERCOATED true
}
}
Je kunt de hele dag "character customizer" spelen (het favoriete spel van velen in elk spel!) met alleen tekst en afbeeldingen. Je kunt veel leuke dynamische objecten maken met afbeeldingen, conditionalen en status. Maar een simpel stukje sfeertekst is vaak nog steeds het leukste deel. Van alle items die ik heb gemaakt, blijft het bescheiden sneeuwbal-item het favoriet van mijn dochter:
item "Sneeuwbal" {
describe "Een deskundig gepakte sneeuwbal."
on "werpen" {
narrate "{player} raakt {target} in het gezicht met een sneeuwbal! _Paff!_"
}
}
Maar niet te veel
Je zult merken dat in zowel de Dueltoverstaf als de responsieve speler/item-afbeeldingen, de conditionalen zeer beperkt zijn. Elke when accepteert één conditie. Er is geen and, or, etc. Er is ook geen equivalent van else if. when neemt één conditie, en een enkel optioneel otherwise-blok. Als je complexere control-flow wilt, kun je when nesten. Opnieuw: dit zal een ervaren programmeur waarschijnlijk als "slecht" bestempelen, maar het dient een doel.
Ten eerste is de gestructureerde editor al ingewikkeld genoeg. De Dueltoverstaf alleen, hoewel verre van het meest geavanceerde item dat je kunt bouwen, wordt visueel al druk. Het toevoegen van optionele combineerblokken zou het moeilijker maken om te navigeren. Maar belangrijker nog: de simpele when is bedoeld om precies goed genoeg te zijn, totdat het dat niet meer is.
Cant is een taal die is ontworpen om op een verhelderende manier frustrerend te zijn. Een redelijke bezwaar zou kunnen zijn dat het slechte codeergewoonten aanleert. Maar vanuit mijn eigen jeugdervaring zal het juist leren waarom de goede gewoonten goed zijn en hoe lagen van abstractie en expressiviteit bovenop elkaar worden gebouwd.
De kleine bouwt al coole dingen met Cant. Uiteindelijk zal ze geërgerd raken door de beperkingen. Maar op dat moment zal ze ook in staat zijn die beperkingen te verwoorden en manieren te bedenken waarop het verbeterd zou kunnen worden. En dat zal een toegangspoort zijn. Wanneer ze overstapt op een grotere, volledigere en expressievere programmeertaal, zal ze begrijpen waarom die beter is.
Een adversarial mindset
Een ander ding dat ik wil dat Canon leert, is hoe je moet hacken. Programmeren buiten de lijntjes. Het kind is al erg dol op ondeugendheid en mazen in de wet, dus dit speelt in op haar sterktes.
Je hebt misschien een klein gebrek opgemerkt in sommige van de voorbeelden hierboven. Als je elke Dueltoverstaf kunt bewerken, kun je gewoon je eigen staf bewerken om jezelf extra vigor te geven, of om nooit schade op te lopen. Als je elke dialoog kunt bewerken, kun je gewoon een glimp opvangen om te zien welke keuzes je het einde geven dat je wilt. Elke ontmoeting is hackbaar.
Ook dit is opzettelijk. Voor het koesteren van een groeiend ingenieursbrein zijn het creëren van puzzels, het oplossen van puzzels en het hacken van puzzels allemaal win-condities.
Vanuit een breder spelperspectief maakt dit deel uit van "alles is consensueel". Canon heeft geen permanente punten om te winnen of te verliezen. Er zijn geen schaarse middelen gekoppeld aan je personage die iemand je kan ontnemen. De enige reden om een PVP-duel te hebben, is om plezier te hebben met je vrienden. De enige reden om een mini-game te spelen, of een quest te voltooien die iemand heeft gemaakt, is om de ervaring te hebben die zij voor je hebben gecreëerd. Of, als je het type persoon bent dat meer plezier heeft in het uit elkaar halen van de ervaring om te zien hoe ze het gemaakt hebben, dan kun je dat ook doen.
Dat gezegd hebbende, er zijn een paar concessies aan auteurcontrole. De belangrijkste zijn de Kingdoms (Koninkrijken). De Canon-kaart bestaat uit een gedeelde overworld en individuele zones die toebehoren aan elke speler. De overworld is vooral een sfeervolle manier om tussen Koninkrijken te reizen, en geen veilige plek om dingen achter te laten. Alles wat je in de overworld neerlegt, kan worden opgepakt door een andere speler. Maar in jouw Koninkrijk kun je als enige items in een kamer plaatsen, en ben jij de enige die ze kan verwijderen. Andere spelers kunnen je creaties klonen om uit te zoeken hoe ze werken, maar ze kunnen de originelen niet wijzigen. Hierdoor kun je stabiele games en ontmoetingen maken over meerdere kamers en items.
Wil je een quest waarbij je met een reeks NPC's in verschillende dorpen moet praten om een mysterie op te lossen? Of waarbij je de juiste keycards moet vinden om de juiste deuren in een doolhof te openen? Of waarbij je een ei verzamelt en verzorgt met de juiste magische ingrediënten om een baby-draak uit te laten komen? Dat is allemaal eenvoudig te maken in jouw Koninkrijk.
Trappen en ladders
Een Canon-kaart ziet eruit als een boom, of een ongerichte acyclische graaf. De kaart groeit alleen door nieuwe kamers af te takken, nooit door twee bestaande kamers met elkaar te verbinden.
Dit heeft enkele wenselijke eigenschappen:
- Omdat er geen vaste afmetingen zijn, kan een "kamer" alles zijn wat je beschrijft. Je kunt een letterlijke enkele kamer in een gebouw maken, of een heel gebouw, of een uitgestrekt terrein. Een lege leegte. Een pocket-universum. Een gemoedstoestand. De abstracte kaart past bij de totale vrijheid van tekst.
- Het stelt eigenaren van Koninkrijken in staat om hun deuren op slot te doen, waardoor private schuilplaatsen, invite-only guild halls en puzzels ontstaan die afhangen van beperkte beweging, terwijl wordt afgedwongen dat sloten alleen werken in de richting weg van de wortelnode. In Canon kun je iemand buiten sluiten, maar nooit binnen sluiten. Je kunt schuilplaatsen maken, maar geen kerkers.
Het leert het kind iets over gebruikersinterface-abstracties en de slimme hacks die in game-design gaan. Bijvoorbeeld: veel populaire level-designs kunnen niet puur in de kaartstructuur van Canon worden uitgedrukt. Stel je een netwerk van boomhutten voor, verbonden door touwbruggen, boven een bosbodem. Het dorp in de boomtoppen is een serie verbonden kamers in het noorden, zuiden, oosten en westen. De bosbodem is hetzelfde. Elke kamer op de bosbodem zou ook verbonden moeten zijn met de bijbehorende kamer in het bladerdak via 'omhoog' en 'omlaag' uitgangen, maar deze zouden cycli in de kaartgraaf vormen.
Canon lost dit op zoals DOOM dat deed: door het te veinzen. Een teleport-actie in Cant, gekoppeld aan een item, biedt de mogelijkheid om spelers tussen willekeurige kamers te transporteren.
item "Touwladder" {
describe "Een touwladder die uit het bladerdak naar beneden hangt als een uitnodiging."
on "beklimmen" {
say "De sporten kraken onder je."
teleport "lomise-anthil-nara"
narrate "{player} klimt uit het zicht omhoog."
}
}
Het gequoteerde adres is de locus van de bestemmingskamer: een willekeurig gegenereerde ID die je alleen kunt leren door in de kamer te staan. Dit is zodat de Cant draagbaar blijft, maar je niet simpelweg het adres van een onbekende kamer kunt raden, aangezien teleportatie sloten kan omzeilen. (Dat klopt, token-beveiliging staat ook op het curriculum!)
Ladders en liften zijn slechts het begin. Je kunt teleportatie gebruiken om het volgende te bouwen:
- Rijdieren: maak een Paard of een Motor of een Draak om je via een
ride-actie naar verschillende bestemmingen te brengen. - NPC's: combineer dialoog en teleport voor een Liftbediende of Portaalmagiër.
- Hearthstones en Boekenmerken: een coole plek op de kaart gevonden? Maak een snelle teleport om er elk moment naar terug te keren.
Agenten en Generatie Alpha
Ik heb Canon gevuld met een reeks speeltjes en games voor de kleine om uit elkaar te halen en te remixen. Maar ik wilde er zeker van zijn dat ze vanaf het begin haar eigen dingen kon maken. Dus heb ik ook een Wish-functie toegevoegd.
Eenmaal per dag kan elke speler een Wens richten tot de Machine-God. Een LLM (Large Language Model) zal een item maken volgens jouw specificaties, inclusief functionele Cant-code met verklarende opmerkingen.
# Gebouwd door De Machine, maar aanpasbaar. Bewerk gerust!
item "Lachende Jas" {
describe "Een lange jas van stormgrijs wol, met een hoge kraag en een voering met een grijnzende naad die nooit helemaal plat ligt, alsof hij altijd iets grappigs vindt."
borne "Een lange jas rust op de schouders van {player}, en af en toe schudt hij en laat hij een zachte, tevreden lach horen om een gevaar dat alleen hij kan zien, alsof gevaar de mooiste grap is die ooit is verteld."
on "oppakken" {
# vuurt vanzelf wanneer iemand dit oppakt – narrate schildert het moment voor de hele kamer
narrate "{player} trekt een lange grijze jas aan, en deze nestelt zich op hun rug met een tevreden klein giecheltje."
}
on "neerleggen" {
# …en dit vuurt wanneer hij weer wordt neergelegd
narrate "Een lange grijze jas glijdt van de schouders van {player} en vouwt zich in een hoop, waarbij het gelach wegsterft tot een slaperig, tevreden gepiep."
}
}
Cool, toch?
Ik heb twee soorten feedback gekregen van volwassenen die Canon hebben geprobeerd:
- "Ik hou van alles behalve Wish. Ik haat AI en wil het niet in de buurt van mijn creatieve uitingen hebben. Je zou mensen moeten waarschuwen bij het aanmelden dat dit een LLM bevat."
- "In plaats van mijn eigen afbeeldingen te uploaden, zou er een knop moeten zijn die ik kan indrukken om een AI een afbeelding te laten genereren op basis van de beschrijving die ik schreef!"
Ik weet niet goed wat ik hiermee moet. Wish is de enige AI-functie in Canon, en het is strikt beperkt tot één tutorial-item per dag. In een gamewereld waar alles andere expliciet door mensen voor mensen is geschreven, was dit alleen al direct polariserend.
Onder volwassenen, dan. De kleine had een gezondere houding: totale onverschilligheid. Ze begon direct met het wensen van dingen, om ze vervolgens onmiddellijk te overschrijven met haar eigen woorden en verbeelding. Ze gebruikt met evenveel gemak afbeeldingen van GIPHY, Image Playground, of haar eigen fotobibliotheek vol originele foto's en tekeningen. AI is voor haar gewoon een andere tool.
Canon begon vele jaren geleden, voordat de kleine werd geboren. Ik hou van virtuele werelden en wilde proberen er zelf een te maken. Helaas had ik veel meer ideeën dan tijd, dus ging het project op de plank liggen.
Onlangs heb ik oude zijprojecten afgestoft en ze "10x-ed" met Claude. Verre van het bederven van de magie, heeft het mijn liefde voor coderen opnieuw aangewakkerd. Het maken van Canon was heerlijk, vereiste veel van mijn oordeel en jarenlange ervaring als engineer, en ging veel sneller dan ik alleen had kunnen volbrengen.
Maar ik heb nu ook een spel gemaakt waarin mijn kind en ik liefdevol samen code maken. Zelfs als de toekomst volledig "agentic" is, denk ik dat het leren van Cant haar nuttige vaardigheden en mentale gewoonten zal aanleren. En het is gewoon leuk. Dat is ook zeer verkwikkend geweest.
Yoink
Ik laat je achter met enkele citaten van mijn tevreden gebruikersgroep van één energieke achtjarige:
"Bedoel je dat ik alles kan maken wat ik wil?! Personages? Quests? Verhalen?! :D"
Ik: "Waarom is je inventory zo vol? Wacht, waarom heb je tien van alles? Je weet dat je er gewoon één kunt houden en hem kunt klonen, toch?" Dochter: "Ja, dat weet ik. Maar ik heb er tien!" Ik: "Je bent erin geslaagd een loot goblin te zijn in een spel zonder loot." Dochter: (manisch gegiechel) Dochter: "Ik ben in je huis gebroken en heb al je spullen gestolen!" Ik: "Je bedoelt dat je mijn raadsel hebt opgelost. Goed gedaan. Maar je kunt niet stelen uit mijn koninkrijk, alleen klonen. Dat zou ik weten, ik heb het zo geschreven." Dochter: "Ja, maar ik heb alles tien keer gekloond, wat betekent dat ik meer van jouw spullen heb dan jij!" Ik: ... Dochter: (manisch gegiechel)
"Ik weet wat we moeten maken! We moeten een item maken dat een computer is. En wanneer je personage op de computer speelt, spelen ze Canon!"
Pas acht jaar en ze vindt recursie al grappig. Ze is echt mijn kleine engineer.
Probeer het zelf
Canon is beslist in bèta, maar je kunt het spelen! Stuur een korte mens-tot-mens e-mail naar nick@tau.dev en ik stuur je persoonlijk een uitnodigingscode. Eenmaal binnen kun je vrienden uitnodigen met je eigen code. Ik wil de groei voorlopig langzaam houden, maar iedereen die oprecht nieuwsgierig is, is welkom.
Er zijn Canon- en Cant-functies die ik hier niet heb genoemd. De documentatie is schaars, maar dat is onderdeel van het spel. Prik, tast en knutsel. Je innerlijke achtjarige weet wat hij moet doen.
Groetjes,