Closed tttppp closed 8 years ago
I think it should be maximum 1 'N'
I am starting to think water dynamics could be a whole game in itself. That's not to say we shouldn't do it in Rabbit Escape - I am just wondering whether there will be a spin-off mini game where you have to get the water to the drain or something...
I think I've got something I'm almost happy with. There's a bug in my code that means occasionally the amount of water in a cell is negative (which you can see by watching the numbers on the right), but other than that, water seems to flow ok.
Code here: https://ideone.com/iPJJL1
I forgot to mention that this is cellular automation, whereas the previous version had a routing algorithm in it. Consequently this latest version should be much less memory intensive.
Very exciting.
The water needs a height difference to spread, but the height difference seems a bit much. Looks a bit like sand piling piling up.
Might it help if the water had a stepped more often than the rabbits? Perhaps a bad idea: introduce a lot of complexity, like the rabbits falling 2 squares per step.
Need to see it in the game with other things moving to see if it looks OK.
Do you want me to do the animations? I can use similar techniques to the fire.
Wow! It does look a bit like sand but I think that is likely to provide more puzzle opportunities so looks great to me. Why do the values Flash e.g. Between N and |?
In the last animation the water in the hole seems to flow back out again sometimes. Is that a bug or a feature of the algorithm?
Water flowing out from hole: I think this is a bug. Probably the same as the bug that causes negative amounts of water sometimes. If we can squash it that would be good.
Sand-like movement: I think I ended up arbitrarily reducing the spread sideways to get water flowing upwards from the U bend. I definitely had trouble building enough pressure to force water upwards.building
Animations: I would be very happy for @colonelfazackerley to do the animations. The fire looks amazing! Currently each cell has an amount of water, and I pick a character to display by using the water in a cell and the water in the cell below. The amounts are "out of" 100 (although pressure causes the numbers to go above this) (and bug causes them to go below zero).
Oh, and ramps have a maximum capacity of 50, rather than 100.
For choosing the animation state, I think it will need to know if the cell has water pouring down. Also possibly left or right in the pools.
During each iteration there is a calculation of how much water to move in each of the four directions. That could be stored against the cell for animation purposes.
In a pool then water will be constantly moving between all adjacent cells. The water level stays roughly the same because it reaches an equilibrium.
OK, that should work. Let me know when there is an interface to your code that I can work with.
This is very cool. I would start simple with the animations.
This is very cool. I would start simple with the animations.
A few more changes, and I'm now happy. Water flows much more consistently and can still flow a reasonably long way around U-bends (although there's probably now a limit). Unless anyone has any further tests or tweaks then I suggest the next step is Java code!
Well (no more bubbling in the well):
U-Bend (water eventually works it's way up the other side):
Bulkhead (this feels very slightly less like sand now):
Ramps (I've shown the level and the animated flow separately as it's quite hard to work out what's going on in ASCII otherwise):
Nice.
That looks ready to me. Fantastic work.
I've made a start on the Java implementation here: https://github.com/tttppp/rabbit-escape/tree/Water
I'm hopeful that the WaterRegion 'interface' is stable, and so animation can be done against it. There's also a new Pipe object that should have an animation.
you used LookupTable2D :)
A pipe should look like a tap?
I'd thought of it as looking like a circle with water pouring out. Maybe something like this: http://thumbs.dreamstime.com/z/sewer-pipe-beach-concrete-outlet-nature-32399041.jpg
OK. I think it should probably have a hand drawn look, as it's a bit like an entrance, in that it brings something into the world.
I think a tap might be easier, as the animation could start on the square below. The actual tap could be static.
Note the convention for test methods. 'generateWaterTable' should be something like 'Generated_water_table_fills_correctly'.
We need to take the state of WaterRegion
private final Set<Direction> connections;
public int capacity;
public int contents;
private Map<Direction, Integer> flow = new HashMap<>();
and note a block in the cell and make an animation for it.
I am thinking it may make sense to not use the rea files, but rather move sprites an amount related to the flow. should end up with less memory used.
Will pipes be metal? Indestructible by bashers etc?
I was definitely thinking pipes were indestructible. I think they're in the same category as Exits and Entrances.
I'm planning that the water will enter the cell that the pipe is in. This makes connectivity calculations simpler, as pipes don't need to worry about them.
I'm confused as to the difference between calcNewState and step. Which should the water move during? Which should the bunnies drown during? My guess is that calcNewState should set the flow, and step should move water in line with the flow, but I wanted to check this before I dive in!
Bunnies should drown in step. You create a new Behaviour called Drowning. It has a behave method (the Rabbit class calls behave in it's step method). In Drowning.behave you call world.changes.killRabbit( rabbit ). See the Falling class.
I'm planning that the water will enter the cell that the pipe is in. This makes connectivity calculations simpler, as pipes don't need to worry about them.
OK. I will work with that.
I'm confused as to the difference between calcNewState and step. Which should the water move during? Which should the bunnies drown during? My guess is that calcNewState should set the flow, and step should move water in line with the flow, but I wanted to check this before I dive in!
step is called first. This does stuff, so this is when the water or rabbits move. your content values change or rabbit coordinates change. then calcNewState is called to work out what the state will be for the next step. as step is first World.init is called to set things up for the the first step.
As a side note I'm not happy with the activated step and calcNewState setup but I haven't thought through how to improve it yet.
@tttppp please could you create a WaterRegionChangeListener in engine like this? https://github.com/colonelfazackerley/rabbit-escape/commit/1d649bcceb99df466d1217ed644dc4836f18776c
and create a method WaterTable.setWaterRegionChangeListener( WaterRegionChangeListener l)
Then each time a region is added because water spills in, or each time a region is deleted from the table because the water has flowed away, WaterTable uses the methods to update the listener.
Actually, there is a way that fits in better with the current code. Please can you list the WaterRegions that are new and removed in WorldChanges.
A suggestion for what to do with git. I pull from andybalaam/master and tttppp/Water regularly. When It's done, I will need to rebase, which is usually a problem. when it's done tttppp/Water is merged into andybalaam/master. I pull that and make a fresh branch from it. I then cherry pick my rebased commits from my old Water branch into my new one.
So, no-one else needs to rebase, but I may occassionally ask for some tweaks by @tttppp, to reduce the final merge conflicts.
This sounds fine. I've been deliberately holding off any rebasing or history tweaking so that I don't create extra work for you @colonelfazackerley. If there are larger changes which you want in my branch then please feel free to pull request to it.
I think that at the end we will want to stabilise our work on my branch before we merge anything to andybalaam/master, because otherwise master will be broken ("Invisible water drowns rabbits. Surprise!")
I will have a look at WorldChanges. I haven't addressed bashing/digging/etc yet, but I will need to react to changes in the block table to make updates to the water table.
We could merge tttppp/Water to master earlier if we have some very simple graphics (I'm thinking static blue rectangles), and then we could replace the graphics when we merge cf/Water. Anyway, probably something to think about for the future.
I think changes in the blocks should now result in changes to the water table. @colonelfazackerley I've updated the WorldChanges class in a way that works, but by listing the coordinates of the changed water regions.
Water currently disappears from these regions, rather than being transferred, but it's a start.
Side note: I did this coding to Peter Rabbit (the CBBC cartoon).
I was thinking WorldChanges would have
public final List<> waterRegionsEmptied = new ArrayList<WaterRegion>();
public final List<> waterRegionsStartedFilling = new ArrayList<WaterRegion>();
So your list of points have both new and going water regions in? I will need to have a think about wether that works for the WaterRegionRenderer.
Merging early is good by me. We have lots of tests to check nothing is broken. The later the merge the harder (and therefore the less effective) the review is.
I added some very simple graphics this morning. Falling water looks horrible, but pipes and water are now visible.are To see some water falling then add a P to a space in a level.
Water doesn't yet cause drowning or extinguishing.
I am now watching CBeebies...
I believe a full cell has 100 water units in. Could this be changed to 1024? For the animations, the cells are a nominal* 32 pixels. 32*32=1024.
This would simplify some thiings for me. Also everything should be a round number (in hex :)
We can certainly have 1024 as the standard capacity of a cell. Cells can contain more water than their capacity, although then they are under pressure, and water will leave if possible. Does that cause any problems?
I might experiment with bridges affecting water in the future, which would result in two water regions in the same cell. Maybe water regions should have a shape to make animation easier?
I have not thought about the pressure issue. How high does the content go?
yes regions probably should have a shape. I am mostly ignoring that for the moment.
With the latest updates, the water model now seems to match the prototype.
@colonelfazackerley There's currently no maximum pressure (although contents is stored in an int, so I guess the answer is currently 32767). I'd be happy saying 8 x capacity
was the maximum? (Or 16 x capacity
if you want it to be square?) Fixing a maximum would be a good idea anyway. If a cell contains more than the maximum then is it ok for the excess to just be destroyed?
The graphics can ignore the excess, I don't mind if you destroy it or not.
I just mean what sort of values are typically reached? Presumably it's deterministic. If you have a water column 5 world tiles deep what's the pressure (excess contents) in the bottom tile?
@colonelfazackerley I did some experiments with a fairly deep U-bend and saw maximum values of about 500 (with the maximum capacity set to 100). The plan is for a full cell to be lethal to the rabbit - although this is made more complicated by ramps/bridges, as the rabbit's head is in the next cell up. I've pushed an initial drowning behaviour now.
After some more thinking, I will ignore any excess capacity. I will try 10 sprites for a full cell first. actually seeing something rendered feels like it's getting closer.
Can you change the capacity units so 1024 is full?
Ok, done. I've also added support for extinguishing fire now. The major thing left is unit tests, as I've been mainly testing by playing so far. Once I've added some tests then I'll create a pull request.
I've started on tests and found there's a problem exposed by some solutions (eg level 12 easy).
The water code broke something? Or you happened to notice that 12 easy is broken by something else?
I'm sure it's the water code. It's an out of bounds exception when checking for drowning. I thought maybe that I've got the x and y coordinates mixed up at some point or something.
This isn't Minecraft, but maybe it could get a little closer...
This is a discussion of water, how it affects rabbits and how it interacts with its surroundings.
I propose four water related states:
Water will follow a path according to the following rules:
Only solid blocks and ramps affect water - bridges have no impact.
Water movement/changes could either be at some speed, or instantaneous. I'm not sure how I feel about this.