NoaCGStudio

Documentation

Guides for making a graphic and putting it on air.

The studio is at noacg.studio/app and it is free. You need an account only to publish a production or to let a coding agent save into your library. Making and exporting graphics works without one.

Getting started

NoaCG Studio makes broadcast graphics in the browser: lower thirds, scoreboards, tickers, quiz boards and countdowns. You make a graphic, then put it on air in the system your studio already uses.

Three ways to start
  1. A template. Pick a design from the catalog, then set its text, colors and logo. Open the studio →
  2. Your own design. Name the layers in Illustrator, save an SVG, import it and choose what it does. Import an SVG → or get the SVG examples →
  3. Your coding agent. Use Claude Code or Codex with the NoaCG CLI. Describe the graphic you want, and it appears in your NoaCG library. Set up your agent →

Then put it on air:

Graphics

Draw your graphic in Illustrator, Figma or Inkscape and import it as an SVG. Every text layer becomes a field the operator can retype. The layer names tell NoaCG what kind of graphic it is, so a scoreboard gets score buttons and a quiz gets quiz buttons.

Pick a type to see how to lay it out:

  • Scoreboard - two teams and two scores.
  • Quiz - a question and two to six answers.
  • Live vote - options with bars that grow as the audience votes.
  • Countdown - a clock that counts down to zero.
  • End credits - roles and names.
  • Ticker - a tag and a story line.

Any other graphic needs no special names. Its text layers become fields.

Import an SVG

  1. Open the studio and choose Import graphic. No account is needed until you publish a production.
  2. Set Project format first. The default is 16:9, 1920×1080, 25 fps. It locks once your file is in, with the message "Remove the current artwork before changing its authored canvas".
  3. Drop your SVG. NoaCG shows the size, the text layers and the fonts it found. Fewer text layers than you drew means some text was exported as outlines. To try it first, use name-tag.svg.
  4. Check the Fields step. Every ticked layer is a field the operator types into, labelled with your layer name. What it does shows the type NoaCG found from your layer names. You can change it and pick the layers yourself.
  5. Choose how the graphic comes on and goes off in Animation.
  6. In Finish, name the graphic and choose Add to the production or Export it. Both save it to your library. Skip to finish in the footer of any earlier step jumps here and keeps the defaults.
The Import graphic step, with the drop zone and the export settings open beneath it.
The drop step. "Exporting the SVG" opens the export settings.
The Fields step for name-tag.svg: Name and Role listed as operator fields beside a live preview of the imported name tag.
The Fields step. Your layer names are the field names the operator reads.

On air

Add to the production takes you to the production with your graphic in the rundown. Press Take to put it on air. Type new text, then press Update to send it. Until you do, the panel says "1 change not on air yet" (before you publish, "not on PROGRAM yet"). Out takes the graphic off. For OBS, vMix or CasparCG, see the playout dashboard.

Prepare the SVG file

  • Give it a size. Use a 1920×1080 artboard with a transparent background and draw the graphic where it sits on screen, so a lower third goes at the bottom of that artboard. In Illustrator tick Use Artboards when you save the SVG, or the file is cut down to the drawing. A smaller artboard imports as a floating object that you place in the wizard.
  • Keep text as text. Do not convert text to outlines, because outlined text cannot be edited.
  • Name your layers. The name is the label the operator sees. For the types below it is also how NoaCG finds each part.
  • Embed pictures. Linked pictures are removed, because an exported graphic has to play without a network.
  • No animation or scripts. SVG animation, scripts and <foreignObject> are removed. Add motion in the Animation step.

Export settings

AppSettings
IllustratorFile → Save a Copy… → SVG, with Use Artboards ticked. In SVG Options: Fonts Type SVG, Subsetting None (Use System Fonts) · Image Location Embed · Preserve Illustrator Editing Capabilities off · under More Options, CSS Properties Style Elements. Do not use Export → Export As for a graphic with hidden layers: Illustrator 2026 leaves every hidden layer out of that file.
FigmaSelect the frame, Export → SVG. Include "id" attribute on, Outline text off.
InkscapeSave As… → Plain SVG. Do not run Object to Path on text. Click to place text instead of dragging a text box: a dragged box exports as <flowRoot>, which browsers do not show.

Fonts

NoaCG lists every font the file uses. For each one it uses a bundled font, offers the same family from Google Fonts, or takes a font file you upload. The font is embedded in the graphic, so it plays offline. If nothing matches, you get a warning and the graphic uses a fallback font.

Layer names

Layer names in 30 seconds
  • Three layers, top of the Layers panel first: Text is what the operator types, Moments is what NoaCG shows or moves, Board stays as drawn. No moments, no Moments layer.
  • Name each text for what it is, the row last after a space: Question, Answer A, Team 1, Score 1. A title is Title and Subtitle, a name tag Name and Role, credits Heading and Credits.
  • A moment is a hidden group, with its row where it has one: Selected A, Flash 1, Full time. A bar is drawn at full length and left visible: Bar 1.
  • On the Board the background is Panel, a plate under a text is that text's name plus box (Question box, Answer box A, Score box 1), and fixed words start with static: (static:Letter A).
  • Anything else on the Board is decoration with any name. Every name is English. Save with File > Save a Copy > SVG.

Layer names are shared across graphic types. Use the layers your graphic needs.

To start from a working file, download the SVG examples: editable Illustrator and SVG sources covering every SVG import behaviour, with previews and authoring guides for clocks, timers and editable credits.

SVG example files

Download an SVG to try it in NoaCG or edit it in Illustrator or Inkscape. The complete package also includes Illustrator sources and layer-name guides.

The three layers

  • Text holds what the operator types. One text object per field, named for what it is: Question, Team 1.
  • Moments holds what NoaCG shows, hides or moves. A hidden group for each moment, such as Selected A or Full time, and a bar drawn at its full length, such as Bar 1.
  • Board holds what stays as drawn: the panel, the row plates, the letters and the labels.
  • A graphic with nothing to show or hide, such as a title, a name tag or the credits, has only Text and Board. Illustrator leaves an empty layer out of the SVG anyway.

Names on the Board

  • The background is Panel.
  • A plate under a text is that text's name plus box, with the row last: Question box, Answer box A, Score box 1. The wizard lists each plate by that name, so the plate and its text read as a pair.
  • Fixed words start with static:, as in static:Letter A.
  • Anything else is decoration and can have any name, like Edge or Rule.

A name is a word and a row

  • The word says what the layer is. The row is one letter or one number, last, after a space: Answer A, Score 1, Winner 2. A quiz counts in letters, because the letters are drawn on the board. Everything else counts in numbers.
  • Layers with the same row belong together. Answer B, Selected B, Correct B and Wrong B are all answer B.
  • A moment is a group that you hide in your design app. A hidden shape on its own is not found, so put it in a group, even a group of one. Text inside a hidden group is drawing, not a field.
  • A text that stays as drawn starts with static:, as in static:Letter A. A text that is a single letter, like the A on a quiz row, starts unticked whatever it is called.
  • The spelling does not matter, the words do. Capitals, spaces, underscores and dashes are all the same to NoaCG. So Answer A, answer_a and ANSWER-A are one name. AnswerA is Answer A too, and Score1 is Score 1.
  • The synonyms in the table below work too. The common words also work in Finnish, Swedish, German and Spanish: Antwort A, Puntos 1. The three layers can be called Text, Moments and Board in your own language, because NoaCG reads the names inside them.
  • In Illustrator, name each text object (double-click its row), or put it alone in a layer with the name: a text inside a layer called Question is Question. Four unnamed texts inside a layer called Answers are all Answers, and no type is found. Save the file with Save a Copy as above, because Export As leaves hidden layers out.
  • When the names fit a type, the wizard picks that type in What it does and fills in every layer. When a name does not fit, pick that layer from the list yourself.
Layers: the quiz
  • ▾Text
    • TAnswer D
    • TAnswer C
    • TAnswer B
    • TAnswer A
    • TQuestion
  • ▾Moments
    • ▸Wrong Dhidden
    • ▸Correct Dhidden
    • ▸Selected Dhidden
    • the same for C and B
    • ▸Wrong Ahidden
    • ▸Correct Ahidden
    • ▸Selected Ahidden
    • ▸Locked inhidden
  • ▾Board
    • Tstatic:Letter D
    • static:Letter C, B, A
    • ▭Answer box D
    • Answer box C, B, A
    • ▭Edge
    • ▭Panel

