Skip to content

D/BASIC Playground User Guide

The D/BASIC Playground is a browser workbench for writing, compiling, and running D/BASIC. It uses the real D/BASIC compiler and shared sliced runner compiled to WebAssembly, rather than a JavaScript reimplementation of the language. The compiler's DBC image is handed to that runner unchanged. The standard dworks.widgets and gx source libraries are built in for self-contained interface and game experiments.

For the language itself—from first console script through objects, widgets, Intents, optimization, and bytecode delivery—open the D/BASIC Language Reference.

Your source stays in the browser; the playground does not upload it. Programs can use the browser host's durable DATA/artifact store and transactional pasteboard/drag services. General-board TEXT copy and paste crosses to the operating-system clipboard only through an explicit D/BASIC transaction and the browser's normal permission policy. Network, FILE, named-media, and AUDIO calls are not exposed by today's canonical callable registry.

Quick start

  1. Open the D/BASIC Playground.
  2. Choose D/Works widget form from the Example menu.
  3. Select Run, or press ++cmd+enter++ on macOS / ++ctrl+enter++ elsewhere.
  4. Click in the live title field to place its visible caret, type to insert there, use ++tab++ to move focus, and press ++enter++ to activate a control.
  5. Edit the source and run it again. Use the download button to save the current .bas file.

The status at the top changes from compiling to idle, running, halted, or refused. An idle window is still live and can receive input.

Every D/BASIC code block in the Language Reference has a ▶ Playground link. It opens a new playground tab and loads that exact sample into the editor. The source travels in the URL fragment, which stays in the browser and is not sent with the web request. Short fragments may intentionally produce a diagnostic until you add the surrounding declarations described by the lesson.

The workbench

Source editor

The left panel contains one D/BASIC source file. Line and column numbers appear below the editor.

  • ++cmd+enter++ or ++ctrl+enter++ compiles and runs the current source.
  • ++tab++ inserts two spaces while the editor has focus.
  • Reset restores and reruns the selected example.
  • The download button saves the current source; it does not save runtime state.

Edits are held only in the current page. Download anything you want to keep before reloading or leaving.

Live surface

Window-face programs draw into a 320 × 192 logical surface. The browser scales that surface to fit the available space while input coordinates remain in the same 320 × 192 coordinate system. A high-density WebGL2 scene surface keeps browser-rendered type from becoming an enlarged low-resolution bitmap.

Click the surface to give it keyboard focus. While focused:

  • Printable ASCII keys are delivered to ON KEY.
  • ++tab++ is key value 9, ++enter++ is 13, ++esc++ is 27, Backspace is 8, and Delete is 127.
  • Insert and Arrow keys use 256 through 260; ++home++ / ++end++ are 261 / 262, Page Up / Page Down are 263 / 264, and function key Fn is 0x0120 + n.
  • The D/Works text field supports click-to-place, Left/Right, Home/End, Backspace, Delete, and insertion at its visible caret.
  • ++esc++ is delivered to the program and then returns focus to the web page.
  • Pointer press, drag, and release events are delivered to ON POINTER with local x, y, and button values.

Console and diagnostics

Console-face output and compiler diagnostics appear in the lower-right panel. Select a compiler diagnostic to move the editor caret to its reported source position.

A runtime refusal names its class, governing rule ID, and detail value. Refusal is deliberate D/BASIC behavior: the runtime stops cleanly when a program requests a capability or operation the browser host does not provide.

Your first console program

PRINT "HELLO FROM D/BASIC"
PRINT "Compiled once. Executed by WebAssembly."
END

This program declares the console face implicitly, prints two lines, and halts with status 0.

Interactive console input is not available in the browser host. A program that waits on INPUT or LINE INPUT reaches the runtime's normal end-of-input refusal.

Window programs

A window program owns its lifecycle through D/BASIC face handlers:

WINDOW SUB OPEN()
  SERVICE SET_TITLE("My D/BASIC window")
  SERVICE INVALIDATE()
END SUB

