kScript (legacy) construct map

Every kScript (legacy) construct beside the Indicator form that replaces it, grouped by lifetime: a value on every bar, a snapshot of the finished run, or an…

Every kScript (legacy) construct beside the Indicator form that replaces it, grouped by lifetime: a value on every bar, a snapshot of the finished run, or an object that keeps its identity while you move it. From kScript covers the numeric core of a port; this page carries the rest: plots and style words, text and tables, profiles and panels, drawing objects and their mutation, pane anchors, frame snapshots, sources, and the constructs with no home yet.

The same AssemblyScript module compiles once and runs on your machine and in the chart tab; source: "series" inputs require the daemon.

In code-first packages, declarations in src/indicator.ts produce the sheet at wrun/metadata.json. Import declarations from ./sdk/declare, read named in_* accessors in state(), and write out_* values followed by emitRow() in finalize(). Numeric outputs remain metrics, including data-only outputs.

The current line declaration is output("close", line, overlay). There is no out.line declaration in this SDK; out.inset is available. A table cell marked sheet only has no equivalent code-first declaration today.

Time series, shapes and backgrounds

Declare the presentation once, then write one numeric value per ready bar.

kScriptSheet fieldCode-first callDifference
plot(value, plotType=...)outputs[].plot and .paneloutput(name, line, overlay) or the matching plot identifierKind is fixed in the declaration; overlay draws on price, lower in the script pane. The browser places the whole package by its first drawn output (or the sheet overlay override): numeric outputs of one package cannot split across panes.
plotLine(value, ...)outputs[]: { plot: "line", color, width, line_style, opacity }output(name, line, overlay, options)One number per bar; no smooth or glow output option.
plotLine(value, fill=true)ranges[]: { upper, lower } over two outputsrange(upperName, lowerName, options)The browser draws a filled band between two declared outputs; a single plot: "area" output renders as an unfilled line today (no overlay area renderer).
plotBar(value, ...)outputs[].plot: "bar"output(name, bar, lower)One scalar per bar; a [low, high] span becomes a box() instead.
plotHistogram(value, base=...)outputs[].plot: "histogram"output(name, histogram, lower)Baseline is zero; emit distance from a baseline or use box() for an absolute span.
plotCandle([o,h,l,c], ...)boxes[] body plus segments[] wickbox(name, { top, bottom, ... }) and segment(name, { yFrom, yTo, ... })No four-output OHLC binding, even though plot: "candle" is accepted.
plotShape(value, shape, ...)renderers[]: { kind: "shape", output, shape, where? }render.shape(name, { output, shape, where })One mark per ready bar; where is a finite, nonzero gate.
plot(plotType="point")renderers[]: { kind: "shape", output, shape }render.shape(name, { output, shape: "circle" })One mark per ready bar at the output value; a plot: "scatter" output renders as a connected line today. Use panel.scatter for numeric x/y pairs.
hline(value, ...)outputs[].plot: "line"output(name, line, lower) and out_<name>(value) on every ready barNo separate horizontal-line primitive; an extended line handle also works.
plotBgColor(color, forceOnChart?)renderers[]: { kind: "bgcolor", where, color?, color_by?, colors? }render.bgcolor(name, { where, color, color_by, colors })Per-bar background tint; a gate selects the bar. No forceOnChart option on this renderer.
barcolor(color)No candle-recolor fieldNo direct call; render.bgcolor(...) is the nearest tintBackground tint does not recolor candle bodies.
plotBatches(count, fn)No batched plot field; handles, levels[] or panels[] serve different lifetimesLoop over handle calls, or declare plot.levels(...) / panel.*(...)Handles keep a bounded live set; frames replace a snapshot, not a history of batches.
plotPie(value, price, radius, ...)No per-bar pie field; panels[].kind: "pie" is a snapshot alternativepanel.pie({ name, title, x: "category", place, frame })A panel pie has up to 24 slices and no bar-time/price/radius placement.
A compact plotBar / plotLine stripoutputs[]: { plot: "inset", inset: { dock, height_px?, shape? } }out.inset(name, { dock: "bottom", height_px: 28, shape: "histogram" })Keeps every ready row in a pane strip; 16..120 px tall, top or bottom, histogram/area/line.