One full tree

The quiz example, exactly as Illustrator's Layers panel shows it. Amber names are the ones NoaCG reads. In Board, Panel is the background, each answer sits on its own Answer box, the letters are fixed words and Edge is decoration.

Illustrator opens the three as groups inside one layer. Three layers of your own with the same names work the same way.

quiz.svg, scoreboard.svg, live-vote.svg, countdown.svg, end-credits.svg, ticker.svg and name-tag.svg.

Every name NoaCG reads

The layers each type looks for. Name it is the spelling the examples use; the names under Also works are read the same way. Change the row to match your own rows: Answer A is also Answer B, and Team 1 is also Team 2.

LayerName itAlso worksWhat it does
Score tracker
Team (one per row)Team 1Side 1, Player 1, Joukkue 1, Lag 1a field the operator types
Score (one per row)Score 1Points 1, Goals 1, Team 1 Score, Pisteet 1, Poäng 1a field - draw a plain number in it
Flash (one per row)Flash 1Goal 1, Scored 1, Maali 1, Mål 1shown for the moment that team's point lands
Full timeFull timeFinal, Game over, Loppu, Full tidonce the game is called (one, whole board)
Two to eight teams.
Quiz
QuestionQuestionKysymys, Frågaalways - it is a field the operator types
Answer (one per row)Answer AVastaus A, Svar Aalways - a field
Selected (one per row)Selected APicked A, Chosen A, Valittu A, Vald Awhile that answer is the pick
Correct (one per row)Correct ARight A, Oikein A, Rätt Aon the reveal, if it is the correct answer
Wrong (one per row)Wrong AIncorrect A, Väärin A, Fel Aon the reveal, if it is not
Locked inLocked inLocked, Lukittu, Låstonce the answer is locked (one, whole board)
Two to six answers.
Live vote
QuestionQuestionKysymys, Frågawritten from the round
Option (one per row)Option 1Choice 1, Answer 1, Vaihtoehto 1, Alternativ 1written from the round
Bar (one per row)Bar 1Palkki 1, Stapel 1draw it at its FULL length - that length is 100%
Percent (one per row)Percent 1Share 1, Osuus 1, Procent 1appears with the result
Winner (one per row)Winner 1Voittaja 1, Vinnare 1only on the row that won, and never on a tie
Total votesTotal votesÄäntä, Rösterwritten from the round
Vote badgeVote badgeÄänestä, Röstawhile voting is open
Two to eight options.
Countdown
Clockanythingthe readout - set its row to Countdown
Timer barTimer barDrain, Countdown bar, Aikapalkki, Tidsbalkdraw it at its FULL length - that length is the whole count
WarningWarningLast stretch, Hurry, Varoitus, Varningthe look the final seconds wear
PausedPausedHold, Tauko, Pauswhile the operator is holding the clock
Time upTime upExpired, Finished, Aika loppu, Tiden uteonce it reaches zero
Standings
Competitor (one per row)Name 1Row 1 name, Competitor 1, Player 1, Nimi 1a field the operator types - it travels with its row
Points (one per row)Points 1Row 1 points, Pts 1, Score 1, Pisteet 1a field - draw a plain number in it; the rows sort by it
Position (one per row)Position 1Row 1 position, Rank 1, Place 1, Sija 1the place number drawn in that slot - it stays put and is renumbered on a tie (1, 2, 2, 4)
Row plate (one per row)Row 1Plate 1, Card 1, Rivi 1a drawing behind the row that travels with it (optional)
Two to ten rows, each drawn in its starting place with first place at the top. Tick Lowest first for times and golf scores.
Meter
BarProgress barMeterdraw it at its FULL length - that length is the target
PercentPercentShare, Osuuswritten as the current figure's share of the target
Survey board
QuestionQuestionKysymys, Frågaa field the operator types
Answer (one per row)Answer 1Vastaus 1, Svar 1draw it as it looks revealed - written from the Answers box, hidden until its reveal
Points (one per row)Points 1Pts 1, Pisteet 1a plain figure - written from the Answers box, shown with its answer
Revealed (one per row)Revealed 1Flip 1, Open 1shown once that answer is revealed
Strike 1Strike 1X 1the first X, lit from the first strike on
Strike 2Strike 2the second X
Strike 3Strike 3the third X - and the Strike button greys
TotalTotalSum, Yhteensäwritten by NoaCG: the points of the revealed answers, added up
Two to eight answers.
Stepped list
Entry (one per row)Item 10Entry 10, Number 10, Kohta 10draw it as it looks revealed - written from the Entries box, hidden until its number comes up
Mark (one per row)Mark 10Current 10, Highlight 10shown on the entry that just arrived, until the next one does
Two to twelve entries; the option decides whether they arrive from the last number down or from 1 up.
Lineup
Guest (one per row)Guest 1Act 1, Speaker 1, Vieras 1a field the operator types
On now (one per row)Now 1Current 1, Nyt 1shown on the guest who is on
Been on (one per row)Done 1Been 1, Past 1shown on every guest who has already been on
Two to eight guests, in the order they come on.
Puzzle board
CategoryCategorya field the operator types
Letter (one per row)Letter 1Tile 1, Kirjain 1one letter, drawn as it looks revealed - written from the phrase, shown once its letter is called
Used (one per row)Used 1White 1shown on every tile the phrase reaches - the white face behind a letter still hidden
SolvedSolvedRatkaistuonce the puzzle is solved (one, whole board)
Four to forty tiles, numbered left to right and then down; the phrase is laid over them in that order, so put spaces where the tiles should stay blank.
Reveal
The revealPriceSecret, Reveal, Hintadraw it as it looks revealed - written from The reveal box, hidden until the press
CoverCoverEnvelope, Sealed, Kansishown until the reveal - the sealed plate over the text
Bingo caller
Numeral (one per row)Number 7Ball 7, Numero 7the numeral on a tile, left as you drew it - naming it keeps it out of the operator’s fields
Called (one per row)Called 7Marked 7, Huudettu 7shown on a number once it has been called
Last called (one per row)Last 7Latest 7, Ring 7shown on the number called most recently, until the next call
Last call readoutLast callLatest, Now callingthe number called most recently, written large - hidden until the first call
CountCountCalls, So farhow many numbers have been called, written by the board
Five to ninety numbers, one Called layer each. Name the numeral on each tile Number 1, Number 2 and so on, and it stays your drawing instead of arriving as a field.
Credits roll
CreditsCreditsCredit list, End credits, Lopputekstit, Eftertexterthe layer the credits are read from: the first role, when each role and each name is its own text layer, or one text object holding every line, which scrolls as fixed artwork
Credits boxCredits boxCredits panel, Credits window, Lopputekstit laatikkoa window used only by credits saved by an earlier version; new imports use the whole frame and need no box

Names for any graphic

  • static: at the start of a text layer's name, as in static:Heading, keeps the text as drawn. It is not an operator field.
  • f: at the start of a picture's name, as in f:Logo, makes it a field the operator can swap. Pictures without it start unticked.
  • Text drawn as a plain number, such as 84, becomes a number field with + and − buttons.
  • Text drawn as a time, such as 05:00, can become a clock or a countdown.
  • Give every layer its own name. If two layers are both called Bar, the second one becomes Bar 2.
  • Panels, lines, gradients and masks stay exactly as drawn.

When the operator types more than fits, NoaCG first uses the room in the shape behind the text, then wraps it onto a new line, then makes it smaller. Nothing is cut off.

Credits: editable or fixed artwork

Draw each role and each name as its own text layer, in one role look and one name look, and the credits stay an editable list in your styling. Draw the whole list as one text object and it scrolls as fixed artwork. No special names are needed. See End credits.

Scoreboard

Two team names and two scores. The operator adds a point with one press.

The example scoreboard: OTAVA 2, KARHUT 1 on a dark bar with an amber edge.
The example file. Download scoreboard.svg
Layers
  • ▾Text
    • TTeam 2
    • TScore 2
    • TScore 1
    • TTeam 1
  • ▾Moments
    • ▸Flash 2hidden
    • ▸Flash 1hidden
    • ▸Full timehidden
  • ▾Board
    • ▭Edge
    • ▭Divider
    • ▭Panel

Layer names

  • Team 1 and Team 2: text. Required.
  • Score 1 and Score 2: text, drawn as a plain number such as 2. Required.
  • Flash 1 and Flash 2: hidden group. Shows for a moment when that team scores. Optional.
  • Full time: hidden group. Shows at the end of the game. Optional.