WINDOW SUB DRAW()
  INTENT GFX.BEGIN_FRAME()
  INTENT GFX.FILL_RECT(0, 0, 320, 192, 2081)
  INTENT GFX.DRAW_TEXT(12, 12, "HELLO, WINDOW!", 3, -1, 2081)
  INTENT GFX.PRESENT()
END SUB

WINDOW SUB RESIZE(W AS INTEGER, H AS INTEGER)
  SERVICE INVALIDATE()
END SUB

WINDOW SUB CLOSE()
END SUB

ON KEY SUB (K AS INTEGER)
  SERVICE INVALIDATE()
END SUB

ON POINTER SUB (X AS INTEGER, Y AS INTEGER, Buttons AS INTEGER)
  SERVICE INVALIDATE()
END SUB

OPEN initializes application state, DRAW emits one frame, RESIZE updates layout, and CLOSE releases owned state. ON KEY and ON POINTER are optional.

The browser supports the canonical GFX intent rows used by D/Works: frame begin and present, clip set and reset, rectangle fill and copy, plain and styled text, and polylines. It also mounts the current SERVICE pasteboard/drag/DOBJ-schema rows and all DATA rows. A malformed, stale, unauthorized, or unavailable operation fails closed instead of being simulated.

D/Works widget support

Add this standalone line to use the canonical widget source library:

IMPORT dworks.widgets BAKED

At build time, the WebAssembly adapter embeds the same dworks/widgets.bas source used by the D/BASIC developer kit. At compile time, the playground bakes that library into your DBC image. The browser does not keep a copied or browser-specific widget implementation.

The library currently includes:

Type Purpose
WorksTheme, WorksMetrics Shared RGB565 palette and layout measurements
WorksSurfaceDamage Surface-owned damage and expose tracking
WorksLocalEvent Synchronous application-owned control actions
WorksPanel, WorksLabel Containers, headings, and static text
WorksButton, WorksIconButton Text and compact command controls
WorksTextField, WorksToggle Editable text and checked state
WorksTooltip, WorksPopoverFrame Bounded transient surfaces
WorksCommandRow Reducible command-list rows
WorksMenuItem, WorksMenu, WorksMenuCascade Application-owned popup menus
WorksStatusStrip Neutral, working, warning, and ready status feedback

The widgets are application-owned objects. They do not install hidden event loops or platform callbacks. Your program:

  1. creates controls in WINDOW SUB OPEN;
  2. applies a WorksTheme and assigns bounds;
  3. paints controls from WINDOW SUB DRAW;
  4. reduces key and pointer input in its own handlers; and
  5. requests another draw only when state or exposed pixels changed.

Choose D/Works widget form for a complete example with a panel, label, text field, toggle, button, focus traversal, pointer hit testing, local events, and resize handling. It is intentionally more useful than a tiny disconnected widget snippet: download it and use its controller as the starting point for a new surface.

Use widget setters for changes

The widget library tracks damage. Methods such as SetText, SetChecked, SetFocused, and SetDown mark a widget only when its visible value changes. Prefer those methods to direct mutation when handling interaction, then use SERVICE INVALIDATE() when the surface has work to present.

GX game-engine support

Add the protected GX library with its simple default import:

IMPORT gx

The playground embeds the same governed gx.bas source used by the developer kit and bakes it into the program image. Choose GX Gravity (official sample port) for the fuller physics demo: movement, jumping, reusable projectiles, gravity, platforms, collision, animation, pause, and a continuously paced window. It is a D/BASIC/Intent port of the official GX physics/gravity.bas program, not a newly invented substitute. The exact upstream PNG sprites, GXM map, and MIT license ship beside it; this alpha live route represents that material with current GFX primitives until named resources are mounted. GX engine first light remains the smaller teaching probe.

The currently admitted GX core supplies caller-owned scene, entity, tilemap, camera, collision, and animation helpers. Your window remains responsible for input and emits ordinary GFX Intents, which is exactly what lets one game model run under a browser, a desktop head, or a constrained D/OS route.

Continue with Gaming & GX, then build the complete first-game tutorial. Every BASIC block opens with its exact source already loaded into the playground.

Imports and source limits

