I think i failed to communicate what i did. I didn't simply create each node in code, i created them through the interface. in my case, the scripts are actually different. here, this is the file system and node tree:
scripts:
node tree:

to verify, if i go to each room node's script and in the ready function execute this code:
var bunker_script = load("res://Locations/GreyAbbeyLibrary/Rooms/Bunker.gd")
var bunker_node = get_parent().get_node("Bunker")
print("bunker node: ", bunker_node, " bunker script:", bunker_script)
and for the attic:
var attic_script = load("res://Locations/GreyAbbeyLibrary/Rooms/Attic.gd")
var attic_node = get_parent().get_node("Attic")
print("attic node: ", attic_node, " attic script:", attic_script)
now when the nodes enter the tree and become ready, the output is this:

as you can see, each script on each room has a different script object, because i manually attached a new script via the editor. yet each room extends the same class via:
extends FSRoom
in this case, it appears as if each node is an object instance of FSRoom, because each room stores it's own instance of properties from the FSRoom class, like light level and room size, independently from other rooms. and all of this happens without the room scripts having to have a single line of code, yet if they did, they could have properties specific to that room that don't apply to other rooms.
so like, it makes me wonder, is there any difference between this implementation and creating actual instances of FSRoom objects. is this implementation.. uncommon?