Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions PACKAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Internal Maven/Gradle package coordinates:

```kotlin
implementation("dev.takesome:sky-simulation:1.4.2")
implementation("dev.takesome:sky-simulation:1.4.3")
```

Install the package into Maven Local:
Expand All @@ -21,7 +21,7 @@ repositories {
}

dependencies {
implementation("dev.takesome:sky-simulation:1.4.2-SNAPSHOT")
implementation("dev.takesome:sky-simulation:1.4.3-SNAPSHOT")
}
```

Expand Down
25 changes: 19 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# SkySimulation

<p align="center">
<img src="docs/sky-simulation-banner.svg" alt="SkySimulation banner" width="100%" />
</p>

<p align="center">
<a href="https://github.com/Take-Some/SkySimulation/actions/workflows/push.yml"><img alt="CI" src="https://github.com/Take-Some/SkySimulation/actions/workflows/push.yml/badge.svg?branch=master" /></a>
<a href="https://github.com/Take-Some/SkySimulation/actions/workflows/release.yml"><img alt="Release" src="https://github.com/Take-Some/SkySimulation/actions/workflows/release.yml/badge.svg" /></a>
<img alt="Version" src="https://img.shields.io/badge/version-1.4.3-blue" />
<img alt="Java" src="https://img.shields.io/badge/Java-17%2B-orange" />
<img alt="Artifact" src="https://img.shields.io/badge/artifact-dev.takesome%3Asky--simulation-7c3aed" />
<img alt="License" src="https://img.shields.io/badge/license-BSD--style-lightgrey" />
</p>

**SkySimulation** is the Take Some() sky and atmosphere package for Java / jMonkeyEngine worlds.

We are **Take Some()** — a small engineering team building game-runtime infrastructure: simulation systems, rendering tools, world technology, and reusable engine modules for our own projects.
Expand Down Expand Up @@ -56,7 +69,7 @@ encapsulated. Public compatibility is preferred over cosmetic directory moves.

## Cloud weather and generated sky materials

Version `1.4.2` adds smooth runtime atmosphere transitions, typed weather-state subscriptions, expanded cloud-weather diagnostics, generated sky material logging, and stronger DDS/BC normal-map inspection for cloud presets.
Version `1.4.3` extracts weather subscription dispatch from the environment runtime, reduces per-event allocation during weather notifications, and keeps cloud/weather runtime state observable for gameplay systems.

- `SkyCloudPreset` provides `CLEAR`, `FAIR`, `OVERCAST`, `WISPY`, `CLOUDY`, `RAIN`, `STORM`, and `NIMBUS`.
- `SkyControl.setCloudPreset(preset, seconds)` changes weather by fading current layers out, swapping alpha/normal/scale/motion while invisible, and fading target layers in.
Expand Down Expand Up @@ -89,7 +102,7 @@ repositories {
}

dependencies {
implementation("dev.takesome:sky-simulation:1.4.2")
implementation("dev.takesome:sky-simulation:1.4.3")
}
```

Expand All @@ -110,7 +123,7 @@ repositories {
}