The browser accepts IMPORT dworks.widgets and IMPORT gx; either may spell BAKED explicitly. Baked delivery is required because this self-contained browser host does not mount a shared-library store. It refuses local paths, other modules, SHARED imports, path traversal, and trailing import syntax. This keeps compilation local and deterministic while following the language-wide rule that imports are baked unless SHARED is written explicitly.

The source limit is 256 KiB before requested built-in library source is added. The D/BASIC compiler may apply narrower language or artifact limits and reports those as normal diagnostics.

How execution stays responsive

Compilation and VM execution run in a dedicated browser worker, so building the full widget library does not lock the editor or status display. The runtime executes a fixed maximum of 5,000 DBC instructions per turn. A cooperative or animated program resumes on a later animation frame. This is the same instruction-budgeted run_slice execution shape used by D/BASIC runners; it prevents a long-running program from monopolizing the page without inventing browser-only language semantics.

The playground clock is synthetic and advances deterministically when a program reads it. It is useful for examples and repeatable behavior, but it is not the browser's wall clock.

Current browser-host boundaries

The playground is a developer/conformance preview, not a named D/OS product route or a hardware qualification result.

  • Mapped by the shared runner: all 112 canonical Intent rows. CORE, GFX, COMPUTE, and MATH execute locally; provider-owned operations cross one typed request boundary.
  • Mounted by this playground today: compilation to DBC, console output, window lifecycle, normalized keyboard and pointer events, baked dworks.widgets and gx, surface services, cancellation acknowledgement, CORE capability/clock/fence operations, all fifteen registered GFX operations, vector/SHA-256 compute, the current MATH family, transactional General and Drag pasteboards, operating-system TEXT clipboard synchronization, generation-checked drag negotiation and receipts, an installed-schema DOBJ resolver, persistent DATA content, attachment writes, and artifact save/read/list/retire/publication operations backed by browser-local durable storage.
  • The DOBJ catalog begins honestly empty. An unknown package/schema identity reaches the mounted resolver and returns the canonical not-found refusal instead of trusting a DOBJ label or inventing package authority.
  • The browser DATA mount has the exact sixteen-byte semantic identity D/BASIC-BROWSER1. OPEN accepts that identity only; an arbitrary nonzero identity does not silently create a pretend database.
  • Not callable in the current canonical registry: FILE, network, AUDIO, and named-media resource operations. The language guide describes their intended portable contracts for this alpha, but they are not among the 112 rows and the playground does not claim or fabricate them. Product packaging and installed SHARED library artifacts are also outside this self-contained browser host; dworks.widgets and gx are baked into the compiled DBC image.
  • Not persisted: source edits, VM memory, open windows, and widget state disappear when the page reloads or a new run starts.
  • Rendering: the browser lowers semantic RGB565 GFX intents through a retained WebGL2 scene. It substitutes Atkinson Hyperlegible for UI font roles and JetBrains Mono for the native-mono role, turns browser glyphs into WebGL textures at display resolution, and keeps final composition on the WebGL surface. Glyph pixels can therefore differ from a classic-machine or native composed head while the D/BASIC intent stream and its 320 × 192 geometry remain the same.

Troubleshooting

The runtime says unavailable

Use a current browser with WebAssembly enabled, then reload. Content blockers or strict enterprise policies can block the .wasm file.

The program is refused before drawing

Read the console's refusal class and rule. The most common cause is requesting a service or Intent route that the browser host does not mount. Start with one of the included examples and add capabilities incrementally.

A compiler diagnostic points into the widget library

Diagnostics in your own source are translated back to your editor line numbers. A line inside the embedded library indicates a library/compiler integration issue; keep the diagnostic code and report it with the source that triggered it.

Keyboard input edits the source instead of the widget

Click the live surface first. Its focus outline confirms that key events will go to the D/BASIC window. Press ++esc++ to return to the page.

My changes disappeared

The playground intentionally has no account or cloud storage. Use the download button before reloading or switching away.

Privacy and security

Compilation and execution happen in WebAssembly inside the page. Source is not submitted to a remote compilation service. Programs receive only the bounded host capabilities described above, and unsupported imports and services are refused by name.