Up to eight teams: Team 3, Score 3 and so on.

Buttons

  • +1 and −1 for each team. +1 also shows that team's Flash layer.
  • Clear flash hides the Flash layer again.
  • Full time shows the Full time layer.
  • New game sets every score to 0.

The operator can also type any score straight into its field.

The Fields step for scoreboard.svg, with Score tracker picked under What it does.
After the drop. The wizard picks Score tracker from the layer names.

Quiz

A question and two to six answers. The operator selects an answer, locks it in and reveals the correct one.

The example quiz board: a question over four lettered answer rows.
The example file. Download quiz.svg
Layers
  • ▾Text
    • TAnswer D
    • Answer C, B, A
    • TQuestion
  • ▾Moments
    • ▸Wrong Dhidden
    • ▸Correct Dhidden
    • ▸Selected Dhidden
    • the same for C, B and A
    • ▸Locked inhidden
  • ▾Board
    • Tstatic:Letter D
    • static:Letter C, B, A
    • ▭Answer box D
    • Answer box C, B, A
    • ▭Edge
    • ▭Panel

Layer names

  • Question: text. Required.
  • Answer A, Answer B and on to Answer F: text. At least two. Required.
  • Selected A: hidden group. Shows on the answer the operator picks. Optional.
  • Correct A: hidden group. Shows on the correct answer at the reveal. Optional.
  • Wrong A: hidden group. Shows on every other answer at the reveal. Optional.
  • Locked in: hidden group. Shows once the answer is locked in. Optional.

Draw the same three for every answer: Selected B, Correct B and so on. A moment you do not draw gets NoaCG's own highlight. The letters on the rows are static:Letter A and so on, so they stay as drawn.

Buttons

  1. Set Correct answer before the show. It changes nothing on screen.
  2. Select answer highlights the letter in Selected answer. Press it again with another letter to change the pick.
  3. Lock it in makes the pick final.
  4. Reveal correct shows the right answer. It uses the letter in Correct answer as it is now, even if you changed it without pressing Update.

Reveal choice keeps the pick secret until you reveal it: choose the letter in Selected answer, press Update, then Lock it in without pressing Select answer. The board shows it is locked but not which answer. Reveal choice then shows the pick.

The Fields step for quiz.svg, with Quiz picked and each answer's selected, correct and wrong layers filled in.
After the drop. The wizard picks Quiz and fills in the hidden layers for each answer.

Live vote

The audience votes on their phones at your join link, and the bars grow with the count.

The example vote board: a question over three options, each with an amber bar and a percentage.
The example file. Download live-vote.svg
Layers
  • ▾Text
    • TTotal votes
    • TPercent 3
    • Percent 2, Percent 1
    • TOption 3
    • Option 2, Option 1
    • TQuestion
  • ▾Moments
    • ▸Vote badgehidden
    • ▸Winner 3hidden
    • Winner 2, Winner 1
    • ▭Bar 3
    • Bar 2, Bar 1
  • ▾Board
    • ▭Track 3
    • Track 2, Track 1
    • ▭Edge
    • ▭Panel

Layer names

  • Option 1, Option 2 and on to Option 8: text. At least two. Required. The vote writes each option's wording here.
  • Bar 1, Bar 2 and so on: a rectangle drawn at full length. Full length is 100%. Required.
  • Question: text. Optional.
  • Percent 1 and so on: text. Shows that option's share. Optional.
  • Winner 1 and so on: hidden group. Shows on the winning row. Optional.
  • Total votes: text. Optional.
  • Vote badge: hidden group. Shows while voting is open. Optional.

The Bar layers are what make the wizard pick Live vote. A bar grows from its left edge. Draw it as a plain rectangle with square ends, because other shapes are stretched. Draw the empty track behind it as its own layer in Board, called Track 1 and so on, never Bar.

Buttons

  • Close voting stops the vote.
  • Show result shows the final figures.
  • Call the winner shows the Winner layer on the row that won.

You open the vote itself on the production's Audience tab. The counts reach the graphic as a cue that you still take to air.

The Fields step for live-vote.svg, with Live vote picked and each option's bar, percent and winner layers filled in.
After the drop. The wizard picks Live vote and pairs each option with its bar.

Countdown

A clock that counts down to zero. The operator sets the length in minutes.

The example countdown card: NIGHT SIGNAL, STARTING IN, 05:00 in large amber digits over a thin bar.
The example file. Download countdown.svg
Layers
  • ▾Text
    • TClock05:00
    • TShow title
  • ▾Moments
    • ▸Time uphidden
    • ▸Pausedhidden
    • ▸Warninghidden
    • ▭Timer bar
  • ▾Board
    • Tstatic:Status
    • ▭Track
    • ▭Edge
    • ▭Panel

Layer names

  • One text layer drawn as a time, such as 05:00. Any name; the example calls it Clock. Required. Keep it the only text in the file shaped like a time.
  • Timer bar: a rectangle drawn at its full length. It shrinks as the time runs out. Optional.
  • Warning: hidden group. Shows in the last 10 seconds. Optional.
  • Paused: hidden group. Shows while the clock is paused. Optional.
  • Time up: hidden group. Shows at zero. Optional.

The wizard picks Countdown when the file has the time layer and at least one of the four named layers. With only the time layer, drawn as minutes and seconds such as 05:00, the Fields step offers a Clock instead: it counts up, counts down from its time, or counts down to a set date and time. A clock can sit beside a score tracker.

The length

  • The operator types the length in minutes. 3 is three minutes and 0.5 is thirty seconds.
  • Do not type the time you want on screen. 2:30 is two minutes, not two and a half.
  • An empty field, or 0, counts five minutes.

Buttons

  • Take starts the count from the full length.
  • Pause holds the count and Start carries on from there.
  • Reset goes back to the full length and waits for Start.
  • Warn at (seconds) is a field that sets when Warning shows.
The Fields step for countdown.svg, with Countdown picked and the time bar, warning, paused and time up layers filled in.
After the drop. The wizard picks Countdown and the 05:00 layer becomes the clock.

End credits

Credits are one list of roles and names. Draw them so they stay easy to edit, or keep them as fixed artwork. Import the SVG and choose Credits roll.

The Illustrator credits artwork: a centred show title and production team. The complete text continues below the artboard.
The example file. Download end-credits.svg
Layers
  • ▾Text
    • TCredits

Layer names

  • Credits: one long text object containing the complete layout. This example scrolls as fixed artwork.
  • Keep its fonts, alignment, line breaks and spacing as you want them on air.
  • Keep the artboard at the output size. Text below it is included in the roll.

No Credits box, background or special punctuation is needed. To change a name or add one, edit the Illustrator source and import its SVG again.

The SVG import step with the Credits text assigned to the credits roll.
The text keeps its layout. Scroll speed is the playout control.

Editable credits in your styling

  • Draw a short sample with each role and each name as its own one-line text layer.
  • Give every role one look and every name another: font, size or colour.
  • Put each role above its names, or beside its first name with the later names under it.
  • In the Fields step pick the first role. The Credits preview shows the roles and names it read. Plays as is a roll, one still page, or cards.

The operator gets one list to paste or edit, kept in your styling. A paste from Google Sheets or Excel works, and the list can be linked to a Google Sheet. A roll or cards on air keep the list they took; the next Take shows the new one.

Fixed artwork

The text stays part of the artwork: it scrolls exactly as drawn and cannot be edited on the production page. That happens when you choose Show as: Fixed artwork, or when the drawing cannot be read as roles and names, such as one text object holding every line. The Fields step says which, in one line. Scroll speed controls the pace. Each Take restarts the roll, and Out clears it.

The editable list, in imported credits and in the catalog credits designs, is written like this:

Director: Alex Rivera

Camera Operators:
Jonas Berg
Lena Fors
  • A colon ends a role. Everything else is a name.
  • Put a role and its name on one line, or put the role on its own line with the names under it.
  • A blank line starts a new section. # PRODUCTION is a department heading.
  • A tab works in place of the colon, so a paste from a spreadsheet works.

Ticker

A tag and a story line along the bottom of the screen.

The example ticker: an amber SPORT tag and the story United win 3-0 in the cup final.
The example file. Download ticker.svg
Layers
  • ▾Text
    • TStory
    • TKicker
  • ▾Board
    • ▭Kicker box
    • ▭Panel

Layer names

  • Kicker: text. The tag, such as SPORT.
  • Story: text. The headline.

