Configuration
It all lives in one file, config/oas/vortexdread.json, on
the server side. Forty-two options in five groups, written whole on first run and rewritten on
every save, so that a version adding an option puts it in the file you are already editing instead
of leaving you to guess it exists. There is no in-game screen: a file you can read again later
beats a panel you walked through once.
What happens when a value is wrong
Every numeric option carries a range. A value outside it is pulled back into the
range rather than refused: someone writing a thousand into a tick budget wants a bigger budget, and
stopping the server over it helps nobody. A key this version does not know is ignored with a log
line naming it. A file that will not parse at all is moved aside as
vortexdread.json.broken and a fresh one takes its place, because someone
spent time in there and quietly overwriting it is the one outcome they cannot recover from.
The command
/vortex wants permission level 2, the
same gate vanilla puts on /weather, since it is the same kind of
decision. /vortex spawn drops a funnel where you stand, with a rating and
a pair of coordinates as optional arguments. /vortex list reports the
live ones within 8192 blocks, with their stage, their distance, their core and how much ground
they are carrying. /vortex clear removes them,
/vortex storms off stops the sky making more, and
/vortex compute names the device doing the arithmetic and counts what
went through each path.
The forty-two options
The values below are those of a fresh file. The right-hand column says what changes when you move them, not what the name means.
| Option | Default | What it moves |
|---|---|---|
| naturalTornadoes | true | False and the sky never makes one, leaving only the command. |
| tornadoChancePerMinute | 0.18 | Chance, per minute of thunder, that a supercell organises. 0 to 1. |
| cooldownTicks | 9600 | Quiet enforced after one dissipates, whatever the odds say. Eight minutes. |
| maxConcurrent | 1 | Funnels alive at once in one dimension. Up to 16. |
| ratingBias | 0.0 | Shifts the random rating, in EF steps. Negative keeps the sky to weak ones. |
| warningRadius | 640 | Distance at which the roar starts and the sky begins to turn. |
| rebuildStorms | true | False and vanilla weather goes back to looking the way it always did. |
| cloudFlashesPerMinute | 34 | Visual-only bolts fired into the cloud, which is what lights it from inside. |
| funnelFlashesPerMinute | 9 | Bolts fired inside the funnel itself once it is on the ground. |
| extraLightning | true | False leaves only the strikes vanilla would have made. |
| Option | Default | What it moves |
|---|---|---|
| coreRadiusAtEf0 | 6.0 | Core radius of the weakest one. Everything else scales off it. |
| radiusGrowthExponent | 1.5 | How fast the core widens as the wind climbs. |
| lifespanMinTicks | 2400 | Shortest life, two minutes. Most of them last no longer. |
| lifespanMaxTicks | 14400 | Longest life, twelve minutes, the rare long-tracked one. |
| travelSpeed | 8.0 | How fast the system travels over the ground, in blocks per second. |
| trackWander | 1.6 | Heading drift allowed, in degrees per second. At zero the track is a straight line. |
| turbulence | 0.22 | Amplitude of the noise riding on the analytic field, as a fraction of the local wind. |
| cloudBaseAltitude | 183.0 | Height of the cloud deck. That is where Photon puts its cumulus at stock settings. |
| formingFraction | 0.12 | Fraction of the life spent reaching down before touching the ground. |
| ropeOutFraction | 0.18 | Fraction of the life spent drawing out into a rope and dying. |
| Option | Default | What it moves |
|---|---|---|
| breakBlocks | true | False and nothing comes out of the ground, leaving the wind and whatever is already up. |
| blockBudgetPerTick | 96 | Blocks examined per tick across every live tornado. The whole cost of destruction sits here. |
| resistanceScale | 1.0 | Multiplies the resistance a block has to survive. Under one, walls stay up. |
| dropItems | false | True and a taken block leaves its item. By default what the wind takes is gone. |
| maxDebris | 220 | Heavy debris carried at once by one tornado, each one a real entity. |
| debrisSettles | false | True and a piece puts its block back down where it lands, rebuilding the track behind it. |
| damageEntities | true | False and neither the wind nor the debris hurts anything. |
| damageScale | 1.0 | Multiplies every point of damage, wind and impact alike. |
| liftPlayers | true | False keeps players on the ground. Mobs and items still fly. |
| liftThreshold | 18.0 | Wind speed under which nothing is lifted at all, in blocks per second. |
| Option | Default | What it moves |
|---|---|---|
| useGpu | true | A kill switch. With no device present the processor path runs and nothing has to be touched. |
| gpuDeviceIndex | -1 | Index into the flat list of OpenCL devices. Negative picks on its own. |
| gpuWorkgroupSize | 0 | Work group size. Zero lets the driver decide, which is the right answer. |
| advectionThreads | 0 | Threads in the processor pool. Zero means cores minus two. |
| advectionBatch | 4096 | Debris handed to one dispatch. Small hides latency, large amortises the upload. |
| Option | Default | What it moves |
|---|---|---|
| funnelSteps | 40 | Steps through the volume. Under sixteen the wall goes banded. |
| funnelLightSteps | 6 | Steps toward the light for the shadow inside. Zero flattens the funnel entirely. |
| funnelDetail | 1.8 | Size of the smallest visible wisp, in blocks. Finer wants more steps. |
| funnelRenderDistance | 1024.0 | Distance past which the storm is only sky and sound. |
| screenShake | true | False and the screen stops moving when the wind does. |
| postEffect | true | False and the darkening, the streaks and the flash all go. |
| skyGreen | 0.55 | How much of the green a tornado sky takes reaches the world colour, 0 to 1. |
Five groups, not five files. A group's name in the JSON comes from the class
holding the option, hence storm, tornado,
damage, compute and
look. An option added to the code lands in its group with no wiring
anywhere else, and an option moved from one group to another is still read: the key looked up is
the option's name, never the full path.
No dead options. The development tooling is compiled in a separate source set and is not in the shipped jar. What appears in the file is what actually drives something, with nothing left in place in case it comes back.