render.shape supports circle, cross, triangle_up, triangle_down, diamond, arrow_up, arrow_down, flag and square. kScript's character marks use text instead. For above/below-bar marks, compute the y output; for fixed pane placement, use anchored handles.

Style words

kScriptSheet fieldCode-first call or optionDifference
colors + per-bar colorIndex; colorGradient(...) / palette(...) used to choose a coloroutputs[].color_by + .colorsoutput(name, line, overlay, { color_by: "tone", colors: [...] })Emit the palette index as another numeric output; there is no built-in gradient/palette helper.
Per-bar widthoutputs[].width_by + .widthsoutput(name, line, overlay, { width_by: "weight", widths: [...] })A ladder of 1..10 widths, each 0.5..20; no arbitrary per-bar width field.
lineStyle, constant opacityoutputs[].line_style, .opacityoutput(name, line, overlay, { line_style: "dashed", opacity: 0.6 })Static series style; handle setters can change individual objects.
label, desc, forceOnChartOutput name, description, paneloutput(name, line, overlay, { description })Placement belongs to each output; there is no script-wide plot call.
Redraw-only style inputsparams[].style: { output, property }Sheet onlyA style parameter changes presentation without reaching the module; compute parameters remain numeric.
zOrder, set_zorderHandle zOrder after mutation; widget zHandle .zorder(n); draw.card, draw.feed, draw.meter option zNumeric plots and declared coordinate drawings have no general zOrder option.

Palette and width indexes are floored; a finite out-of-range index selects entry zero. A non-finite width index keeps the static width. A non-finite background color index selects no tint. Names of palette and gate outputs must differ from the output they control.

Text, labels and tables

String slots carry text per bar; the renderer decides which rows remain visible.

kScriptSheet fieldCode-first callDifference
plotText(text, price, ...)string_slots[] plus renderers[]: { kind: "text", y, text, color?, size? }string(slot, { max_bytes }); render.text(name, { y, text: slot, color, size })One mark for each ready row with a present slot; even a present empty string is a write.
plotPriceLabel(price, text, ...)Text renderer with style: "price_label"Sheet only for style; render.text declares plain textwrun-3 or later; no tooltip, URL/SVG icon or pill-position options.
plotLabel(text, position, x, y, ...)renderers[]: { kind: "label", text, position }, or handles.label.anchor and handles.label.alignSheet only for renderer position; handles.label({ text: slot, anchor: "top_left", align: "left" }) for movable pixel placementRenderer keeps the latest nonempty text; a handle copies text when drawn, supports pixel offsets, and align picks which text edge sits on x.
plotTable(data, position, ...)renderers[]: { kind: "table", rows, cols, cells, position }render.table(name, { rows, cols, cells, position })Snapshot from the latest ready row with every cell slot present; up to 32 rows and 8 columns, within the shared 64-slot limit.
table.new(...), setCell(...)panels[]: { kind: "table", frame, series, ... } or the table renderer abovepanel.table({ name, title, x: "category", place, series, frame })Write the whole frame instead of mutating cells; styled cells support text, color, an inline bar and spark.
plotStatRow(value, title, format, polarity, priority)renderers[]: { kind: "stats_row", output, title?, format?, polarity? }render.stats_row(name, { output, title, format, polarity })Per-bar strip values, including NaN gaps; no priority option.
A small plotTable / plotTiles status carddrawings[]: { kind: "card", title, rows, anchor?, offset?, z?, state_by? }draw.card(name, { title, rows, anchor, offset, z, state_by })Up to 8 cards with 12 rows each; latest complete ready row wins, with an incomplete-row fallback.
A chart inside a table cell / card rowPanel cell spark: [values...]; card row spark: { output, window }panel.table(...) frame cell; draw.card(...) row sparkFrame sparks contain 1..64 finite numbers; card sparks select the last 2..64 ready output values.

