Chunkloading of Oilsprings with air on top.
leagris opened this issue ยท 19 comments
While Oilsprings are generating new oil blocks only if chunk is loaded, keeping these chunks loaded in multi-player world can be an issue:
- Keeping chunks loaded is costly in CPU and Memory
- MP Servers usually allow some player placeable chunk-loaders at the cost of fuel item or power source, and accounting restriction.
Because of this, making affordable use of Oilsprings is not possible unless player always stay in range. The slow production rate, can never offload cost of running a powered chunkloader.
Solution:
Making Oilspring blocks send chunk load tickets while they have a block of air above would allow Oil regeneration to occur while keeping an affordable limited number of chunks loaded:
- World generated oil pockets would prevent Oilsprings chunk load tickets until they are empty (pumped out)
- Players having on-site pumping equipment would have them operate remotely given they can have everything within the Oilspring chunk
- Abandoned or covered Oilsprings would not create any chunkload ticket or would stop doing so, as soon as they generate an oil block above.
Possible logic with fictive calls to create or cancel chunkload tickets within
BuildCraft/common/buildcraft/core/BlockSpring.java:
//...
private Ticket chunkTicket;
//...
public void invalidate() {
if (chunkTicket != null) {
ForgeChunkManager.releaseTicket(chunkTicket);
}
super.invalidate();
destroy();
}
//...
private void assertSpring(World world, int x, int y, int z) {
int meta = world.getBlockMetadata(x, y, z);
int graceTicksLeft = 0;
/* Should be a config option into main.conf general
* # Graceful spring tile ticks count to keep chunk loaded, while it can not generate more fluid.
* I:spring.chunkload.graceTics=5 Server Ticks = graceTicks * spring.tickRate
*/
final int graceTicks = 5;
EnumSpring spring = EnumSpring.fromMeta(meta);
world.scheduleBlockUpdate(x, y, z, this, spring.tickRate);
if (!spring.canGen || spring.liquidBlock == null) {
return;
}
if (!world.isAirBlock(x, y + 1, z)) {
if (chunkTicket != null) {
graceTicks = chunkTicket.getModData().getInteger("graceTicksLeft");
if (graceTicks == 0) {
ForgeChunkManager.releaseTicket(chunkTicket);
} else {
chunkTicket.getModData().setInteger("graceTicksLeft", graceTicksLeft - 1);
}
}
return;
} else {
if (chunkTicket == null) {
chunkTicket = ForgeChunkManager.requestTicket(BuildCraftFactory.instance, worldObj, Type.NORMAL);
if (chunkTicket != null) {
chunkTicket.getModData().setInteger("springX", x);
chunkTicket.getModData().setInteger("springY", y);
chunkTicket.getModData().setInteger("springZ", z);
chunkTicket.getModData().setInteger("graceTicksLeft", graceTicks);
ForgeChunkManager.forceChunk(chunkTicket, new ChunkCoordIntPair(x >> 4, z >> 4));
}
}
}
if (spring.chance != -1 && rand.nextInt(spring.chance) != 0) {
return;
}
world.setBlock(x, y + 1, z, spring.liquidBlock);
}
Yeah they are basically cosmetic at this point. Perhaps they should either be removed, or improved by quite a large amount.
this would basicly turn those blocks into free (non movable) chunkloaders and would as said above cause almost untracable issues of how one chunk is kept loaded and nothing around it
those blocks are also ment to be extremely slow as they provide free oil and thus power, while not enough to run your base on it's still free and infinite so i don't think we should be making it also chunkload itself to give people even more free oil
also has an outdated milestone and can probably be closed
So, really those oil springs serve no purpose as is. Because if you actually need/use oil, you are better exploring for oil pockets rather than trying to maintain lots of remote infrastructures, transports and chunk loading for 1 bucket of oil every few minute.
Do those springs just fill a single block above them or do they attempt to fill the entire bubble with oil after a while?
If they do you could perhaps keep a timestamp from when their chunk is unloaded and then when the chunk is loaded again get the difference between that timestamp and the current timestamp and calculate how much oil it should have generated in that time. Then attempt to fill the bubble with that amount.
That way the oil will be refilled if you leave it alone for a while, loaded or not.
This costs no CPU or memory for keeping the chunks loaded since you won't need to keep them loaded.
As far as I know, they fill a single block above. So if you intent to make some "use" of it, you need to pump oil or it will not generate again.
Getting a chunk load ticket while the block above is empty/air and a few ticks to allow pumping and cycling back to empty block above and a new chukload ticket would be just enough, while keeping safe on the # of loaded chunks.
We also could have pumps to chunkload as quarries, but it would make for very cheep chunkloaders with lots of potential abuses. There are already players abuses with quarry chunkloading instead of using item or energy powered chunkloaders. And a quarry is significantly more expansive to build.
Well that renders my suggestion useless.
So if I understand it correctly you want the chunk to load when the spring wants to generate an oil block and then keep it loaded for a short time after?
So if that is correct the chuck is unloaded between those times but now I am wondering if it is possible to do any processing on the oil spring while the chunk is unloaded (I don't know Forge or Minecraft's inner workings very well). I mean how do you know a spring in an unloaded chunk wants to generate oil?
So if I understand it correctly you want the chunk to load when the spring wants to generate an oil block and then keep it loaded for a short time after?
True
So if that is correct the chuck is unloaded between those times but now I am wondering if it is possible to do any processing on the oil spring while the chunk is unloaded (I don't know Forge or Minecraft's inner workings very well). I mean how do you know a spring in an unloaded chunk wants to generate oil?
We don't care of unloaded springs.
Un unloaded spring was either:
- Not been generated terrain yet
- Generated with some oil pocket or stone over it, so it is not candidate for oil generation and or chunkloading ticket.
- Has had all oil pumped but chunkload ticket time expired and the block above is occupied by a new generated oil or other block.
The idea is to get a chunkload ticket only when a spring "wants" and is "able" to generate oil. The ticket should last until actual oil is generated or more precisely until there is something other than air above the spring + some extra chunkload ticket time.
So any pumping or anything in the same chunk can operate while the chunk is loaded, during the time this active spring is eligible to oil generation + extra time (graceful period where pumping has a chance to proceed, and then return the spring to eligible generation witch would trigger another chunkload ticket).
If oil is generated and nothing pumped/removed it (there is no air over the spring) after this extra time. Chunkload ticket expire, chunk is unloaded and that's it.
One possibility would be a tick handler:
- each oil spring which has a free block above it is put into that list (on chunk load, or after a block update)
- springs are also removed from that list if the block above is no longer free - but not on chunk unload
- oil springs no longer need to tick
- the tick handler will load at max 1 oil spring chunk and generate oil if possible - the chunk stays loaded ~3 seconds to give pumps time to work
A way suggested by @Amelia- is IMHO the best. Just save timestamp of last update and recalculate time spent unloaded when loading a chunk or random tick. Save timestamp again, repeat.
@Kubuxu @Ameila- - I just thought of that independently, heh. That's what I'll do.
As @Amelia- wrote:
If they do you could perhaps keep a timestamp from when their chunk is unloaded and then when the chunk is loaded again get the difference between that timestamp and the current timestamp and calculate how much oil it should have generated in that time. Then attempt to fill the bubble with that amount.
Current spring regen only refill 1 block above spring block. It should be updated to full bubble/well regen with very same algorithm as worldgen.
It means spring regen has to refill the whole bubble instead of just block above as it does now.
Water springs should generate water as 1x1 wells in straight up line and stop at ground level+1
Oil springs should generate oil as spherical bubbles filling any air above and up to a max radius, with bubble center at y+bubble_radius
@leagris - that's going too far in my opinion
@laz2727 - When we do balance, we only look at BuildCraft. Possibly mods which balance with BuildCraft well. Not mods which take power creep through the roof. I don't care that 60RF/t generation is puny nowadays, within our ecosystem it's not puny at all.
As for filling the bubble, I kind of thought that was already what was happening and based my suggestion on that.
I can see how it's a lot of work to put that in unless perhaps if it's possible to use the mechanics the floodgate uses. Just use a smaller area, oil springs only show up below large oil wells and you have the dimensions of those. You can make it use a cube or cilinder with the width of a large oil well and a specific height (doesn't have to go all the way to the surface) and it should only fill in the air blocks of the bubble.
If someone is playing smart and digs out the entire cylinder or cube sure they will have a large reservoir but that won't increase how quickly it regenerates. It only reduces how often they have to visit it and pump the oil out.
@leagris it is not lightweight. Chunkloading is never lightweight and can cause untraceable problems ("Why my boiler blew up.").
On 07/04/2015 11:59, @Amelia wrote:
As for filling the bubble, I kind of thought that was already what was
happening and based my suggestion on that.
Or you can just check my sample code in description. It need tweaking,
missing imports and a suggested config option.
It is lightweight.
It is based on Quarry chunkloading but much more restricted.
Hardcoed default graceticks may need adjustments and tests.
It does not destabilize balance or bring significant game change.
It is a very small less than 20 lines commit.
Logic match expressed needs and requirements, (I checked it, but
3rd-party check is welcome)
IMHO: Any change in spring regen size or rate should be subject to a
distinct issue# and discussion. Refilling entire bubbles? why not? But
it is a whole distinct while similar issue.
Lets stick to subject here:
- Making useful exploitation of spring regen, can benefit from some
chunk loading help. - For now, there are no real use of it because no one would keep a
pumping infrastructure, energy, pipings and chunkloading gears for an
oil spring regenerating 1 block of oil every 1 or 2 Minecraft days and
only if block above is not already filled.
I'd say it is a game-play non-sense to let springs as-is.
I know no one making any use of current spring regen.
I have another idea.
Why not give the spring a tank or container that holds oil and as long as that has oil it will keep replacing the air block above itself with an oil block if that is being taken away and take that oil out of its tank until it's empty?
You can use the method with the timestamps to refil that internal tank and add oil each time it would otherwise spawn a new block of oil now if it was chunkloaded. Do this even if the block above it is covered.
Have a limit of maybe a 1000 buckets or so to the tank? I've pumped over 5000 buckets of oil out of a large well before so 1000 is not too silly I think.