Both are ordinary fields. Panel is the strip and Kicker box is the kicker's plate.

The Fields step for ticker.svg: Kicker and Story ticked as the two operator fields.
After the drop. Kicker and Story are the two fields.

A crawl

An imported ticker shows one story and does not move. For a crawl or a rundown of several stories, start from a ticker design in the catalog instead. It has one text box for the whole rundown:

SPORT: United win 3-0
SPORT:
City held at home
Rovers sign a goalkeeper

Storm warning issued
  • A colon ends a kicker. Everything else is the story.
  • A kicker on its own line applies to every line under it, until a blank line.
  • The colon needs a space after it, so 2:1 and 20:45 stay part of the story.

Pictures, logos and Lottie animations

An SVG is the best thing to bring in, because its text stays text. Other files work too.

FileWhat it is good for
PNG, WebPA finished design, or a logo. Both carry transparency, which is what lets video show through.
JPEG, AVIF, GIFPhotographs and stills. No transparency in a JPEG, so it covers whatever is behind it.
Lottie (.json)A vector animation from After Effects. Stays sharp at any size.
A font file (.woff2, .woff, .ttf, .otf)A licensed face your design needs. Taken by the SVG import when it lists the families it found.
Video (.webm, .mp4)A short sting inside a graphic. Capped at 3 MB, so it is not the way to play a clip.

Ways in

  • As the graphic itself. The studio → New graphic → Import graphic takes a PNG, a JPEG or a WebP as well as an SVG. A picture has no layers to read, so you place the text fields yourself.
  • As a logo on a catalog design. Designs with a logo slot let you upload your file while you make the graphic. You can also leave it empty and fill it at playout.
  • As a file in the graphic. Not available yet. The editor lists the files a graphic carries but cannot add one.

Pictures for a live show are separate. On a production, Add pictures builds one picture graphic that holds all of them, with a cue each. Taking picture three replaces picture one instead of stacking on top of it. A production takes up to twenty.

Files are copied in

A file you bring in is copied into the graphic. Nothing links back to your computer and nothing is fetched when the graphic plays, so a package works on a playout machine with no internet. A web address is not a substitute for the file: the studio warns about one, and a machine that cannot reach it shows nothing.

A picture larger than the frame is re-encoded at the frame's size, which costs no quality. A PNG stays a PNG and a JPEG stays a JPEG. An SVG is never touched, and a smaller picture is never enlarged.

Get the transparency right before you import. A full-frame picture with no transparent areas covers the whole picture on air. That is right for a title card and wrong for a lower third. Export it again as a PNG or a WebP with a transparent background.

What comes out in an export

  • A folder package (OGraf, or a playout system that loads a whole template folder) writes your files beside the template: pictures under images/, fonts under fonts/. Paths are relative, so the folder can be copied anywhere.
  • A single-file package (CasparCG, an OBS or vMix overlay) embeds every file in the one HTML file.

Either way the package is complete and works from a local disk.

The operator page in the package lets an image field switch between the pictures that graphic already carries, plus None. It is not a file browser. If an operator will need another logo on the night, bring it in before you export.

Lottie animations

Adding a Lottie is not available yet. A graphic that already carries one keeps it.

A Lottie plays as soon as the graphic loads and it loops. It does not follow the graphic on and off air, so it suits a badge, a spinner or a looping ornament rather than something that has to hit a cue. It travels inside the package.

Fonts, and what a missing one does

A missing font is silent. The browser uses the next font it has, so the graphic airs in the wrong typeface and nothing warns you.

So NoaCG puts the fonts in the package, with their licences. A font of your own comes in through the SVG import's font matching.

When a font file is missing:

  • A folder package still builds, and you can repair it by dropping the file into fonts/.
  • A single-file package refuses to build, because there is no folder to repair.

Which package do I want

First: are you exporting at all? If NoaCG is running the show, the answer is no. A production gives you an output URL to add as a browser source and an operator page to drive it from, and nothing is downloaded.

Export when another system will own the graphic, or when it has to run without NoaCG. Every graphic exports to every package below. Take the row for the system that will play it.

Playing it inTakeWhat you get
OBS, vMix, or anything that renders a web page HTML overlay (OBS / vMix) One .html that plays itself when the source loads, and an operator page for live edits. The guide.
CasparCG CasparCG export One .html with everything inlined that reads CasparCG's own data payloads, and an operator page. The guide.
A playout system that loads a folder of templates, such as SPX SPX export A folder to drop into that system's templates directory. Your fields appear in its rundown by name, and an operator page comes with it for anything else.
An OGraf renderer OGraf (EBU) export A folder holding the OGraf manifest and the graphic as a web component. This is the EBU's interchange format, so it is also the one to take when you do not yet know what will play it.
LiveOS (NetOn.Live) LiveOS (NetOn.Live) export The same OGraf package, with that engine's install steps beside it. Its fields become LiveOS operator inputs.
H2R Graphics H2R Graphics export One .html for H2R's Custom HTML graphic type. The fields become H2R inputs, and its on and off drive the entrance and the exit.

None of them needs the internet: everything the graphic uses travels inside the package (what comes out in an export). If you pick the wrong one, export again. The last step of making a graphic offers the export.

OBS, vMix & any browser source

A published production has one output URL. It shows the whole show on a transparent background, and the playout dashboard drives it live. Any source that can load a web page can show it.

  • Copy the URL from the Playout panel: press the playout status in the production page header. It ends …/output?production=<slug>, where the slug is a random id made when you publish.
  • Load it once and leave it up. The operator cues the graphics from NoaCG.

For every browser source:

  • The page is already transparent. Do not add a chroma key. If you see a black or white box behind the graphic, the host is forcing a background: check its custom CSS and background settings.
  • Match the resolution exactly. Graphics are made in real pixels, 1920×1080 unless you chose otherwise. A different size scales the picture instead of cropping it, and scaled text looks soft.
  • Resize the source, never the layer it sits on. In OBS, set the browser source's own Width and Height. Dragging its box in the scene scales the finished picture, and the text goes soft again.
  • Set the source's FPS to the channel's. Motion plays at the right speed at any rate, but a 30 fps source in a 50 Hz channel judders.

OBS Studio

  1. Sources → + → Browser.
  2. Paste the production's output URL. For an exported overlay, unzip the export first, then tick Local file and pick <name>.html from inside the unzipped folder.
  3. Set Width and Height to the graphic's own resolution, and FPS to your channel's.
  4. Leave the background alone.

Leave "Shutdown source when not visible" off for a production output. When it is on, OBS tears the page down each time you hide the scene and rebuilds it when the scene comes back.

An exported overlay comes with a small launcher: Start controller.cmd on Windows, start-controller.command on macOS and ./start-controller.sh on Linux. It serves the folder locally, opens the operator page and relays every command into the graphic that OBS or vMix is showing. It needs no network and nothing to install.

vMix

  1. Add Input → More → Web Browser.
  2. URL: the output URL, or the full local path to an exported file.
  3. Set the width and height to the graphic's resolution.
  4. Put it on an overlay channel and leave it there all show. Higher-numbered channels draw on top.

Take graphics in and out from NoaCG, so they animate. Taking the input off its overlay in vMix removes every graphic at once, with no exit animation: keep that for emergencies.

When it does not work

What you seeDo this
Black or white box behind the graphicClear any custom CSS setting a background. Do not add a chroma key.
Graphic looks soft or wrong-sizedSet the browser source to the graphic's own resolution. Resize the source, never the layer.
Motion juddersSet the source's FPS to the channel's.
Output URL shows "not available"Re-copy the URL from the production page. Unpublishing revokes the URL.
Blank after a network dropWait. It rebuilds on its own without replaying animations on screen. If it does not, reload the layer.
A take airs nothingRead the playout status in the production page's header. Offline means there is no output to air to, so press ▶ Start production. If the production is started, press the status to see which check is failing, then re-copy the output URL and check the browser source is still loading it.

The full playout setup reference, including the self-hosted routes, is PLAYOUT_INTEGRATION.md.

CasparCG

CasparCG plays web pages through its HTML producer, so there are two ways in: load the production's live output URL, or play an exported file from disk with no network at all.

Playing the production's output URL

