Vier jaar met Decker

  • Nieuwe Horizonnen: functies die het scala aan mogelijke projecten met Decker uitbreiden.
  • Een taal laten groeien: verbeteringen aan Lil, de scriptingtaal van Decker.
  • Het Deckerverse: hoogtepunten van de gebruikersgroep van Decker.
  • Een belofte voor menselijke creativiteit: een toezegging.

Nieuwe Horizonnen

Een van de meest prominente nieuwe functies die dit jaar aan Decker zijn toegevoegd, is de ondersteuning voor gamepad-input, met een fallback naar toetsenbordbediening waar beschikbaar. Veel Decker-gebruikers zijn specifiek geïnteresseerd in het bouwen van videogames, en de gamepad brengt arcade- en actiegenres binnen handbereik.

Bijschrift: Het gamepad-testdeck

Er is nog aanzienlijke ruimte om meer voorbeelden en bibliotheken te bouwen die aantonen wat met deze functionaliteit mogelijk is. Om te beginnen is het Sokoban-voorbeeld nu speelbaar met een gamepad of toetsenbord. De dialogizer-module upgrade stilzwijgend elk spel dat deze gebruikt naar ondersteuning voor toetsenbordbediening voor het verder gaan in dialoogvensters en het maken van keuzes in dialoogbomen. Dialogizer maakt ook gebruik van het nieuwe app.cursor-veld om het hover-gedrag van gewone knoppen te simuleren tijdens "synchrone" scripts.

Een andere belangrijke verbetering vereist geen actie van de gebruikers: betere beeldcompressie. Voor de eenvoud vertrouwde Decker oorspronkelijk op eenvoudige bit-packing en run-length encoding bij het opslaan van graphics, maar de datablock-formaten lieten ruimte voor het introduceren van betere codecs in de toekomst. De nieuwe IMG3-beeldencoder maakt gebruik van de LZW-gebaseerde kern van de GIF-codec van Decker en realiseert een verbetering van 2 tot 4 keer in de totale bestandsgrootte voor veel decks, vooral diegene die gebruikmaken van geditherde kleur graphics. In situaties waar de nieuwe codec niet beter presteert dan IMG0, IMG1 of IMG2, worden de oude codecs geselecteerd. Auteurs van E-Zines kunnen nu veel meer op een diskette passen.

De contraptions van Decker zijn subtiel krachtiger geworden door de introductie van nieuwe "attribuuttypes", die de aangepaste gebruikersinterface voor het configureren van contraption-instellingen aansturen. Deze attributen kunnen nu "data" of "note" zijn. Een "data"-attribuut wordt weergegeven als en geparsed vanuit een veld van LOVE, waardoor het gemakkelijker is om gestructureerde waarden bloot te leggen zonder dat er eenmalige tekstuele formaten hoeven te worden bedacht. Een "note"-attribuut toont een inline blok proza in plaats van een editor aan te bieden, wat meer manieren biedt voor contraptions om zelfdocumenterend te zijn.

Bijschrift: Een contraption met een note-attribuut waarin wordt uitgelegd hoe deze gebruikt moet worden

De ondersteuning voor kleur blijft uitbreiden en verbeteren. Alle widgets hebben nu een .pattern-attribuut dat hun uiterlijk bestuurt in combinatie met de bestaande .show- en .font-attributen. Je kunt het patroon van geselecteerde widgets snel wijzigen via Widgets → Pattern… in het menu of door simpelweg op een patroonsteekproef in de rechterwerkbalk te klikken.

Bijschrift: Het wijzigen van het .pattern-attribuut van widgets

Wanneer rich text is geselecteerd, kun je nu ook de rechterwerkbalk gebruiken om snel het patroon of de kleur van de tekst te wijzigen.

Bijschrift: Het wijzigen van het patroon van rich text runs

Er zijn ook veel verbeteringen aangebracht aan bestaande functies om het maken van decks gemakkelijker en intuïtiever te maken. Zo past het plakken van afbeeldingen in geschaalde canvases nu de dimensies van de "logische grootte" van het canvas aan om te voorkomen dat de geplakte afbeelding per ongeluk wordt afgesneden. Bovendien kunnen afbeeldingen in het klembord als nieuwe canvas-widgets worden geplakt vanuit elke editor-modus.