dependencies {
implementation("dev.takesome:sky-simulation:1.4.2-SNAPSHOT")
implementation("dev.takesome:sky-simulation:1.4.3-SNAPSHOT")
}
```

Expand All @@ -132,7 +145,7 @@ gradlew.bat packageLocal
Build release artifacts locally:

```bat
gradlew.bat :SkyLibrary:assemble -PskySimulationVersion=1.4.2
gradlew.bat :SkyLibrary:assemble -PskySimulationVersion=1.4.3
```

Artifacts are generated in:
Expand All @@ -146,8 +159,8 @@ SkyLibrary/build/libs
A GitHub release is produced by pushing a version tag:

```bat
git tag -a v1.4.2 -m "SkySimulation v1.4.2"
git push origin v1.4.2
git tag -a v1.4.3 -m "SkySimulation v1.4.3"
git push origin v1.4.3
```

The release workflow publishes the Maven package to GitHub Packages and attaches the JAR, sources, Javadoc, POM, and Gradle module metadata to the GitHub Release.
Expand Down
27 changes: 27 additions & 0 deletions RELEASE_NOTES_v1.4.3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# SkySimulation v1.4.3

SkySimulation 1.4.3 improves the runtime architecture around game-facing weather events and prepares the package for safer growth behind the protected `master` branch.

## Highlights

- Extracted weather subscription management from `SkyEnvironmentRuntime` into `SkyWeatherSubscriptionRegistry`.
- Reduced weather-event dispatch overhead by avoiding per-event `ArrayList` snapshots and active-list `contains()` checks.
- Preserved the existing typed weather subscription API, cancellable handles, listener isolation, and current-state replay behavior.
- Kept runtime weather observability for gameplay, UI, AI, fog-of-war, and audio systems.
- Added release documentation for the `1.4.3` package coordinates.

## Coordinates

```kotlin
implementation("dev.takesome:sky-simulation:1.4.3")
```

Local development snapshot:

```kotlin
implementation("dev.takesome:sky-simulation:1.4.3-SNAPSHOT")
```

## Validation

- `gradlew.bat :SkyLibrary:test --no-daemon --console=plain --stacktrace`
8 changes: 8 additions & 0 deletions SkyLibrary/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# release log for the SkyControl library and related software

## Version 1.4.3 released on 27 June 2026

Notable changes:
+ extract weather subscription dispatcher from the environment runtime
+ reduce weather event dispatch allocation and active subscription scans
+ preserve weather listener replay, cancellation, and failure isolation behavior
+ update package coordinates and release documentation for version 1.4.3

## Version 1.4.2 released on 27 June 2026

Notable changes:
Expand Down
2 changes: 1 addition & 1 deletion SkyLibrary/src/main/java/jme3utilities/sky/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,6 @@ private Constants() {
* @return branch and revision (not null, not empty)
*/
public static String versionShort() {
return "master 1.4.2";
return "master 1.4.3";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ public void setCloudsNormalMap(int layerIndex, String assetPath) {
normalMap.setWrap(Texture.WrapMode.Repeat);
setTexture(parameterName, normalMap);
logger.log(Level.FINE,
"cloud normal map applied: layer={0}, parameter={1}, path={2}, image={3}",
"cloud normal map applied: layer={0}, parameter={1}",
new Object[]{layerIndex, parameterName, assetPath,
normalMap.getImage()});
}
Expand Down Expand Up @@ -701,7 +701,7 @@ private Texture loadNormalMap(String assetPath) {
throw exception;
}
logger.log(Level.INFO,
"using internal compressed texture reader for cloud normal map: {0}",
"using compressed reader for cloud normal map: {0}",
assetPath);
result = SkyDdsTextureLoader.loadTexture(assetManager, assetPath);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ private static SkyCloudPresetDefinition parseDefinition(
SkyCloudPresetDefinition result = new SkyCloudPresetDefinition(
id, description, seconds, layers, metrics);
logger.log(Level.FINE,
"parsed sky weather preset: id={0}, seconds={1}, layers={2}, metrics={3}",
new Object[]{id, seconds, layers.size(), metrics});
"parsed sky weather preset: id={0}, seconds={1}, layers={2}",
new Object[]{id, seconds, layers.size()});
return result;
}

Expand Down Expand Up @@ -154,8 +154,8 @@ private static SkyCloudLayerSpec parseLayer(LuaValue value) {
alphaMap, normalMap, opacity, scale, uRate, vRate);
}
logger.log(Level.FINER,
"parsed cloud layer: alpha={0}, normal={1}, opacity={2}, scale={3}, uRate={4}, vRate={5}",
new Object[]{alphaMap, normalMap, opacity, scale, uRate, vRate});
"parsed cloud layer: alpha={0}, normal={1}, opacity={2}",
new Object[]{alphaMap, normalMap, opacity});
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public SkyCloudTransitionRuntime(CloudLayer[] layers) {
public void cancel() {
if (active && elapsed < duration) {
logger.log(Level.FINE,
"cloud weather transition cancelled: target={0}, elapsed={1}, duration={2}",
"cloud transition cancelled: target={0}, elapsed={1}",
new Object[]{target == null ? null : target.id(),
elapsed, duration});
}
Expand Down Expand Up @@ -133,8 +133,8 @@ public void transitionTo(SkyCloudPresetDefinition definition,
}

logger.log(Level.INFO,
"cloud weather transition started: id={0}, seconds={1}, layers={2}",
new Object[]{definition.id(), seconds, definition.layerCount()});
"cloud transition started: id={0}, seconds={1}",
new Object[]{definition.id(), seconds});
if (seconds == 0f) {
applyTargetTextures();
applyTargetOpacities();
Expand Down Expand Up @@ -204,9 +204,9 @@ private void applyTargetTextures() {
layer.setNormalMap(spec.normalMap());
layer.setMotion(0f, spec.uRate(), 0f, spec.vRate());
logger.log(Level.FINER,
"cloud layer target applied: index={0}, alpha={1}, normal={2}, scale={3}, opacity={4}, uRate={5}, vRate={6}",
new Object[]{layerI, spec.alphaMap(), spec.normalMap(),
spec.scale(), spec.opacity(), spec.uRate(), spec.vRate()});
"cloud target applied: index={0}, alpha={1}, normal={2}",
new Object[]{layerI, spec.alphaMap(), spec.normalMap()});

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ private static Image readImage(InputStream stream) throws IOException {
MipData mipData = copyMipData(
data, width, height, mipLevels, format.blockBytes);
logger.log(Level.INFO,
"loaded compressed sky texture: width={0}, height={1}, mips={2}, code={3}, format={4}, blockBytes={5}",
"loaded compressed sky: width={0}, height={1}, mips={2}",
new Object[]{width, height, mipData.sizes.length, fourCc,
format.imageFormat, format.blockBytes});
Image result = new Image(format.imageFormat, width, height,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public static SkyMaterial createTop(AssetManager assetManager,
}

logger.log(Level.INFO,
"top sky material created: objects={0}, cloudLayers={1}, stars={2}",
"top sky material created: objects={0}, clouds={1}, stars={2}",
new Object[]{topObjects, topClouds, starsOption});
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import jme3utilities.Validate;
import jme3utilities.sky.cloud.SkyCloudPreset;
import jme3utilities.sky.cloud.SkyCloudPresetDefinition;
Expand All @@ -48,21 +43,15 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* @author Take Some
*/
final public class SkyEnvironmentRuntime {
/** Message logger for this class. */
final private static Logger logger
= Logger.getLogger(SkyEnvironmentRuntime.class.getName());

/** World clock facade. */
final private SkyWorldClock clock;
/** Optional weather sink implemented by the visual sky control. */
final private WeatherApplier weatherApplier;
/** Active weather subscriptions. */
final private List<SkyWeatherSubscription> weatherSubscriptions
= new ArrayList<SkyWeatherSubscription>();
/** Weather subscription registry and dispatcher. */
final private SkyWeatherSubscriptionRegistry weatherSubscriptions
= new SkyWeatherSubscriptionRegistry();
/** Latest lighting output. */
private SkyLightingSnapshot lightingSnapshot = SkyLightingSnapshot.empty();
/** Runtime-local event sequence counter. */
private long weatherEventSequence = 0L;
/** Current weather state. */
private SkyWeatherState weatherState = SkyWeatherState.fair();

Expand Down Expand Up @@ -100,13 +89,7 @@ public float ambientLightLevel() {
* Remove all weather subscriptions.
*/
public void clearWeatherSubscriptions() {
for (SkyWeatherSubscription subscription : weatherSubscriptions) {
subscription.markCancelled();
}
int removed = weatherSubscriptions.size();
weatherSubscriptions.clear();
logger.log(Level.FINE,
"sky weather subscriptions cleared: removed={0}", removed);
}

/**
Expand Down Expand Up @@ -173,21 +156,8 @@ public float precipitation() {
public int removeWeatherListener(SkyWeatherListener listener) {
Validate.nonNull(listener, "listener");

int removed = 0;
Iterator<SkyWeatherSubscription> iterator
= weatherSubscriptions.iterator();
while (iterator.hasNext()) {
SkyWeatherSubscription subscription = iterator.next();
if (subscription.listener() == listener) {
subscription.markCancelled();
iterator.remove();
++removed;
}
}
logger.log(Level.FINE,
"sky weather listener removed: listener={0}, removed={1}",
new Object[]{listener, removed});
return removed;
int result = weatherSubscriptions.removeListener(listener);
return result;
}

/**
Expand Down Expand Up @@ -362,13 +332,8 @@ public SkyWeatherSubscription subscribeWeather(SkyWeatherFilter filter,
Validate.nonNull(filter, "filter");
Validate.nonNull(listener, "listener");

SkyWeatherSubscription result = new SkyWeatherSubscription(
this, filter, listener);
weatherSubscriptions.add(result);
logger.log(Level.FINE, "sky weather subscription added: {0}", result);
if (notifyCurrent) {
dispatchCurrent(result);
}
SkyWeatherSubscription result = weatherSubscriptions.subscribe(
this, filter, listener, weatherState, notifyCurrent);
return result;
}

Expand All @@ -395,13 +360,8 @@ public boolean unsubscribeWeather(
return false;
}

boolean removed = weatherSubscriptions.remove(subscription);
if (removed) {
subscription.markCancelled();
logger.log(Level.FINE,
"sky weather subscription removed: {0}", subscription);
}
return removed;
boolean result = weatherSubscriptions.unsubscribe(subscription);
return result;
}

/**
Expand Down Expand Up @@ -451,41 +411,6 @@ public float windStrength() {
return weatherState.windStrength();
}

/**
* Deliver a current-state replay to a new subscription.
*
* @param subscription subscription to notify
*/
private void dispatchCurrent(SkyWeatherSubscription subscription) {
assert subscription != null;
if (!subscription.matches(weatherState)) {
return;
}

SkyWeatherEvent event = new SkyWeatherEvent(++weatherEventSequence,
weatherState, weatherState, 0f, SkyWeatherChangeSource.CURRENT);
dispatchSafely(subscription, event);
}

/**
* Dispatch an event and isolate listener failures.
*
* @param subscription destination subscription
* @param event event payload
*/
private void dispatchSafely(SkyWeatherSubscription subscription,
SkyWeatherEvent event) {
assert subscription != null;
assert event != null;
try {
subscription.dispatch(event);
} catch (RuntimeException exception) {
logger.log(Level.WARNING,
"sky weather listener failed: subscription="
+ subscription + ", event=" + event, exception);
}
}

/**
* Publish a weather-state change.
*
Expand All @@ -497,24 +422,7 @@ private void dispatchSafely(SkyWeatherSubscription subscription,
private void publishWeatherChange(SkyWeatherState previous,
SkyWeatherState current, float seconds,
SkyWeatherChangeSource source) {
assert previous != null;
assert current != null;
assert seconds >= 0f : seconds;
assert source != null;

SkyWeatherEvent event = new SkyWeatherEvent(++weatherEventSequence,
previous, current, seconds, source);
logger.log(Level.INFO, "sky weather changed: {0}", event);

SkyWeatherState eventState = event.currentWeather();
List<SkyWeatherSubscription> snapshot
= new ArrayList<SkyWeatherSubscription>(weatherSubscriptions);
for (SkyWeatherSubscription subscription : snapshot) {
if (weatherSubscriptions.contains(subscription)
&& subscription.matches(eventState)) {
dispatchSafely(subscription, event);
}
}
weatherSubscriptions.publish(previous, current, seconds, source);
}

/**
Expand Down
Loading
Loading