CG 1-20 ADD 1 "https://noacg.studio/output?production=<slug>" 1
  • 1-20 is channel 1, layer 20. Use whatever your rundown expects.
  • Put your own production's URL in place of the quoted one. It is in the Playout panel on the production page.
  • Anyone who has the URL can show the production, but not operate it. Treat it like a password.
  • Load it once at the start and leave it up. Graphics are cued from the dashboard, not by adding the layer again.
  • While you set up, add &debug=1 to see a status readout on screen. Take it off before air.
  • After a network drop or a layer restart the page recovers by itself. It rebuilds what was on air without replaying the animations.

Which server version you have matters

ServerEngineWhat it means
2.3.xChromium 71The live output URL works with nothing to do. A graphic's own modern CSS can render differently: see below.
2.4.xCEF 117The oldest version NoaCG designs for. Nothing special to do.
2.5.xCEF 142Current.

On 2.3.x

  • The engine rejects modern JavaScript syntax and drops modern CSS without an error.
  • The production output page is built for this engine and brings what it lacks, so the live route needs nothing from you.
  • This engine ignores flex gap. Every export and the output page carry a shim that puts it back.
  • NoaCG builds designs against 2.4, so a design that uses color-mix(), the inset shorthand or backdrop-filter renders differently here.
  • Hand-edited template code that uses ?. or ?? stops the layer with a SyntaxError that only the server log shows.

Every export screen has a Playout compatibility section with one line per system: whether the graphic renders as designed there, and which CSS needs which version.

Let NoaCG load the layer: NoaCG Bridge