A text renderer's size is 6..64 integer pixels. At most 64 string slots share the sheet, each with max_bytes of 1..4096. Write through generated str_<slot>() or the reusable sb_* builder and str_<slot>_sb(). Omitting a string write is different from writing an empty string.

Profiles, panels and compact widgets

Frames carry the whole snapshot, including category or numeric axes independent of bar time.

kScript builtin or idiomSheet fieldCode-first callDifference
plotBatches of plotBar, plotShape, plotRange or plotPriceLabel used as a docked profilelevels[]: { name, frame, dock, width_frac?, poc?, labels?, color? }plot.levels({ name, frame, dock: "right", width_frac: 0.12 })One docked snapshot, up to 512 strictly monotonic prices; width fraction 0.05..0.5.
plotCurve(..., style="bars")panels[].kind: "bars"panel.bars({ name, title, x, place, series, frame, orientation?, stacked? })Up to 8 series and 2000 rows; keys are categories, integer indexes or epoch seconds.
plotCurve(..., style="line")panels[].kind: "line"panel.line({ name, title, x, place, series, frame, stacked? })Snapshot lines over category/index/time keys; arbitrary fractional x uses scatter.
plotCurve / plotShape used for numeric x/y pointspanels[].kind: "scatter"panel.scatter({ name, title, x: "index", place, frame })[key, x, y, size?, color?, label?]; x/y are finite numbers and each point may carry style.
plotCurve(..., style="bars") used for a distributionpanels[].kind: "histogram"panel.histogram({ name, title, x: "category", place, frame, bins?, orientation? })Supply [binLabel, nonnegativeCount] rows; bins is 2..200, not automatic binning of raw samples.
plotPie(...) shown as one summarypanels[].kind: "pie"panel.pie({ name, title, x: "category", place, frame, hole? })Snapshot slices [name, nonnegativeValue, color?]; at most 24, hole 0..0.8.
plotMatrix(...); heatmaps made from colored plotCandle cellspanels[].kind: "heatmap"panel.heatmap({ name, title, x: "category", place, frame })Up to 2000 [xKey, yKey, valueOrNull] cells; no separate summary/highlight fields.
plotTable(...), table.new(...) as a side data tablepanels[].kind: "table"panel.table({ name, title, x: "category", place: "side", series, frame })At most 32 rows and 8 columns; row cells match series exactly, with no extra key cell.
plotTiles(...)panels[].kind: "tiles"panel.tiles({ name, title, x: "category", place, frame })At most 24 [label, value, caption?, color?, spark?] tiles; no columns/accent/format declaration.
plotMiniChartGrid(...)No OHLC mini-grid field; panels[].kind: "line" or a card spark provides a simpler viewpanel.line(...) or draw.card(...)Panels use below/side, not arbitrary viewport grid geometry; no candle-grid binding.
plotTable / plotPriceLabel used for an order ladderdrawings[]: { kind: "ladder", frame, side, divider? }draw.ladder({ name, frame, side: "right", divider? })One snapshot with 1..64 [price, value, fraction, color?] rows; fraction is 0..1.
plotText / table.new used as a recent-events feeddrawings[]: { kind: "feed", frame, anchor?, offset?, z? }draw.feed({ name, frame, anchor, offset, z })Snapshot of 1..50 [epochMilliseconds, text, color?] lines; text 1..80 characters.
plotShape / plotTable used as a progress gaugedrawings[]: { kind: "meter", label, fraction: { output }, ramp, text?, ... }draw.meter({ name, label, fraction: { output }, ramp, text, anchor, offset, z })Latest ready numeric output, not a frame; produce 0..1 and choose 2..5 ramp colors.

Every panel binds a declared frame and uses place: "below" or "side". At most eight panels and four level profiles share a sheet. Bars, line and table require 1..8 series entries; the other panel kinds forbid series. Histogram and heatmap require x: "category".

