Releases / v0.117.0-rc2
v0.117.0-rc2 Whole Worlds
2026-10-20 Latest
Planets several times the size generate in seconds, with mountain ranges, rivers, lakes and climates. Wind and lightning, props that keep their own look, craft that articulate, and meshes and textures a script builds itself.
Bigger planets, made in seconds
A generated planet now costs its surface, not its volume. A 400 m world that
took nearly three minutes fills in about four seconds and keeps a third of the
memory. deferCaves = true leaves the buried cave zone until a dig reaches
it, so a world fills and keeps about a quarter less; with it, a 1.5 km world
fills in under a minute on a 16-core desktop. Two players' games agree on every
cave either way.
terrain.generatePlanet takes new layers: ridged mountain ranges, warped and
terraced ground, plateaus, overhangs and arches, steep-walled ravines, and
rivers that run downhill in valleys they carve. biomes paints the surface by
latitude, altitude, slope, moisture and nearness to a river.
terrain.planetRivers(opts) and terrain.planetLakes(opts) say where the
rivers run and where lakes would settle, without generating anything.
docs/planet-generator.md has five example worlds to
start from.
Ground that looks the way it collides
Terrain within 64 m of the camera is always drawn at full detail, and nothing within 120 m is drawn coarser than half detail, so mountains no longer appear only once you walk into them and pits are always drawn. Coarse ground far away settles onto the real surface instead of floating metres above it. Undug ground shows its own texture, not the subsoil under it.
A dig no longer stalls the frame: collision is rebuilt in the background and the old ground holds until the new one lands. A ray past a planet costs about what a ray into it does, so a script can cast several a frame.
Wind and lightning
weather.addWind{ velocity = vec3(4, 0, 0), gust = 0.4, turbulence = 0.2 }
declares a wind, and weather.windAt(point) reads it back. A wind given a
parent turns with its planet. One given a center and radius is a local
cell, a storm or a valley's down-draught, that adds to the winds under it.
Gusts travel downwind, so one is seen crossing a field instead of everything
moving at once.
weather.bolt(from, to) gives a lightning bolt as strands to draw, a jagged
channel with forks. The same seed gives the same bolt on every machine.
Scattered props look and behave like the model
Props now draw from their model's own colour, maps and glow, and a source's
tint and emissive shade them instead of replacing them, so one model serves
a field of any colour. A source on a planet lands on the right face of it.
Instance ids survive a round trip through Lua, so scatter.remove takes the
prop scatter.near found. Props settle a few at a time, so walking into a
field is smooth, and a script's sources are freed when it is hot-reloaded or
its node is destroyed. "Smooth + mipmaps" on a model's textures now builds the
mip chain, so far textures stop shimmering.
Craft that articulate
Either end of a joint can be an assembly, so a vessel built from several
assemblies moves: hinges, pistons, rotors, robotic arms. A hinge or slider
motor can drive to a goal, set from a script each tick with Joint.goal. A
wheel hung from an assembly grips the ground and parks on a slope.
assembly.grip welds a craft to the ground under it, or to another body.
A part's mass is readable and writable from Lua, and the assembly re-weighs itself on the next tick. A parked assembly falls asleep and costs nothing, and a fast one stops at the ground instead of tunnelling in and being thrown out.
Meshes and textures from a script
mesh.build{ positions, indices [, normals, uvs, colors] } builds a mesh and
answers a name that goes anywhere a model path does, node.model and
scatter.create included. assets.textureFromPixels(w, h, pixels) makes a
texture from raw RGBA. anim:setBones poses many bones in one call, and
node.name can be assigned.
Materials and sky
A glTF model's metallic-roughness, normal, occlusion and emissive textures
come in with it, and draw exactly as the same maps set by hand. Materials take
an emissive map. Surface shaders get litPbr, the built-in Physical lighting,
and the derivatives dpdx, dpdy and fwidth. Shots, captures and docked
Game views draw a material's maps and shading, where before they drew it flat.
A model's textures are filtered the way its file says: a texture exported with nearest filtering keeps crisp pixels, and one exported with linear filtering draws smooth, with mipmaps. A model's embedded texture filter in the Inspector still chooses for the whole model.
On a round world with air, flat fog fills only the view inside the air, so the
sun and other planets keep their colour. The sun low in thick air turns orange
instead of fading, and a world's cloud deck can be tinted, darkened and raised
from setCelestial.
Smaller things
app.monitors(),app.displayModes()andapp.setDisplayMode{...}let a game offer resolution and monitor settings, andui.engineSettings(container, "controls")builds the engine's rebinding page into a game's own panel.save.setkeeps tables nested 16 deep.- Renaming, retagging or reparenting a node no longer rebuilds the scripts' copy of the whole scene.
- A sound or shader under a linked project folder resolves inside the project.
- Mixer changes hold across
scene.load;audio.tracks()lists the mixer. perf.buckets()namesgpuWait,presentandassets, and what is left isuntimed.- In a flat 2D view, a click selects what is drawn under the cursor, not the tilemap behind it.
- A package's
scene.docsandmesh.readare answered the next frame, even when it queued nothing else, andxpcall(f, debug.traceback)catches an error in a package with the stack that raised it.
The Hub
The Hub now counts installs with an anonymous ping once a day: a random install
id made on your machine, the Hub's version, your OS and CPU type, and its update
channel. Nothing that identifies you is sent. The Hub tells you before it sends
anything, and Settings ▸ Install ping turns it off and deletes the id.
FOPULL_NO_PING=1 turns it off for every Fopull app. The editor never pings.
Upgrading
Nothing to do. Five things look or behave differently:
- A glTF part with a metallic-roughness texture now shades as Physical. Parts that name only a base colour draw as before.
- A model whose file says its textures are filtered linearly now draws them smooth, where before every model drew crisp. Blender exports linear unless an image's interpolation is set to Closest. To keep a model crisp, set its embedded texture filter to crisp.
- On a round world with air, flat fog no longer covers things out in space.
perf.ms("other")still answers the time no bucket measured; the bucket is now nameduntimed.- Joints get twice the solver passes, so they hold stiffer.
Floptle Hub
Engine
The binaries are not signed yet. On macOS, right-click the app and pick Open the first time. On Windows, if SmartScreen appears, pick More info then Run anyway.