Instead of typing the command into the CasparCG Client, you can let the production page send it. A browser cannot talk to CasparCG directly, so a small program on the machine you operate from does it: NoaCG Bridge.

  1. Download NoaCG Bridge from the Downloads page. Playout on a production page links it too.
  2. Double-click it. There is nothing to install: the file is the whole program. Windows warns once because it is not signed yet, so choose More info, then Run anyway. Leave its window open while you work.
  3. It opens a page in your browser. One click pairs the browser with the Bridge. If that is not the browser you use, copy the link into the one you use instead.
  4. The same page then asks for the IP address of your CasparCG server. Enter it, and the AMCP port if it is not 5250, and press Connect. It shows the version the server reports. This computer and every server used before are one click each.
  5. Name the server's channels and say where NoaCG's output goes under Playout settings (the production's Playout panel opens them, and the same form is under Settings → Playout). Test connection there checks the server without changing what is remembered.

NoaCG Bridge remembers each server and its setup: the channels and their names, the slot NoaCG's output plays on and the channel new media starts on. Every browser paired with the same Bridge connects to the last server by itself and opens with the same setup. To pair another browser, copy a pairing link into it: the pairing page, Playout settings and Enter in the NoaCG Bridge window each make one. A link works once, within two minutes. With a Bridge older than 0.8.0 each browser keeps its own setup.

The production page has a Put on air / Take off row beside its output URL, and Put on air sits beside Connect in its Playout settings too. Put on air sends the one command above, and only when you press it: pairing and connecting never touch a layer. After that, every cue reaches the page CasparCG is showing through the production itself, and the Bridge sends nothing more.

Network and browsers

  • The Bridge listens on 127.0.0.1 only. CasparCG can be any machine on the studio network, as with the Client, and nothing is exposed to the internet.
  • On the hosted studio, the browser asks once whether the site may reach your local network. Firefox words it “access other apps and services on this device”. The pairing page tells you before you click.
  • Chrome and Edge are recommended, and Firefox works. Safari refuses to let a page reach a local program at all, and has no setting that allows it.
  • A browser set to forget site permissions, which is common on shared school computers, asks again every day or every tab. The browser notes on the Downloads page name the policy that allows NoaCG once, for good.

Templates and clips already on the server

With the Bridge paired, the foot of the rundown has + From the playout server…. It lists the HTML templates and media in the server's own folders, folder by folder. Pick one to add it as a cue beside the production's graphics.

  • A server template is taken with its field values, updated, stepped with Next and taken off.
  • A clip rolls, pauses, resumes and stops. Tick Loop in a clip's cue and CasparCG repeats it until you take it off.
  • Clips play on layer 10, below every graphic, so a lower third never disappears behind a rolling clip.
  • The file stays on the server. The production stores only its name.

The list comes from the server's media scanner, which runs beside CasparCG: scanner.exe in the Windows download, a separate scanner process on Linux. When it is not running, the picker says so and still lets you type a template or clip name.

A template NoaCG exported brings its fields with it. For any other template, type its field ids (f0, f1) once. Get them from its own FIELDS.md or from its author.

Channels and layers

List the channels your server has under Settings → Playout, then put each server item where it belongs:

  • Add channel adds Channel 2. A name is optional.
  • Every server video, still, audio file and template has a Channel pick beside its Layer in its editor. The rundown shows its address the way CasparCG writes it: 2-10 is channel 2, layer 10.
  • NoaCG output is where NoaCG plays the production's own graphics, 1-20 unless you change it. Media on that channel plays under the graphics on a lower layer (videos and stills start on 10, audio on 5) and over them on a higher one. No server item may use the output's own layer: playing something there would replace the output.
  • New media is the channel a newly added video, still or audio file gets.
  • All out takes off every server cue the rundown put up, on any channel, and leaves everything else on the server alone.

A studio with one channel sees one row, and nothing changes.

Video with transparency

A video with an alpha channel can play over the programme from a key channel, for example as fill and key into a vision mixer's downstream keyer. Render it as ProRes 4444 or QuickTime Animation with premultiplied alpha (in After Effects, "Premultiplied (Matted)" with black). CasparCG reads a video's alpha as premultiplied, so a straight-alpha render looks too bright wherever it is partly transparent: soft edges, shadows and fades. WebM (VP9) alpha does not work on CasparCG 2.3. Transparent PNG stills are always right. On the vision mixer, set the keyer to a pre-multiplied key.

Checked on CasparCG 2.3 and 2.5 by recording the channel. Not yet checked through an SDI card and a vision mixer.

What has been verified

On a real CasparCG 2.5.0 with its media scanner running: the Bridge paired, and a published quiz and scoreboard went on the channel with one command. They were revealed and scored from the dashboard. A template and a still from the server's own library were cued, taken, updated and taken off.

The 2.3.2 install answered the same listing and one template round.

Not yet verified: the pairing prompt on the hosted studio, a Linux server, and Safari. If it misbehaves on yours, the manual command above is the same live link, and we would like to hear about it.

Playing an exported file

Export with the CasparCG target and you get one self-contained .html, with fonts and images inside it and no network needed. Put it in the server's template folder, which is the template-path in casparcg.config, and drive it as a normal HTML template.

Below, <template-name> is the file name without its .html extension, relative to that folder:

CG 1-20 ADD 1 "<template-name>" 1 "<templateData>…</templateData>"
CG 1-20 PLAY
CG 1-20 NEXT
CG 1-20 STOP

The <templateData> block carries the field values, and a CasparCG client sends them by field id (f0, f1, …). Every exported package has a FIELDS.md that lists each field's id, name, type and default, with ready-to-paste payloads for that graphic. Keep it open beside the client.

The playout dashboard

A production is one show: its graphics, a rundown of cues you prepare in advance, and one output URL that stays the same. Each graphic is its own layer, so a bug, a lower third and a ticker can be on air at once.

Making one

  1. In your library, press + Production on a graphic's row. Pick a production you already have, or type a name in the New production… field to make one with that graphic in it.
  2. Add the show's other graphics the same way. A graphic you are still making goes in from the wizard's Finish step, in one press.
  3. Build the rundown on the production page. A cue is a graphic plus the values it airs with.
  4. Press ▶ Start production in the page header. This publishes the show and makes two links: the output URL that a browser source loads, and a control page for operating from another device.

Publishing needs an account, because the published pages live in your cloud space. Everything before it works offline.

The playout status

The header has one status for playout, a colour with a short text beside it. Press it to open the Playout panel: it says which check set the colour, lists the outputs, and holds the actions, the playout setup and the links, each with a Copy button.

ColourMeansFor example
GreyNot started, or nothing to check yetOffline, Connected, Checking
AmberSomething needs your attentionUnpublished changes, an output behind, preparing, loading on CasparCG, no output connected
GreenLive, connected and readyReady · on air 1-20
RedSomething that should work is brokenBridge not running, CasparCG not answering, output not on air, another production on the layer, a channel the server does not have, a graphic that cannot play

The program monitor says the same in its heading: PROGRAM · ON AIR once the production is started, PREVIEW · NOT LIVE before. A clip or still from the playout server is on air as soon as you take it, so while one plays the monitor reads PROGRAM · ON AIR. To send later changes to the output, press ⟳ Publish changes in the Playout panel. The status reads Preparing until the outputs have loaded the new version.

Running it

  • Preview, then take. The page has two panes. Preview is what you are checking, program is what the audience sees. Select a cue, check it in preview, then press Take. Selecting and previewing never reach air, and an edit airs only on a take, never while you type.
  • Any browser can drive it, including an OBS dock or a phone at the desk.
  • Quick presses keep their order. A second press on the same graphic leaves once the first has reached the server, so it lands a fraction of a second later than a press on its own.
  • It recovers by itself. Every command is saved in order. After a network drop or a restart, the output catches up in that order and rebuilds what was on air without replaying the animations.
  • Pictures need no template. + Add pictures… turns image files into cues, such as a holding slide or a sponsor card. There is one picture layer per production, so a new still replaces the last one.

Working with other people

Two different things both get called sharing, and they have different answers:

  • Running one show from several devices needs no accounts at all.
  • Preparing one show together, each person signed in as themselves, is what a team is for.

A published production has links that work for whoever holds them. They are in the Playout panel, which opens from the playout status in the production page header.

  • The control page drives the show from a second laptop or a phone at the desk.
  • The presenter view shows the host what is coming, without the operator controls.
  • The output URL is what a browser source loads.
  • The audience join page collects votes and messages.

Several people can run one show this way with one account and nothing to set up. The playout dashboard and audience join pages cover what each link does. Only the account that made the production can edit its rundown or republish it.

Make a team

Teams need an account, so sign in first.

  1. Open a production you own and press Share in its header. The same dialog is Share with a team… in the ⋯ (More actions) menu on a production's card in Productions. There is no team entry in the topbar or in Settings: a production is the only door.
  2. Press + New team…. It is the quiet text button under the list, not the amber one in the footer.
  3. Fill in both boxes. Team name is what the class or the crew is called. Your name, as teammates see it is you. It starts as the part of your email before the @, and you can change it.
  4. Press Create team. The next screen shows the join code and the member list, with you on it as the owner.

Teammates see your name and nothing else. Email addresses are never shown to anybody.

Get somebody in

The team screen shows a large join code. Under it is a link ending #/join-team/<code>, with a Copy link button.

Send the link, not the code. The screen that takes a code opens only from a join link, so a code read out to a room gets nobody in who does not already hold a link. Paste the link into the class chat, or wherever you already talk. There is no email invitation.

A code is still a key. Anybody who has ever held a join link to any team is one paste away from using a code they overheard.

The person who gets the link opens it, signs in or makes an account, types the name teammates will see and presses Join team. Joining shares nothing from their library, and nothing from yours.

Anyone in the team can pass the link on. Only the owner can press Rotate code, which makes a new code and retires the old one. Everybody already in the team stays in, so rotate when a link reaches the wrong chat.

Your display name is fixed when you join. To change it, join again through the team's current link with a different name.

Who can do what

There are two roles. Whoever made the team is its owner, and everyone else is a member.

Every Yes below has one condition: you need a production of your own to open the team dialog. An empty one is enough.

OwnerMember
See the join code, and pass the link onYesYes
See who else is in the teamYesYes
Rotate the join codeYesNo
Remove somebody from the teamYesNo
Leave the teamNoYes
Delete the teamYesNo

There is no Leave button for an owner. An owner gets out by deleting the team, which cannot be undone and takes the productions the team holds with it. That button asks a second time before it does anything.

Removing somebody, or being removed, takes nothing away from their own library.

What has been verified

Run against the live service: making a team, handing out its link, joining through it, reading the member list, rotating the code and deleting the team.

Removing a member and leaving a team have not yet been run with a second person in the team, so treat them as expected rather than proven.

Moving a production into a team does not work yet. The Move to team button in that dialog is switched off. To work on a show together in the meantime, use the links above.

Audience join pages

A public join page at noacg.studio/join/<name> collects viewer messages and votes from any phone, with no app and no account.

The link is in the same Playout panel as the output URL. Its name comes from the production's name at the first publish, and the Readable name row changes it to something you can say out loud. Do that before you give the link out, because a new name breaks the old one.

  • Nothing viewers send airs on its own. Messages land in a moderation inbox, and an operator picks what goes into the graphic.
  • Votes count live into poll graphics. Open the vote on the Audience tab. The board's own buttons close it, show the result and call the winner. The board can be one of ours or one you drew yourself.
  • A presenter view (a separate link) shows the host what is coming without giving them operator controls.

You do not need a Twitch or YouTube channel for any of this. An audience with no Twitch and no YouTube walks through it on one small show, from publishing to a vote on air.

Graphics with behaviour

A lower third plays and stops. A quiz board has to know which answer was locked in, and whether it has been revealed. NoaCG graphics carry that as states and buttons, and a button the current state does not allow is greyed out.

  • A quiz runs Select answer, Lock it in, Reveal, each a button on the dashboard.
  • A scoreboard carries score up/down and clock start/stop as events. The numbers are data an operator or a feed writes.
  • A live vote opens, closes and shows a result. The bars are driven by a real audience at your join link.
  • Data never changes the state. Updating a name or a score redraws those fields and nothing more. A graphic changes state on an operator's press, or on its own timer where the design has one. So a feed can run through the whole show.
  • Other playout systems step through it. In any other system the graphic walks its steps in order like an ordinary template. The extra buttons appear when NoaCG drives it.

You build behaviour without code: draw each moment as a hidden layer in your SVG and the import wires it up. See Layer names.

Live data

A data update changes what a graphic shows, and nothing else. It cannot play a graphic, take it off, or change its state. Data updates and operator commands apply in the order they arrive, so an operator's change made after a feed update wins.

Type it on the dashboard

Every field is editable live from the production page: edit, then take. For most shows nothing else is needed.

A Google Sheet

A Sheet connects to the production, not to the graphic. On the Playout tab, select a cue of the graphic and press Connect data…. Paste the link from the Sheet's Share button and press Read. Every field is offered a column or a row of that tab; check the list on the PREVIEW monitor and press Connect once.

  • The production reads the tab about every five seconds while a page of it is open. Published, the server reads it about once a minute when every page is closed.
  • The Sheet's line under the cue editor, and the production's Data tab, say when it was last checked and last changed. Pause there holds the values on air until Resume.
  • The same tab can feed several graphics: choose it again under Use existing content….

A graphic that reads a Sheet in its own code. Older graphics could carry their own Sheet reader. They keep working, in the studio and in every export. The production lists such a graphic beside its sources and says that Pause does not stop it. To connect it here instead, press Connect data… on it and choose Stop its own reader: the reader leaves the graphic's code (in every production that uses it), and then you connect the Sheet as above. On a published production, publish the change first, so only one reader ever writes the fields.

The Production Data API

For a timing system, a results service or your own scripts: push values into a published production over HTTPS, with the production's own data key. In the studio this source is called Another system.

Connect the fields first. On the Playout tab, select a cue of the graphic, press Connect data… and then Another system. Every field is offered its own path, such as api.riverside_count.leading. Check the list and press Connect.

Where to find the address and the key. Publish the production and open its Data tab. The Another system card shows the address, the key behind Reveal, an example made from the connected fields and when the last values arrived. Put the key in your integration's server-side configuration. Publishing again makes a new key and the old one stops working, which is also how you revoke one.

curl -X PATCH https://noacg.studio/api/data/patch \
  -H "Authorization: Bearer $NOACG_DATA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api": {"riverside_count": {"leading": "Harbour List", "margin": "412"}}}'
  • /api/data/patch (PATCH, or POST behind a proxy that eats PATCH) writes data paths. Every field connected to a path follows, so the feed does not have to know the rundown. A null removes a value from the tree; the field keeps what it shows.
  • The key writes data and reads the production's current data back. It cannot play, stop, take or clear anything. Cueing and clearing stay with the operator.
  • Pause on the card holds what the key sends. Nothing it sends goes on air, and the answer to each request says "paused": true. Your own presses still go on air. Resume sends the latest values once.
  • /api/data/update is the older door that addresses one graphic by name and its fields by the labels the operator sees. It still works, and Pause holds it too.
  • The full reference, limits, errors and a sample sender are in DATA_API.md.

One show, worked through puts all of this in a real rundown.

One show, worked through

Production data, bindings and tables decide where the number on screen comes from. They are easier to tell apart in a real show, so here is a small one.

