Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
79dbb39
ScriptsLoader - ensure directories are loaded first
ShaneBeee Feb 5, 2026
1061d32
SkriptCommand - change reload subcommand "all" to "scripts"
ShaneBeee Feb 5, 2026
2de2202
build.gradle.kts - switch skript-parser back to dev branch
ShaneBeee Feb 5, 2026
69f22cd
SkriptCommand - add some more aliases
ShaneBeee Feb 5, 2026
31b1ea4
EnumRegistry - fix value map names and parsing
ShaneBeee Feb 5, 2026
6616492
ExprGameMode - small changes and fix threading issue
ShaneBeee Feb 5, 2026
c06d671
ExprEntityHealth - fix threading issue
ShaneBeee Feb 5, 2026
b37bc4a
EffExplosion - add new effect
ShaneBeee Feb 5, 2026
17d0313
StoreUtils - add method to get command buffer
ShaneBeee Feb 5, 2026
1ad54e7
checkstyle.xml - more line length changes
ShaneBeee Feb 5, 2026
6a9c91a
EvtPlayerCraftRecipe - add recipe event
ShaneBeee Feb 5, 2026
f6b6b83
EvtPlayerCraftRecipe - remove debugs
ShaneBeee Feb 5, 2026
1ad4e4b
EvtPlayerCraftRecipe - remove unused import
ShaneBeee Feb 5, 2026
52c48bc
EffExecuteCommand - add command effect
ShaneBeee Feb 5, 2026
5e3a743
Add somemore stuff
ShaneBeee Feb 5, 2026
e28688d
Add some shutdown logic
ShaneBeee Feb 6, 2026
fc2a8a1
EffExplosion - make it better
ShaneBeee Feb 6, 2026
791f6cd
Add some interaction stuff
ShaneBeee Feb 6, 2026
094b89f
EvtPlayerCraftRecipe - wrong return type
ShaneBeee Feb 6, 2026
da179f9
build.gradle.kts - fix publications... AGAIN!
ShaneBeee Feb 6, 2026
77e6bd9
HySkriptAddon - change setup to start, to match Hytale plugins
ShaneBeee Feb 6, 2026
25d1bd5
manifest.json - update some stuff
ShaneBeee Feb 6, 2026
6bdbf14
ScriptCommand - make trigger optional
ShaneBeee Feb 6, 2026
c3e729d
ScriptcommandBuilder - fix long line issues
ShaneBeee Feb 6, 2026
2994f83
ScriptCommand - refactor contexts to allow player default in message …
ShaneBeee Feb 6, 2026
0562691
SkriptRegistration - change asset store registration
ShaneBeee Feb 6, 2026
7867d78
SkriptRegistration - change enum registration
ShaneBeee Feb 6, 2026
975b1ba
TypesAssetStore - remove auto gen message
ShaneBeee Feb 6, 2026
1c06ca5
Use new function methods
ShaneBeee Feb 6, 2026
d96d034
JsonDocPrinter - replace parse tags in patterns
ShaneBeee Feb 6, 2026
e85fbfc
Skript - add a checkstyle test to see if the build fails
ShaneBeee Feb 6, 2026
06a2258
Skript - remove test string
ShaneBeee Feb 6, 2026
8f7abec
checkstyle.yml - remove as it also runs in build
ShaneBeee Feb 6, 2026
8125423
Types - added NotificationStyle
ShaneBeee Feb 6, 2026
8125d9e
SecSendNotification - add buggy notification section
ShaneBeee Feb 6, 2026
a3f1047
SecSendNotification - some fixes
ShaneBeee Feb 6, 2026
21fec5d
ScriptsLoader - don't load scripts prefixed with a hyphen
ShaneBeee Feb 6, 2026
ae46209
ScriptsLoader - skip loading disable files and hidden files
ShaneBeee Feb 6, 2026
06d9f93
ScriptCommandBuilder - Fix sub commands not adopting the type of thei…
ShaneBeee Feb 6, 2026
2444f00
EvtPlayerAddToWorld - add should broadcast context
ShaneBeee Feb 6, 2026
36264ee
Add some sample scripts
ShaneBeee Feb 6, 2026
1088b02
build.gradle.kts - update Hytale to release version and add to manifest
ShaneBeee Feb 6, 2026
3722dd8
manifest.json - add contributors link to authors
ShaneBeee Feb 6, 2026
f042282
join-message.sk - fix spelling mistake
ShaneBeee Feb 7, 2026
375a247
EffDelay - add world as an option to prevent thread issues
ShaneBeee Feb 7, 2026
08bc329
Add contexts to commands
ShaneBeee Feb 7, 2026
fd34e93
JsonVariableStorage - remove error when thread stopping
ShaneBeee Feb 7, 2026
78afdc7
MemoryLeak - Fix local variables never clearing (part 2)
ShaneBeee Feb 7, 2026
cf3b9ce
EvtPlayerMouseClick - remove unused imports (checkstyle)
ShaneBeee Feb 7, 2026
1394c5b
EffDelay - fix local variables being cleared before delay can finish
ShaneBeee Feb 7, 2026
58c8ef5
ExprNPCType - add role change
ShaneBeee Feb 7, 2026
cc8576c
EffDamage - add damage effect
ShaneBeee Feb 7, 2026
6e0a2d0
ScriptCommandBuilder - fix me breaking commands
ShaneBeee Feb 7, 2026
8632fb4
Skript - improve error
ShaneBeee Feb 7, 2026
c716fd9
ErrorHandler - even more error handling
ShaneBeee Feb 7, 2026
8f9dd19
TypesEntity - add ability to delete an entity
ShaneBeee Feb 7, 2026
e4629a4
EffectCommands - fix up OP check and remove local vars
ShaneBeee Feb 7, 2026
6fd528e
EvtPlayerDiscoverZone -
ShaneBeee Feb 7, 2026
0e3edc6
EffSendTitle - add send title effect
ShaneBeee Feb 7, 2026
c778762
EffSendTitle - move to other package as its not just for players
ShaneBeee Feb 7, 2026
5438aca
README.md - update description
ShaneBeee Feb 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ ij_java_class_count_to_use_import_on_demand = 1024
ij_java_names_count_to_use_import_on_demand = 1024
[*.yml]
indent_size = 2
[*.json]
indent_size = 2
[*.md]
trim_trailing_whitespace=false
[*.sk]
Expand Down
37 changes: 0 additions & 37 deletions .github/workflows/checkstyle.yml

