The spotlight object data was fine. spotlight.iff still had TTAB 0x0081 with Turn On, Turn Off, Power Status, and Recharge. The bug was in runtime TTAB selection for multitile subobjects.
The spotlight is a multitile object. The clicked in-world entity is one of the subtiles, and those subtiles have TreeTableID = FFFF, meaning they rely on the master tile’s pie menu. During VMEntity construction, though, the subtile was resolving a fallback TTAB from SurfacePlacementSemiGlobal because ShouldUseStandardSemiglobalTTABFallback() allows standard semiglobal fallback TTABs for non-person objects.
That meant the subtile already had a non-null TreeTable before multitile setup reached:
VMContext.cs (line 1451)
csharp
vmObject.UseTreeTableOf(objDefinition);
But UseTreeTableOf() immediately returned when TreeTable != null, so the real master object TTAB was never inherited. Result: local spotlight interactions disappeared, while global interactions like Salvage still showed.
The fix is in VMEntity.cs (line 450). UseTreeTableOf() now checks whether the supplied master object has a real local TTAB. If it does, and the current object does not have its own local TTAB, it replaces the existing table with the inherited master TTAB:
csharp
var ownTreeTable = Object?.Resource?.Get(Object.OBJ.TreeTableID);
var inheritedTreeTable = obj.Resource.Get(obj.OBJ.TreeTableID);
if (inheritedTreeTable != null && (TreeTable == null || ownTreeTable == null))
{
TreeTable = inheritedTreeTable;
TreeTableStrings = obj.Resource.Get(obj.OBJ.TreeTableID);
RemoveSuppressedBedInteractions();
return;
}
This preserves legitimate subtile-specific TTABs, but prevents a generic semiglobal fallback TTAB from blocking master TTAB inheritance.
Important remaining note: the spotlight TTAB rows are flagged Owner + Roommates, not Visitors, so visitors will still only see global options unless the object’s TTAB permissions are changed.
