How nice it is to talk — BeeDialogue lands in BeeEngine 2.11.0 Antonio, a 53-year-old independent developer, released BeeEngine 2.11.0, adding BeeDialogue, a dialogue-tree plugin for his open-source 2D HTML5 Canvas engine. The plugin handles speakers, lines, branching choices and straight-line advances, attaches through the engine's plugin contract without monkey-patching the loop or update/render methods, and has no tick or DOM listeners of its own — scenes call handleInput and draw directly. It supports optional localization via BeeLocale, emits change events for start, node, choice, advance and end, and can serialize tree state through toJSON/fromJSON for saving. Hi. I'm Antonio. I'm 53. I build things out of pure passion. I don't talk much. But when I do… BeeDialogue comes out. BeeEngine is a small 2D HTML5 Canvas engine I keep shaping in the open. Physics, scenes, sprites, tiles, audio buses, an inventory plugin, a locale plugin. Useful pieces. Quiet pieces. What was missing for story-shaped games was obvious: a place for NPCs to say something without me inventing a new if tree every weekend. So v2.11.0 adds BeeDialogue . Not a chatbot. Not a voice synthesizer. A dialogue tree : speakers, lines, branching choices, straight-line advances. The kind of thing you wire to a blue rectangle that pretends to be a guide on a bridge. BeeEngine has a plugin contract I take seriously. The core does not import plugins. A plugin attaches itself. js import { BeeEngine } from 'beeengine'; import { BeeDialogue, BeeLocale } from 'beeengine/plugins'; const game = new BeeEngine 'c', 800, 480 ; const locale = new BeeLocale { / strings… /, engine: game } ; const dialogue = new BeeDialogue { engine: game, locale, cancelKey: 'Escape' } ; // attach registers it as 'dialogue' — detach unregisters No monkey-patch of loop . No hijacking of update / render . BeeDialogue has no tick of its own and no DOM listeners. Your scene calls the verbs: handleInput input from scene.update draw ctx from scene.draw screen space, after the camera The motor stays a motor. The plugin stays a plugin. I sleep better. You load a tree once. Nodes can be an array easier to skim or a map. Literal text / speaker work. Or textKey / speakerKey if you pass an optional BeeLocale constructor, setLocale , or engine.plugin 'locale' . dialogue.load { start: 'intro', nodes: { id: 'intro', speakerKey: 'guide', textKey: 'hi', choices: { textKey: 'ask map', next: 'map', data: { topic: 'map' } }, { textKey: 'bye', next: null, data: { topic: 'bye' } } }, { id: 'map', speakerKey: 'guide', textKey: 'map', next: 'tip' }, { id: 'tip', speakerKey: 'guide', textKey: 'tip' } } ; Rules that saved me from myself: choices → advance follows next or ends . choose index . false and warns. Good. I need warnings more than cleverness. start while already open does a clean restart end with reason restart , then start again . BeeDialogue is not BeeText.drawHUD . It draws a simple panel when you ask. js const scene = { update dt, input { if input.wasPressed 'KeyE' && dialogue.isOpen dialogue.start ; dialogue.handleInput input ; // Space / Enter advances or confirms; arrows move the highlight }, draw ctx { dialogue.draw ctx, { x: 40, width: ctx.canvas.width - 80 } ; } }; onChange reports start , node , choice , advance , and end with a reason : finished , cancel , restart , reload , missing-node … . Enough to feed a future quest plugin without hard-wiring anything today. And yes — toJSON / fromJSON save the tree and where you stood, so you can tuck the DTO into BeeSave next to inventory slots. Definitions stay yours; restore reopens on the saved node and emits node not a fake second start . The demo is examples/dialogue.html . Press E . The English string does not say “E to talk”. It says “E to interact” . Because BeeDialogue does not talk. It does not clear its throat. It does not do regional accents. It advances nodes. The joke writes itself, and I left it in the locale table on purpose talk: 'E to interact' . Press L if you want Italian. The guide still will not speak aloud. She will, however, mention a village east of a bridge, which is already more social than most of my week. I like small contracts: | Piece | Job | |---|---| | BeeLocale | t key — pure read | | BeeInventory | stacks, use, equip — no draw loop | | BeeDialogue | tree state — you draw and feed input | Together they feel like a tiny RPG toolkit without pretending to be one. Next ideas on the shelf one at a time : Quest, Post FX, scene Transition, action remapping… Lights, Spine, Net later. Those touch more surface area. Dialogue was the polite guest who hangs its coat on attach and leaves with detach . beeengine examples/dialogue.html node scripts/test-beedialogue.mjs import { BeeDialogue } from 'beeengine/plugins' If you break it, tell me how. If you use it in a jam game with three lines of dialogue and a torch tip, tell me that too. Short messages welcome — I don't talk much. But when I do… you already know what comes out. — Antonio