Add patches and mod script

This commit is contained in:
2025-10-27 19:34:10 +01:00
committed by Alessandro
parent cfdc2b17b0
commit 79cb5efd57
7 changed files with 2040 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
From 483938fcb2b3168a64a841adb7b8e720c47dbb11 Mon Sep 17 00:00:00 2001
From: Jika <vandechat@tutanota.com>
Date: Fri, 12 Sep 2025 23:59:18 +0200
Subject: [PATCH 1/9] Add qol scripts for local server dev
---
.pakku/server-overrides/start_server.sh | 22 +++++++++++++
scripts/update_forge_auto_install.sh | 41 +++++++++++++++++++++++++
2 files changed, 63 insertions(+)
create mode 100755 .pakku/server-overrides/start_server.sh
create mode 100755 scripts/update_forge_auto_install.sh
diff --git a/.pakku/server-overrides/start_server.sh b/.pakku/server-overrides/start_server.sh
new file mode 100755
index 00000000..5b824061
--- /dev/null
+++ b/.pakku/server-overrides/start_server.sh
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+# Simple Linux server start script.
+# Usage (from the serverpack root):
+# chmod +x start_server.sh
+# ./start_server.sh
+#
+# Configure via env vars:
+# JAVA_BIN=/path/to/java XMS=2G XMX=8G ./start_server.sh
+
+JAVA_BIN="${JAVA_BIN:-java}"
+XMS="${XMS:-1G}"
+XMX="${XMX:-6G}"
+
+if [ ! -f minecraft_server.jar ]; then
+ echo "minecraft_server.jar not found in $(pwd)." >&2
+ exit 1
+fi
+
+exec "$JAVA_BIN" -Xms"$XMS" -Xmx"$XMX" -jar minecraft_server.jar nogui
+
diff --git a/scripts/update_forge_auto_install.sh b/scripts/update_forge_auto_install.sh
new file mode 100755
index 00000000..9c82cc96
--- /dev/null
+++ b/scripts/update_forge_auto_install.sh
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+# Update placeholders in serverpack run file and inside serverpack zip(s)
+# using values from pakku-lock.json. Mirrors the GitHub workflow logic.
+
+
+LOCK_JSON="./pakku-lock.json"
+BASE_FILE=".pakku/server-overrides/forge-auto-install.txt"
+RUN_FILE="./build/serverpack/forge-auto-install.txt"
+SERVERPACK_DIR="./build/serverpack"
+
+# Extract info like in the workflow
+MC_VERSION=$(jq -r '.mc_versions[0]' "$LOCK_JSON")
+LOADER_KEY=$(jq -r '.loaders | keys[0]' "$LOCK_JSON")
+LOADER_VERSION=$(jq -r --arg k "$LOADER_KEY" '.loaders[$k]' "$LOCK_JSON")
+
+# Normalize loader type to expected casing
+case "$LOADER_KEY" in
+ forge|Forge) LOADER_TYPE="Forge" ;;
+ neoforge|NeoForge) LOADER_TYPE="NeoForge" ;;
+ *) LOADER_TYPE="$LOADER_KEY" ;;
+esac
+
+echo "minecraftVersion=$MC_VERSION"
+echo "loaderType=$LOADER_TYPE"
+echo "loaderVersion=$LOADER_VERSION"
+
+cp "$BASE_FILE" "$RUN_FILE"
+
+sed -i -e "s/LOADER_VERSION/${LOADER_VERSION}/g" "$RUN_FILE"
+sed -i -e "s/LOADER_TYPE/${LOADER_TYPE}/g" "$RUN_FILE"
+sed -i -e "s/MINECRAFT_VERSION/${MC_VERSION}/g" "$RUN_FILE"
+
+for z in "$SERVERPACK_DIR"/*.zip; do
+ zip -q -u -j "$z" "$RUN_FILE"
+ echo "patched zip: $z"
+done
+
+rm "$RUN_FILE"
+
diff --git a/pakku.json b/pakku.json
index 3224be1c..1a1328cb 100644
--- a/pakku.json
+++ b/pakku.json
@@ -19,5 +19,6 @@
"server.properties",
"server_starter.conf",
"server-icon.png",
+ "start_server.sh",
"start_server.bat",
"README.md"
--
2.51.1.dirty

View File

@@ -0,0 +1,78 @@
From 7eb9a3842e741c4786f6a95a82cdff0df4aa045b Mon Sep 17 00:00:00 2001
From: Jika <vandechat@tutanota.com>
Date: Sat, 13 Sep 2025 12:53:34 +0200
Subject: [PATCH 2/9] Add blazemap config
---
config/blazemap-client.toml | 52 +++++
kubejs/server_scripts/main_server_script.js | 6 +-
.../server_scripts/storagedrawers/recipes.js | 66 ++++++
kubejs/server_scripts/storagedrawers/tags.js | 13 ++
pakku-lock.json | 193 ++++++++++++++++++
pakku.json | 12 +-
6 files changed, 339 insertions(+), 3 deletions(-)
create mode 100644 config/blazemap-client.toml
create mode 100644 kubejs/server_scripts/storagedrawers/recipes.js
create mode 100644 kubejs/server_scripts/storagedrawers/tags.js
diff --git a/config/blazemap-client.toml b/config/blazemap-client.toml
new file mode 100644
index 00000000..25dd627c
--- /dev/null
+++ b/config/blazemap-client.toml
@@ -0,0 +1,52 @@
+[general]
+ #Enable debug mode?
+ enableDebug = false
+
+#Enable or disable (un)desired features
+[clientFeatures]
+ #Enables current coordinates to render under minimap
+ displayCoords = true
+ #Enables markers showing the location of nearby friendly mobs
+ displayFriendlyMobs = true
+ #Enables markers showing the location of nearby hostile mobs
+ displayHostileMobs = true
+ #Enables markers showing the location of other players
+ displayOtherPlayers = true
+ #Enables waypoints to be shown on the map itself
+ displayWaypointsOnMap = true
+ #Enables waypoints to be rendered in the world
+ renderWaypointsInWorld = false
+
+[worldmap]
+ #List of disabled Layers, comma separated
+ activeMap = "cartography:temperature"
+ #List of disabled Layers, comma separated
+ disabledLayers = []
+ #Zoom level. Must be a power of 2
+ #Range: 0.125 ~ 8.0
+ zoom = 4.0
+
+[minimap]
+ #List of disabled Layers, comma separated
+ activeMap = "blazemap:aerial_view"
+ #List of disabled Layers, comma separated
+ disabledLayers = []
+ #Zoom level. Must be a power of 2
+ #Range: 0.5 ~ 8.0
+ zoom = 1.0
+ #Enable the minimap?
+ enabled = false
+ #Minimap horizontal position on screen
+ #Range: 0 ~ 16000
+ positionX = 15
+ #Minimap vertical position on screen
+ #Range: 0 ~ 9000
+ positionY = 15
+ #Minimap widget width
+ #Range: 128 ~ 1600
+ width = 256
+ #Minimap widget height
+ #Range: 128 ~ 1600
+ height = 256
+
+
--
2.51.1.dirty

View File

@@ -0,0 +1,902 @@
From b77da7755473b73f530cf118e33e182a43a534e6 Mon Sep 17 00:00:00 2001
From: Jika <vandechat@tutanota.com>
Date: Sun, 21 Sep 2025 21:10:11 +0200
Subject: [PATCH 6/9] Distant horizon and qol/perf config / add headlights js
---
config/DistantHorizons.toml | 790 ++++++++++++++
config/smoothchunk.json | 10 +
kubejs/server_scripts/headlight/recipes.js | 24 +
kubejs/server_scripts/headlight/tags.js | 14 +
kubejs/server_scripts/main_server_script.js | 2 +
pakku.json | 7 +-
7 files changed, 1909 insertions(+), 3 deletions(-)
create mode 100644 config/DistantHorizons.toml
create mode 100644 config/smoothchunk.json
create mode 100644 kubejs/server_scripts/headlight/recipes.js
create mode 100644 kubejs/server_scripts/headlight/tags.js
diff --git a/config/DistantHorizons.toml b/config/DistantHorizons.toml
new file mode 100644
index 00000000..e3ce8515
--- /dev/null
+++ b/config/DistantHorizons.toml
@@ -0,0 +1,790 @@
+_version = 3
+
+[server]
+ #
+ # Defines the Z-coordinate of the central point for generation boundaries, in blocks.
+ generationBoundsZ = 0
+ #
+ # Defines the distance the player will receive updates around.
+ realTimeUpdateDistanceRadiusInChunks = 256
+ #
+ # Prefix of the level keys sent to the clients.
+ # If the mod is running behind a proxy, each backend should use a unique value.
+ # If this value is empty, level key will be based on the server's seed hash.
+ levelKeyPrefix = ""
+ #
+ # Defines the distance allowed to be synchronized around the player.
+ # Should be the same or larger than maxGenerationRequestDistance in most cases.
+ maxSyncOnLoadRequestDistance = 4096
+ #
+ # If true, clients will receive updated LODs when joining or loading new LODs.
+ synchronizeOnLoad = true
+ #
+ # Defines the distance allowed to generate around the player.
+ maxGenerationRequestDistance = 4096
+ #
+ # Defines the X-coordinate of the central point for generation boundaries, in blocks.
+ generationBoundsX = 0
+ #
+ # Makes the server send level keys for each world.
+ # Disable this if you use alternative ways to send level keys.
+ sendLevelKeys = true
+ #
+ # How many LOD generation requests per second should a client send?
+ # Also limits the number of client requests allowed to stay in the server's queue.
+ generationRequestRateLimit = 20
+ #
+ # How many LOD sync requests per second should a client send?
+ # Also limits the amount of player's requests allowed to stay in the server's queue.
+ syncOnLoadRateLimit = 50
+ #
+ # Defines the radius around the central point within which generation is allowed, in blocks.
+ # If this value is set to 0, generation bounds are disabled.
+ generationBoundsRadius = 0
+ #
+ # Maximum speed for uploading LODs to the clients, in KB/s.
+ # Value of 0 disables the limit.
+ maxDataTransferSpeed = 500
+ #
+ # If true, clients will receive real-time LOD updates for chunks outside the client's render distance.
+ enableRealTimeUpdates = true
+
+ [server.experimental]
+ #
+ # When enabled on the client, this allows loading lower detail levels as needed to speed up terrain generation.
+ # This must also be enabled on the server; otherwise, it will have no effect.
+ # For better performance when switching LOD detail levels, enabling [upsampleLowerDetailLodsToFillHoles] is recommended.
+ enableNSizedGeneration = false
+
+[common]
+
+ [common.lodBuilding]
+ #
+ # How should block data be compressed when creating LOD data?
+ # This setting will only affect new or updated LOD data,
+ # any data already generated when this setting is changed will be
+ # unaffected until it is modified or re-loaded.
+ #
+ # MERGE_SAME_BLOCKS
+ # Every block/biome change is recorded in the database.
+ # This is what DH 2.0 and 2.0.1 all used by default and will store a lot of data.
+ # Expected Compression Ratio: 1.0
+ #
+ # VISUALLY_EQUAL
+ # Only visible block/biome changes are recorded in the database.
+ # Hidden blocks (IE ores) are ignored.
+ # Expected Compression Ratio: 0.7
+ worldCompression = "VISUALLY_EQUAL"
+ #
+ # When DH pulls in pre-existing chunks it will attempt to
+ # run any missing world generation steps; for example:
+ # if a chunk has the status SURFACE, DH will skip BIOMES
+ # and SURFACE, but will run FEATURES.
+ #
+ # However if for some reason the chunks are malformed
+ # or there's some other issue that causes the status
+ # to be incorrect that can either cause world gen
+ # lock-ups and/or crashes.
+ # If either of those happen try setting this to True.
+ assumePreExistingChunksAreFinished = false
+ #
+ # If true LOD generation for pre-existing chunks will attempt to pull the lighting data
+ # saved in Minecraft's Region files.
+ # If false DH will pull in chunks without lighting and re-light them.
+ #
+ # Setting this to true will result in faster LOD generation
+ # for already generated worlds, but is broken by most lighting mods.
+ #
+ # Set this to false if LODs are black.
+ pullLightingForPregeneratedChunks = false
+ #
+ # What algorithm should be used to compress new LOD data?
+ # This setting will only affect new or updated LOD data,
+ # any data already generated when this setting is changed will be
+ # unaffected until it needs to be re-written to the database.
+ #
+ # UNCOMPRESSED
+ # Should only be used for testing, is worse in every way vs [LZ4].
+ # Expected Compression Ratio: 1.0
+ # Estimated average DTO read speed: 1.64 milliseconds
+ # Estimated average DTO write speed: 12.44 milliseconds
+ #
+ # LZ4
+ # A good option if you're CPU limited and have plenty of hard drive space.
+ # Expected Compression Ratio: 0.36
+ # Estimated average DTO read speed: 1.85 ms
+ # Estimated average DTO write speed: 9.46 ms
+ #
+ # LZMA2
+ # Slow but very good compression.
+ # Expected Compression Ratio: 0.14
+ # Estimated average DTO read speed: 11.89 ms
+ # Estimated average DTO write speed: 192.01 ms
+ dataCompression = "LZMA2"
+ #
+ # Enabling this will drastically increase chunk processing time
+ # and you may need to increase your CPU load to handle it.
+ #
+ # Normally DH will attempt to skip creating LODs for chunks it's already seen
+ # and that haven't changed.
+ #
+ # However sometimes that logic incorrectly prevents LODs from being updated.
+ # Disabling this check may fix issues where LODs aren't updated after
+ # blocks have been changed.
+ disableUnchangedChunkCheck = false
+ #
+ # True: Recalculate chunk height maps before chunks can be used by DH.
+ # This can fix problems with worlds created by World Painter or
+ # other external tools where the heightmap format may be incorrect.
+ # False: Assume any height maps handled by Minecraft are correct.
+ #
+ # Fastest: False
+ # Most Compatible: True
+ recalculateChunkHeightmaps = false
+
+ [common.lodBuilding.experimental]
+ #
+ # When active DH will attempt to fill missing LOD data
+ # with any data that is present in the tree, preventing holes when moving
+ # when a N-sized generator (or server) is active.
+ #
+ # This is only used when N-sized world generation is available
+ # and/or when on a server where [generateOnlyInHighestDetail] is false.
+ #
+ # Experimental:
+ # Enabling this option will increase CPU and harddrive use
+ # and may cause rendering bugs.
+ upsampleLowerDetailLodsToFillHoles = false
+
+ [common.multiThreading]
+ #
+ # How many threads should be used by Distant Horizons?
+ numberOfThreads = 8
+ #
+ # A value between 1.0 and 0.0 that represents the percentage
+ # of time each thread can run before going idle.
+ #
+ # This can be used to reduce CPU usage if the thread count
+ # is already set to 1 for the given option, or more finely
+ # tune CPU performance.
+ threadRunTimeRatio = "1.0"
+
+ [common.logging]
+ #
+ # If enabled, the mod will log information about the renderer OpenGL process.
+ # This can be useful for debugging.
+ logRendererGLEvent = "LOG_ERROR_TO_CHAT_AND_INFO_TO_FILE"
+ #
+ # If enabled, the mod will log performance about the world generation process.
+ # This can be useful for debugging.
+ logWorldGenPerformance = "LOG_ERROR_TO_CHAT_AND_INFO_TO_FILE"
+ #
+ # If enabled, the mod will log information about network operations.
+ # This can be useful for debugging.
+ logNetworkEvent = "LOG_ERROR_TO_CHAT_AND_INFO_TO_FILE"
+ #
+ # If enabled, the mod will log information about the renderer buffer process.
+ # This can be useful for debugging.
+ logRendererBufferEvent = "LOG_ERROR_TO_CHAT_AND_INFO_TO_FILE"
+ #
+ # If enabled, the mod will log information about the world generation process.
+ # This can be useful for debugging.
+ logWorldGenEvent = "LOG_ERROR_TO_CHAT_AND_INFO_TO_FILE"
+ #
+ # If enabled, the mod will log information about the world generation process.
+ # This can be useful for debugging.
+ logWorldGenLoadEvent = "LOG_ERROR_TO_CHAT_AND_INFO_TO_FILE"
+
+ [common.logging.warning]
+ #
+ # If enabled, a chat message will be displayed when DH has too many chunks
+ # queued for updating.
+ showUpdateQueueOverloadedChatWarning = false
+ #
+ # If enabled, a chat message will be displayed if Java doesn't have enough
+ # memory allocated to run DH well.
+ showLowMemoryWarningOnStartup = true
+ #
+ # If enabled, a chat message will be displayed when a replay is started
+ # giving some basic information about how DH will function.
+ showReplayWarningOnStartup = true
+ #
+ # If enabled, a chat message will be displayed when a potentially problematic
+ # mod is installed alongside DH.
+ showModCompatibilityWarningsOnStartup = true
+ #
+ # If enabled, a chat message will be displayed if vanilla MC's
+ # render distance is higher than the recommended amount.
+ showHighVanillaRenderDistanceWarning = true
+ #
+ # If enabled, a chat message will be displayed if DH detects
+ # that any pooled objects have been garbage collected.
+ showPoolInsufficientMemoryWarning = true
+
+ [common.worldGenerator]
+ #
+ # How detailed should LODs be generated outside the vanilla render distance?
+ #
+ # PRE_EXISTING_ONLY
+ # Only create LOD data for already generated chunks.
+ #
+ #
+ # SURFACE
+ # Generate the world surface,
+ # this does NOT include trees,
+ # or structures.
+ #
+ # FEATURES
+ # Generate everything except structures.
+ # WARNING: This may cause world generator bugs or instability when paired with certain world generator mods.
+ #
+ # INTERNAL_SERVER
+ # Ask the local server to generate/load each chunk.
+ # This is the most compatible and will generate structures correctly,
+ # but may cause server/simulation lag.
+ # Note: unlike other modes this option DOES save generated chunks to
+ # Minecraft's region files.
+ distantGeneratorMode = "PRE_EXISTING_ONLY"
+ #
+ # How should distant generator progress be displayed?
+ #
+ # OVERLAY: may be the same as CHAT for some Minecraft versions
+ # CHAT
+ # LOG
+ # DISABLED
+ showGenerationProgress = "OVERLAY"
+ #
+ # How often should the distant generator progress be displayed?
+ generationProgressDisplayIntervalInSeconds = 2
+ #
+ # For how many seconds should instructions for disabling the distant generator progress be displayed?
+ # Setting this to 0 hides the instructional message so the world gen progress is shown immediately when it starts.
+ generationProgressDisableMessageDisplayTimeInSeconds = 20
+ #
+ # Should Distant Horizons slowly generate LODs
+ # outside the vanilla render distance?
+ # Depending on the generator mode, this will import existing chunks
+ # and/or generating missing chunks.
+ enableDistantGeneration = false
+
+[client]
+ #
+ # Should Distant Horizon's config button appear in Minecraft's options screen next to the fov slider?
+ showDhOptionsButtonInMinecraftUi = true
+
+ [client.advanced]
+
+ [client.advanced.autoUpdater]
+ #
+ # If DH should use the nightly (provided by Gitlab), or stable (provided by Modrinth) build.
+ # If [AUTO] is selected DH will update to new stable releases if the current jar is a stable jar
+ # and will update to new nightly builds if the current jar is a nightly jar (IE the version number ends in '-dev').
+ updateBranch = "AUTO"
+ #
+ # Automatically check for updates on game launch?
+ enableAutoUpdater = false
+ #
+ # Should Distant Horizons silently, automatically download and install new versions?
+ # This setting is force disabled on dedicated servers for stability reasons.
+ enableSilentUpdates = false
+
+ [client.advanced.debugging]
+ #
+ # If enabled this will disable (most) vanilla Minecraft rendering.
+ #
+ # NOTE: Do not report any issues when this mode is on!
+ # This setting is only for fun and debugging.
+ # Mod compatibility is not guaranteed.
+ lodOnlyMode = false
+ #
+ # Stops vertex colors from being passed.
+ # Useful for debugging shaders
+ enableWhiteWorld = false
+ #
+ # What renderer is active?
+ #
+ # DEFAULT: Default lod renderer
+ # DEBUG: Debug testing renderer
+ # DISABLED: Disable rendering
+ rendererMode = "DEFAULT"
+ #
+ # If enabled the LODs will render as wireframe.
+ renderWireframe = false
+ #
+ # If true the F8 key can be used to cycle through the different debug modes.
+ # and the F6 key can be used to enable and disable LOD rendering.
+ enableDebugKeybindings = false
+ #
+ # If true overlapping quads will be rendered as bright red for easy identification.
+ # If false the quads will be rendered normally.
+ showOverlappingQuadErrors = false
+ #
+ # Should specialized colors/rendering modes be used?
+ #
+ # OFF: LODs will be drawn with their normal colors.
+ # SHOW_DETAIL: LODs' color will be based on their detail level.
+ # SHOW_BLOCK_MATERIAL: LODs' color will be based on their material.
+ # SHOW_OVERLAPPING_QUADS: LODs will be drawn with total white, but overlapping quads will be drawn with red.
+ debugRendering = "OFF"
+ #
+ # If true OpenGL Buffer garbage collection will be logged
+ # this also includes the number of live buffers.
+ logBufferGarbageCollection = false
+
+ [client.advanced.debugging.debugWireframe]
+ #
+ # Render LOD section status?
+ showRenderSectionStatus = false
+ #
+ # Render queued network sync on load tasks?
+ showNetworkSyncOnLoadQueue = false
+ #
+ # Render full data update/lock status?
+ showFullDataUpdateStatus = false
+ #
+ # Render queued world gen tasks?
+ showWorldGenQueue = false
+ #
+ # A white box will be drawn when an LOD starts rendering
+ # and a purple box when an LOD stops rendering.
+ #
+ # This can be used to debug Quad Tree holes.
+ showRenderSectionToggling = false
+ #
+ # Render Quad Tree Rendering status?
+ showQuadTreeRenderStatus = false
+ #
+ # If enabled, various wireframes for debugging internal functions will be drawn.
+ #
+ # NOTE: There WILL be performance hit!
+ # Additionally, only stuff that's loaded after you enable this
+ # will render their debug wireframes.
+ enableRendering = false
+
+ [client.advanced.debugging.f3Screen]
+ #
+ # Shows how many chunks are queud for processing and the max count that can be queued.
+ showQueuedChunkUpdateCount = true
+ #
+ # Shows the memory use and array counts for each DH object pool.
+ showSeparatedObjectPools = false
+ #
+ # Shows info about each thread pool.
+ showPlayerPos = true
+ #
+ # Shows the combined memory use and array counts for all DH pooled objects.
+ showCombinedObjectPools = false
+ #
+ # Defines what internal detail level the player position will be shown as.
+ # Internal detail level means: 6 = 1x1 block, 7 = 2x2 blocks, etc.
+ playerPosSectionDetailLevel = 6
+ #
+ # Shows info about each thread pool.
+ showThreadPools = true
+ #
+ # Shows what levels are loaded and world gen/rendering info about those levels.
+ showLevelStatus = true
+
+ [client.advanced.debugging.openGl]
+ #
+ # Defines how OpenGL errors are handled.
+ # Requires rebooting Minecraft to change.
+ # Will catch OpenGL errors thrown by other mods.
+ overrideVanillaGLLogger = true
+ #
+ # Defines how OpenGL errors are handled.
+ # May incorrectly catch OpenGL errors thrown by other mods.
+ #
+ # IGNORE: Do nothing.
+ # LOG: write an error to the log.
+ # LOG_THROW: write to the log and throw an exception.
+ # Warning: this should only be enabled when debugging the LOD renderer
+ # as it may break Minecraft's renderer when an exception is thrown.
+ glErrorHandlingMode = "IGNORE"
+ #
+ # Massively reduces FPS.
+ # Should only be used if mysterious EXCEPTION_ACCESS_VIOLATION crashes are happening in DH's rendering code for troubleshooting.
+ validateBufferIdsBeforeRendering = false
+ #
+ # If true each Open GL error will only be logged once.
+ # Enabling this may cause some error logs to be missed.
+ # Does nothing if overrideVanillaGLLogger is set to false.
+ #
+ # Generally this can be kept as 'true' to prevent log spam.
+ # However, Please set this to 'false' if a developer needs your log to debug a GL issue.
+ onlyLogGlErrorsOnce = true
+
+ [client.advanced.debugging.exampleConfigScreen]
+ shortTest = "69"
+ mapTest = "{}"
+ byteTest = "8"
+ longTest = "42069"
+ listTest = ["option 1", "option 2", "option 3"]
+ boolTest = false
+ doubleTest = "420.69"
+ floatTest = "0.42069"
+ linkableTest = 420
+ intTest = 69420
+ stringTest = "Test input box"
+
+ [client.advanced.graphics]
+
+ [client.advanced.graphics.culling]
+ #
+ # If false all beacons near the camera won't be drawn to prevent vanilla overdraw.
+ # If true all beacons will be rendered.
+ #
+ # Generally this should be left as true. It's main purpose is for debugging
+ # beacon updating/rendering.
+ disableBeaconDistanceCulling = true
+ #
+ # Determines how far from the camera Distant Horizons will start rendering.
+ # Measured as a percentage of the vanilla render distance.
+ #
+ # 0 = auto, overdraw will change based on the vanilla render distance.
+ #
+ # Higher values will prevent LODs from rendering behind vanilla blocks at a higher distance,
+ # but may cause holes in the world.
+ # Holes are most likely to appear when flying through unloaded terrain.
+ #
+ # Increasing the vanilla render distance increases the effectiveness of this setting.
+ overdrawPrevention = "0.0"
+ #
+ # If enabled caves won't be rendered.
+ #
+ # Note: for some world types this can cause
+ # overhangs or walls for floating objects.
+ # Tweaking the caveCullingHeight, can resolve some
+ # of those issues.
+ enableCaveCulling = true
+ #
+ # Identical to the other frustum culling option
+ # only used when a shader mod is present using the DH API
+ # and the shadow pass is being rendered.
+ #
+ # Disable this if shadows render incorrectly.
+ disableShadowPassFrustumCulling = false
+ #
+ # At what Y value should cave culling start?
+ # Lower this value if you get walls for areas with 0 light.
+ caveCullingHeight = 60
+ #
+ # A comma separated list of block resource locations that shouldn't be rendered
+ # if they are in a 0 sky light underground area.
+ # Air is always included in this list.
+ # Requires a restart to change.
+ ignoredRenderCaveBlockCsv = "minecraft:glow_lichen,minecraft:rail,minecraft:water,minecraft:lava,minecraft:bubble_column,minecraft:cave_vines_plant,minecraft:vine,minecraft:cave_vines,minecraft:short_grass,minecraft:tall_grass,minecraft:small_dripleaf,minecraft:big_dripleaf,minecraft:big_dripleaf_stem,minecraft:sculk_vein"
+ #
+ # A comma separated list of block resource locations that won't be rendered by DH.
+ # Air is always included in this list.
+ # Requires a restart to change.
+ ignoredRenderBlockCsv = "minecraft:barrier,minecraft:structure_void,minecraft:light,minecraft:tripwire,minecraft:brown_mushroom"
+ #
+ # If true LODs outside the player's camera
+ # aren't drawn, increasing GPU performance.
+ #
+ # If false all LODs are drawn, even those behind
+ # the player's camera, decreasing GPU performance.
+ #
+ # Disable this if you see LODs disappearing at the corners of your vision.
+ disableFrustumCulling = false
+
+ [client.advanced.graphics.ssao]
+ #
+ # Determines how many points in space are sampled for the occlusion test.
+ # Higher numbers will improve quality and reduce banding, but will increase GPU load.
+ sampleCount = 6
+ #
+ # Determines how dark the Screen Space Ambient Occlusion effect will be.
+ strength = "0.2"
+ #
+ # The radius, measured in pixels, that blurring is calculated for the SSAO.
+ # Higher numbers will reduce banding at the cost of GPU performance.
+ blurRadius = 2
+ #
+ # Increasing the value can reduce banding at the cost of reducing the strength of the effect.
+ bias = "0.02"
+ #
+ # Determines how dark the occlusion shadows can be.
+ # 0 = totally black at the corners
+ # 1 = no shadow
+ minLight = "0.25"
+ #
+ # Enable Screen Space Ambient Occlusion
+ enableSsao = true
+ #
+ # Determines the radius Screen Space Ambient Occlusion is applied, measured in blocks.
+ radius = "4.0"
+
+ [client.advanced.graphics.noiseTexture]
+ #
+ # Should a noise texture be applied to LODs?
+ #
+ # This is done to simulate textures and make the LODs appear more detailed.
+ enableNoiseTexture = true
+ #
+ # Defines how far should the noise texture render before it fades away. (in blocks)
+ # Set to 0 to disable noise from fading away
+ noiseDropoff = 1024
+ #
+ # How many steps of noise should be applied to LODs?
+ noiseSteps = 4
+ #
+ # How intense should the noise should be?
+ noiseIntensity = "5.0"
+
+ [client.advanced.graphics.experimental]
+ #
+ # This is the earth size ratio when applying the curvature shader effect.
+ # Note: Enabling this feature may cause rendering bugs.
+ #
+ # 0 = flat/disabled
+ # 1 = 1 to 1 (6,371,000 blocks)
+ # 100 = 1 to 100 (63,710 blocks)
+ # 10000 = 1 to 10000 (637.1 blocks)
+ #
+ # Note: Due to current limitations, the min value is 50
+ # and the max value is 5000. Any values outside this range
+ # will be set to 0 (disabled).
+ earthCurveRatio = 0
+
+ [client.advanced.graphics.genericRendering]
+ #
+ # If true LOD clouds will be rendered.
+ enableCloudRendering = true
+ #
+ # Sets the maximum height at which beacons will render.This will only affect new beacons coming into LOD render distance.Beacons currently visible in LOD chunks will not be affected.
+ beaconRenderHeight = 6000
+ #
+ # If true LOD beacon beams will be rendered.
+ enableBeaconRendering = true
+ #
+ # If true non terrain objects will be rendered in DH's terrain.
+ # This includes beacon beams and clouds.
+ enableGenericRendering = true
+ #
+ # Can be disabled to use much slower but more compatible direct rendering.
+ # Disabling this can be used to fix some crashes on Mac.
+ enableInstancedRendering = true
+
+ [client.advanced.graphics.quality]
+ #
+ # What is the maximum detail LODs should be drawn at?
+ # Higher settings will increase memory and GPU usage.
+ #
+ # CHUNK: render 1 LOD for each Chunk.
+ # HALF_CHUNK: render 4 LODs for each Chunk.
+ # FOUR_BLOCKS: render 16 LODs for each Chunk.
+ # TWO_BLOCKS: render 64 LODs for each Chunk.
+ # BLOCK: render 256 LODs for each Chunk (width of one block).
+ #
+ # Lowest Quality: CHUNK
+ # Highest Quality: BLOCK
+ maxHorizontalResolution = "BLOCK"
+ #
+ # If true LODs will fade away as you get closer to them.
+ # If false LODs will cut off abruptly at a set distance from the camera.
+ # This setting is affected by the vanilla overdraw prevention config.
+ ditherDhFade = true
+ #
+ # How bright LOD colors are.
+ #
+ # 0 = black
+ # 1 = normal
+ # 2 = near white
+ brightnessMultiplier = "1.0"
+ #
+ # How should LODs be shaded?
+ #
+ # AUTO: Uses the same side shading as vanilla Minecraft blocks.
+ # ENABLED: Simulates Minecraft's block shading for LODs.
+ # Can be used to force LOD shading when using some shaders.
+ # DISABLED: All LOD sides will be rendered with the same brightness.
+ lodShading = "AUTO"
+ #
+ # How saturated LOD colors are.
+ #
+ # 0 = black and white
+ # 1 = normal
+ # 2 = very saturated
+ saturationMultiplier = "1.0"
+ #
+ # This indicates how well LODs will represent
+ # overhangs, caves, floating islands, etc.
+ # Higher options will make the world more accurate, butwill increase memory and GPU usage.
+ #
+ # Lowest Quality: HEIGHT_MAP
+ # Highest Quality: EXTREME
+ verticalQuality = "MEDIUM"
+ #
+ # What blocks shouldn't be rendered as LODs?
+ #
+ # NONE: Represent all blocks in the LODs
+ # NON_COLLIDING: Only represent solid blocks in the LODs (tall grass, torches, etc. won't count for a LOD's height)
+ blocksToIgnore = "NON_COLLIDING"
+ #
+ # The radius of the mod's render distance. (measured in chunks)
+ lodChunkRenderDistanceRadius = 256
+ #
+ # What the value should vanilla Minecraft's texture LodBias be?
+ # If set to 0 the mod wont overwrite vanilla's default (which so happens to also be 0)
+ lodBias = "0.0"
+ #
+ # How should the sides and bottom of grass block LODs render?
+ #
+ # AS_GRASS: all sides of dirt LOD's render using the top (green) color.
+ # FADE_TO_DIRT: sides fade from grass to dirt.
+ # AS_DIRT: sides render entirely as dirt.
+ grassSideRendering = "FADE_TO_DIRT"
+ #
+ # Should the blocks underneath avoided blocks gain the color of the avoided block?
+ #
+ # True: a red flower will tint the grass below it red.
+ # False: skipped blocks will not change color of surface below them.
+ tintWithAvoidedBlocks = true
+ #
+ # This indicates how quickly LODs decrease in quality the further away they are.
+ # Higher settings will render higher quality fake chunks farther away,
+ # but will increase memory and GPU usage.
+ horizontalQuality = "MEDIUM"
+ #
+ # How should LOD transparency be handled.
+ #
+ # COMPLETE: LODs will render transparent.
+ # FAKE: LODs will be opaque, but shaded to match the blocks underneath.
+ # DISABLED: LODs will be opaque.
+ transparency = "COMPLETE"
+ #
+ # How should vanilla Minecraft fade into Distant Horizons LODs?
+ #
+ # NONE: Fastest, there will be a pronounced border between DH and MC rendering.
+ # SINGLE_PASS: Fades after MC's transparent pass, opaque blocks underwater won't be faded.
+ # DOUBLE_PASS: Slowest, fades after both MC's opaque and transparent passes, provides the smoothest transition.
+ vanillaFadeMode = "DOUBLE_PASS"
+
+ [client.advanced.graphics.fog]
+ #
+ # Should Minecraft's fog render?
+ # Note: Other mods may conflict with this setting.
+ enableVanillaFog = false
+ #
+ # What is the maximum fog thickness?
+ #
+ # 0.0: No fog.
+ # 1.0: Fully opaque fog.
+ farFogMax = "1.0"
+ #
+ # Determines if fog is drawn on DH LODs.
+ enableDhFog = true
+ #
+ # At what distance should the far fog start?
+ #
+ # 0.0: Fog starts at the player's position.
+ # 1.0: Fog starts at the closest edge of the vanilla render distance.
+ # 1.414: Fog starts at the corner of the vanilla render distance.
+ farFogStart = "0.4"
+ #
+ # What is the minimum fog thickness?
+ #
+ # 0.0: No fog.
+ # 1.0: Fully opaque fog.
+ farFogMin = "0.0"
+ #
+ # What color should fog use?
+ #
+ # USE_WORLD_FOG_COLOR: Use the world's fog color.
+ # USE_SKY_COLOR: Use the sky's color.
+ colorMode = "USE_WORLD_FOG_COLOR"
+ #
+ # How should the fog thickness should be calculated?
+ #
+ # LINEAR: Linear based on distance (will ignore 'density')
+ # EXPONENTIAL: 1/(e^(distance*density))
+ # EXPONENTIAL_SQUARED: 1/(e^((distance*density)^2)
+ farFogFalloff = "EXPONENTIAL_SQUARED"
+ #
+ # Used in conjunction with the Fog Falloff.
+ farFogDensity = "2.5"
+ #
+ # Where should the far fog end?
+ #
+ # 0.0: Fog ends at player's position.
+ # 1.0: Fog ends at the closest edge of the vanilla render distance.
+ # 1.414: Fog ends at the corner of the vanilla render distance.
+ farFogEnd = "1.0"
+
+ [client.advanced.graphics.fog.heightFog]
+ #
+ # Where should the height fog start?
+ #
+ # ABOVE_CAMERA: Height fog starts at the camera and goes towards the sky
+ # BELOW_CAMERA: Height fog starts at the camera and goes towards the void
+ # ABOVE_AND_BELOW_CAMERA: Height fog starts from the camera to goes towards both the sky and void
+ # ABOVE_SET_HEIGHT: Height fog starts from a set height and goes towards the sky
+ # BELOW_SET_HEIGHT: Height fog starts from a set height and goes towards the void
+ # ABOVE_AND_BELOW_SET_HEIGHT: Height fog starts from a set height and goes towards both the sky and void
+ heightFogDirection = "BELOW_SET_HEIGHT"
+ #
+ # What is the minimum fog thickness?
+ #
+ # 0.0: No fog.
+ # 1.0: Fully opaque fog.
+ heightFogMin = "0.0"
+ #
+ # If the height fog is calculated around a set height, what is that height position?
+ heightFogBaseHeight = "80.0"
+ #
+ # What is the maximum fog thickness?
+ #
+ # 0.0: No fog.
+ # 1.0: Fully opaque fog.
+ heightFogMax = "1.0"
+ #
+ # How should the height fog thickness should be calculated?
+ #
+ # LINEAR: Linear based on height (will ignore 'density')
+ # EXPONENTIAL: 1/(e^(height*density))
+ # EXPONENTIAL_SQUARED: 1/(e^((height*density)^2)
+ heightFogFalloff = "EXPONENTIAL_SQUARED"
+ #
+ # What is the height fog's density?
+ heightFogDensity = "20.0"
+ #
+ # How should height effect the fog thickness?
+ # Note: height fog is combined with the other fog settings.
+ #
+ # SPHERICAL: Fog is calculated based on camera distance.
+ # CYLINDRICAL: Ignore height, fog is calculated based on horizontal distance.
+ #
+ # MAX: max(heightFog, farFog)
+ # ADDITION: heightFog + farFog
+ # MULTIPLY: heightFog * farFog
+ # INVERSE_MULTIPLY: 1 - (1-heightFog) * (1-farFog)
+ # LIMITED_ADDITION: farFog + max(farFog, heightFog)
+ # MULTIPLY_ADDITION: farFog + farFog * heightFog
+ # INVERSE_MULTIPLY_ADDITION: farFog + 1 - (1-heightFog) * (1-farFog)
+ # AVERAGE: farFog*0.5 + heightFog*0.5
+ heightFogMixMode = "SPHERICAL"
+ #
+ # Should the start of the height fog be offset?
+ #
+ # 0.0: Fog start with no offset.
+ # 1.0: Fog start with offset of the entire world's height. (Includes depth)
+ heightFogStart = "0.0"
+ #
+ # Should the end of the height fog be offset?
+ #
+ # 0.0: Fog end with no offset.
+ # 1.0: Fog end with offset of the entire world's height. (Include depth)
+ heightFogEnd = "0.6"
+
+ [client.advanced.multiplayer]
+ #
+ # How should multiplayer save folders should be named?
+ #
+ # NAME_ONLY: Example: "Minecraft Server"
+ # IP_ONLY: Example: "192.168.1.40"
+ # NAME_IP: Example: "Minecraft Server IP 192.168.1.40"
+ # NAME_IP_PORT: Example: "Minecraft Server IP 192.168.1.40:25565"NAME_IP_PORT_MC_VERSION: Example: "Minecraft Server IP 192.168.1.40:25565 GameVersion 1.16.5"
+ serverFolderNameMode = "NAME_ONLY"
+
diff --git a/config/smoothchunk.json b/config/smoothchunk.json
new file mode 100644
index 00000000..d9a2d386
--- /dev/null
+++ b/config/smoothchunk.json
@@ -0,0 +1,10 @@
+{
+ "chunkSaveDelay": {
+ "desc:": "Delay before a chunk is saved to disk, default: 300 seconds",
+ "chunkSaveDelay": 300
+ },
+ "debugLogging": {
+ "desc:": "Enables debug logging of how many chunks got saved in a tick. default: false",
+ "debugLogging": false
+ }
+}
\ No newline at end of file
diff --git a/kubejs/server_scripts/headlight/recipes.js b/kubejs/server_scripts/headlight/recipes.js
new file mode 100644
index 00000000..4536816f
--- /dev/null
+++ b/kubejs/server_scripts/headlight/recipes.js
@@ -0,0 +1,24 @@
+// priority: 0
+"use strict";
+
+// Headlight: replace default recipe and add TFG-specific one
+/**
+ * @param {Internal.RecipesEventJS} event
+ */
+const registerHeadlightRecipes = (event) => {
+ // Remove default Headlight recipe (as done in Gravitas²)
+ event.remove({ id: "headlight:headlight" })
+
+ // Add shaped recipe aligned with Gravitas², using TFG ID namespace
+ event.shaped("headlight:headlight", [
+ " I ",
+ "LPL",
+ "S S"
+ ], {
+ I: "minecraft:item_frame",
+ L: "#forge:leather",
+ P: "tfc:wool_cloth",
+ S: "minecraft:string"
+ }).id("tfg:headlight/headlight")
+}
+
diff --git a/kubejs/server_scripts/headlight/tags.js b/kubejs/server_scripts/headlight/tags.js
new file mode 100644
index 00000000..4cb3cbcd
--- /dev/null
+++ b/kubejs/server_scripts/headlight/tags.js
@@ -0,0 +1,14 @@
+// priority: 0
+"use strict";
+
+// Headlight integration: define which items count as lights
+// Adds TFC torches to Headlight's lights tag so they emit handheld light
+/**
+ * @param {Internal.TagsItemEventJS} event
+ */
+const registerHeadlightItemTags = (event) => {
+ event.add("headlight:lights", [
+ "tfc:torch"
+ ])
+}
+
diff --git a/kubejs/server_scripts/main_server_script.js b/kubejs/server_scripts/main_server_script.js
index b6fd1223..a43d62c3 100644
--- a/kubejs/server_scripts/main_server_script.js
+++ b/kubejs/server_scripts/main_server_script.js
@@ -41,6 +41,7 @@ ServerEvents.tags('item', event => {
registerModernMarkingsItemTags(event)
registerMoreRedItemTags(event)
registerHotOrNotItemTags(event)
+ registerHeadlightItemTags(event)
registerPrimitiveCreaturesItemTags(event)
registerRailWaysItemTags(event)
registerRnrItemTags(event)
@@ -241,6 +242,7 @@ ServerEvents.recipes(event => {
registerGreateRecipes(event)
registerGTCEURecipes(event);
registerHandGliderRecipes(event)
+ registerHeadlightRecipes(event)
registerHotOrNotRecipes(event)
registerImmersiveAircraftRecipes(event)
registerMacawsForTFCRecipes(event)

View File

@@ -0,0 +1,721 @@
From 86ee31e0014894c244bc152d0e63516c360a69e2 Mon Sep 17 00:00:00 2001
From: Jika <vandechat@tutanota.com>
Date: Wed, 24 Sep 2025 12:29:14 +0200
Subject: [PATCH 8/9] Port gregitas certus to waffer chain
---
.../textures/item/calculation_wafer.png | Bin 0 -> 6075 bytes
.../kubejs/textures/item/certus_boule.png | Bin 0 -> 5887 bytes
.../kubejs/textures/item/certus_wafer.png | Bin 0 -> 6135 bytes
.../textures/item/engineering_wafer.png | Bin 0 -> 6102 bytes
.../kubejs/textures/item/logic_wafer.png | Bin 0 -> 6094 bytes
kubejs/assets/tfg/lang/en_us.json | 13 +-
kubejs/server_scripts/ae2/recipes.js | 189 +++++++++++++-----
kubejs/startup_scripts/ae2/materials.js | 34 +++-
kubejs/startup_scripts/gtceu/materials.js | 4 +-
kubejs/startup_scripts/tfg/element.js | 7 +-
kubejs/startup_scripts/tfg/items.js | 15 ++
11 files changed, 211 insertions(+), 51 deletions(-)
create mode 100644 kubejs/assets/kubejs/textures/item/calculation_wafer.png
create mode 100644 kubejs/assets/kubejs/textures/item/certus_boule.png
create mode 100644 kubejs/assets/kubejs/textures/item/certus_wafer.png
create mode 100644 kubejs/assets/kubejs/textures/item/engineering_wafer.png
create mode 100644 kubejs/assets/kubejs/textures/item/logic_wafer.png
diff --git a/kubejs/assets/kubejs/textures/item/calculation_wafer.png b/kubejs/assets/kubejs/textures/item/calculation_wafer.png
new file mode 100644
index 0000000000000000000000000000000000000000..b2192d49600c2fcc9478ae5aa833791ae535fb73
GIT binary patch
literal 6075
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
OWT2<3pUXO@geCxERaFK6
literal 0
HcmV?d00001
diff --git a/kubejs/assets/kubejs/textures/item/certus_boule.png b/kubejs/assets/kubejs/textures/item/certus_boule.png
new file mode 100644
index 0000000000000000000000000000000000000000..1706a26525644cc129b0a694dc4f4fae30c23c1a
GIT binary patch
literal 5887
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
literal 0
HcmV?d00001
diff --git a/kubejs/assets/kubejs/textures/item/certus_wafer.png b/kubejs/assets/kubejs/textures/item/certus_wafer.png
new file mode 100644
index 0000000000000000000000000000000000000000..c27fb674d0de8642dbe8bc40ebfdeb571e135903
GIT binary patch
literal 6135
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
X{rd+OS8aWF4`iUHtDnm{r-UW|`T~q&
literal 0
HcmV?d00001
diff --git a/kubejs/assets/kubejs/textures/item/engineering_wafer.png b/kubejs/assets/kubejs/textures/item/engineering_wafer.png
new file mode 100644
index 0000000000000000000000000000000000000000..2a3b34bf1f30756074b074444917c043100f7c9c
GIT binary patch
literal 6102
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
F0syb6h&KQL
literal 0
HcmV?d00001
diff --git a/kubejs/assets/kubejs/textures/item/logic_wafer.png b/kubejs/assets/kubejs/textures/item/logic_wafer.png
new file mode 100644
index 0000000000000000000000000000000000000000..5222fb8863d5ccd8a1985e31c4b04c2923f763e5
GIT binary patch
literal 6094
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
literal 0
HcmV?d00001
diff --git a/kubejs/assets/tfg/lang/en_us.json b/kubejs/assets/tfg/lang/en_us.json
index c4c08398..bcb4565e 100644
--- a/kubejs/assets/tfg/lang/en_us.json
+++ b/kubejs/assets/tfg/lang/en_us.json
@@ -843,6 +843,11 @@
"item.tfg.flintlock_mechanism": "Flintlock Mechanism",
"item.tfg.advanced_clockwork_mechanism": "Advanced Clockwork Mechanism",
"item.tfg.certus_mechanism": "Certus Mechanism",
+ "item.tfg.certus_boule": "Certus Boule",
+ "item.tfg.certus_wafer": "Certus Wafer",
+ "item.tfg.engineering_wafer": "Engineering Wafer",
+ "item.tfg.calculation_wafer": "Calculation Wafer",
+ "item.tfg.logic_wafer": "Logic Wafer",
"item.tfg.small_bullet_casing": "Small Bullet Casing",
"item.tfg.large_bullet_casing": "Large Bullet Casing",
"item.tfg.shell_bullet_casing": "Shell Bullet Casing",
@@ -1066,6 +1071,12 @@
"material.tfg.refined_nuclear_residue": "Refined Nuclear Residue",
"material.tfg.mars_air": "Mars Air",
"material.tfg.liquid_mars_air": "Liquid Mars Air",
+ "material.tfg.certus": "Certus",
+ "material.tfg.trichlorocertane": "Trichlorocertane",
+ "material.tfg.dichlorocertane": "Dichlorocertane",
+ "material.tfg.chlorocertane": "Chlorocertane",
+ "material.tfg.certus_tetrachloride": "Certus Tetrachloride",
+ "material.tfg.certane": "Certane",
"material.tfg.certus_regolith": "Certus Regolith",
"material.tfg.goethe_regolith": "Goethe Regolith",
"material.tfg.bright_regolith": "Bright Regolith",
@@ -4268,4 +4279,4 @@
"quests.tfg_tips.tools_tips.harvest_basket.subtitle": "For competitive pie bakers.",
"quests.tfg_tips.tools_tips.harvest_basket.task": "Any #tfg:harvester",
"quests.tfg_tips.tools_tips.harvest_basket.desc": "&l&2Harvest Baskets&r&r are a new tool made just for &5TFG&r! These baskets can be used to harvest whole trees and bushes of fruit in one right-click! A regular &6Harvest Basket&r has a base durability of &n128&r. But an &3Aluminium Harvest Basket&r takes no damage on use."
-}
\ No newline at end of file
+}
diff --git a/kubejs/server_scripts/ae2/recipes.js b/kubejs/server_scripts/ae2/recipes.js
index 4bdd1f24..6a759f41 100644
--- a/kubejs/server_scripts/ae2/recipes.js
+++ b/kubejs/server_scripts/ae2/recipes.js
@@ -1614,59 +1614,156 @@ global.MINECRAFT_DYE_NAMES.forEach(dye => {
.EUt(GTValues.VA[GTValues.HV])
.dimension('ad_astra:moon')
- // Printed Calculation Processor
- event.recipes.gtceu.forming_press('ae2:printed_calculation_processor')
- .itemInputs('#forge:plates/certus_quartz')
- .notConsumable('ae2:calculation_processor_press')
- .itemOutputs('ae2:printed_calculation_processor')
- .duration(20)
- .circuit(1)
- .EUt(480)
+ // Certus wafer chemistry chain
- event.recipes.gtceu.forming_press('ae2:printed_calculation_processor_moon')
- .itemInputs('#forge:plates/certus_quartz')
- .notConsumable('ae2:calculation_processor_press')
- .itemOutputs('2x ae2:printed_calculation_processor')
- .duration(20)
- .dimension('ad_astra:moon')
- .circuit(2)
- .EUt(480)
+ event.recipes.gtceu.electrolyzer('tfg:certus_quartz_electrolysis')
+ .itemInputs('ae2:certus_quartz_dust')
+ .itemOutputs('tfg:certus_dust', 'gtceu:silicon_dioxide_dust')
+ .duration(20 * 40)
+ .EUt(GTValues.VA[GTValues.MV])
- // Printed Engineering Processor
- event.recipes.gtceu.forming_press('ae2:printed_engineering_processor')
- .itemInputs('#forge:plates/diamond')
- .notConsumable('ae2:engineering_processor_press')
- .itemOutputs('ae2:printed_engineering_processor')
- .duration(20)
- .circuit(1)
- .EUt(480)
+ event.recipes.gtceu.chemical_reactor('tfg:trichlorocertane')
+ .itemInputs('tfg:certus_dust')
+ .inputFluids(Fluid.of('gtceu:hydrochloric_acid', 3000))
+ .outputFluids(Fluid.of('tfg:trichlorocertane', 1000), Fluid.of('gtceu:hydrogen', 2000))
+ .duration(40)
+ .EUt(GTValues.VA[GTValues.MV])
+
+ event.recipes.gtceu.chemical_reactor('tfg:dichlorocertane')
+ .inputFluids(Fluid.of('tfg:trichlorocertane', 2000))
+ .outputFluids(Fluid.of('tfg:dichlorocertane', 1000))
+ .itemOutputs('gtceu:certus_gem')
+ .duration(40)
+ .EUt(GTValues.VA[GTValues.MV])
- event.recipes.gtceu.forming_press('ae2:printed_engineering_processor_moon')
- .itemInputs('#forge:plates/diamond')
+ event.recipes.gtceu.chemical_reactor('tfg:chlorocertane')
+ .inputFluids(Fluid.of('tfg:dichlorocertane', 2000))
+ .outputFluids(Fluid.of('tfg:chlorocertane', 1000), Fluid.of('tfg:certus_tetrachloride', 1000))
+ .duration(40)
+ .EUt(GTValues.VA[GTValues.MV])
+
+ event.recipes.gtceu.chemical_reactor('tfg:certane')
+ .inputFluids(Fluid.of('tfg:chlorocertane', 2000))
+ .outputFluids(Fluid.of('tfg:certane', 1000), Fluid.of('tfg:dichlorocertane', 1000))
+ .duration(40)
+ .EUt(GTValues.VA[GTValues.MV])
+
+ event.recipes.gtceu.electric_blast_furnace('tfg:certus_boule')
+ .itemInputs('gtceu:silicon_wafer')
+ .inputFluids(Fluid.of('tfg:certane', 16000))
+ .itemOutputs('tfg:certus_boule')
+ .blastFurnaceTemp(1800)
+ .duration(1600)
+ .EUt(GTValues.VA[GTValues.MV])
+
+ event.recipes.gtceu.cutter('tfg:cut_certus_boule_water')
+ .itemInputs('tfg:certus_boule')
+ .itemOutputs('16x tfg:certus_wafer')
+ .inputFluids(Fluid.of('minecraft:water', 45))
+ .duration(600)
+ .EUt(48)
+
+ event.recipes.gtceu.cutter('tfg:cut_certus_boule_distilled_water')
+ .itemInputs('tfg:certus_boule')
+ .itemOutputs('16x tfg:certus_wafer')
+ .inputFluids(Fluid.of('gtceu:distilled_water', 34))
+ .duration(450)
+ .EUt(48)
+
+ event.recipes.gtceu.cutter('tfg:cut_certus_boule_lubricant')
+ .itemInputs('tfg:certus_boule')
+ .itemOutputs('16x tfg:certus_wafer')
+ .inputFluids(Fluid.of('gtceu:lubricant', 11))
+ .duration(300)
+ .EUt(48)
+
+ event.recipes.gtceu.laser_engraver('tfg:engrave_engineering_certus')
+ .itemInputs('tfg:certus_wafer')
.notConsumable('ae2:engineering_processor_press')
- .itemOutputs('2x ae2:printed_engineering_processor')
- .duration(20)
- .dimension('ad_astra:moon')
- .circuit(2)
- .EUt(480)
+ .itemOutputs('tfg:engineering_wafer')
+ .duration(900)
+ .EUt(GTValues.VA[GTValues.MV])
- // Printed Logic Processor
- event.recipes.gtceu.forming_press('ae2:printed_logic_processor')
- .itemInputs('#forge:plates/gold')
- .notConsumable('ae2:logic_processor_press')
- .itemOutputs('ae2:printed_logic_processor')
- .duration(20)
- .circuit(1)
- .EUt(480)
+ event.recipes.gtceu.laser_engraver('tfg:engrave_calculation_certus')
+ .itemInputs('tfg:certus_wafer')
+ .notConsumable('ae2:calculation_processor_press')
+ .itemOutputs('tfg:calculation_wafer')
+ .duration(900)
+ .EUt(GTValues.VA[GTValues.MV])
- event.recipes.gtceu.forming_press('ae2:printed_logic_processor_moon')
- .itemInputs('#forge:plates/gold')
+ event.recipes.gtceu.laser_engraver('tfg:engrave_logic_certus')
+ .itemInputs('tfg:certus_wafer')
.notConsumable('ae2:logic_processor_press')
- .itemOutputs('2x ae2:printed_logic_processor')
- .duration(20)
- .dimension('ad_astra:moon')
- .circuit(2)
- .EUt(480)
+ .itemOutputs('tfg:logic_wafer')
+ .duration(900)
+ .EUt(GTValues.VA[GTValues.MV])
+
+ event.remove({ id: 'ae2:inscriber/engineering_processor_print' })
+ event.remove({ id: 'ae2:inscriber/calculation_processor_print' })
+ event.remove({ id: 'ae2:inscriber/logic_processor_print' })
+
+ event.recipes.gtceu.cutter('tfg:cut_engineering_water')
+ .itemInputs('tfg:engineering_wafer')
+ .itemOutputs('8x ae2:printed_engineering_processor')
+ .inputFluids(Fluid.of('minecraft:water', 338))
+ .duration(1800)
+ .EUt(GTValues.VA[GTValues.MV])
+
+ event.recipes.gtceu.cutter('tfg:cut_engineering_distilled_water')
+ .itemInputs('tfg:engineering_wafer')
+ .itemOutputs('8x ae2:printed_engineering_processor')
+ .inputFluids(Fluid.of('gtceu:distilled_water', 254))
+ .duration(1350)
+ .EUt(GTValues.VA[GTValues.MV])
+
+ event.recipes.gtceu.cutter('tfg:cut_engineering_lubricant')
+ .itemInputs('tfg:engineering_wafer')
+ .itemOutputs('8x ae2:printed_engineering_processor')
+ .inputFluids(Fluid.of('gtceu:lubricant', 84))
+ .duration(900)
+ .EUt(GTValues.VA[GTValues.MV])
+
+ event.recipes.gtceu.cutter('tfg:cut_calculation_water')
+ .itemInputs('tfg:calculation_wafer')
+ .itemOutputs('8x ae2:printed_calculation_processor')
+ .inputFluids(Fluid.of('minecraft:water', 338))
+ .duration(1800)
+ .EUt(GTValues.VA[GTValues.MV])
+
+ event.recipes.gtceu.cutter('tfg:cut_calculation_distilled_water')
+ .itemInputs('tfg:calculation_wafer')
+ .itemOutputs('8x ae2:printed_calculation_processor')
+ .inputFluids(Fluid.of('gtceu:distilled_water', 254))
+ .duration(1350)
+ .EUt(GTValues.VA[GTValues.MV])
+
+ event.recipes.gtceu.cutter('tfg:cut_calculation_lubricant')
+ .itemInputs('tfg:calculation_wafer')
+ .itemOutputs('8x ae2:printed_calculation_processor')
+ .inputFluids(Fluid.of('gtceu:lubricant', 84))
+ .duration(900)
+ .EUt(GTValues.VA[GTValues.MV])
+
+ event.recipes.gtceu.cutter('tfg:cut_logic_water')
+ .itemInputs('tfg:logic_wafer')
+ .itemOutputs('8x ae2:printed_logic_processor')
+ .inputFluids(Fluid.of('minecraft:water', 338))
+ .duration(1800)
+ .EUt(GTValues.VA[GTValues.MV])
+
+ event.recipes.gtceu.cutter('tfg:cut_logic_distilled_water')
+ .itemInputs('tfg:logic_wafer')
+ .itemOutputs('8x ae2:printed_logic_processor')
+ .inputFluids(Fluid.of('gtceu:distilled_water', 254))
+ .duration(1350)
+ .EUt(GTValues.VA[GTValues.MV])
+
+ event.recipes.gtceu.cutter('tfg:cut_logic_lubricant')
+ .itemInputs('tfg:logic_wafer')
+ .itemOutputs('8x ae2:printed_logic_processor')
+ .inputFluids(Fluid.of('gtceu:lubricant', 84))
+ .duration(900)
+ .EUt(GTValues.VA[GTValues.MV])
// Printed Silicon
event.recipes.gtceu.forming_press('ae2:printed_silicon')
diff --git a/kubejs/startup_scripts/ae2/materials.js b/kubejs/startup_scripts/ae2/materials.js
index 316f6fe3..867bd288 100644
--- a/kubejs/startup_scripts/ae2/materials.js
+++ b/kubejs/startup_scripts/ae2/materials.js
@@ -14,4 +14,36 @@ const registerAE2Materials = (event) => {
.components('1x nether_quartz', '1x certus_quartz')
.color(0x8f5ccb)
.secondaryColor(0x252f5a)
-}
\ No newline at end of file
+
+ event.create('tfg:certus')
+ .gem()
+ .dust()
+ .iconSet(GTMaterialIconSet.CERTUS)
+ .color(0xc5e3de)
+ .element(GTElements.get('certus'))
+
+ event.create('tfg:trichlorocertane')
+ .liquid()
+ .color(0xb1d9f0)
+ .components('1x tfg:certus', '1x hydrogen', '3x chlorine')
+
+ event.create('tfg:dichlorocertane')
+ .liquid()
+ .color(0x90cfd1)
+ .components('1x tfg:certus', '2x hydrogen', '2x chlorine')
+
+ event.create('tfg:chlorocertane')
+ .liquid()
+ .color(0xccede3)
+ .components('1x tfg:certus', '3x hydrogen', '1x chlorine')
+
+ event.create('tfg:certus_tetrachloride')
+ .liquid()
+ .color(0xccede3)
+ .components('1x tfg:certus', '4x chlorine')
+
+ event.create('tfg:certane')
+ .liquid()
+ .color(0xccede3)
+ .components('1x tfg:certus', '4x hydrogen')
+}
diff --git a/kubejs/startup_scripts/gtceu/materials.js b/kubejs/startup_scripts/gtceu/materials.js
index 2f2c05b6..e1c32f83 100644
--- a/kubejs/startup_scripts/gtceu/materials.js
+++ b/kubejs/startup_scripts/gtceu/materials.js
@@ -424,7 +424,7 @@ const registerGTCEuMaterialModification = (event) => {
GTMaterials.get('tfg:kaolinite').setFormula("Al2Si2O5(OH)4", true)
GTMaterials.get('tfg:vitrified_pearl').setFormula("(Al2Si2O5(OH)4)(BeK4N5)", true)
GTMaterials.get('tfg:tmos').setFormula("Si(OCH3)4", true)
- GTMaterials.get('tfg:fluix').setFormula("?(?SiO2)(SiO2)", true)
- GTMaterials.CertusQuartz.setFormula("?SiO2", true)
+ GTMaterials.get('tfg:fluix').setFormula("?(CtSiO2)(SiO2)", true)
+ GTMaterials.CertusQuartz.setFormula("CtSiO2", true)
GTMaterials.GraniteRed.setFormula("?", true)
}
diff --git a/kubejs/startup_scripts/tfg/element.js b/kubejs/startup_scripts/tfg/element.js
index b71cadcb..a6d8f9a6 100644
--- a/kubejs/startup_scripts/tfg/element.js
+++ b/kubejs/startup_scripts/tfg/element.js
@@ -10,4 +10,9 @@ const registerTFGElement = (event) => {
.protons(90)
.neutrons(232)
.symbol("Th²³²")
-}
\ No newline at end of file
+
+ event.create("certus")
+ .protons(14)
+ .neutrons(18)
+ .symbol("Ct")
+}
diff --git a/kubejs/startup_scripts/tfg/items.js b/kubejs/startup_scripts/tfg/items.js
index bad26cd0..b53a0619 100644
--- a/kubejs/startup_scripts/tfg/items.js
+++ b/kubejs/startup_scripts/tfg/items.js
@@ -375,6 +375,21 @@ const registerTFGItems = (event) => {
event.create('tfg:certus_mechanism')
.translationKey('item.tfg.certus_mechanism')
+ event.create('tfg:certus_boule')
+ .texture('kubejs:item/certus_boule')
+
+ event.create('tfg:certus_wafer')
+ .texture('kubejs:item/certus_wafer')
+
+ event.create('tfg:engineering_wafer')
+ .texture('kubejs:item/engineering_wafer')
+
+ event.create('tfg:calculation_wafer')
+ .texture('kubejs:item/calculation_wafer')
+
+ event.create('tfg:logic_wafer')
+ .texture('kubejs:item/logic_wafer')
+
event.create('tfg:small_bullet_casing')
.translationKey('tfg:small_bullet_casing')
event.create('tfg:shell_bullet_casing')
--
2.51.1.dirty

View File

@@ -0,0 +1,193 @@
From 4a8847cfd88590c66d82b88a0bcc9b4078bc676a Mon Sep 17 00:00:00 2001
From: Jika <vandechat@tutanota.com>
Date: Wed, 24 Sep 2025 16:53:11 +0200
Subject: [PATCH 9/9] Update ae2 quest with new prog
---
.../chapters/applied_energistics_2.snbt | 119 +++++++++++++++++-
kubejs/assets/tfg/lang/en_us.json | 18 +++
2 files changed, 132 insertions(+), 5 deletions(-)
diff --git a/config/ftbquests/quests/chapters/applied_energistics_2.snbt b/config/ftbquests/quests/chapters/applied_energistics_2.snbt
index 73a1c96e..5c7fac4c 100644
--- a/config/ftbquests/quests/chapters/applied_energistics_2.snbt
+++ b/config/ftbquests/quests/chapters/applied_energistics_2.snbt
@@ -11,8 +11,8 @@
image: "ae2:block/mysterious_cube_end_emissive"
rotation: 0.0d
width: 1.5d
- x: -3.5d
- y: 2.0d
+ x: -2.0d
+ y: -3.0d
}
{
height: 1.5d
@@ -232,6 +232,115 @@
}
{
can_repeat: true
+ dependencies: ["396E85A39FF414CF"]
+ description: ["{quests.ae2.certane_chem_one.desc}"]
+ icon: "tfg:trichlorocertane_bucket"
+ id: "6D4E21B4C1B0ACFB"
+ subtitle: "{quests.ae2.certane_chem_one.subtitle}"
+ tasks: [{
+ amount: 1000L
+ fluid: "tfg:trichlorocertane"
+ id: "4B7F0548E5C9B211"
+ type: "fluid"
+ }]
+ title: "{quests.ae2.certane_chem_one.title}"
+ x: -9.5d
+ y: -2.0d
+ }
+ {
+ dependencies: ["6D4E21B4C1B0ACFB"]
+ description: ["{quests.ae2.certane_chem_two.desc}"]
+ icon: "gtceu:dichloroethane_bucket"
+ id: "533D7E0B4C1F0B77"
+ subtitle: "{quests.ae2.certane_chem_two.subtitle}"
+ tasks: [{
+ amount: 1000L
+ fluid: "tfg:dichlorocertane"
+ id: "43A028F0B3BCE0F4"
+ type: "fluid"
+ }]
+ title: "{quests.ae2.certane_chem_two.title}"
+ x: -8.0d
+ y: -2.0d
+ }
+ {
+ dependencies: ["533D7E0B4C1F0B77"]
+ description: ["{quests.ae2.certane_chem_three.desc}"]
+ icon: "tfg:chlorocertane_bucket"
+ id: "0E6BA12358D01D42"
+ subtitle: "{quests.ae2.certane_chem_three.subtitle}"
+ tasks: [{
+ amount: 1000L
+ fluid: "tfg:chlorocertane"
+ id: "0BFB1E2F5629A971"
+ type: "fluid"
+ }]
+ title: "{quests.ae2.certane_chem_three.title}"
+ x: -6.5d
+ y: -2.0d
+ }
+ {
+ dependencies: ["0E6BA12358D01D42"]
+ description: ["{quests.ae2.certane_loop.desc}"]
+ icon: "tfg:certane_bucket"
+ id: "5DA0B4E3FECBA611"
+ subtitle: "{quests.ae2.certane_loop.subtitle}"
+ tasks: [{
+ amount: 1000L
+ fluid: "tfg:certane"
+ id: "33A4A6DCB77128C1"
+ type: "fluid"
+ }]
+ title: "{quests.ae2.certane_loop.title}"
+ x: -5.0d
+ y: -2.0d
+ }
+ {
+ dependencies: ["5DA0B4E3FECBA611"]
+ description: ["{quests.ae2.certus_boule.desc}"]
+ icon: "tfg:certus_boule"
+ id: "4AE613F2DE8315A9"
+ subtitle: "{quests.ae2.certus_boule.subtitle}"
+ tasks: [{
+ id: "03027FD4EB0B1A38"
+ item: "tfg:certus_boule"
+ type: "item"
+ }]
+ title: "{quests.ae2.certus_boule.title}"
+ x: -3.5d
+ y: -2.0d
+ }
+ {
+ dependencies: [
+ "4AE613F2DE8315A9"
+ "1DF9B1FB98CCD6EB"
+ ]
+ description: ["{quests.ae2.ae_wafers.desc}"]
+ icon: "tfg:engineering_wafer"
+ id: "5E07ABDCB4F72F3C"
+ subtitle: "{quests.ae2.ae_wafers.subtitle}"
+ tasks: [
+ {
+ id: "56D2D6E2DA6EB96F"
+ item: "tfg:engineering_wafer"
+ type: "item"
+ }
+ {
+ id: "29823F44D0D6A74B"
+ item: "tfg:calculation_wafer"
+ type: "item"
+ }
+ {
+ id: "50A9DA8AB1F6C57C"
+ item: "tfg:logic_wafer"
+ type: "item"
+ }
+ ]
+ title: "{quests.ae2.ae_wafers.title}"
+ x: -2.0d
+ y: -1.5d
+ }
+ {
dependencies: ["0C0B09D66D0CFFBA"]
description: ["{quests.ae2.ae_guide.desc}"]
id: "6CF08AFB924905F0"
@@ -315,8 +424,8 @@
}
]
title: "{quests.ae2.ae_press.title}"
- x: -3.5d
- y: 2.0d
+ x: -2.0d
+ y: -3.0d
}
{
dependencies: ["3C3C21482E31267B"]
@@ -477,7 +586,7 @@
{
dependencies: [
"5C98FE05CAE3DFD8"
- "674ACE84D9EA6FB9"
+ "5E07ABDCB4F72F3C"
]
description: ["{quests.ae2.ae_processor.desc}"]
id: "0C0B09D66D0CFFBA"
diff --git a/kubejs/assets/tfg/lang/en_us.json b/kubejs/assets/tfg/lang/en_us.json
index bcb4565e..0d104c78 100644
--- a/kubejs/assets/tfg/lang/en_us.json
+++ b/kubejs/assets/tfg/lang/en_us.json
@@ -1552,6 +1552,24 @@
"quests.ae2.fluix_liquid.title": "Liquid Fluix",
"quests.ae2.fluix_liquid.subtitle": "The Moon is so cheap",
"quests.ae2.fluix_liquid.desc": "We told you you'd need a vast quantity of Liquid Fluix… but we didnt mention theres a way to drastically increase your yield per Fluix Crystal.\n\nIntroducing: &bCryogenized Fluix&r, an ultra-cold fluid only craftable on the Moon using a &bVacuum Freezer&r. Simply combine Liquid Fluix with Helium-3!\n\nThis special fluid can be used as a substitute in nearly all recipes that require Liquid Fluix—but only when you're crafting on the Moon.\n\nMoon-based AE2 recipes come with huge benefits: reduced energy costs, less components needed, or sometimes both! Investing in a proper Moon base for AE2 production will pay off massively, especially in early game.\n\nIts not strictly mandatory — yet. But setting up a second base now will ease your future progression, as planet-based infrastructure becomes essential later on. So… why not get ahead of the curve?",
+ "quests.ae2.certane_chem_one.title": "Trichlorocertane",
+ "quests.ae2.certane_chem_one.subtitle": "Chemical Madness 1",
+ "quests.ae2.certane_chem_one.desc": "You will need around 128 of this to make the certus boule.",
+ "quests.ae2.certane_chem_two.title": "Dichlorocertane",
+ "quests.ae2.certane_chem_two.subtitle": "Chemical Madness 2",
+ "quests.ae2.certane_chem_two.desc": "You will need around 64 of this to make the certus.\nNow we get some certus back nice.",
+ "quests.ae2.certane_chem_three.title": "Chlorocertane",
+ "quests.ae2.certane_chem_three.subtitle": "Chemical Madness 3",
+ "quests.ae2.certane_chem_three.desc": "You will need around 32 of this to make the certus.\nYou can electrolize the Certus Tetrachloride to get some chlorine and certus back.",
+ "quests.ae2.certane_loop.title": "Certane",
+ "quests.ae2.certane_loop.subtitle": "Chemical Madness 4",
+ "quests.ae2.certane_loop.desc": "We are done.\nAlmost\n\nOhh by the way this last step you got some Dichlorocertane back this can be use in the previous step.",
+ "quests.ae2.certus_boule.title": "Certus Boule",
+ "quests.ae2.certus_boule.subtitle": "Finally",
+ "quests.ae2.certus_boule.desc": "Now that we have this we can start with AE2.\nWell cut this",
+ "quests.ae2.ae_wafers.title": "AE2 Wafers",
+ "quests.ae2.ae_wafers.subtitle": "Precision slicing",
+ "quests.ae2.ae_wafers.desc": "Sapphire for Engineering.\n\nDiamond for Calculation.\n\nRuby for Logic.",
"quests.ae2.ae_processor.title": "Processors",
"quests.ae2.ae_processor.subtitle": "AE2 Components",
"quests.ae2.ae_processor.desc": "All three &eProcessors&r will be used extensively across Applied Energistics 2 recipes.\n\nThis also gives you a great opportunity to see how effective the &3Moon&r recipes can be for crafting them.\n\nBut in the end, the choice is yours — build your infrastructure where it suits you best.",
--
2.51.1.dirty

View File

@@ -0,0 +1,19 @@
## 483938fc Add QoL Scripts for Local Server Dev
- Adds `.pakku/server-overrides/start_server.sh`, a parameterised Bash launcher that validates `minecraft_server.jar` and honours `JAVA_BIN`, `XMS`, `XMX` overrides before execing the server.
- Introduces `scripts/update_forge_auto_install.sh`, which pulls loader data from `pakku-lock.json` via `jq`, refreshes `forge-auto-install.txt`, and patches every built serverpack ZIP to mirror the CI workflow.
## 7eb9a384 Add BlazeMap and Storage Drawers
- Ships `config/blazemap-client.toml` with default overlays (coords, mob markers, layered maps) and adds the launcher script to the serverpack payload list.
## b77da775 Distant Horizon Headlights and QoL/Perf
- Adds curated configs for Distant Horizons and Smooth Chunk to stabilise long-range rendering performance.
- Integrates Headlight via KubeJS, replacing the default recipe and tagging TFC torches so they emit handheld light.
## 86ee31e0 Port Gregitas Certus to Wafer Chain
- Establishes a Certus element/material family, adds boule/wafer items with textures, and rebuilds AE2 processor production around MV-tier chemistry, EBF boule growth, and laser engraving.
- Removes the legacy inscriber print recipes in favour of GTCEu cutters that slice wafers into eight processor prints per press.
- Updates localisation with names for the new fluids/materials and fixes the chemical formulas for Certus and Fluix to reflect the revamped chain.
## 4a8847cf Update AE2 Quest with New Progression
- Extends the AE2 quest chapter to cover every step of the certus chemical loop—four fluid tasks, boule crafting, and wafer slicing—aligning it with the new wafer pipeline.
- Adds localisation strings for the fresh quests and repositions several quest nodes to accommodate the expanded progression path.

26
scripts/sync-extra-mods.sh Executable file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env bash
# Extremely simple helper: add the local tweaks via Pakku.
PAKKU_JAR="$(dirname "$0")/../pakku.jar"
mods=(
auroras
blaze-map
caelum
cartography
clumps
crash-assistant
crash-utilities
cupboard
headlight
precision-prospecting
smooth-chunk-save
tfc-caelum
tfc-volcanoes
zume
)
java -jar "$PAKKU_JAR" add ${mods[*]} -y
java -jar "$PAKKU_JAR" add prj --mr distanthorizons --cf distant-horizons -y