mirror of
https://github.com/hanzo-templates/godot-arcade.git
synced 2026-10-30 20:52:56 +00:00
Orb Runner: a complete 3D arcade game in ~150 lines of GDScript, world built in
code so there are no binary scenes to merge-conflict on. Ships the non-threaded
export (runs everywhere incl. iOS Safari); flip thread_support in
export_presets.cfg for the threaded build, which hanzo.app already serves the
COOP/COEP for when the project declares framework=godot.
The export basename is fingerprinted (orb-<sha8>.html) because every sibling
asset inherits it — that is what makes index.js/.wasm/.pck cacheable forever
instead of stale-forever.
Why this exists: static-SPA builders cannot ship a game. Proving hanzo.app can
meant finding what actually stopped it, and three things did:
1. POST /v1/projects/:slug/deploy carries the entire build in ONE request body and
the public edge caps a body at 4 MiB (measured: 4194304 accepted, 4198400 gets
the opaque fasthttp "Error when parsing request"). Godot emits a 43 MB engine
wasm; Unity 22 MB + 5.7 MB of data. The artifact lane cannot express a game at
all, so these ship through the release lane instead: stage to the object store,
then POST /v1/sites/:slug/publish promotes it server-side with no body.
2. Engine loaders emit NON-fingerprinted filenames (index.js, <name>.loader.js), and
clients/sites.CacheControlFor only marks a content-hashed name immutable. A
redeploy therefore leaves the CDN and the browser running the OLD loader against
the NEW wasm. That is not a visible error: emscripten just prints "still waiting
on run dependencies" forever and the canvas stays 300x150. Cost hours to find.
Every template here fingerprints its own asset names so the case cannot recur.
3. A cross-origin-isolated document (COEP: require-corp) BLOCKS a plain cross-origin
script, so the shared a.hanzo.ai runtime needs crossorigin="anonymous" on exactly
the pages that opt into isolation — game pages.
Co-authored-by: Hanzo Dev <[email protected]>
56 lines
3.4 KiB
Plaintext
56 lines
3.4 KiB
Plaintext
; Engine configuration file.
|
|
config_version=5
|
|
|
|
[application]
|
|
|
|
config/name="Orb Runner"
|
|
run/main_scene="res://main.tscn"
|
|
config/features=PackedStringArray("4.4", "GL Compatibility")
|
|
boot_splash/show_image=false
|
|
|
|
[display]
|
|
|
|
window/size/viewport_width=1280
|
|
window/size/viewport_height=720
|
|
window/stretch/mode="canvas_items"
|
|
window/stretch/aspect="expand"
|
|
|
|
[rendering]
|
|
|
|
renderer/rendering_method="gl_compatibility"
|
|
renderer/rendering_method.mobile="gl_compatibility"
|
|
textures/vram_compression/import_etc2_astc=true
|
|
anti_aliasing/quality/msaa_3d=1
|
|
|
|
[input]
|
|
|
|
move_left={
|
|
"deadzone": 0.5,
|
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
|
]
|
|
}
|
|
move_right={
|
|
"deadzone": 0.5,
|
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
|
]
|
|
}
|
|
move_up={
|
|
"deadzone": 0.5,
|
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
|
]
|
|
}
|
|
move_down={
|
|
"deadzone": 0.5,
|
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
|
]
|
|
}
|
|
jump={
|
|
"deadzone": 0.5,
|
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
|
]
|
|
}
|