Panel table cells accept a number, a string of at most 64 characters, or { text?, color?, bar?, spark? }. A cell bar is a fraction in 0..1. Cards, feeds and meters default to anchor: "top_right", offset: [0, 0] and z: 0; offsets are integers in -200..200. Ladder placement uses side.

Drawing objects and mutation

Declare each handle kind once, create objects with distinct ids, and reuse those ids to move or delete them.

kScriptSheet fieldCode-first declaration and runtime callDifference
line.new(x1,y1,x2,y2,opts)handles.linehandles.line({ panel: "overlay" }); draw.line(id).set(x1,y1,x2,y2)Chart x uses epoch seconds, not kScript milliseconds; extension past the loaded range is allowed.
box.new(left,top,right,bottom,opts)handles.boxhandles.box({ color, borderColor, opacity }); draw.box(id).set(left,top,right,bottom)Persistent object; boxes[] / box(...) instead produces one declarative shape per bar.
label.new(time,price,text,opts)handles.label plus string_slots[]handles.label({ text: "note", size: 12, align: "left" }); draw.label(id).set(x,y).text(str_note_sb)Text is copied from the slot write on that call; position alone does not create the label. align (left, center, right) is the text edge on x; omitted centres.
polyline.new(points,opts)handles.polylinehandles.polyline({ color, width }); draw.polyline(id).setPoints(points,count)Reuse a StaticArray<f64> of x/y pairs; 1..256 points per handle.
linefill.new(line1,line2,opts)No linefill handle kindNo direct call; box(...) slices or box handles approximate a fillNo object that tracks a fill between two moving line ids.
table.new(position,rows,cols,opts)No table handle kindrender.table(...), panel.table(...) or draw.card(...)Replace a selected table/card snapshot; no set_position() or table-handle deletion.
plotRange(time1,price1,time2,price2,...)boxes[], or drawings[].kind: "box", or handles.boxbox(name, { top, bottom, from, to }), draw.box(name, {...}), or a box handlePer-bar boxes use offsets within ±500 bars and clamp to loaded data; handles use absolute coordinates.
Last-bar line.new, box.new, label.new, polyline.new without ongoing identitydrawings[] with the corresponding kinddraw.line, draw.box, draw.label, draw.polyline from ./sdk/declareDeclared coordinates name outputs; only the last ready row selects the object, with up to 64 polyline points.

The two draw imports have different jobs: ./sdk/declare declares a run-level drawing, while ./gen/draw operates on handles. Alias one when using both. Allocate each generated handle object once at module scope or in init(), and call its geometry/style methods in finalize().

kScript mutationGenerated handle methodRule
Line set_xy, set_xy1, set_xy2.set(...), .setXy1(...), .setXy2(...)Create with .set(...) before a partial setter.
Line/polyline set_color, set_width, set_style.color(rgba(...)), .width(n), .style(LineStyle.Dashed)Width 0.5..20; line styles solid, dashed, dotted.
Line set_extend.extend(Extend.Right)None, Left, Right or Both.
Box set_bounds, set_lefttop, set_rightbottom.set(...), .setLeftTop(...), .setRightBottom(...)Geometry updates keep the same id.
Box set_bgcolor, set_border_color, set_border_width.fill(rgba(...)), .color(rgba(...)), .border(n)Border width 0..10; no box border-style setter.
Label set_xy, set_text, set_color, set_bgcolor, set_size.set(x,y).text(sender), .text(sender), .color(...), .fill(...), .size(n)Send text on every position/text update; size 6..64 integer pixels.
Label set_textalign.align(ALIGN_LEFT), .align(ALIGN_RIGHT); ALIGN_DEFAULT restores centred textThe text edge that sits on x; (x, y) stays the point. Labels only.
Line/box/label set_opacity, set_zorder.opacity(n), .zorder(n)Opacity 0..1; z-order is an integer.
Polyline set_points.setPoints(points,count)Re-emits the entire point list under the same id.
Line/box/label/polyline delete().delete()Frees the shared id; a missing id is harmless.