Hall Cup is a school sports night. It has four graphics, one data tree, one table and a hall full of phones. Every picture below was taken while building it.

The four graphics

Make each one from the catalog. On the wizard's Finish step, the Production box says where the graphic goes.

  • For the first graphic, choose + New production… and call it Hall Cup.
  • For the other three, pick Hall Cup from the same list.
GraphicCatalog categoryWhat it asks you to type
Match Strip
the bug that stays up
Scoreboards Team A, Score A, Team B, Score B
Quiet Score
the card you cut to at half time
Scoreboards Team A, Score A, Team B, Score B
House Wire
the ticker along the bottom
Tickers Ticker items, Label, Scroll speed (%)
House Strap
the name under an interviewee
Lower thirds Name, Title

The field names matter. The rest of this example binds by them, which is why the two scoreboards use the same four.

The tree: what the whole show knows

Open the production and go to its Data tab. Press ▾ Raw JSON, paste this in, and press Apply JSON.

{
  "match": { "teamA": "Otava", "scoreA": 2, "teamB": "Karhut", "scoreB": 1 },
  "tickerItems": [
    "Junior final starts at 19:30",
    "Canteen closes at 20:00",
    "The bus home leaves from gate 4"
  ]
}
The Production data panel listing five values with their paths: match.teamA, match.scoreA, match.teamB, match.scoreB and tickerItems.
Five values, five addresses. The panel shows one row per value. The grey text on the left is that row's address.

That address is a path. Dots walk down the tree. The number 2 lives at match.scoreA, and the three ticker lines live together at tickerItems.

You do not have to paste JSON. The row at the bottom adds a path and a value by hand. If the path does not exist yet, it is created.

  • The type is kept. 4 is a number, true is a boolean, [1, 2] is a list, and anything else is text. Number rows get − and + buttons. A list is one line per item, which is what a ticker's text box takes.
  • This is state, not a command. Nothing on this panel plays, stops or takes a graphic. That is the rule of Live data. It is why a feed can run all night without putting anything on air.
  • Save the numbers you want to start from. ⬇ Save as seed stores the current tree in the production itself. ⟲ Reset to seed puts it back. Do it before the first rehearsal: until the production is published, the live tree exists only in this browser.

The bindings: which field reads which path

A path does nothing on its own. A binding points one field of one graphic at one path. Scroll to Bindings and press Bind all by title.

The Bindings list: both scoreboards bound to the same four paths and House Wire's Ticker items bound to tickerItems, each reading its value back, with House Strap's two fields left unbound.
Nine bound, four left alone. Both scoreboards landed on the same four paths, because they ask for the same four things. The right-hand column shows what each field shows right now. A mistyped path shows up here as a blank.

It matched by the words. "Score A" found match.scoreA: the last part of that path is the field's title, once case, spaces and punctuation are ignored. "Ticker items" found tickerItems the same way.

If two paths match one title, the row stays empty and names both. The strap's Name and Title matched nothing, which is right: a guest's name is not something the whole show shares.

To bind a row by hand, click its box and pick a path from the list, or type one. To unbind it, press ✕ twice.

One value, every graphic

Press + beside match.scoreA on the Data tab. Both scoreboards now say 3, whichever of them is on air and whichever was cued first.

The score belongs to the show, not to one cue, so nobody retypes it on the half-time card.

You can also change it from the Playout tab. A bound field shows there read-only, with its path beside it. The ± LIVE NUMBERS row underneath changes the shared value with one press.

The Match Strip cue on the Playout tab: four read-only fields each labelled with the production-data path it follows, and a row of plus and minus buttons for Score A and Score B.
The same values, on the operator's screen. A bound box shows what the tree says and cannot be typed in. The buttons under it change the value on air at once.

Where the tree lives depends on one thing, publishing:

  • An unpublished production keeps it in the browser you are using. That is why the seed is worth saving.
  • A published production keeps it with the production. Every operator and every feed sees the same numbers, and the Data API writes into this same tree.

The table: rows an operator picks from

Hall Cup interviews three people. Their names belong to no particular moment in the show. That is what a table is for: a bank of rows, none of them live. The operator loads the row they want, when they want it.

Under Tables, choose Line-up / roster and press + New table. Call it Interviews. It starts with the columns Name, Number and Position. Rename Position to Title, remove Number, and type the rows.

The Interviews table on the Data tab: two columns called Name and Title, with three rows of guests.
Two columns, three rows. The column names are the strap's field titles. That is how a row finds its way into a graphic.

The matching is by words again:

  • A column called Title loads into the field called Title.
  • A column that matches no field is carried along and ignored.
  • A field that no column names keeps whatever it had.

So a spreadsheet that already uses your field names needs no mapping step. ⬆ Import CSV / JSON takes it as it is, and then says which of its columns matched. ⬇ Blank CSV goes the other way: it gives you a file with the right header row to fill in.

Now go back to the Playout tab and select the House Strap cue. It now has a Load data row control. Picking a guest fills the cue you are editing, which is the preview, and nothing more. The name goes on air when you press ⟳ Take, like everything else.

Which of the two you want

Production dataTables
What it holdsOne value that is true right now Many rows, none of them current
Who writes itAn operator, a feed, or the Data API You, or a spreadsheet you import
How a graphic gets itA binding, and then always An operator loads a row into one cue
Changing itMoves every bound graphic at once Changes nothing until a row is loaded
Hall Cup uses it forThe score and the ticker lines The guest list

When both would work: if more than one graphic needs the same value at the same time, use the tree.

An audience with no Twitch and no YouTube

The first panel on the Audience tab is Chat sources. It asks for a Twitch channel or a YouTube video. Most people running a hall, a school event or a club night have neither, and they are not missing anything.

Those two only pull an existing chat into the same inbox. The room's own join page takes messages without them, and that is what Hall Cup uses.

First add two more graphics from the catalog: House Question (Audience & questions) for the messages, and House Vote (Live votes) for the poll. Then:

  1. Publish the production. Nothing for the audience exists until you do. An unpublished production shows ▶ Start production in the header and has no links to give out. Publishing is free and needs an account.
  2. Get the audience link. Press the playout status in the header, then Audience link in the panel it opens. It reads noacg.studio/join/<name>. The name comes from the production's name when you first published it.
  3. Give it a name you can say. The Readable name row below the link changes it to something you can read out loud. Do this before you hand the link out, because a new name stops the old link working.
  4. Give it to the room. Read it out, put it on a holding slide, or print a QR code of it. There is no app to install and nothing to sign in to.
  5. Open the door. On the Audience tab, tick Accepting messages. Until you do, every phone with the link says the production is not taking part right now.

Hall Cup leaves the mode beside that tick box on Questions. Comments works the same way and asks for something shorter.

The viewer's page on a phone: the production name, the heading Send us your question, a box for a name, a box for the question, and a Send button.
What the room gets. A name they can leave blank, a box, and Send. The studio shows the same page under What viewers see on the Audience tab.

Every message lands in the inbox on the same tab. It takes two steps to reach air:

  1. The operator presses → Send to rundown. That adds an ordinary cue to the House Question graphic.
  2. The operator takes that cue, like any other.

Before sending, the operator can edit a broadcast version of the message. What the viewer sent is never changed.

The moderation inbox: filter tabs reading Inbox, Approved, Shortlist and All, then two arrivals, each with an editable name and message and a row of buttons ending in Send to rundown.
The inbox, and the only way out of it. The two boxes on each row are the broadcast version, yours to tidy. Shortlist, Approve and Reject sort the pile. Now and Next point the presenter's screen at one message. Only Send to rundown reaches the rundown.

Rehearse first. On an unpublished production the bar has ⟳ Simulate 3 arrivals. It makes up messages marked "(rehearsal)" so you can practise moderating. A published production has no such button.

Putting a vote to the room

Type a question under Put a question to the room. Give it two to eight options, one per line, and press Open voting. Every phone with the link switches to the ballot at once. A viewer can change their vote while voting is open.

An open poll on the Audience tab: the question, its three options with a bar and a count each, and the buttons that stage the counts to a graphic or close the voting.
The counts are here and nowhere else. The join page never shows a tally, in any mode. The result reaches the room as a graphic, on air, when the operator chooses.

Stage counts to a graphic writes the question, the options and the counts into a cue for House Vote. Take puts it on air. Pressing it again while voting is open updates the same cue.

The figures on air change when the operator shows the result, not while the room is still voting.