Bijschrift: Een afbeelding plakken in een canvas en als een nieuw canvas

De Font/DA Mover toont meer nuttige informatie over resources, inclusief hun bijdrage aan de grootte van een deck op schijf. Je kunt nu ook het script van de Lil-module vanuit deze dialoog openen.

Bijschrift: Resource-metadata bekijken

Zoals gebruikelijk zijn er diverse toevoegingen gedaan aan de scripting-API's:

  • De System Interface bevat nu sys.z voor het verkrijgen van de lokale tijdzoneverschuiving, en sys.ops voor het meten van het werk dat is verricht door de bytecode-interpreter van Lil.
  • De App Interface heeft app.gridsize, app.penstroke en app.penfill gekregen voor het inspecteren en wijzigen van de status van de bewerkingshulpmiddelen van Decker, app.kiosk voor het vergrendelen van Decker in weergaveomgevingen, en app.params voor toegang tot URL-parameters die aan Web-Decker worden meegegeven.
  • De RText Interface biedt rtext.trim[] als een algemenere versie van de nieuwe trim-operator voor rich text-tabellen.
  • De Sound Interface interpoleert lineair over samples wanneer deze wordt benaderd via niet-integrale sample-indices; de functie sound.scale[] kan waveforms indrukken, uitrekken en omkeren met betrekking tot tijd, en de overload read["sound" "samples"] kan grote audiobestanden importeren als een Array van samples.
  • De Image Interface biedt image.transform["turn"] als een snelkoppeling voor het roteren van afbeeldingen met 180 graden, image.outline[] voor het toevoegen van een rand langs de randen van elk ondoorzichtig gebied van de afbeelding, en image.merge[] ondersteunt nu XOR-compositing met de ^ operator.
  • De Danger Interface biedt danger.open[] om Decker aan te sturen een specifiek document te openen, via URL/pad of een Deck Interface, waardoor het mogelijk is om launchers te bouwen of zeer grote projecten uit meerdere decks aan elkaar te rijgen.
  • De Array Interface ondersteunt nu casts van f32l, f32b, f64l of f64b voor het werken met floating-point waarden, en het array.value-attribuut biedt een handige snelkoppeling voor het converteren van een volledige array naar een primitieve lijst of string.

Een taal laten groeien

De evolutie van de scriptingtaal van Decker, Lil, beweegt zich voortdurend naar stabiliteit, maar er zijn enkele verfijningen en toevoegingen gedaan, beginnend met correcties aan het gedrag van verschillende operators.

De vergelijkingsoperators < en > zijn overbelast om numerieke vergelijkingen uit te voeren wanneer ze een paar numerieke argumenten krijgen, en om een paar strings lexicografisch te vergelijken. Wanneer waarden van gemengde typen werden gegeven, "voorkeurden" deze operators oorspronkelijk om beide argumenten als strings te interpreteren. In de praktijk leidde dit tot verwarrende resultaten, zoals wanneer gebruikers een getal in een veld opsloegen en het .text-attribuut (een string) van het veld gebruikten in plaats van het .data-attribuut (numeriek):

theField.text      # "23"
3 > theField.text  # 1

De < en > operators geven nu de voorkeur aan een numerieke interpretatie als een van de argumenten numeriek is, consistent met het gedrag van de | (maximum) en & (minimum) operators:

3 > "23"  # 0
30 > "23" # 1

Ook is een subtieler defect in het gedrag van de tabel-operator gecorrigeerd. Deze operator onderzoekt de structuur van zijn argument om zowel list-of-dict als list-of-list data om te zetten in een Lil-tabelwaarde. Met de introductie van de nil-waarde is dit gedrag aangepast, waarbij nils in een lijst worden geaccepteerd als lege lijsten, en nils in een lijst van dictionaries als lege dictionaries:

table "%j" parse "[[11,22],null,['a','b']]"
# +-----+-----+
# | c0  | c1  |
# +-----+-----+
# | 11  | 22  |
# | nil | nil |
# | "a" | "b" |
# +-----+-----+