All four kinds share one nonnegative id space. Caps are 500 live handles per kind, 1500 total, and 4096 draw calls per row. Delete expired objects explicitly. A cap breach refuses the run; the host never silently drops drawings. Declarative caps are 16 boxes, 16 segments, 32 renderers and 64 drawings, including cards, ladders, feeds and meters.

Pane anchors

handles.line|box|label|polyline({ anchor: "top_left" }) sets the default for new handles. After creation, .anchor(ANCHOR_TOP_LEFT) changes it; import the constant from ./gen/draw. .anchor(ANCHOR_CHART) restores chart coordinates even when a default anchor is declared. A label adds align (left, center, right): the text edge that sits on x, with (x, y) staying the point; handles.label({ align: "left" }) is the default, .align(ALIGN_RIGHT) changes a live label, and .align(ALIGN_DEFAULT) restores centred text.

Anchorx coordinatey coordinate
Absent / ANCHOR_CHARTEpoch secondsPrice
Nine pane spots, top_left through bottom_rightCSS pixels from left, centre or rightCSS pixels from top, middle or bottom
top, bottomEpoch secondsCSS pixels from that edge
left, rightCSS pixels from that edgePrice

Left/top offsets point right/down; right/bottom offsets point left/up. Centre offsets are signed, and negative offsets are legal. Coordinates start at the pane's content rectangle and clip to that pane. A pane anchor keeps a HUD in place while the chart pans; it is not a timestamp offset.

Frame snapshots

Declare frame(name) once and call generated writeFrame(slot, json) in finalize() to replace that run's snapshot.

Sheet or operationCode-first wordLifetime and bound
frames: [{ name, max_bytes? }]frame("profile"), optionally { max_bytes }Up to 8 slots, each at most 96 KiB (98304 UTF-8 bytes).
Write the slotwriteFrame(FRAME_PROFILE, json) from ./gen/framesFinalize only; newest write replaces the previous bytes across the entire run, not just the current bar.
Level profile frameplot.levels({ frame: "profile", ... }){ prices, values, colors? }, matching array lengths, 1..512 monotonic prices; null values are gaps.
Panel framepanel.*({ frame: "summary", ... }){ rows }, with the selected panel kind's tuple grammar; empty rows are legal.
Unwritten / invalid frameNo extra declarationUnwritten consumers are absent; invalid written JSON or payload refuses selection with wrun_frame_invalid.

Frames and per-row strings share a 2 MiB wrun-4 transport budget. Expanded render selections have a separate 2 MiB cap, including panels, handles and sparks. Frames are snapshots, so writing on every bar does not create a history of frames. Accumulate what the snapshot needs in bounded guest memory, then write it, commonly under bar.isLast().

Example: a docked profile and side bars

These declarations share a close output but bind two independent frames. The fixed payloads show the exact accepted shapes; computed aggregates use the same shapes.

import { frame, input, line, ohlcv, output, overlay, panel, plot } from "./sdk/declare";
import { in_close } from "./gen/inputs";
import { emitRow, out_close } from "./gen/outputs";
import { FRAME_PROFILE, FRAME_SIDES, writeFrame } from "./gen/frames";
import { bar } from "./gen/draw";

input("close", ohlcv.close);
output("close", line, overlay);
const profile = frame("profile");
const sides = frame("sides");
plot.levels({ name: "volume_levels", frame: profile, dock: "right", poc: true });
panel.bars({
  name: "side_totals", title: "Volume by side", x: "category", place: "side",
  series: [{ name: "Volume", color: "#38bdf8" }], frame: sides,
});

let closeValue: f64 = NaN;
export function init(): void {}
export function state(): i32 { closeValue = in_close(); return 1; }
export function finalize(): void {
  out_close(closeValue);
  if (bar.isLast()) {
    writeFrame(FRAME_PROFILE, '{"prices":[100,101,102],"values":[8,21,13]}');
    writeFrame(FRAME_SIDES, '{"rows":[["Buy",26],["Sell",16]]}');
  }
  emitRow();
}
export function reset(): void { closeValue = NaN; }

The extractor selects wrun-4, resolves frame handles to names in the sheet, and generates FRAME_* indexes. Frame declaration names, output names, string-slot names and visual names must not collide.