A board you drew yourself can have a Live figures layer. The Audience tab then offers a tick box to show the percentages live instead. A catalog board like House Vote has no such layer, so this show does not get the tick box.

What was and was not run

Everything in this section was run in the studio: the tree, the bindings, the table and loading a row, the inbox, and a vote from opening it to staging the counts.

One step is taken on trust: the published noacg.studio/join/<name> link itself, which needs an account and the hosted backend. The page a phone loads there is the one in the picture above, drawn by the same code.

Make graphics with Claude Code, Codex or any coding agent

  1. Use Claude Code, Codex or another compatible coding agent.
  2. Install the NoaCG CLI for your agent, or start without installing: one prompt runs it in the session you have open. The install commands are under Reference.
  3. Prompt the graphic you want. In Claude Code you can also type /noacg:graphic.
  4. It appears in your NoaCG library, ready for a rundown.

HTML an agent writes on its own has no operator controls and no promise about how it behaves in a playout system. The NoaCG CLI adds them:

  • It gives the agent the contract a NoaCG graphic has to meet.
  • It checks what the agent wrote with the studio's own validator.
  • It saves the graphic into your library once it passes.

The result is an ordinary NoaCG graphic: put it in a production, operate it with its buttons, and feed it live data.

Paste this to your agent and start building

It works in the session you have open, with nothing to install first. The agent checks its setup and, if this computer is not connected yet, asks you to connect your NoaCG account in the browser. Then it asks what to make. Each graphic it finishes goes into your library, and it gives you the links. If you do not connect, it works locally and says that nothing was saved.

Use npx -y @noacg/cli@0.12.4 for every NoaCG command in this session. Run its doctor, read docs skill and follow it, and check whoami. If I am not logged in, run login so I can connect my account in the browser; if I decline, work locally and say nothing was saved. Then ask what to make. Build, validate with screenshots, save every graphic to my library, and return the direct links. Clearly state anything still pending or unconfirmed.

You need:

  • Node.js 20 or newer.
  • Chrome or Edge installed on the system. The validator runs it in the background, with no window.
  • An account, but only when you save a graphic into a library.

To install the plugin as well, see Reference. It brings the NoaCG skill from your next session on.

Then describe the graphic you want

For example: "Make me a clean scoreboard for a floorball stream: home, away, period, clock." In Claude Code, /noacg:graphic starts the same thing.

The noacg-graphic skill tells the agent how a NoaCG graphic is built, validated and saved. How it looks is up to the agent. The plugin brings the skill from your next session on. Until then, noacg docs prints the same texts.

The agent then works in five steps:

  1. Scaffold. It creates a starting package with the fields and operator events of a graphic type. This step is optional. It can also write from scratch against the contract.
  2. Author. It writes the graphic, the way it writes any code.
  3. Validate. The studio's own checks run, then a live playout test. The agent gets screenshots off air, on air and with doubled text, so it can see what it made.
  4. Fix. It works through the findings until there are none.
  5. Save. The graphic goes into your NoaCG library, and the agent prints its link.

Saving is the one step that needs you. Log in once per machine, and approve it in the browser that opens:

npx @noacg/cli login

The key it stores can save graphics to your library, make productions of the graphics it saves, and send packages to your Home. It cannot publish or play anything. To revoke it, go to Settings, then Account, then Agent access.

save refuses a graphic that does not pass validation. A saved graphic is editable in the studio like any other, and exports to every target NoaCG supports.

Ask for a whole package

For example: "Make me the graphics for a fight night: opener, name straps, fight bug, round card."

The agent builds each graphic and saves the whole set to your library in one save, with a link for each graphic. If you also ask for a production with a running order, the same save makes it, with its layers and running order, and the agent gives you its link. There is nothing to install. If the agent says a save is unconfirmed, it runs the same command again, which never saves a second copy.

A package sent with noacg pack --save is the older route. It waits on your Home under Waiting to install until you press Install, and Home tells you when its graphics were already delivered.

Reference

The install commands, one by one. The plugin is optional: the prompt above works without it. All three routes install the same package.

Claude Code. The plugin brings the /noacg:graphic skill and runs nothing until you make a graphic. Type this in a Claude Code session (version 2.1.275 or newer). It adds the NoaCG marketplace, asks you to confirm it, and installs the plugin:

/plugin install noacg --marketplace NoaCG/NoaCG-Studio

From a terminal or a setup script, the same install is two commands:

claude plugin marketplace add NoaCG/NoaCG-Studio
claude plugin install noacg@noacg-studio

An optional second plugin adds an MCP server that is always on. It puts the noacg tool in every session and keeps a browser ready between calls, at the cost of a process and some context in every session.

/plugin install noacg-mcp --marketplace NoaCG/NoaCG-Studio

Codex. The same plugin, from the same repository. Codex has no one-command form, so run these two in a terminal:

codex plugin marketplace add NoaCG/NoaCG-Studio
codex plugin add noacg@noacg-studio

Any other agent that speaks MCP. Register the server over stdio, with the command npx and the arguments -y @noacg/cli mcp. It brings the tools, and the contract text comes with them as the server's resources.

npx -y @noacg/cli mcp

The package. All three routes install one npm package, @noacg/cli. It gives you one command, noacg. You can also install it yourself:

npm i -g @noacg/cli

Or run any command with nothing installed, as npx @noacg/cli <command>. The loop by hand is three commands:

npx @noacg/cli scaffold --type scoreboard --design neutral --out my-scorebug
npx @noacg/cli validate my-scorebug --screenshots shots
npx @noacg/cli save my-scorebug

scaffold creates the --out folder relative to where you run it. The folder has to be new or empty. noacg types lists the graphic types you can pass to --type, with their fields and operator events.

The MCP server without the skill. This gives Claude Code the tools without the plugin, for the folder you run it in:

claude mcp add noacg -- npx -y @noacg/cli mcp

To have it in every folder, add --scope user before the name:

claude mcp add --scope user noacg -- npx -y @noacg/cli mcp

A server added this way runs in every session of that scope. It has one tool, noacg, whose command is the CLI verb: types, scaffold, validate, inspect, screenshot, docs or save.

Which files to edit. A package holds sources and generated files. Edit the sources: <name>.html, css/template.css, js/template.js, and the images/ and fonts/ folders.

Leave the generated files alone: <name>.ograf.json, graphic.mjs, FIELDS.md, README.md, GETTING-ON-AIR.md and controlpanel.html. validate rewrites them from the sources, so an edit made there is lost.

Which deployment it talks to. https://noacg.studio, unless you set one of these environment variables:

  • NOACG_URL points it at a local dev server or a self-hosted one.
  • NOACG_BROWSER names a Chromium executable, when the system Chrome or Edge is not the one to use.
  • NOACG_AGENT_KEY supplies a key in CI, where nothing can open a consent page in a browser.

When something fails and the findings do not say why, run doctor. It prints which browser it will drive, which deployment NOACG_URL points at, the bridge version it found there, and whether a key is held.

npx @noacg/cli doctor

What the package is. The folder is at the same time a valid SPX package and an EBU OGraf v1 graphic, with no build step. Zip it and it imports through the studio's Import door, or plays in any OGraf renderer.

The graphic itself is plain HTML, CSS and JavaScript. So the same sources also export to CasparCG, an OBS or vMix overlay, H2R and LiveOS. The full reference is AGENT_CLI.md.

Prepare a show from a chat app

Add NoaCG to a chat app as a connector and sign in. The app can then read your library and put a production with its rundown on your Home. You open it with Install.

Checked with Claude.ai, the Claude desktop app and Claude Code. ChatGPT and other apps that take a custom connector are expected to work the same way, but have not been tried yet.

The connector address:

https://noacg.studio/mcp
  1. In the chat app, add a custom connector with this address.
  2. Sign in to NoaCG when the app asks, and press Allow.
  3. Ask for what you need, for example a rundown from an order of service, in your brand.
  4. Open Home in the studio and press Install.

In Claude Code, the same connector is one command:

claude mcp add --transport http noacg https://noacg.studio/mcp

The connector reads your graphics, brands and productions (team productions too), picks designs from the catalog, copies your own graphics, applies a brand and fills the cues. It does not write new graphic code, and it does not edit, delete, publish or play anything. For new designs, use a coding agent with the CLI.

Every connected app is listed in Settings → Account → Agent access, where Revoke ends it. What an app reads goes to that app’s provider, under its terms (privacy).