table "%j" parse "[{'a':11},null,{'a':22}]"
# +-----+
# | a   |
# +-----+
# | 11  |
# | nil |
# | 22  |
# +-----+

Ten slotte zijn er aanpassingen gedaan aan de raze-operator, die verantwoordelijk is voor het reduceren van lijsten. De basisgevallen van raze maakten voorheen elementen met een enkele waarde plat tot atomen; het herziene gedrag houdt ze als lijsten voor een betere interne consistentie:

raze list 23  # was 23        nu is (23)
raze 23       # was 23        nu is (23)
raze "AB"     # was ("A","B") nu is ("AB")

Lil heeft vier nieuwe monadische operators gekregen om veelvoorkomende idiotismen te vereenvoudigen: trim, ceil, rev en distinct.

De trim-operator verwijdert witruimte aan het begin en/of einde van een string. Deze kan over een hele lijst worden toegepast:

trim "  ab c\n"      # "ab c"
trim (" a"," b")     # ("a","b")

De ceil (ceiling) operator rondt getallen naar boven af, als tegenhanger van floor. Ook deze is conformistisch:

ceil (0.1,2.5,37.9)  # (1,3,38)

De rev-operator keert de volgorde van elementen in een string, lijst of dict om:

rev "abc"            # "cba"
rev (11,22,33)       # (33,22,11)
rev "abc"dict"def"   # {"d":"a","e":"b","f":"c"}

De distinct-operator extraheert de niet-duplicerende elementen uit een string, lijst, dict of tabel:

distinct "cabba"     # "cab"
distinct (2,1,3,2,1) # (2,1,3)

De trim-operator voorkomt onnodige interne string-kopieën wanneer deze wordt gebruikt om prefixen te trimmen, en distinct maakt gebruik van interne hashsets. Bij correct gebruik kunnen deze nieuwe operators een aanzienlijke positieve impact hebben op de prestaties.

De Bits-interface is uitgebreid met .decode[] en .encode[] operaties voor het afbreken van getallen in lijsten van binaire cijfers, of het opnieuw verpakken van binaire cijfers in getallen.

bytes:112,112,32,112,168,32,80,80
i:image[8,count bytes]
i.pixels:bits.decode[8 bytes]
i.pixels
# ((0,1,1,1,0,0,0,0),
#  (0,1,1,1,0,0,0,0),
#  (0,0,1,0,0,0,0,0),
#  (0,1,1,1,0,0,0,0),
#  (1,0,1,0,1,0,0,0),
#  (0,0,1,0,0,0,0,0),
#  (0,1,0,1,0,0,0,0),
#  (0,1,0,1,0,0,0,0))
bits.encode[8 i.pixels]
# (112,112,32,112,168,32,80,80)

Een ander hulpmiddel voor extra prestaties in Lil is de nieuw gegeneraliseerde KeyStore Interface. Oorspronkelijk ontworpen voor modules om persistente data te serialiseren, kunnen KeyStores nu ook vrij worden geconstrueerd met de keystore[] functie en gebruikt worden als algemene muteerbare "dictionary-builders".

# een gegeneraliseerde breadth-first search routine,
# gebruikmakend van een KeyStore voor het bijhouden van state predecessors:
on bfs successors start do
local pred:keystore[]
local todo:list start
while count todo
local here:first todo
todo:1 drop todo
each there in successors[here]
if nil~pred[there]
pred[there]:here
todo:todo,list there
end
end
end
pred
end

Het Deckerverse

Er zijn dit jaar veel interessante ontwikkelingen geweest binnen het Decker-ecosysteem. Decker wordt nu geleverd met vijf handige nieuwe voorbeelddecks:

  • Leer over transitie-effecten in All About Transitions.
  • Bereken nuttige statistische maten met de Stats module.
  • Manipuleer en teken vector-tekst met de Hershey module.
  • Genereer procedurele geluidseffecten met Dfxr.
  • Genereer QR-codes met de Qr module.

Naast de officiële Deck-Month 3 en Decker Fantasy Camp 2026 jams, hebben gebruikers diverse andere events georganiseerd:

  • De Hybrid Decker Zine Jam van Millie was gebaseerd op een template om decks te maken die online bekeken of geprint en gevouwen kunnen worden tot boekjes van 8 pagina's.
  • De Decker App Jam richtte zich op het maken van tools en functionele applicaties.
  • De Decker VN Jam van Swanchime gaat over het maken van Visual Novels.