Example: a box and label HUD

Both handles use pane pixels and retain their ids while the last close changes.

import { handles, input, none, ohlcv, output, overlay, string } from "./sdk/declare";
import { in_close } from "./gen/inputs";
import { emitRow, out_last_close } from "./gen/outputs";
import { sb_clear, sb_f64, sb_text, str_caption_sb } from "./gen/strings";
import { ALIGN_LEFT, ANCHOR_TOP_LEFT, bar, draw } from "./gen/draw";

input("close", ohlcv.close);
output("last_close", none, overlay);
string("caption", { max_bytes: 48 });
handles.box({ color: "#111827", borderColor: "#38bdf8", opacity: 1 });
handles.label({ text: "caption", color: "#ffffff", size: 12 });
const background = draw.box(0);
const caption = draw.label(1);
let closeValue: f64 = NaN;

export function init(): void {}
export function state(): i32 { closeValue = in_close(); return 1; }
export function finalize(): void {
  out_last_close(closeValue);
  if (bar.isLast()) {
    background.set(12, 12, 200, 46).anchor(ANCHOR_TOP_LEFT);
    sb_clear(); sb_text("Close "); sb_f64(closeValue, 2);
    caption.set(20, 22).text(str_caption_sb).anchor(ANCHOR_TOP_LEFT).align(ALIGN_LEFT);
  }
  emitRow();
}
export function reset(): void { closeValue = NaN; }

This sheet needs wrun-3, not a frame. Anchors are also available under wrun-4. The label's .text(...) creates it before .anchor(...) and .align(...) mutate it; ALIGN_LEFT starts the caption at x = 20 instead of centring it there.

Sources and the bar grid

Keep a market input at index zero; all other inputs align to its grid.

kScript source or idiomSheet fieldCode-first callDifference
source("ohlcv", ...)inputSources.close: { source: "ohlcv", field: "close" }input("close", ohlcv.close)One field per named input; input zero supplies the primary grid.
source("volume_profile", ...)Source volume_profile; input cellType: "array", max_cellsinput("profile", volume_profile.cells, { max_cells: 512 })Tuples are [low, high, buy, sell]; cap counts tuples, not f64 cells.
source("orderbook", ...)Source book, block_size, optional max_depth; celled inputinput("book", book.cells, { max_cells: 128, block_size: 1 })Tuples are [price, abs(size), side], +1 bid / -1 ask; exact join to primary bars.
source("trades", ...) raw tapeNo raw tape sourceinput(name, trades.volume, { side: "BUY" }) for aggregatesThe trades source means side-split period aggregates, not individual trade prints.
source("trade_volume_by_size", ...)Celled trade_volume_by_size vocabularyinput(name, trade_volume_by_size.cells, { max_cells })Declares successfully but this daemon refuses the unavailable data lane.
Other-symbol source / request and higher-timeframe htfinputSources[name].symbol, .exchange, .intervalinput(name, ohlcv.close, { symbol, exchange, interval })Pins are daemon behavior; coarser direct feeds align as of candle close. Chart inputs use the chart market/grid.
Watch values or installed non-market readings, with no legacy builtininputSources[name]: { source: "series", ref, missing }Sheet only; read generated in_<name>()Daemon only, never primary; no series.* code-first source namespace.

For source: "series", ref is watch/<slug>/<key> or an installed @scope/name. missing is carry (default) or nan, never zero. Readings bucket to the primary interval; the last reading in each bucket wins. Carry uses the latest bucket at or before the bar; nan requires a reading in that bar's own bucket. A series input has no field, selector, params or interval pin and cannot densify the grid.

Example: a watch series sheet

Use a metadata-first workspace for this sheet. The generated in_watch_flow() reads the watch value in state(); out_flow(value) writes the plotted value in finalize() before emitRow().

