Concept
A RailCommand detection block is a named run of track that the layout watches for occupancy. On the schematic a block is a single straight segment of cells: exactly 1 cell on its thin axis and at least 2 cells on its long axis, horizontal or vertical — never diagonal. Editors clamp every create and resize to this rule, so a square or 1×1 input resolves to a horizontal 2×1; import keeps a decoded sub-minimum span as-is and warns.
A block's Track Class says what kind of railroad it is: Main, Branch, Siding, Yard, Lead, Industry, Staging, Interchange, Runaround or Maintenance. A block that has not been given one reads Unclassified, which is a state with a name rather than an empty field, and it is what you will see in the Block Editor list and in the class picker. A block whose own class is empty but whose track carries one uniform class of its own takes that class: the value was authored, so it is read rather than guessed at. Marking a block Dark territory (no detection by design) says there is no detector; it says nothing about what kind of railroad it is, so a dark territory block still needs a class.
Paint mode is how a classification is given to many blocks at once. Both editors have it, with the
same brushes: one per Track Class, a Dark territory toggle, and an Unclassified eraser. Pick a
brush, then click a block or drag across several, and each block you cross takes that brush once. The
keyboard does the same: with a brush in hand, Enter paints the block under the cursor, . and ,
step through the brushes and Escape puts the brush down. Painting acts on BLOCKS, never on raw cells:
a stroke that crosses track belonging to no block writes nothing, says so at that spot, and offers to
create a block there. Nothing is created until you press it. A drag writes one block at a time on either
editor, so a block the write could not reach leaves the rest of the stroke saved: the report names
that block, says no verdict was reached for it, and the blocks painted around it stay painted. The eraser clears the block's
classification including the classes its cells carried, which is what it takes for the block to
really read Unclassified; a class brush leaves the Dark territory flag alone, and the Dark
territory brush leaves the classification alone. A Dark territory DRAG is one gesture with one
intent on either editor: it takes its direction from the first block it crosses and writes that same
state to every block after it, and the report says which way it went. On the Avalonia desktop a block
whose write is refused shows the refusal at the block itself, in the engine's or the host's own
words, outlined in red; a place with nothing to paint, such as a piece of track belonging to no
block, is outlined in amber instead, because one is something to go and fix and the other is
something you can act on where you are. Switching the desktop canvas out of Edit puts the brush
down, the way it puts the element palette down.
Clearing a block's Track Class does the same thing wherever you do it. Choosing the empty option in the block's settings modal, or in the cell properties panel on either editor, clears the block's classification exactly as the eraser brush does: the block's own class AND any classes its individual cells were carrying, so the block genuinely reads Unclassified afterwards rather than picking its old class back up from the track underneath. Editing anything else about a block leaves its classification alone.
An unclassified block is drawn distinctly on both schematics while you are editing: its box is stroked in a dashed amber outline. It is an outline rather than a fill because a block can be unclassified and dark territory at once, and the dark neutral fill has to keep reading; a block in both states shows both. Operating displays are unchanged, on either editor: the outline is drawn in Edit and in no other display mode, because classification is something you author rather than something you operate. On the desktop the outline appears on a layout you are editing online; while a layout package is mounted the package does not yet carry the block-level answer, so the desktop draws no marking at all rather than guessing (see the troubleshooting list).
CTC generation is refused until every block on the chosen switchboards is classified, and until every piece of track on them belongs to a block. A dispatcher panel cannot tell a mainline from a yard ladder unless the track says which it is, and the refusal lists each block and each unblocked piece of track by name so you can go straight to it.
Each block carries a governed config: zero or more sensors that report occupancy, and markers that tell an approaching train where to brake or stop. A current sensor detects a length (drawn as a bar); a point sensor is a momentary IR/reed contact (a dot). Occupancy is the logical OR of the block's sensors — any active sensor recolours the whole block bar. Markers are classified purely by ramp: ramp above zero is a Brake marker, ramp of zero a precise Stop. It serves layout owners and editors configuring RailCommand, and operators reading block state in a session.
When a layout is imported from TrainController, a block's markers arrive with the block: the block decode carries them, and the import's Warnings tab counts the marker records it saw (444 on a large layout) rather than reporting them as skipped contacts: a marker is a block-family virtual contact, not a wired sensor, and it never carries a feedback address. Not all of them come across yet. On that same large layout the block decode reaches 215 of the 444, because some blocks' member tables do not read on the current decoder; the count on the Warnings tab is the number of marker records in the file, not the number placed on blocks. A marker's role does not import either: TrainController stores it somewhere the decoder has not read, so an imported marker carries its distance and its raw direction flag and no Brake/Stop name. Set the role by editing its ramp in the Block Detail panel, the same way a hand-built marker gets one.
The operating engine enforces these markers for automated trains. A train arriving in its destination block no longer brakes at the block boundary: it holds speed until the brake point — a Brake marker's distance, or as late as its calibrated stopping distance allows before a Stop point — then decelerates to stop at the marker. A destination block with no markers keeps the original behaviour (braking begins the moment the block reports occupied), and any unresolvable configuration falls back to that same immediate braking — the safe direction. Markers imported from TrainController with an unconfirmed direction flag are applied in both travel directions until the flag semantics are confirmed, which can only make a train brake earlier, never later.
How To
Prerequisites: an imported or authored layout, and owner/editor access in the organization that owns it.
Review and configure blocks on the Block Editor page:
- Open
/app/railcommand/layouts/{LayoutId}/blocks. Summary cards count Total Blocks, Well Configured, Missing Detection, No Signal, and Needs Review; filter by Track Class, Configuration (well configured, or questions still open), or Detection. Well Configured counts a block with no question left open, and the card says so under the number. There are six questions: its name, its track class, its length, its maximum speed, its detection (a block marked dark territory has answered that one by design), and a signal. Maximum speed and signal are the two that are asked only of a block that has one: a block with no posted limit, and a block that owns no signal, have answered those rather than left them blank, so an unsignaled layout is not marked down for being unsignaled. The other four, detection included, are asked of every block, so a block with no sensors and no dark-territory flag has its detection question open. Under the cards, Questions Still Open lists each question with the number of blocks it is open on: that list, not the single number above it, is what to work from after an import, because one bulk action can close the same question on every block at once. Hovering a row's Config bar says how many of that block's questions are answered and names the ones that are not. A block whose saved configuration cannot be read is counted under Needs Review only, and appears under no question, because nothing is known about what it is missing; the card counts out of the blocks the page could read, and says how many it could not. Needs Review also counts a block whose configuration reads fine but holds something a block's governed configuration cannot carry: that block keeps its counts and its score, and its row says which part and why. - Click a block row to expand its inline editor and set Block Name, Track Class, Direction, Unit and Total Length, Foul End A/B, Max Speed (mph), Restricted Speed, and the Electrified, Terminal, and Critical Section flags. A speed limit that came from a TrainController import is shown in the box under a "from the import" note: it is saved as your own value only if you change it, and emptying the box goes back to the imported one rather than leaving your last number behind.
- In the Block Detail panel edit governed Length (inches), each sensor's kind (point, current, flagman, delayed action) with debounce and memory (ms), and each marker's distance and ramp (inches: the fields carry an
insuffix and match the Length field's unit; values are stored internally in millimetres). A marker whose distance plus ramp runs past the end of its block is flagged "past end of block". The Block Detail panel is labelled "Changes here save immediately" and auto-persists, unlike the Cancel/Save fields above. A sensor the block owns (one TrainController decoded as a block member, with no contact symbol drawn for it) also carries its address here: board, input and mode, checked by the same rule the Sensor Configuration page checks a drawn contact by, and the same rule again behind the DCC Address field the Layout Editor's cell properties panel shows for a drawn contact, so a board and an input accepted on one of those three surfaces is accepted on all of them and a refusal reads the same wherever you meet it. An empty board is allowed and says so: a sensor you have not wired yet reads Without Connection on the sensor table, which is an answer about the railroad rather than an error. Changing the board or the input drops the flat LocoNet number the import decoded, because that number named the old address and cannot be recomputed here; the panel says so when it happens, and the note stays while you keep editing. If the import decoded an address the rule would refuse, the panel says Needs review beside the fields when you open it, rather than waiting for you to type into a field that was already wrong. A sensor a block owns carries its namespace in its stored number, so Plain number is kept only while it has a board: choose Plain number with the board empty and the panel says so and asks for the board. Beside the address the panel offers the other resolution, place this sensor on a cell: choose a panel, a column and a row, and the sensor leaves the block's own list to become a feedback contact of its own, carrying its address with it, edited from then on like any contact you drew. The picker starts on the block's own panel, and a column or row outside that panel's grid is refused with the panel's size, because a cell outside the grid is not drawn. Where a block carries two sensors that cannot be told apart, because neither was decoded with a name, a board, an input or a number, placing one of them is refused and says so: give one of them a name or an address here first, and the two stop being the same sensor to everything that reads them. Neither resolution is forced, and a sensor whose occupancy is computed (a flagman) is offered neither, because it has no detector: its way out is a block rule, and the panel links to Webb to author one. Length is a single value: the Block Detail Length and the row's Total Length are the same measurement, kept in step whichever surface you edit (stored governed in centimetres, shown in the block's chosen unit). An imported block's decoded length shows in both without re-entry. - Click Save to persist the row fields.
Edit geometry and per-block settings from the Layout Editor:
Open
/app/railcommand/layouts/{LayoutId}/editor. In Edit mode, double-click a block to open its Properties panel, then choose Open advanced settings… for the Block settings modal (tabs: Block, Block Editor, Speed & Rules, Conditions). In Simulate or Live mode, double-click opens the advanced modal directly. The Block Editor tab hosts the same Block Detail view, but changes here are staged with the rest of the modal: OK persists them and Cancel discards them. The Speed & Rules tab carries the block's rule flags — Release Rule, Routing Cost, Min Hold Time, Depart Delay, Permissive working, Out of service, and Dark territory (no detection by design). Drag-resize on the canvas or use the numeric span editor; both clamp to the geometry rule. A turntable or transfer-table cell routes through Properties to its own dedicated editor (tabs: General, Tracks, Connection, Display, Levels), not the block or turnout modal; its General tab also carries the authored physical startup position used by session-start reset. An indicator lamp cell (the band-15 indicator elements) routes the same way to its own small Lamp modal — display name, lens-colour override, and Flash when lit — and Open advanced settings… is the only path to it, because double-click opens the Properties panel rather than the modal.Classify several blocks at once with paint mode. In Edit mode, choose the paint tool in the editor header (beside Select, Draw and Pan) and pick a brush: one for each Track Class, a Dark territory toggle, and an Unclassified (eraser). Click a block to paint it, or drag across several to paint each one. Painting acts on blocks, never on individual cells, so the brush paints whichever block owns the cell under the pointer. Keyboard: the arrow keys move a dashed paint cursor around the canvas, Enter paints the block under it, and . and , step forward and back through the brushes without leaving the canvas (the same two keys the desktop editor uses), and Escape puts the brush down and returns you to Select, keeping whatever was selected, which is what Escape does in the desktop editor too. The paint tool never moves your selection, and while it is active the canvas keys that delete, rotate, resize, copy and paste are switched off. Every stroke reports what it did, and names every place it could not paint. A drag writes one block at a time, so a block the editor cannot write does not undo the rest of the stroke: the blocks painted around it are saved, and the report names the one that could not be written and says so. Two brushes are worth reading before you use them: the Dark territory brush only turns that flag on or off and leaves the Track Class exactly as it was, and the eraser clears the block's classification including any classes its individual cells were carrying, which is what makes the block genuinely read Unclassified afterwards. A drag with the Dark territory brush takes its direction from the first block it crosses and writes that same state to every block in the stroke, so one drag turns the flag on (or off) across all of them rather than flipping each one separately, and the report says which way it went. Undo does not cover painting, so it is switched off while the paint tool is active: the editor's undo is for geometry (drawing, deleting, moving and rotating cells) and it carries no classification. To change a class back, paint the block again with another brush; a class the eraser cleared from a block's individual cells cannot be restored by undo at all, which is why the eraser says what it clears before you press it.
Painting a piece of track that belongs to no block does nothing, says so, and offers Create a block here, which runs the ordinary block creation you would get from the element palette. Nothing is created until you press it, and the block you get reads Unclassified straight away, with the dashed amber outline (on the desktop, on a layout you are editing online), until you paint it. On the canvas, a block with no Track Class is drawn with a dashed amber outline and a block marked Dark territory takes the neutral slate fill it wears during operation, so you can see which blocks CTC generation will refuse on without opening any of them.
In Edit mode the element palette is an overlay pinned to the canvas's left edge, so it sits on top of any blocks drawn there. Use the chevron in the editor header to collapse it and reveal those cells, and the same control to bring it back; leaving the editor is a separate Exit editor button, still guarded by the unsaved-changes prompt.
On the Layout Editor canvas, track is drawn at a line weight that follows its Track Class: Main is heaviest, then Branch, Staging, Interchange and Runaround, then Siding, Yard and Lead, with Industry spurs lightest. A cell whose class comes from its block inherits the block's weight, and a cell with no class resolved keeps the standard weight. This is an engineering-drawing convention and it is deliberately limited to the Layout Editor; the CTC dispatch panel keeps a single uniform weight for every class, because a period dispatcher's board draws to its own idiom rather than to a track chart. Changing a block's Track Class therefore changes how its cells are drawn on the editor, and never changes their weight, their dash or their colour on the CTC panel.
On a generated CTC panel the class does exactly two things: it supplies the label a block is drawn with when the block has no name of its own, and it sets the order the branches off one control point are placed in. The block's shape on that panel comes from how it connects in the layout graph and never from its class: connected at both ends it is drawn as through track, connected at one end as a stub, and a fan of tracks off one throat as a yard. So the same class is drawn three different ways on three different layouts, and a double-ended interchange or a through maintenance-of-way track is not drawn as a dead end.
On the canvas, turntable and transfer-table cells render through the same shared cell-producer path as other special cells: the renderer reads each one's saved configuration through the shared resolver, so a turntable's ring and a transfer-table's tracks draw from their stored config rather than a block's geometry. A cell still flagged Needs configuration draws its placeholder until you complete it in that editor.
Worked example: a 4-cell horizontal siding renders as a bar with one full-length current sensor and a Stop marker at its clearance point. Set the marker's ramp to 0 so it reads Stop, save, and confirm the Detection column shows a green check.
Troubleshooting
CTC generation says it is refused, and lists blocks and track. Every block on the switchboards you chose has to carry a Track Class, and every piece of track on them has to belong to a block. The refusal names each one: a block by its name (or by its position if it has none), and a piece of unblocked track by its switchboard, column and row. Set the class on each block listed, draw a block over each piece of track listed, then generate again. A block marked Dark territory is included in that list if it has no class: the marking says there is no detector, not what kind of track it is. Track you have taken out of service drops off the list at the next derive of the layout's graph. From that derive on, the generated panel does not draw it, so it is not something you could go and fix, and it is off the list whether the graph holds it as a node or as an edge. Until that derive it is still on the live graph and still listed, because the panel would still draw it. A block you have taken out of service drops off the same way, and so does the track its retirement cut off from the rest of the railroad. The track that block COVERED is a different question: any of it still on the live graph is listed as track that belongs to no block, because the panel still draws it and the retired block is no longer there to hold it. Draw a block over that track, or take it out of service too.
Paint mode says a block could not be painted. The reason on the line is the one the layout's own write gave back, not a guess: a block deleted since the editor last read the panel asks you to reload the layout and paint again, and a cell that is not a block says which of the two things is true: the cell is inside a block, which it names so you can paint that block instead, or no block governs the cell, so a block has to be drawn over the track first. A line that says the editor got no verdict for a block is a different case: nothing was decided about that block, so paint it again, and any block the same stroke painted before it is already saved. The same reason also appears as a red "!" badge on the cell it is about, and the next stroke clears it.
Ctrl+Z does nothing while I am painting. That is deliberate, and the paint panel says so: the editor's undo is for geometry, so it has nothing to reverse about a class, and undoing while a brush is armed would quietly reverse whatever you drew before you picked the brush up. Paint the block again with another brush to change its class; put the paint tool down and undo works as it always did.
A block's Track Class box is empty, but the block says it is classified. Both are true and neither is a fault. The box is the block's OWN class, which is what you edit; the line under it is what the block IS classified as. A block with no class of its own over track that uniformly carries one reads that class, because somebody authored it on the track. Set the box if you want the block to carry the class itself. A block that really has no classification says Unclassified on that line, which is the state CTC generation refuses on.
I painted a class onto a block and nothing on the canvas changed. Check what the brush was. The Dark territory brush changes the detection flag only, and the eraser sets the block to Unclassified. If a class brush appears to do nothing, the block probably already carried that class. A block whose own class is empty but whose track uniformly carries one class of its own already reads that class before you paint.
A switch click in Simulate shows a red "!" badge, or a notification, instead of throwing. The editor recorded the command but the layout's simulated plant did not act, or the command was refused by the safety kernel; the notification says which. The badge clears on the next successful command on that cell. The page stays live: a failed command never terminates the editor session any more, and the fault is logged with the layout and the command so support can find it.
- Missing Detection (red ✕): the block has no resolved sensor. Add or resolve one in Block Detail; an unresolved indicator renders as a "missing sensor config" placeholder, never dropped. Two blocks never draw that cross: one you marked Dark territory shows a grey moon and reads "no detection by design", and one whose saved configuration could not be read shows an amber warning and reads Needs review, because in that case nobody knows whether it has detection.
- A block row reads "Needs review" with a reason: its saved configuration could not be read (for example it is not valid JSON), so its sensors, signals, limits and completeness are all unknown and the page reports none of them as missing. The Rules Debugger reports the same block with the same reason. Open the block in the Layout Editor and re-enter its configuration, or re-import the layout.
- A block row reads "Needs review" and still shows its counts: the block reads, and one part of it is in a shape a block's governed configuration cannot carry. The commonest is a marker added in the Layout Editor's Markers list or in the desktop panel editor beside the markers that came from an import: those are cosmetic, the operating engine's brake planner skips them, and the row names which marker and why. Expand the block to clear it. That marker has its own Needs review row in the Block Detail marker list, and the row carries both ways out: type a dist in inches, and a ramp if the train should slow into it rather than stop at it, to make it a real marker; or press Delete to remove it. Either one acts on that marker alone and leaves the markers that came from the import exactly as they were. The ramp box starts with the ramp that marker already carries, and leaving it blank keeps it, so typing a distance alone never turns a marker that brakes into one that stops. A marker you added in the Layout Editor's Markers list is still listed and still deletable there, and adding another one there never disturbs the imported markers. The Markers list and the Block Editor tab beside it edit one list: a marker you add, retype or remove in the Markers list is still that way after you clear a Needs review row on the other tab, and the row you cleared stays cleared. In the import preview, before the import is committed, the same row is read-only and says so: the block is not saved yet, and the two ways out are in Block Detail once it is.
- Imported blocks read "0 well configured", "no detection" and "no signals" on the Block page: fixed 2026-09-12. The page counted a block's sensors and signals from keys only the Layout Editor block modal writes, while a TrainController import writes the governed ones, so every imported block answered false and zero however much the import had decoded. Two of the eight things the page scored could not be filled by any import either, which kept an imported block off the Well Configured card on arithmetic alone. Blocks now count what they actually carry, including the per-block signals TrainController draws on no page, and the score asks only questions that can be answered. An already-imported layout picks this up the next time the page is opened; nothing is re-imported and no data changes.
- An unsignaled layout, or a layout with no posted speed limits, still read low on Well Configured: fixed 2026-09-13. Most TrainController layouts carry no posted limit on a block and are not signaled at all, and the score treated both as omissions, so those blocks could not reach the card however complete they were. "No posted limit" and "no signal on this block" are now answers: the question is not put to a block that gives them, and a block that has answered everything it was asked reads 100 percent. A limit typed by hand, or a signal placed on the block, is a question the layout does ask, and it counts. Nothing was loosened for a block that is genuinely unfinished: a missing name, track class, length or detection still counts against it, and Questions Still Open names which one.
- A block whose signals are both set to "None" still counted as having signals: fixed 2026-09-13. The block modal stores a hidden per-end flag that it switches on for every block it saves and offers no control for, and the page counted that flag rather than the signal TYPE you chose. A block with both ends set to None reported two signals, the score answered its signal question for you, and the Rules Debugger said the same block had no internal signals. The count, the No Signal card, the score and the Rules Debugger now all read the type you chose, so they give one answer about one block.
- A block still reads 83 percent and is not counted under Well Configured: that is the rule, not a rounding fault. Well Configured counts a block with nothing left open, so a block that answers five of its six questions is not on that card until the sixth is answered. Questions Still Open names it, and the row's percentage is the progress towards it.
- A change made in the Block Detail panel did not update the row's percentage: fixed 2026-09-13. That panel saves immediately, and only the surrounding Save used to re-read the page, so a length or a limit supplied there left the row and the Questions Still Open list showing the old answer until something else saved or the page was reloaded. The edited block is now re-read and re-scored as soon as the panel's change is stored.
- A block shows a maximum speed of 0: that is not a limit, and the score reports Maximum speed as still open on it rather than treating it as "no posted limit". A TrainController limit of 0 is decoded as no limit, so a 0 on the row came from somewhere else; set the limit, or empty the box to fall back to the imported value.
- "defaulted to current — confirm" — the sensor kind was not imported. Confirm point vs current; an untouched default is never written back.
- "length not imported" / "positions spaced by order" — those values were not decoded. Set the length; sensor positions stay approximate (order-based).
- Blocks along the left edge are hidden and panning will not reach them — the element palette is an overlay covering that strip, not a cause of missing blocks. Collapse it with the header chevron.
- Deleting a panel will not delete the blocks and cells on it: that is the rule, not a fault. A panel that still holds any live cell is refused for deletion, and the refusal says how many it holds: move those cells to another panel, or delete them, and then delete the panel. Nothing you drew is ever removed by a decision you made about a panel. A layout also keeps at least one layout panel at all times, so its only one cannot be deleted; a CTC board does not satisfy that, because a board shows the railroad rather than describing it, so deleting the last board is ordinary.
- Cannot make a block 1×1 or diagonal — the geometry rule forbids it; the editor normalizes to a horizontal 2×1.
- "past end of block" on a marker — the marker's distance plus ramp is longer than the block. Usually a unit mistake: these fields take inches, like Length. A TrainController value typed as millimetres lands the glyph at the far left of the bar.
- Blocks you marked Out of service long ago have suddenly turned grey — expected, and the grey is the correct rendering. The web schematic reader looked for the flag under a different spelling than the editors write, so the Out of service checkbox has been inert on the schematic since it shipped; that mismatch was fixed on 2026-08-14. Any block already ticked out of service starts showing its out-of-service grey on the web schematic at that point without anyone editing it. Untick the flag if the block is back in service.
- A block shows out-of-service grey on the web schematic but looks unchanged on the Avalonia desktop: no longer expected. Both schematics drew the out-of-service state from 2026-09-06; before that only the web did, because nothing on the desktop projected the flag onto its render context at scene build. If the two surfaces still disagree on a build from that date onward, the block is genuinely different between them (check you are looking at the same layout and panel) rather than the desktop simply not drawing the state.
- A block has started showing the colours you picked in its Block settings: expected from 2026-09-06, and the colours are the correct rendering. The Display colours on a block (occupied, unoccupied, reserved, out of service) were written by the modal under one spelling and read by the schematic under another, so every block drew the standard palette no matter what you chose. Both schematics now read what the modal writes, and both draw all four. One difference is deliberate: on the desktop schematic a block whose detection has reported nothing yet keeps its standard not-yet-reported colour instead of your unoccupied colour, because nothing has reported that block clear. Reopen the block's settings and reset a colour if you would rather have the standard one back.
- A paint stroke says the track belongs to no block. That is the rule, not a fault. A Track Class is a property of a BLOCK, so there is nothing on bare track for the brush to classify. Take the offer to create a block there, then paint the block. Nothing is created unless you press it.
- A paint stroke says the track is decommissioned. Expected, and no block is offered there. A decommissioned segment (ADR-0201) is not part of the live layout, so it needs no block and no class, and CTC generation does not ask for one over it either. Bring the track back into service first if it should be classified.
- The eraser cleared classes off the cells under the block, not just the block. Expected, and the brush says so before you use it. A block with no class of its own over uniformly classed track takes that class, so an eraser that stopped at the block would appear to do nothing at all.
- A block on the Avalonia desktop says it could not be painted, and names a cell. A cell inside the block is locked and carries a class of its own, so the classification could not be cleared. Nothing about the block was changed: a part-cleared block would read as the locked cell's class. Unlock the cell the message names, then paint again.
- The dashed amber outline does not appear on the desktop while a layout package is mounted. Expected today, and tracked as RailScanProUE#539. The block-level answer to "is this block classified" is the host's, and the mounted package projection does not carry it yet, so the desktop draws no marking rather than guessing and prompting you to fix blocks that are already correct. The block's properties panel says the same thing in words on that route: it reports that the package does not carry the block's classification, rather than calling every block Unclassified.
- A block is out of service and dark territory, and shows grey rather than the dark neutral — out of service wins. The display order is out of service, then occupied, then reserved, then the dark-territory neutral, then free.
- The Layout Editor modal's Block tab showed "Sensors (0)" and the name "Block" on an imported block — fixed 2026-08-18. That tab read a page-local copy of the block config whose field names did not match the governed ones the importer writes, so sensors, length and name all fell back to defaults. Worse, pressing OK wrote that default name back, renaming the block to "Block". The sibling Block Editor tab was always correct. If a block is currently named "Block" and should not be, rename it; the save path no longer blanks it.
- Sensor addresses read as flat LocoNet numbers — a General-Input contact on board 109, input 3 shows as 1731 ((board - 1) x 16 + input), the same form BDL168 wiring sheets and JMRI use. The stored value is shown as imported and never recomputed, so a contact whose import did not decode cleanly shows its board rather than an invented address. A Plain-Number contact also shows its board, because its stored value carries a synthetic offset that is not an address on any sheet.
- A sensor drawn as its own contact cell showed a blank address — fixed 2026-08-27. Those sensors keep their addressing on the drawn cell rather than in the block, and the import used to carry only the board onto that cell, so the address column had nothing truthful to show. The import now writes the board, the input and the flat value onto the cell, and one shared rule renders every sensor, so the Block Editor and the Layout Editor Block tab cannot disagree. An already-imported layout picks this up at its next connected sign-in, when the layout is re-derived from the backend; no re-import and no data migration is needed. A contact TrainController marked Without Connection still shows blank, because its stored address is stale and blank is the honest answer.
- The flat address shows only when it was imported — a sensor you address by hand shows the board and input you entered, with no flat number beside them. RailScanPro does not calculate one, because the inputs-per-board figure depends on the digital system (14 on an NCE AIU, 16 on LocoNet) and that system is not yet recorded against each contact. Calculating one anyway would print the wrong number for anybody running more than one bus, so the honest answer is to show what was decoded.
- A sensor listed under a block reads "no conn" and nothing could set its address: fixed 2026-09-13. Sensors TrainController decodes as block members have no contact cell, so the only editor they had offered kind, debounce and memory: the one property the sensor table flagged was the one property no screen could change, and the badge said the address came from the import. The Block Detail panel now carries that sensor's board, input and mode, the sensor table's row links straight to that field, and the badge names it. An already-imported layout picks this up the next time the block is opened; nothing is re-imported and no data changes.
- You would rather have that sensor drawn on the panel like your other contacts: use place this sensor on a cell in the same panel. The sensor leaves the block's own list, a feedback contact appears at the column and row you chose carrying its address, and the block lists that cell as one of its occupancy sensors. An occupied square is refused with its position, and the layout graph is re-derived afterwards, exactly as it is when you add a sensor from the sensor table.
- Flagman sensor — its occupancy is computed by TrainController logic RailScanPro does not decode. Re-author it as a block rule (the panel links to Webb, the rules assistant).
Safety Notes
Blocks are authored and edited only on the web. Neither the web app nor the Avalonia desktop actuates hardware or drives trains — the desktop presents state and forwards operator intent, and the local/UE5 runtime owns all safety-critical execution (occupancy enforcement, interlocking, movement authority). Editing a block in the browser changes how the layout is modeled and displayed; it does not by itself power, move, or stop a train. During operation the occupancy recolour and the train-in-box name are indications, not controls: the head block shows the train name, while trailing straddle and reserved-ahead blocks recolour without it, and reservation is distributed before occupancy. Never treat a cleared block indication as authority to move — confirm with the operating runtime and procedure.