Deze jams hebben collectief geresulteerd in meer dan 113 nieuwe decks op itch.io alleen. Vorig jaar telde ik 213 games op itch.io met de tag #decker; vandaag zijn dat er 353, of 474 als we andere categorieën zoals boeken en strips meetellen.

Enkele opmerkelijke publicaties:

  • Phield Notes van Phinxel: een prachtige multimedia-gids voor beginners over het maken van dingen met Decker.

Bijschrift: Iedereens favoriete behulpzame kleine mannetje, Phinxel

  • Font importer utility van Screwtapello: een tool die diverse bitmap-fontformaten aanpast voor Decker.

Bijschrift: Importeer .fzx, .uf1, .uf2, .uf3, .yaff fonts en meer!

  • Contraptions en art-tools van Missooni, waaronder minart, een tekentool voor 16x16 iconen.

Bijschrift: Exquise miniaturen

  • A bunch of decker tools van Durian: een collectie kleine nuttige programma's.

Bijschrift: De journaling mini-app

  • Zine of Millie EX Compilation: een verzameling zines die ideaal is voor een Deck Kiosk.

Bijschrift: Een op maat gemaakt apparaat voor onderdompeling in Decker

  • What 2000s Skate Video Are You? van Salty P. Slug: een uitgebreid persoonlijkheidsquiz vol vintage 2000s-lore.

Bijschrift: Kies je wagen wijselijk

  • Bonelust van Dogpink (let op: content warnings, waarschijnlijk Not-Work-Safe!): een creatie voor de 2026 Toxic Yuri VN Jam met indrukwekkend schrijfwerk en sound design.

Bijschrift: Nolls verhaal begint

  • The Dreams in the Peacock House van Harlequin Diver: een hybride point-and-click / parser-gedreven interactief verhaal en het eerste Decker-spel dat op Steam is gepubliceerd.

Bijschrift: Een schitterende mix van prerenderde 3D, collage en pixelart

Een belofte voor menselijke creativiteit

De afgelopen jaren zijn creatieve gemeenschappen op het web getroffen door een reeks verontrustende supply-chain aanvallen: kritieke delen van de digitale infrastructuur zijn geïnfecteerd door de uitstoot van zogenaamde "generatieve AI"-tools. Ik geloof dat deze tools diep schadelijk en respectloos zijn voor creatieve expressie, menselijke samenwerking en educatie. Creatieve mensen — inclusief programmeurs, schrijvers, beeldend kunstenaars en game-designers — zouden zich niet gedwongen moeten voelen om "slop" (AI-troep) te accepteren om hun vak uit te oefenen.

Decker is gemaakt door en voor mensen. Decker is nooit ontwikkeld met de hulp van enige vorm van LLM of "genai"-tool. Ik heb geen intentie om deze in de toekomst te gebruiken. De belangrijkste externe afhankelijkheid van Decker is SDL, die een strikt anti-LLM bijdragebeleid heeft, en ik zal mijn best doen om afhankelijkheden die slop bevatten te vermijden of geleidelijk te vervangen. Browser- en besturingssystemen die volledig vrij zijn van slop vormen een grotere uitdaging, maar Native-Decker ondersteunt netBSD en Haiku.

De creatieve arbeid van mensen heeft onze online wereld gebouwd. Als we daartoe gedwongen worden, kunnen we stukje bij stukje een nieuwe bouwen.

Conclusies

Als Decker interessant klinkt, overweeg dan om lid te worden van het Decker Community Forum! Er is ook een Decker-resource-index beschikbaar met veel lettertypen en andere extra's.

De volgende officiële Decker jam, Deck-Month the fourth, staat gepland voor december 2026. Afhankelijk van wanneer je dit leest, is er wellicht nog een kleine kans om deel te nemen aan The Decker VN Jam. Daarnaast is er een in-person Decker jam gepland voor 24 oktober in de regio Rochester.

Bouw iets waar je gelukkig van wordt.