{
  "id": "watch-flow",
  "name": "Watch flow",
  "inputSources": {
    "close": { "source": "ohlcv", "field": "close" },
    "watch_flow": { "source": "series", "ref": "watch/flow/imbalance", "missing": "carry" }
  },
  "inputs": [{ "index": 0, "name": "close" }, { "index": 1, "name": "watch_flow" }],
  "outputs": [{ "index": 0, "name": "flow", "plot": "line", "panel": "lower" }]
}

Series inputs are ABI-neutral; the sheet above uses the wrun-1 default. Add abi_version: "wrun-4" when the same module also declares frames.

No home yet

These legacy behaviors need a deliberate substitute; an accepted sheet field alone does not provide every legacy visual.

kScript builtin or behaviorMissing Indicator wordNearest workaround
plotLine(..., fillGradient=...), gradient lines, momentum_fill, smooth, glowNo continuous gradient, smoothed-line or glow output optionUse stepped color_by/colors, or several bounded box/line layers.
linefill.new(...) and its setters; gradient cloudsNo linefill handle that tracks two moving line ids; no gradient fillranges[] (range(upperName, lowerName, options)) draws a flat filled band between two numeric outputs, with edge width, line style and palette; a fill between two line handles needs per-bar box() slices.
Per-bar plotPie(...) and plot(plotType="pie")No pie at each bar's time and priceSummarize the current values with panel.pie; it replaces one frame.
plotCandle(...) OHLC binding; OHLC tick bars in plotMiniChartGridNo four-output candle binding or OHLC mini-gridBody boxes plus wick segments on the chart; panel.line or card sparks for compact history.
plotMiniChartGrid grid, moving averages, badges and volume stripsNo candle-panel grid or automatic MA/badge compositionSeveral bounded panels, a card with sparks, or anchored handles.
barcolor(...)No candle body recolor channelrender.bgcolor for a regime tint, or draw your own candle bodies.
hline(...); plotHistogram(..., base=...) with a nonzero baselineNo dedicated hline or adjustable histogram baselineEmit a constant line; subtract the baseline for zero-centred columns, or use absolute-price boxes.
Arbitrary plotBatches per-bar payload arraysNo batched output channelBounded handle loops for retained objects; plot.levels, panels or ladders for snapshots.
plotShape(shape="char"), special location/size behaviorNo character-shape, relative-bar-location or size-output option on the shape rendererrender.text for characters, computed y for above/below bars, anchored label handles for pane placement.
plotPriceLabel / label.new icons; set_icon, set_glow, set_tooltip; plot/table tooltipsNo URL/SVG/image, glow or tooltip fields on these Indicator visualsText labels, captions or additional card/table rows.
plotText / plotLabel font family, weight; rich table spans and headersNo matching typography, colspan/rowspan or header-style vocabulary (label handles do take align: left, center, right)Use panel cells for basic text/color/bar/spark content, or anchored, aligned labels and boxes for explicit layout.
Box set_border_style, table set_position / delete, line/label stickyRightNo matching object settersUse styled line handles for borders, rebuild a frame for table content, or edge anchors for pixel-x/price-y placement.
plotCurve marker "spot", markers and arbitrary fractional line x; plotMatrix summary/highlight; plotTiles columns/accent/formatNo exact panel options for those legacy featuresScatter for fractional x; extra rows/series, formatted tile strings, and explicit colors for the annotations.
requestBars(...) independent OHLC arrays; ltf(...) lower-timeframe arrays; unsupported registered source(...) classesNo general nested-bars or arbitrary source adapterUse supported scalar/celled inputs, or prepare a daemon series and render an appropriate snapshot.
String, symbol, color, select or other nonnumeric compute input(...)No nonnumeric compute parameter channelNumeric parameters, sheet-only style bindings, or metadata source pins.
print(...) / log(...) console outputNo guest console importEmit a numeric diagnostic output or a bounded text/card row.

The contracts behind this map live on their published pages: Plotting for outputs, renderers and declared drawings, Drawing objects for handles and their setters, Drawing primitives for pane anchors, frames, panels and the compact widgets, Data sources for the source classes, and the Limits reference for every cap. The ABI contracts a sheet names are on Script definition.