Replies: 6 comments 6 replies
-
|
For now I will continue to play whack-a-mole with large music files: When I have done this before, I have found unattributed third-party assets, so it is worth doing anyway! |
Beta Was this translation helpful? Give feedback.
-
My first attempt here was to define 2 new presets:
I then exported the whole "Web minus StoryQuests" export, and just the I patched the web HTML shell to preload diff --git a/web/full-size.html b/web/full-size.html
index 0e184f9a..aa5f5bd9 100644
--- a/web/full-size.html
+++ b/web/full-size.html
@@ -237,6 +237,7 @@ const engine = new Engine(GODOT_CONFIG);
Promise.all([
engine.init(exe),
engine.preloadFile(pack, pack),
+ engine.preloadFile('storyquests.pck', 'storyquests.pck'),
]).then(() => {
return new Promise((resolve) => {
setStatusMode('ready');and added the following in var success := ProjectSettings.load_resource_pack(OS.get_executable_path().get_base_dir().path_join("storyquests.pck"))
prints("hello", success)The resulting
This isn't what I expected but it does make sense. I told Godot that the project now only contains the scenes & resources in Next stop: skip the patch stuff, just export the story_quest folder & see how many duplicates are in there. |
Beta Was this translation helpful? Give feedback.
-
|
Zooming out a little bit… Let's ignore for now the GitHub Pages site size limit (this could be worked around by e.g. switching to a different hosting provider; this is a question of migration work + money spent rather than a fundamental limitation) and focus on the DLC StoryQuest piece. From that perspective I don't think there is any advantage in splitting up the game as built from this repo into smaller It's more interesting when we think about out-of-tree StoryQuests. You could imagine having a way for a team to publish a The big problem there is that StoryQuests are tightly coupled to the surrounding game. We saw this in #2032 most recently - every StoryQuest needed to be updated for the changes in the player scene. So any StoryQuest A different approach: add an export preset that only exports a single quest, plus its dependencies. Add an export plugin that changes the main scene to the first scene of that quest. Assume this can be done. (I quickly tried this and "Export selected resources (and dependencies)" is not sufficient, e.g. having ticked all of Then the game would launch a quest by suspending itself and running a new instance of Godot with the StoryQuest's |
Beta Was this translation helpful? Give feedback.
-
|
Switching gear back to the size angle... From this angle, the point of splitting the build artifact in this repo up into 1 pck for the main game and 1 (or more!) pcks for StoryQuests is not to reduce the amount of data downloaded by players. The point is that, if the Alternatively you could imagine putting all the large music files into a For this deduplication to work, the split-off Any (non-patch) Only the Then the question is: is Godot's export pipeline deterministic. Unfortunately the answer is no. I made 2 fresh checkouts of exactly the same commit (on my test branch) and opened each copy in the editor and a StoryQuest-only --- threadbare_tmp2/tmp.tscn 2026-04-01 13:18:33.261179188 +0100
+++ threadbare_tmp/tmp.tscn 2026-04-01 13:18:10.924901926 +0100
@@ -488,11 +488,11 @@
[node name="FireFly26" parent="." unique_id=1657380025 instance=ExtResource("5")]
position = Vector2(963, 2556)
-[connection signal="dialogo_terminado" from="quest_arbol/ArbolFantasma1" to="." method="reportar_arbol_contactado"]
-[connection signal="dialogo_terminado" from="quest_arbol/ArbolFantasma1" to="." method="_on_arbol_fantasma_1_dialogo_terminado"]
[connection signal="dialogo_terminado" from="quest_arbol/ArbolFantasma1" to="." method="_on_arbol_dialogo_terminado"]
-[connection signal="dialogo_terminado2" from="quest_arbol2/ArbolFantasma2" to="quest_arbol2" method="_on_arbol_fantasma_2_dialogo_terminado_2"]
+[connection signal="dialogo_terminado" from="quest_arbol/ArbolFantasma1" to="." method="_on_arbol_fantasma_1_dialogo_terminado"]
+[connection signal="dialogo_terminado" from="quest_arbol/ArbolFantasma1" to="." method="reportar_arbol_contactado"]
[connection signal="dialogo_terminado2" from="quest_arbol2/ArbolFantasma2" to="quest_arbol2" method="reportar_arbol_contactado2"]
+[connection signal="dialogo_terminado2" from="quest_arbol2/ArbolFantasma2" to="quest_arbol2" method="_on_arbol_fantasma_2_dialogo_terminado_2"]
[connection signal="dialogo_terminado3" from="quest_arbol3/ArbolFantasma3" to="quest_arbol3" method="reportar_arbol_contactado3"]
[connection signal="dialogo_terminado3" from="quest_arbol3/ArbolFantasma3" to="quest_arbol3" method="_on_arbol_fantasma_3_dialogo_terminado_3"]
[connection signal="body_entered" from="Area2D" to="Area2D" method="_on_Area2D_body_entered"]At this point I'm going to give up on this angle of trying to deduplicate unmodified stuff between different branches by splitting up the game. A more fruitful angle might be to say: when building a PR, if the PR does not modify any files in |
Beta Was this translation helpful? Give feedback.
-
|
Another size limit that may at some point become relevant: itch.io. A web game there has these limits:
The approach of splitting out large music etc. to a separate pck seems relatively common to work around that first limit. https://github.com/Motto73/TUASGuessr was an example I found where someone has split the game into 4 packs: 2 asset packs, one dlc pack, and the main game. The main game is a patch on top of the other three packs. They then have a custom HTML shell which hardcodes the approximate file sizes of each pck file: And preloads each of the split packs into the virtual filesystem: Then they have an autoload that loads the external packs: I guess they carefully ensure that no assets from those packs are needed until that autoload has become There seems no built-in way to automate the "export the project as multiple pcks" workflow. You have to manually, or in an external script, export the components of the project in the correct order. There's also no great way to add the file sizes for the split-off pcks dynamically in the HTML shell; or indeed to set some flag to tell the JavaScript code whether or not it needs to load the extra .pcks. You could automate this with external scripts, but I think this is excessive complexity when we depend so heavily on web builds for our education flows. |
Beta Was this translation helpful? Give feedback.
-
|
Sorry in advance for the side comment. I don't want to ruin this thread, which contains a lot of interesting facts. On the StoryQuest submission (or cherry-picking) to upstream, I think that we should start considering the size of assets. In particular for the ones that weren't created by learners but are third-party free-licensed assets (which is the case of all music in existing SQs). Giving more priority to original content. I think that it can be a good learning in working with limits / constrains. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Background
I have been gently exploring how hard it would be to split the game into multiple .pck files. There are a couple of reasons why one might want to do this:
Game size
The
.pckfile has ballooned to 93.8 MB. This is a practical issue because we use GitHub Pages for test builds, and GitHub Pages has a 1 GB soft limit on the size of the site, i.e. around 10 branches. I implemented deduplication for the Godot binary itself but this has relatively little impact.The vast majority of the 93.8 MB is music. This makes sense because the pixel-art style compresses well, and scene files & code are small and compress well. But a typical bitrate for compressed music is 128 kbps, i.e. 16 kilobytes per second, and any given background music loop might be, say, 2 minutes long, which comes out to 1.83 MiB. But these music files change very rarely. So hypothetically we could split all
.oggand.mp3resources tomusic.pck, and then deduplicate that file in the same way. This would allow us to have more simultaneous test builds published before hitting the size limit.StoryQuests as DLC
Another way of looking at the size of the game is that around 2/3 comes from StoryQuests. Again, this is mostly music! As the number of StoryQuests in the tree increases, the size will steadily grow.
An alternative model would be to publish each StoryQuest as a separate
.pckfile, which would be downloaded on demand based on what the player chooses to play. We can't really version StoryQuests separately to the host game because the internal APIs of the game are not stable, but it's interesting to explore what it would look like anyway.Exporting multiple
.pcks at onceGodot has some documentation on this: https://docs.godotengine.org/en/stable/tutorials/export/exporting_pcks.html. However I have to say it's not that clear how to use it in our case. I would have expected to be able to define in (say) the Web export preset that the preset should export multiple
.pckfiles, sliced in a defined way. However it appears that each export preset only produces one.pckfile. So instead you are supposed to have multiple presets, for each platform × slice of the game.As far as I can tell this breaks the remote-deploy workflow, which I use for testing the game in a web browser. For that, you declare that the Web preset is runnable, and then you can click a button to export the web build, run a local web server, and open it in your browser. Super useful! But if additional presets need to be exported to have the full game, this can't work.
Maybe it's possible to write a plugin that hooks the export flow and runs additional exports as part of the process? Some automation would certainly be necessary to split 10+ StoryQuests out into 10+
.pckfiles because we can't manually manage this, especially as the number grows.Also, if you define a preset that exports only certain resources, their dependencies are also included, meaning that each StoryQuest
.pckwould also include whatever elements of the base game are used. I think the workaround here would be to build each StoryQuest as a patch, where you tell Godot what other.pckfiles are guaranteed to have been loaded, and then the new.pckonly contains changed files.Loading extra
.pcks on the webThe documentation shows how to load additional
.pcks in GDScript. Fine. On the web there is the additional complication that files need to be downloaded on the browser side, and loaded into the fake filesystem that the WASM Godot binary can see.I don't think this is especially difficult. After modifying the HTML shell a little to drive the "download and launch" API a bit more directly (which was necessary to add a click-to-play screen #2060) then downloading an additional
.pckthat will always be needed boils down to:and if one is needed dynamically, one can call JavaScript code from GDScript (we already do to use the URL hash as a scene switcher) so one could do that on-demand.
Beta Was this translation helpful? Give feedback.
All reactions