Files
transcience/addons/gut/singleton_parser.gd
claude c4beeae38f Initial commit: Transcience MVP
Top-down twin-stick bullet-hell, Godot 4.7, server-authoritative dedicated
server with client-side prediction. Clients send input only; the server
resolves every hit for both players and enemies (no PvP).

- SimWorld: whole simulation as plain RefCounted objects (no nodes, no
  physics server), ~0.24ms/tick at peak load -- runs headless for free and
  drives 78 tests in under a second
- BulletPool: struct-of-arrays bullet storage, replicated as spawn/despawn
  events rather than per-tick state
- Emitter framework (Ring/AimedSpread/WallGap/ArcSweep) shared by trash
  enemies and bosses -- a new boss is data in src/content/content.gd, no
  simulation changes
- The Warden of the Fold: stationary 4-phase boss built entirely on that
  format
- Lobby hub with a portal into on-demand dungeon instances; one process
  hosts the hub plus every concurrent dungeon
- Emergency escape: 3s server-owned channel, cancelled by damage
- tools/check.sh, test.sh (GUT), smoke.sh (real server + bot clients over
  ENet), bench.gd; git hooks wired to the same scripts
- docs/ARCHITECTURE.md, NETCODE.md, WORKFLOW.md, ROADMAP.md
2026-09-03 16:03:57 +02:00

88 lines
2.5 KiB
GDScript

class GutParsedSingleton:
var methods_by_name = {}
var enums = {}
var properties = {}
var signals = {}
var singleton_name = 'unknown'
var singleton_id = -1
var base_singleton = null
func _init(singleton):
base_singleton = singleton
var sname = singleton.get_class()
singleton_name = sname
singleton_id = singleton.get_instance_id()
for method in ClassDB.class_get_method_list(sname, true):
var pm = GutUtils.ScriptCollector.GutParsedMethod.new(method)
methods_by_name[method.name] = pm
for e in ClassDB.class_get_enum_list(sname, true):
for c in ClassDB.class_get_enum_constants(sname, e):
enums[c] = singleton.get(c)
# Some singletons have integer constants that are not in the enum list.
# All enum constants appear to be integer constants, but I don't want
# to assume that will always be true.
for c in ClassDB.class_get_integer_constant_list(sname, true):
# just overwrite existing or add, seems faster than checking if it
# exists first.
enums[c] = singleton.get(c)
for p in ClassDB.class_get_property_list(sname, true):
properties[p.name] = singleton.get(p.name)
for s in ClassDB.class_get_signal_list(sname, true):
signals[s.name] = s
func get_signal_text(signal_meta):
var text = ""
for arg in signal_meta.args:
if(text.length() > 0):
text += ", "
text += arg.name
return str('signal ', signal_meta.name, '(', text, ')')
func get_all_signal_text():
var text = ''
for key in signals:
if(text.length() > 0):
text += "\n"
text += get_signal_text(signals[key])
return text
func get_all_constants_text():
var text = ""
for key in enums:
text += str('const ', key, ' = ', enums[key], "\n")
return text
func get_all_properties_text():
var text = ""
# This defaults values to what the singleton is currently set to. This was
# easier than remembering how to turn the defaults in the meta into code.
# This might be the wrong choice.
for key in properties:
# AudioServer had a property in the meta named "Fallback values" and I
# don't know what it is, so I'm ignoring all properties with a space in
# the name.
if(key.find(" ") == -1):
text += str("var ", key, " = ", singleton_name, ".", key, "\n")
return text
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
var singletons = {}
func parse(singleton):
if(!singletons.has(singleton)):
singletons[singleton] = GutParsedSingleton.new(singleton)
return singletons[singleton]