A procedural universe, and an observatory that has to find what is in it - #26
Conversation
- three unrelated quantities shared the literal 100 in one file - distance scale, atmosphere scale and star-temperature scale now distinct - year, lunar month, ticks-per-day and the star-radius scale named - default rotational period named separately from the platform tick rate - constants are int with explicit casts so each site keeps its own arithmetic - pins the frame by value first; no computed number changes
- install ARPlanetWorldInfo before the provider caches its values - terrainGeneratorOptions per dimension, in XML and NBT - one TerrainResolution so provider and WorldInfo cannot disagree - forward getGeneratorOptions through the weather wrapper - drop two setTerrainType calls that never did anything - report the published identity from dim info and report_state
- region scan, telescope survey, and the observatory that runs them - the interstellar jump leg flies, and its duration is now measured - no conflicts; the one shared file (test probe) took both sides' verbs - gate on the merged tree: 586 server tests, 1007 unit and integration
- planet physics derived from (seed, cell); type is an XML preset - mass and radius primary, gravity derived as M/R^2 - a descent realizes a procedural body into a dimension, idempotently - long-tailed retinue with moons, belts, rings and distinct cells - 43 new unit tests and one server e2e
- add /artest player far-tp, delivering like a dimension change - walk, stand and collide measured clean from 0 to 24M - pin the reserved-shipyard teleport veto with predicted outcomes - keep the server far-coordinate integrity spike as a guard
- derive moon periods from the parent's mass, not its surface gravity - a Jupiter's moons ran 11.2x too slowly on both placement paths - sum stellar flux over the primary and its companions - a black hole's companion no longer cancels its accretion dimming - pin both as contract tests; single-star numbers are unchanged
- key orbital periods on the star's mass, deriving M from R when unstated - rewrite equilibrium temperature over the summed flux, unchanged per star - give every planet type an albedo; ice reflects, lava and ocean do not - delete the (1/g)^3 rotation law from both the realizer and the generator - pin each as a contract test, including one gravity cannot satisfy
…s a moon - the legacy generator fed its atmosphere table into orbital distance - both quantities sit near 100, which is why the swap stayed invisible - a realized procedural moon had no parent, so isMoon was false forever - it stood at its parent's own orbit and every moon path was dead for it - take a moon's own distance from its ephemeris, the only place it lives
- the convenience ctor pinned every procedural body to a static frame - the orbit belongs in the frame, as an authored system already has it - moons now ride the parent's frame instead of a static one of their own - share the cell-angle function so the frame and baseOrbitTheta agree - pin it with a test proven to fail on the previous code
- delete the SystemBody constructors that silently chose a static frame - replace them with SystemBody.fixedAt, which names the choice - the two production users are a star at its anchor and a belt round it - 38 call sites converted; javac enumerated every one
- seat-mount takes an optional near <x> <y> <z> [maxDist] selector - the seat is resolved through the owning ship chunk claim - every reply carries seatsLoaded, so the bare form is visible - shipIdOwningBlock answers identity, not proximity
- both client spikes delivered into the reserved quadrant and never ran - render shows zero repeated frames out to 24M against an origin control - a sub-block position survives the round trip exactly at every rung - a ship assembled at 16M flies and keeps its rider like one at zero - the same holds with its blocks at subspace 19.2M
- four conflicts resolved against their auto-merged neighbours - the descend gate keeps canDescend, so unvisited worlds stay landable - the shell rides the same predicate as the flag it sits beside - procedural realization moved inside the incoming cached-target loop - the stronger of two independently added client-state guards survives
- state the chart scale (250 m/block) and derive AU, light year, orbit unit - place procedural bodies by their own orbital law, not a second layout - a system that will not fit loses bodies, never scale - separate star spacing from a system's clear space (10 000 AU floor) - tilt an orbit without enlarging it - companions become first-class stars with real orbits and ids - every star of a system lights every world in it - fix groupMax reading the groupMin attribute
- units, the chart scale, and the file's read/rewrite lifecycle - what minSpacing bounds and what it does not - companion orbits, and changing a generator parameter mid-save - a combinations section: what wins when two fields disagree - retarget the texture pointer at this repository
- about half of systems draw companions; ids come from a reserved slot - a companion is a body of its system, seated from its own elements - a world is dropped where a companion would tear it away - separations depend on nothing but their own draw, so the zone stays computable
- AbsolutePos holds a sector triple and an in-cell offset, not three block longs - GalacticCoord.absoluteX/Y/Z retired: the product overflowed seven orders before the sector index did, silently - a frame's base is saved as sector + offset - distances come from the two deltas; a block vector saturates instead of wrapping
- Galaxies are seated objects; the percolating blob mask is gone - A galaxy's radius is drawn conditional on its type - Systems are placed by the owning galaxy's density profile - Galactic rotation lands as an analytic, tested law - The galaxy index is derived from the sector, never stored - Reserve the home galaxy so authored content is not intergalactic - Sweep find-procedural by super-cell instead of by cell
- Expansion and peculiar motion carry a galaxy's centre, not its insides - A position is bound to its galaxy or comoving in the void, never both - Star clusters refine the lattice by an exact commensurate subdivision - Authored anchors are declared against a galaxy, not an absolute cell - Galaxy archetypes become authorable, disc thickness among them - Seat the home galaxy around the origin so it is not the nucleus
- A nebula is derived from its cluster, not seated on a lattice of its own - Dark, emitting and reflecting are one age sequence, not three draws - A starless molecular cloud is a cluster that refines nothing - Expose how thick a cloud is at a point, with no consumer yet
…is a length - resolve a look through the owning anchor, not a seat query - stride a survey by one star's territory; the local radar keeps cells - state the reach in light years, derive the aim in steps - show the aim's length in the GUI, computed server-side
- ask the generator which clouds are within reach of a cell - send each as a direction and an apparent size, never a position - draw them behind the stars, and the dark ones in front - report what is seated beside what is drawn
…ress - integrate the density along the sight line, once, for both consumers - read the column as magnitudes, cut at the real boundary - an obscured look writes the bare coordinate and says why - zero magnitudes turns the mechanic off entirely
- replace the hardcoded 0/5000/0 with a doubling cell-info search - gate on systemBodies + bodiesAt, the render feed's own predicate - stop before the probe's int-sized sector range - verify each reply echoes the cell that was asked for
- drop the velocity clamp from both Newtonian and both assist laws - rename MAX_SPEED to FA_SETPOINT_MAX_SPEED, bounding the setpoint only - auto-range the HUD velocity bars so they cannot peg - pin the new law: linear gain, first cosmic velocity, assist deceleration
- raise CELL to 32,000,000 and move the shipyard clear of it - derive the addressing floor a bigger cell spends on inner orbits - size a body by the angle it subtends, from a radius it carries - send the body's radius and its parent on the render channel - delete the legacy random planet generator and derive instead - widen the test JSON readers that could not read an exponent
- add CellSeam: when a pose has left, and where it lands - add CellSeamController: destination taken before source released - ask the carry before reporting position; saturation is now refusal - margins are cell fractions, so the hysteresis rests on no speed - add seam-carry probe, since a slot world does not tick its tiles
- add atmosphericDrag: the bound is where you are, not the law - derive the drag constant from a stated terminal speed - re-assert a held pilot input, phased per seat, so a lost one costs 1s - make server wait admit it never advanced the clock - retarget the FA capture test at the contract that still exists
- add artest server tick-count, an instant read of the clock - both server verbs report onServerThread, so the premise is measured - ServerTicks.await polls from the test jvm and throws on no advance - migrate 17 server wait sites and 2 bare sleeps - keep one deliberate caller: the verb's own test - derive the shipyard rungs from ShipChunkAllocator, not from 2026 values
- derive the threshold from the two phase windows, never a third number - one predicate decides, read by the console forecast and the departure - generalize the seam controller: a jump is a carry with a chosen cell - no lane, no snapshot, no IN_TRANSIT row for a crossing - require the fixture jump speed so no caller picks a mechanism blindly - give transit-tick a count and resolve its anchor by ship identity - measure the fixture cell spacing instead of writing it down
- galaxy reference radius 1500 -> 50000 light years - galaxy type radius bands re-derived from real radii - nucleus subdivision back to its ratified k=215 - BlockDelta reports saturation instead of clamping silently - RegionScan refuses an unwalkable region loudly - systemsInRegion walks only the sub-cells it needs
- the galaxyType reader's defaults were a stale copy of it - a pack writing one attribute got a 900 ly "spiral" - defaults now read off GalaxyGenConfig.stockSpiral() - weight stays 1: an unweighted type is the rarest
- satellites are children inside the primary's own cube - count and size drawn from the galaxy type's own band - galaxyContainingSector answers which galaxy a point is in - the seat margin is the whole retinue's reach - a nucleus contrast scales to its own galaxy's population
- DriveTier with the galactic band gap derived, not written - JumpSpeed takes the tier; no overload defaults it - routeEnergy: the closed form where power cancels - powerForCoils is the single home of the power law - a dampener absorbs a fraction of a baseline arrival
- it becomes a Forge Energy receiver like every other machine - heat sinks bound what the buffer accepts; they make nothing - extraction is refused: a jump bank is not the ship's battery - the cooldown is a forecast at full inflow, and says so - retracts the unloaded-cell fairness the free charge bought
- a drained bank stays at zero through 100 real server ticks - artest drive push feeds it through the real energy capability - one push is bounded by throughput, not by capacity - a charge survives a real chunk save, drop and reload
- add an ejecta halo outside every galaxy's declared radius - draw the star lattice a second time for unbound systems - add ROGUE_PLANET and a starless branch in PlanetDerivation - rename StarSystem to PlanetarySystem with an optional star - seat self-bound clusters outside a galaxy with their own field
- make averageTemperature private with one setter and a pure getter - recompute only where an input changes, not on every read - admit a planet type at the temperature its own albedo gives it - end the derivation on the albedo the dimension model will read
- take the observed free-floating abundance and giant fraction - expose rogue tuning through galaxyGen, read and written back - give a rogue its own giant rate instead of the bound outer-zone one - move the feed fixture clear of the shipped system's neighbourhood
- schema selects generator, derivation, metric and expansion - every released version stays in the jar; the save picks its own - save stamps schema version, config and laws fingerprints - a telescope look pins the system it reports - golden corpus of 7 seeds decides minor vs major byte for byte - ships as version 0 "0.1", warned as alpha at boot and on login - /stellurgy universe status and upgrade, with one-shot arming
- moon orbits drawn in parent radii, not absolute blocks - authored moon orbits floored above the parent surface - descent shell follows body radius plus a Karman atmosphere - entry ring derived from the shell, keeping the hysteresis - planet-view size scales by radius, mass indicator by mass - star weights reweighted to observed abundance by number - star lattice edge derived from separation and occupancy - galaxy and cluster densities stated as knobs, not readings - golden corpus regenerated against the new placement
- survey becomes a cone: apex, direction, half-angle, walked outwards - reach derived from the aperture's limiting magnitude, not configured - detection split from characterisation; detection derives no bodies - a look resolves its whole territory instead of one seat of it - star territories divided uniformly, both occupancies per sub-seat - passive radar strides by territory, and reaches a neighbour - seat resolution stops fabricating the system it discards - dust measured only after clear-sky brightness admits the star - golden corpus regenerated against the divided field
- resolution needs a margin of magnitudes over the detection limit - the margin is derived from the signal-to-noise two tasks need - resolvability decided where the aperture is known, carried on the hit - an unresolved system is still written down as a position
- take mainline's rewritten README wholesale - keep the planetDefs bullet's per-attribute tail
- a changed galaxyGen refuses the load and has a defined way through - say what the upgrade cannot reach: crystals nobody could read - one cell is 32 000 000 blocks, not 4 000 000
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 969ec2078c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| OptionalInt existing = registry.realizedDimAt(bodyCell); | ||
| if (existing.isPresent()) { | ||
| return existing.getAsInt(); |
There was a problem hiding this comment.
Realize the approached body instead of any body in its cell
When a procedural planet and its moons share a cell, realizedDimAt(bodyCell) identifies only the cell's first realized descendable body, not the specific body the flight computer approached. After the parent has been realized, approaching a moon therefore returns the parent's dimension here and descends onto the parent; if nothing is realized yet, the later cell-wide scan likewise selects the parent first. Pass a stable body identity or variant through realization so each moon can obtain and reuse its own dimension.
Useful? React with 👍 / 👎.
The authored systems stop being all there is: the universe around them is generated, and a system has to be found before it can be flown to. Authoring does not go anywhere - a pack still writes the systems it cares about, an authored star owns its anchor cell and its whole neighbourhood, and the generator fills what is left. What changes is that the sky no longer ends where the XML ends, and the coordinates out there are earned rather than listed. Everything below is the price of that, its consequence, or a boundary it draws.
Five things a pack has to do. The first one stops a server from starting; the rest are silent, which is why they are here:
<galaxyGen>parameter is a procedure, not an edit - and the world will not open until you follow it. These are inputs to a derived universe, so changing one moves every system nobody has visited yet. The save carries a fingerprint of what generated it; on a mismatch the load stops and names both fingerprints rather than handing the players a different sky. The way through: restore the previous<galaxyGen>(in an existing world a template edit reaches the live copy only throughresetPlanetsFromXML), start, run/stellurgy universe upgrade confirm- which freezes every system anyone has seen, including the addresses on the memory crystals of players online at that moment - stop, install the new configuration, start again. An address that was not frozen still resolves afterwards, but names whatever the new universe puts in that cell.separationwithorbitalDistanceon authored companion stars. The attribute is gone, and an unrecognised attribute is ignored without a warning, so a companion written the old way keeps loading and quietly moves to the default 0.05 AU - which recomputes the climate of every world in that system, because illumination is summed from each star at its own distance.telescopeScanRangeSectors,telescopeScanHalfWidthSectors,telescopeScanMaxSectors,telescopeScanTicksPerSector,telescopePassiveRadiusSectors. They no longer exist. Left in place they are ignored in silence, and a pack that had tuned its survey runs at shipped defaults without ever saying so.<galaxyGen>in planetDefs to get the procedural sky. Omit it and the universe holds only what the file names, exactly as today. That is the off switch, and it is the default. The observatory is rebuilt either way - see condition 3 - so an authored-only pack still gets the new survey, pointed at its own systems.The universe, and finding your way around it
A telescope pointing buys positions long before it buys detail. One pointing covers a patch of sky, is paid for in steps, survives an unload, and writes real addresses into a memory crystal - the carryable item a ship's navigation computer reads its destinations from. Registering a system and making out what orbits it are two different observations, and the second needs 6.5 magnitudes more light. Measured at shipped defaults, a full pointing registers 14 systems and can resolve 1 - the starting instrument is a coordinate finder, and the aperture is what changes that.
Dust costs you a system's detail, never its address. A cloud between the instrument and a system dims it: past five magnitudes of extinction the survey still writes down where the system is, but can no longer say what is in it. Nothing an observatory can do sees through that - a concealed system is charted by flying to it, and
telescopeObscuredAtMagnitudes=0turns concealment off for a pack that does not want the mechanic.A survey costs about ten minutes, and it is paid in steps rather than in one wait. A pointing is walked one star territory at a time - about 77 000 of them at full depth on shipped defaults, roughly 600 steps of work - and a shorter pointing costs proportionally less. The scan survives an unload, so those ten minutes are not ten minutes of standing at the telescope. With research off an observation is instant, as before.
The addresses a player collects are worth collecting. Galaxies are objects with a centre, a disc and an edge, so the star field thins outwards and stops; clusters are genuinely denser than the field around them and carry the cloud they condensed out of; between galaxies there is a measured void rather than nothing. One astronomical unit is 598 391 400 blocks at 250 m per block, and insolation, temperature, orbital period and flight time all follow from that one number rather than from a table.
Worlds, and what a pack can do with them
A DERIVED planet's kind follows from its physics instead of being chosen first. Orbit, star, mass and radius produce its temperature, atmosphere, gravity and type. A system may hold more than one star, and a moon travels with the planet it orbits. Authored planets are untouched by all of it: a value written in XML still wins, planet types classify procedural worlds only and never reclassify an authored
<planet>, and only what a pack leaves unstated is ever derived.A pack can hand a planet type to another mod's world generator.
<planetType>declares weighted terrain options - the built-in generator, a world type registered by another mod, or a pre-generated template - so a procedural world can be built by RTG, Biomes O' Plenty or anything else already installed instead of being another variation of one generator. An option whose mod is absent is dropped before the draw, so a missing mod cannot break world generation.Declaring any
<planetType>or<starType>REPLACES the built-in table wholesale - the example below is an illustration, not a starter file, and copied as-is it leaves a universe whose only planet type is ice and whose only stars are these two archetypes.A survey never allocates a world. A procedural body has no dimension until a ship actually descends to it, which is what stops one telescope sweep from minting planets by the dozen. When a landing does mint one, it materializes what the scan already promised rather than rolling fresh values, and from then on the save is authoritative: a later seed, config or modset change cannot reshape a planet that has been landed on.
Flying
A pilot is bounded by acceleration, not by a speed limit. The velocity clamp is gone from the flight law; what bounds a craft now is its own thrust and, in atmosphere, drag with a terminal speed. A held control key keeps arriving at the server instead of being sampled once, and a ship flown past the face of its space cell is carried across it instead of being stopped at it.
A jump is paid for by the ship's own generation. The capacitor fills from what the ship produces rather than from the clock, so a jump is armed by building power and not by waiting; a drive generation buys efficiency while its size buys power; and a short hop is a single crossing rather than a flight through hyperspace.
Running a server on it
A world can be asked which universe made it.
/stellurgy universe statusreports the model the world was generated under, whether the pack now states a different one, and how many systems the save has already frozen by being seen. Accepting a different pack universe is a deliberate act -/stellurgy universe upgrade- and not a side effect of editing XML.The universe is derived, so the save grows with what has been SEEN and not with the size of space. Galaxies, clusters and systems are values computed from the seed and the coordinate - nothing about them is stored - and what the save does keep is the systems somebody has already seen, which is precisely the count
universe statusreports back. An unexplored galaxy costs nothing at all.This build labels itself an alpha, at boot, at login and in status. The universe ships as schema
0, and the leading zero means the model may be replaced in a later release rather than extended: only what somebody has already seen is frozen./stellurgyis an alias of the command root.Fixes
SILENT- a planet published the save's world type instead of its own, so the world a scan described was not the world you landed on.SILENT- the jump capacitor filled from the clock rather than from the ship, so a jump could be armed by waiting instead of by generating power.SILENT- the telescope resolved the cell it pointed at rather than the system that owns it, and its reach was stated in sectors, so a better aperture did not make it see farther.SAVE- a galactic coordinate could name a position it cannot express and saturated quietly instead of being refused, so an address written down that way pointed somewhere else.Internals worth knowing
No addon is known to build against these, so nothing here asks anyone to migrate.
FreeFlightPhysics.MAX_SPEEDis nowFA_SETPOINT_MAX_SPEEDand clamps only the fly-by-wire setpoint;ATMOSPHERIC_TERMINAL_SPEEDandatmosphericDragare new.StellarBody.getStarSeparation/setStarSeparationgive way togetOrbitalDistance/setOrbitalDistance, plusseparationAuFromandapparentSeparationDegrees.DimensionProperties.averageTemperatureis private behindsetAverageTempandrecalculateTemperature; a body's bulk arrives asgetMass,getRadius,setBulkandderivedGravity.PacketSystemBodiesSynccarries a body's radius and parent index, and a nebula section; client and server must be the same build, as before.MixinWorldProviderjoinsmixins.advancedrocketry.jsonso a planet publishes its own world type.