This file was deleted.

6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
![landscape](https://github.com/user-attachments/assets/2234f5ea-c2dc-4e79-b51c-4300b795e64f)


HySkript is a [**Skript**](https://github.com/SkriptLang/Skript) like plugin for Hytale servers.
It allows writing your own little plugins in English like syntaxes.
This way you can program your server to do marvelous things without having to learn Java.
**HySkript** brings the power of intuitive scripting to Hytale.
Inspired by the legendary Minecraft plugin [**Skript**](https://github.com/SkriptLang/Skript), HySkript allows you to customize your server using a natural, English-like syntax.
Whether you're creating custom commands or complex game mechanics, you can bring your vision to life instantly—no Java knowledge required.

## Docs/Tutorials:
Check out our [**wiki**](https://github.com/SkriptDev/HySkript/wiki)
Expand Down
7 changes: 4 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ java.sourceCompatibility = JavaVersion.VERSION_25

group = "com.github.SkriptDev"
val projectVersion = "1.0.0-beta5"
val hytaleVersion = "2026.01.29-301e13929"
val hytaleVersion = "2026.02.06-aa1b071c2"
// You can find Hytale versions on their maven repo:
// https://maven.hytale.com/release/com/hypixel/hytale/Server/maven-metadata.xml
// https://maven.hytale.com/pre-release/com/hypixel/hytale/Server/maven-metadata.xml
Expand All @@ -26,7 +26,7 @@ repositories {
dependencies {
compileOnly("com.hypixel.hytale:Server:${hytaleVersion}")
compileOnly("org.jetbrains:annotations:26.0.2")
implementation("com.github.SkriptDev:skript-parser:1.0.4") {
implementation("com.github.SkriptDev:skript-parser:dev~patch-SNAPSHOT") {
isTransitive = false
}
implementation("com.github.Zoltus:TinyMessage:2.0.1") {
Expand All @@ -44,7 +44,7 @@ tasks {
}
processResources {
filesNotMatching("assets/**") {
expand("pluginVersion" to projectVersion)
expand("pluginVersion" to projectVersion, "hytaleVersion" to hytaleVersion)
}
}
compileJava {
Expand All @@ -54,6 +54,7 @@ tasks {
}
shadowJar {
archiveFileName = project.name + "-" + projectVersion + ".jar"
archiveClassifier.set("")
relocate("io.github.syst3ms", "com.github.skriptdev.skript")
relocate("fi.sulku.hytale", "com.github.skriptdev.skript.tinymessage")
}
Expand Down
2 changes: 1 addition & 1 deletion config/checkstyle/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<module name="Checker">
<module name="LineLength">
<property name="max" value="150"/>
<property name="max" value="140"/>
</module>
<property name="charset" value="UTF-8"/>
<property name="severity" value="error"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.github.skriptdev.skript.api.hytale;

import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.Store;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class StoreUtils {

@SuppressWarnings("unchecked")
public static <T> CommandBuffer<T> getCommandBuffer(Store<T> store) {
try {
Method method = store.getClass().getDeclaredMethod("takeCommandBuffer");
method.setAccessible(true);
return (CommandBuffer<T>) method.invoke(store);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}

}
110 changes: 110 additions & 0 deletions src/main/java/com/github/skriptdev/skript/api/skript/ErrorHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package com.github.skriptdev.skript.api.skript;

import com.github.skriptdev.skript.api.utils.Utils;
import io.github.syst3ms.skriptparser.lang.Effect;
import io.github.syst3ms.skriptparser.lang.Statement;
import io.github.syst3ms.skriptparser.registration.SkriptEventInfo;
import io.github.syst3ms.skriptparser.registration.SyntaxInfo;
import io.github.syst3ms.skriptparser.registration.SyntaxManager;
import org.jetbrains.annotations.Nullable;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;

public class ErrorHandler {

private static final Map<String, SkriptEventInfo<?>> EVENT_MAP = new HashMap<>();
private static final Map<String, SyntaxInfo<? extends Effect>> EFFECT_MAP = new HashMap<>();

public static void init() {
for (SyntaxInfo<? extends Effect> effect : SyntaxManager.getEffects()) {
EFFECT_MAP.put(effect.getSyntaxClass().getSimpleName(), effect);
}
for (SkriptEventInfo<?> event : SyntaxManager.getEvents()) {
EVENT_MAP.put(event.getSyntaxClass().getSimpleName(), event);
}
setup();
}

private static @Nullable SkriptEventInfo<?> getEvent(String name) {
return EVENT_MAP.get(name);
}

private static @Nullable SyntaxInfo<? extends Effect> getEffect(String name) {
return EFFECT_MAP.get(name);
}

private static void setup() {
// Set up how HySkript handles IllegalStateExceptions
Statement.setIllegalStateHandler(e -> {
String message = e.getMessage();
if (message.contains("Assert not in thread!")) {
// Hytale has threads for each world, effects involving a world must happen on a world thread
boolean failedInCommand = false;
for (StackTraceElement ste : e.getStackTrace()) {
if (ste.getClassName().contains("ScriptCommandBuilder")) {
failedInCommand = true;
break;
}
}
if (failedInCommand) {
Utils.logToAdmins(Level.WARNING, "A command was executed on the wrong thread, see console for more info.");
Utils.error("A command was executed on the wrong thread!");
Utils.warn("If you have a regular/global command that a player is running, which executes code in a world, consider:");
Utils.warn(" - Using the 'player command' or 'world command' command types.");
Utils.warn(" - Using 'execute in %world%' section.");
Utils.error("Original error message: %s", message);
} else {
Utils.logToAdmins(Level.WARNING, "Something was executed on the wrong thread.");
if (message.contains("World")) {
Utils.error("A world was accessed on the wrong thread!");
Utils.warn("Consider using 'execute in %world%' section.");
Utils.error("Original error message: %s", message);
}
}
} else if (message.contains("calling a store method from a system")) {
// Hytale doesn't allow store methods to be called within System-based events
String eventName = "unknown event";
String effectName = "unknown effect";

for (StackTraceElement stackTraceElement : e.getStackTrace()) {
String fileName = stackTraceElement.getFileName();
if (fileName == null) continue;
fileName = fileName.replace(".java", "");

// Try to find the event
if (eventName.contains("unknown")) {
SkriptEventInfo<?> event = getEvent(fileName);
if (event != null) {
eventName = event.getDocumentation().getName();
if (eventName == null) eventName = event.getClass().getSimpleName();
}
}

// Try to find the effect
if (effectName.contains("unknown")) {
SyntaxInfo<? extends Effect> effect = getEffect(fileName);
if (effect != null) {
effectName = effect.getDocumentation().getName();
if (effectName == null) effectName = effect.getClass().getSimpleName();
}

}

}
Utils.logToAdmins(Level.WARNING, "An effect was executed incorrectly, see console for more info.");
Utils.error("The effect '%s' was executed incorrectly in the event '%s'.", effectName, eventName);
Utils.error("Hytale doesn't allow Store-based effects to be executed within System-based events.");
Utils.warn("Consider waiting a tick before using this effect to prevent this.");

} else {
Utils.error("An error ocrrured while executing a script: %s", message);
for (StackTraceElement stackTraceElement : e.getStackTrace()) {
Utils.error(" - %s", stackTraceElement);
}
}
});
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.skriptdev.skript.api.skript;

import com.github.skriptdev.skript.api.utils.FileUtils;
import com.github.skriptdev.skript.api.utils.Utils;
import com.github.skriptdev.skript.plugin.Skript;
import com.hypixel.hytale.server.core.receiver.IMessageReceiver;
Expand All @@ -8,8 +9,12 @@
import io.github.syst3ms.skriptparser.parsing.ScriptLoader;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class ScriptsLoader {
Expand All @@ -26,14 +31,25 @@ public void loadScripts(IMessageReceiver receiver, Path directory, boolean reloa
Utils.log(receiver, (reload ? "Reloading" : "Loading") + " scripts...");
long start = System.currentTimeMillis();

File directoryFile = directory.toFile();
if (!directoryFile.isDirectory()) {
if (!directoryFile.mkdirs()) {
File scriptsDirectory = directory.toFile();
if (!scriptsDirectory.isDirectory()) {
if (!scriptsDirectory.mkdirs()) {
Utils.error("Failed to create scripts directory!");
return;
}
try {
// Add sample scripts when creating a new scripts folder
File scriptsDir = new File(scriptsDirectory, "-sample-scripts");
if (!scriptsDir.mkdir()) {
throw new RuntimeException("Failed to create sample scripts directory");
}
FileUtils.copyFromJar("/sample-scripts/", scriptsDir.toPath());
} catch (IOException | URISyntaxException e) {
Utils.error("Failed to load sample scripts, message: %s", e.getMessage());
}
}

List<String> scriptNames = loadScriptsInDirectory(receiver, directoryFile);
List<String> scriptNames = loadScriptsInDirectory(receiver, scriptsDirectory);

long end = System.currentTimeMillis() - start;
Utils.log(receiver, (reload ? "Reloaded" : "Loaded") + " %s scripts in %sms", this.loadedScriptCount, end);
Expand All @@ -46,23 +62,32 @@ public void loadScripts(IMessageReceiver receiver, Path directory, boolean reloa
}
}

@SuppressWarnings("DataFlowIssue")
public List<String> loadScriptsInDirectory(IMessageReceiver receiver, File directory) {
if (directory == null || !directory.isDirectory()) return List.of();
List<String> loadedScripts = new ArrayList<>();

for (File file : directory.listFiles()) {
File[] files = directory.listFiles();
if (files == null) return loadedScripts;

Arrays.sort(files,
Comparator.comparing(File::isDirectory).reversed() // Directories first
.thenComparing(File::getName, String.CASE_INSENSITIVE_ORDER)); // Then sort by name alphabetically

for (File file : files) {
// Skip disabled files and hidden files
String fileName = file.getName();
if (fileName.startsWith("-") || fileName.startsWith(".")) continue;
if (file.isDirectory()) {
loadedScripts.addAll(loadScriptsInDirectory(receiver, file));
} else {
if (!file.getName().endsWith(".sk")) continue;
Utils.log(receiver, "Loading script '" + file.getName() + "'...");
if (!fileName.endsWith(".sk")) continue;
Utils.log(receiver, "Loading script '" + fileName + "'...");
List<LogEntry> logEntries = ScriptLoader.loadScript(file.toPath(), false);
this.loadedScriptCount++;
for (LogEntry logEntry : logEntries) {
Utils.log(receiver, logEntry);
}
loadedScripts.add(file.getName().substring(0, file.getName().length() - 3));
loadedScripts.add(fileName.substring(0, fileName.length() - 3));
}
}
return loadedScripts;
Expand Down Expand Up @@ -106,4 +131,8 @@ public void reloadScript(IMessageReceiver receiver, String name) {
}
}

public void shutdown() {
// TODO clear triggers here
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ private void loadAddon(File file) {
}
if (mainClassIntance instanceof HySkriptAddon addon) {
addon.setManifest(manifest);
addon.setup();
addon.start();
this.addonCount++;
// Finalize registration and logging
for (LogEntry logEntry : addon.getSkriptRegistration().register()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public HySkriptAddon(String name) {
* Called when the addon starts to load.
* This is a good time to set up your syntaxes.
*/
abstract public void setup();
abstract public void start();

/**
* Called when the addon is shutting down.
Expand Down
Loading
Loading