Friday 27 Nov
- Doors open, registration
- Harbour kitchen opens
- Opening ceremony
- Seminar: a city in 4 kilobytes
- Shader showdown heats
- Live act on the bigscreen
Demoparty · 27–29 November 2026
Three days of real-time art at the dark end of the year. Demos, intros, tracked music and pixels on a 14-metre bigscreen, a sauna on the pier, and coffee that never stops.
The old ferry terminal, Pier 4Doors open Friday at 16:00
The competitions
Bring a prod or make one on the spot. Deadlines are Saturday at 18:00 unless a card says otherwise, and remote entries are welcome through the party system.
Up to eight minutes, any graphics API, one compo machine with a very loud GPU. The main event.
€1,500 prize poolEverything in one 65,536-byte executable: the music, the meshes, the story.
€6004,096 bytes. Shaders welcome, sanity optional.
€600Amiga, C64, Atari ST and friends, shown on the real hardware. Copper bars mandatory. Not really. Mostly.
€600Two coders, two screens, twenty-five minutes of live coding while a DJ plays. The hall votes.
A golden keyboardPatterns and samples: MOD, XM or IT, up to four minutes. Channel count is between you and your tracker.
€400Anything that plays, up to four minutes. Headphones in the hall on request.
€400Hand-placed pixels only. Bring your work stages; the jury loves a timelapse.
€400Plotters, oscilloscopes, knitting machines, a demo on a fridge. If it runs, it competes.
€400Timetable
The harbour
The old terminal on Pier 4 hasn't seen a ferry since 1998. Once a year it sees six hundred sceners instead.
A 14-metre LED wall in the old departure hall, with 7.1 sound and a compo machine for every platform.
Upstairs in the old waiting lounge, quiet from 02:00. Bring a sleeping bag and a mat.
On the end of the pier, Saturday 20:00 to 02:00. Towels at the info desk. The sea is four degrees.
Soup, smoked salmon and a vegan pot, from noon to midnight. Breakfast on Saturday and Sunday.
Around the clock, from a machine old enough to have a name. Ask the info desk what it is.
One socket and a gigabit per seat. Bring an extension cable, and please no space heaters.
Tickets
Every ticket includes a seat, the sleeping hall and the sauna. Card, cash or a very convincing floppy.
€40
All three days, a seat with power and network, and a spot in the sleeping hall.
€80
The same, plus the party shirt and a line in the closing scroller. You keep the party free for students.
€10
Watch the stream, vote from home, and enter any compo remotely.
Free
With a parent or guardian. The next generation of sceners gets in for nothing.
Questions
Yes. Half the hall comes to watch the bigscreen, not to compete. Say hello to your neighbours; they have been waiting all year to show someone their work.
No, but most people do. Every seat has a socket and a wired gigabit. The compo machines are ours, so you don't need to bring one to compete.
Day tickets are €20 at the door on Saturday and Sunday. Saturday night is when the big compos run.
The line of text that waves across the bottom of an old demo, full of greetings and inside jokes. Ours answers questions: try it.
Something else? The info desk is open around the clock, in the scroller at the bottom of the page.
How it works
Stand's widget is optional. The scroller along the bottom of this page is a complete Stand chat built from scratch on the Visitor API: it asks Stand who can answer, starts a conversation with the visitor's first message, sends over HTTP, listens on a WebSocket, and recovers after reloads. Everything else is a 1993 demo: a sine scroller, copper bars, a starfield and glenz vectors, drawn with WebGL 2 in a pixel font made for it.
siteId: 'demo', Stand Chat's shared demo site, which works on any domain. Its demo Stand-in plays the info desk from the page's prompt. With your own Site ID, your own Stand-ins answer, and your team can take over.stand-client.js is the whole network side, with no UI and no dependencies. It is the Vintage terminal's client, unchanged but for where it saves the chat. It follows the custom chat UI guide, including the parts that are easy to skip: recovering after a reload or a dropped socket, merging messages without duplicates, and never starting two conversations from one click.
// Who can answer on this page? Public: no key, no token.
const offer = await get(`/v1/reps/find?siteId=${siteId}&page=${page}&greetingsEnabled=false`);
// The visitor's first message starts the conversation, once.
const session = await post('/v1/sessions', {
siteId, page,
standinProfileId: offer.standinProfileId, // or repId, when a person answers
initialMessage: text,
includeOpeningGreeting: true, openingMessage: greeting, // the scroller's words
prompt, // the info desk persona and the party's facts
});
// Later messages over HTTP, replies and handoffs over a WebSocket.
await post(`/v1/sessions/${id}/messages`, { body, type: 'text', clientMessageId }, token);
const socket = new WebSocket(`wss://api.stand.chat/ws/sessions/${id}?token=${token}`);
The greeting in the scroller is the one the conversation opens with: Stand stores it as the first message, so your team sees what the visitor saw. The prompt gives the demo Stand-in its info desk voice and the party's facts: doors, compos, the sauna.
A sine scroller bends every letter column by column along the wave. When you open the chat, strip.js takes a snapshot of every lit pixel on screen. The greeting's pixels are paired with the pixels of the same letters in the chat, each on a curve that bursts outwards before it pulls home, and the rest fall away like sparks. The particles land exactly on the letters' pixels, so the chat's text takes over without a seam.
for (let k = 0; k < n; k++) {
const [sx, sy] = from[Math.floor((k * from.length) / n)]; // a pixel on the wave
const [lx, ly] = lit[Math.floor((k * lit.length) / n)]; // the same letter, in the chat
const tx = target.x + lx * target.size;
const ty = target.y + ly * target.size;
// A burst outwards first, then the pull home: a quadratic Bézier.
const angle = rnd() * Math.PI * 2;
particles.push({ sx, sy, tx, ty, cx: sx + Math.cos(angle) * burst, cy: sy + Math.sin(angle) * burst });
}
Replies don't type out. Each letter leaves the right edge in reading order, rides the sine wave, and stops where it belongs, so a reply arrives as a little scroller that comes to rest as text. Long replies speed up; Enter on an empty line lands everything at once.
const emit = glyph.order / rate; // when the letter leaves the right edge
const distance = startX - x; // how far it flies
const land = emit + distance / speed; // when it gets there
if (age < emit) continue; // not yet
if (age < land) {
const left = distance - (age - emit) * speed;
x += left; // still flying,
y += Math.sin(x / wavelength - now * 7) * amplitude * Math.min(1, (left / distance) * 2.5); // on the wave
}
Nearly everything is a sprite, drawn in a few instanced WebGL 2 calls a frame: letters, copper bars, stars, particles. The pixel font is drawn in text in font.js, one glyph per little grid, and accented letters are composed from a letter and a mark, so Mäkinen and Łódź work too. Anything the font doesn't have, like emoji or Japanese, the browser draws at twice the font's resolution. The glenz vectors are the real thing: 24 see-through triangles, rotated on the CPU and drawn at the chunky virtual resolution.
const SHEETS = [
[2, `
a b c d e f g
..... #.... ..... ....# ..... ..## .....
..... #.... ..... ....# ..... .#.. .....
.###. ####. .###. .#### .###. #### .####
....# #...# #.... #...# #...# .#.. #...#
.#### #...# #.... #...# ##### .#.. #...#
#...# #...# #.... #...# #.... .#.. #...#
.#### ####. .###. .#### .###. .#.. .####
..... ..... ..... ..... ..... .... ....#
..... ..... ..... ..... ..... .... .###.
`],
// …
];
The hero's glenz is part of the party site, not of the chat, so the two talk through events. When the glenz is clicked, or batted three times in three seconds, intro.js hands the chat its position and spin. The chat takes over: the glenz hops and drops onto the scroller, the impact bursts the letters away from where it hit, and the glenz rises to its place beside the chat. When the chat closes, the glenz drops back into the hero.
dispatchEvent(new CustomEvent('scroller-chat:open', {
detail: { glenz: { x, y, r, a, b, c } }, // where it is on screen, in CSS pixels, and its rotation
}));
addEventListener('scroller-chat:closed', () => dropBackIn());
The music keeps time for everything: music.bar() says how far the tune is through the current bar, so the glenz lands every bounce on the first beat, and music.level() flares the copper bars on the drums.
stand-client.js is the part to copy: discovery, one-time creation, idempotent sends, WebSocket receive, recovery, handoffs, follow-ups and link clicks.transcript.js turns Stand's state into what the chat shows: replies, your own lines, notices, link cards and who is speaking.screen.js is the chat screen: layout, the text writer, the input line with its block cursor, scrolling and the header.strip.js is the scroller and the morph from scroller to chat.effects.js and gl.js are the demo: copper bars, starfields, glenz vectors, and WebGL 2 sprites with a glyph atlas.font.js is the pixel font; music.js a four-channel tune synthesized in Web Audio, on by default; intro.js the hero's invitation intro and its glenz, with the same effects.scroller-chat.js puts it on the page: the settings, layout, opening and closing, the keyboard and a screen-reader version of the chat./music, turns it off, and the page remembers. It pauses in a hidden tab.This example is nearly a one-shot. Claude Opus 5.5, with max effort, in Claude Code, built it in one session from the prompt below and one follow-up: the pixel font, the effects, the tune and the party. It read the custom chat UI guide, tested the info desk's voice in real conversations with Stand's demo site, and checked its own work in headless Chrome, from screenshots at desktop and phone sizes to a recording of the music.
Now that AI writes the front end, a chat can look like anything your site's world calls for, even a scroller from 1993. Stand's Visitor API keeps the conversation, the AI Stand-in and your team behind it.
The prompt, lightly edited
Think of Future Crew's Unreal and other legendary demos of that era. Could some of their visual effects make a fun experience that transforms into a chat? Imagine such an effect and build an example for this repo: - A creative website on a fitting topic - A demo effect that captures the attention and transforms into a chat
The follow-up
This is cool! Have the music on by default on the page. The track is awesome. Have the bouncing shape react to the cursor and scrolling, subtly. If the visitor seems to play with it on purpose, have it open the chat, and have it take part in that animation.
If you try this yourself
demo Site ID, so the agent can hold real conversations while it builds and tests, then switch to yours.stand-client.js here is the one from the Vintage terminal; only the presentation is new.npx degit standchat/examples/raster-harbour my-scroller