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
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
var _registry = {}
|
||||
|
||||
|
||||
func _create_reg_entry(base_path, subpath):
|
||||
var to_return = {
|
||||
"base_path":base_path,
|
||||
"subpath":subpath,
|
||||
"base_resource":load(base_path),
|
||||
"full_path":str("'", base_path, "'", subpath)
|
||||
}
|
||||
return to_return
|
||||
|
||||
func _register_inners(base_path, obj, prev_inner = ''):
|
||||
var const_map = obj.get_script_constant_map()
|
||||
var consts = const_map.keys()
|
||||
var const_idx = 0
|
||||
|
||||
while(const_idx < consts.size()):
|
||||
var key = consts[const_idx]
|
||||
var thing = const_map[key]
|
||||
|
||||
if(typeof(thing) == TYPE_OBJECT and thing.resource_path == ''):
|
||||
var cur_inner = str(prev_inner, ".", key)
|
||||
_registry[thing] = _create_reg_entry(base_path, cur_inner)
|
||||
_register_inners(base_path, thing, cur_inner)
|
||||
|
||||
const_idx += 1
|
||||
|
||||
|
||||
func register(base_script):
|
||||
var base_path = base_script.resource_path
|
||||
_register_inners(base_path, base_script)
|
||||
|
||||
|
||||
func get_extends_path(inner_class):
|
||||
if(_registry.has(inner_class)):
|
||||
return _registry[inner_class].full_path
|
||||
else:
|
||||
return null
|
||||
|
||||
# returns the subpath for the inner class. This includes the leading "." in
|
||||
# the path.
|
||||
func get_subpath(inner_class):
|
||||
if(_registry.has(inner_class)):
|
||||
return _registry[inner_class].subpath
|
||||
else:
|
||||
return ''
|
||||
|
||||
func get_base_path(inner_class):
|
||||
if(_registry.has(inner_class)):
|
||||
return _registry[inner_class].base_path
|
||||
|
||||
|
||||
func has(inner_class):
|
||||
return _registry.has(inner_class)
|
||||
|
||||
|
||||
func get_base_resource(inner_class):
|
||||
if(_registry.has(inner_class)):
|
||||
return _registry[inner_class].base_resource
|
||||
|
||||
func get_full_path(inner_class):
|
||||
if(_registry.has(inner_class)):
|
||||
var entry = _registry[inner_class]
|
||||
return str(entry.base_path.get_file(), entry.subpath.replace('.', '/'))
|
||||
else:
|
||||
return "/Unregistered-Inner-Class"
|
||||
|
||||
func to_s():
|
||||
var text = ""
|
||||
for key in _registry:
|
||||
text += str(key, ": ", _registry[key], "\n")
|
||||
return text
|
||||
Reference in New Issue
Block a user