Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (799)
Games in Android Showcase (236)
games submitted by our members
Games in WIP (865)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  How to simulate Electricity in Tile-based game  (Read 40028 times)
0 Members and 1 Guest are viewing this topic.
Offline JJengineering
« Posted 2014-10-18 17:09:32 »

Hello dear JGO-community  :)

I've been lurking around threads for quite time, but finally i need some personal advice, and i hope i chose the right place to post and/or do not violate any rules I may have overlooked.

I' ll try to keep it short and simple, so for my question:

First: I want to implement an 'electricity layer' in a tile based 2D game.(As model think of Terraria). In fact, the electric layer has a limited number of tile types , basically sorts of connections for instance: 'vertical' | 'horizontal' | '+' which is just a way of mapping the current from one tile to another. Kind of like its done in dwarf fortress.

Second: Then i have an object layer (i.e Entities with different Components) which both 'affect' the electric layer AND 'are affected' by the electric layer.
Eventually thers will be 1) Power sources (Batteries etc.) 2)Controllers (Buttons, Latches, etc.) 3)electric consumers(lights, etc).

I have tried some different things, which i dont think is worth explaining here.
So the issue i have is: However i do it, i need a way to update from:
1) the power sources -> towards -> 2) the switches etc -> towards -> 3) the elec. consumers

The stage where i am at now is that I thought of a 'Node based system', where an entity would be composed of in/ outputs and the create a node object for EVERY connection made. The way i visualize it, is the way 'Blender 3D' does it when connecting nodes in the nodes editor. I guess you know what i mean if you know blender.
I actually made some images explaining the case, but since i dont have a place to upload the images without making one more account on some site, i won't for now.

At last: I thought of having an 'impulse base system' , where i iterate all the power sources and send impulses from there to everything connected (over Nodes), but still, i cant think of a simple, linearly/update friendly way of doing it.

I think writing more would make my question only more complicated, so i'll leave it at that for now  :D

I hope/guess there is somebody who has some more experience in this sort of stuff ^^
Thank you very much in advance.

Greetings and all the best, JJ

(And off course i use LWJGL btw :P)

Offline matheus23

JGO Kernel


Medals: 138
Projects: 3


You think about my Avatar right now!


« Reply #1 - Posted 2014-10-18 19:53:43 »

Oh I like this kind of stuff Cheesy

I know it's kind of a different approach - not so simple, admittedly, but maybe you could try to use a cellular automata, for example Wireworld. It's not so much usable for energy than for information transmittion, but still, would kind of add an interesting twist to your game, similar to redstone in minecraft, maybe try that out Smiley

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #2 - Posted 2014-10-18 19:56:59 »

Love wireworld.

You could start with something like that because it's simple, and if you decide you like the aesthetic, keep it, otherwise go farther.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline JJengineering
« Reply #3 - Posted 2014-10-18 20:47:26 »

Wow, I didnt think anybody would answer this quickly Tongue

@matheus23
Thank you very much for the idea, allthough i looked at cellular automata as a whole, i always found it odd to use one.
Maybe it is just me but, if i look at a big tile map, and the cellular automata has to be fed with where the 'current comes from', what kind of tile it is and where the power should flow to, this technique seems like an obvious choice, but, other like in 'conways game of life' i couldnt just:
1)iterate over from am array start to finish and FLAG the changes accordingly and
2)iterate over again and actually APPLY the changes.
Because if i did that, there would be alot of unnessecary iteration to get the circuit to represent the right state , let alone the components Undecided.

Thank you very much again for pointing out wireworld Tongue i have to look into it to see if it is applicable in my case, from what i've read there are some things i didnt consider. but i guess if it is do-able in Minecraft, it should be manageable in 2D aswell Tongue

@BurntPizza
As i looked over a cellular automata, i thought it to be pretty simple, like: whats left?whats right? -> Do this. Seems easy Tongue
Actually the only reason i want to do it 'per tile' so to say, is because i want the connections to be breakable and mess up the circuits, and i love that stuff.
Sometimes in a simple tile-game, what i enjoy doing most is just placing and removing blocks, and looking at it ^^

Thank you both very much for the replies Smiley


Offline matheus23

JGO Kernel


Medals: 138
Projects: 3


You think about my Avatar right now!


« Reply #4 - Posted 2014-10-18 21:59:30 »

@matheus23
1)iterate over from am array start to finish and FLAG the changes accordingly and
2)iterate over again and actually APPLY the changes.

Two arrays: One for reading all the tile values, one for writing. Then swap them (double-buffering) Smiley
You only iterate once that way Smiley (swapping is almost costless Wink )

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline matheus23

JGO Kernel


Medals: 138
Projects: 3


You think about my Avatar right now!


« Reply #5 - Posted 2014-10-18 22:05:22 »

(shameless double-post)

Just found this, seems interesting: Wink
http://cell-auto.com/optimisation/#naive

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline JJengineering
« Reply #6 - Posted 2014-10-18 22:44:34 »

Your double buffer tip is one of the most simple and useful things i've come across in the last few months, i've never thougt of that :P
And believe me, i pounded my head against a lot off stuff lately, from java to crazy patterns to OpenGl, i feel like a hungry man starving in front of a huge menu list.

I guess it's all about choosing your own poison ^^

And thank you also for the link, i'll definitely look into that. (and also i'll spread the double buffering tip around, as if it was my own, too simple but so damn effective => genius)  ;D

Thank you so much again ^^, ridiculous how hard it can be at times to get around the most simple things.

Btw, nice looking RPG you have there :P (kinda feel like an account stalker)
Offline lcass
« Reply #7 - Posted 2014-10-22 18:45:26 »

Do you mean simulating it a bit like in the minecraft mod industrial craft 2? The key to something like that is to have a NET for the power , this is where you store all connections to the wire in a single grouping , meaning you can spread the power.
Offline JJengineering
« Reply #8 - Posted 2014-10-26 23:04:16 »

Hi :)

I just looked at what industrial craft 2 is, since i never heard of that mod before :P
But by what i read in 5 minutes, to post an answer quickly (sorry for the late answer), this seems to go in the direction I wanted,
since i am not at all a fan of cellular automata.

I will actually dig in if I can find anything explained on the industrial craft 2 site, but as it seems, you know about it allready :P
If you could, please point me in the right direction ? :P

I am making a fairly complex tile game, with many different layers, that use some kind of connectivity (water, electricity, pressure etc...) which should basically
be possible to be made with the same technique, but i havent figured it out yet.

What makes it worse, is that the different grids will have to affect each other, so doing it the cellular automata way yould be a painfull way (at least for me).

What do you mean by 'NET', i suppose you mean something different than a tile map as a 'net'?
I will also need some kind of 'power measure', like voltage, etc, you get the idea.
If you could explain the data structure behind it, that would be awesome.

It this something that is handled through sending 'packets' from entity to entity, and letting each type of entity handle the packet on its own?
And also, i was so concerned to find a way to iterate and actualize every state of the circuit components in one frame, but from what i've seen, games generally do that more 'randomly', every 50 ms or so.

I am really looking forward for your answer, since im heavily in the development, and smashed my head against it the last few days ^^

Thank you in advance! :)
Offline rv3392

Senior Devvie


Medals: 2
Projects: 2
Exp: 4 years


Programmer | Modder | Gamer


« Reply #9 - Posted 2014-10-27 05:19:05 »

You could try and find the source code for Indutrial Craft 2 or Thermal Expansion 4 (?), both mods for minecraft but with different power systems. Of course you won't be able to implement their methods directly but it would definitely help.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Grunnt

JGO Kernel


Medals: 143
Projects: 8
Exp: 5 years


Complex != complicated


« Reply #10 - Posted 2014-10-27 10:55:55 »

I've been thinking about a similar system for the power systems on my prototype ship design / shooter game. The general idea would be that energy flows from generators (optionally via buffers) to consumers.

The approach I'm now thinking of requires a simple algorithm to be run after a block/tile is placed or removed:
1. Start from one of the generators (does not matter which one). This will form an energy network, lets call it network "A".
2. Do a "fill" from the generator outwards along all tiles that conduct energy, and for each tile:
   - if a conduit (only function of which is conducting flow of energy) do nothing and continue the fill
   - if generator, buffer or consumer, assign it to this network (say set attribute network="A")
3. Repeat from 1 for each generator that is not in a network yet untill all generators are assigned (creating network "B", "C" etc)

In addition, my plan is to construct a graph of connected nodes for each network while the above algorithm is running. The graph's "roots" would be generators, the leaves would be consumers, and in between could be buffers in any configuration (i guess there also could be switches etc).
A simple network could be:
1  
2  
3  
4  
5  
          Producer   Producer
             |          |
           Buffer       |
            /  \       /
     Consumer   Consumer


Energy flows from the top to the bottom. One consumer would then receive energy from both producers, with one source buffered (if consumption is lower than production), and the other consumer would only receive buffered energy from a single producer.

Constructing such a energy network graph would be somewhat expensive, but would only be needed during construction (or destruction, heh) time, whenever the network could be altered. Simulating the network operation would be much faster, as it would be a matter of following the graph from producers to consumers.

Anyway, I have no idea if you are thinking along these lines, but maybe it is of some us to you.

Offline JJengineering
« Reply #11 - Posted 2014-10-27 13:07:14 »

Hi Grunnt :P

I see similarities in our line of thinking, and also your ship design/shooter , does have some components of what i am trying to achieve (customizable ships, ship steering and collision , torque etc).

I tried to make a circuit work like :
Iterate each power source -> output to the wires around it (by a method) and use and open/closed list -> then let every wire/component handle the maping aka. forwarding of the impulse itsel -> do it again.
But the problem was that i would have to 'tag' the connections between the wires and components, input/output/reserved etc.(too nasty for me)

But for the last 2 hours i tried to figure out a way, to implement a 'shoot and forget' method, so that components just emit 'events' and receive callbacks (i hate the word event for this but you get the idea), and the iterate every 50 ms, then set the states.(which i refer to as 'impulse' based)

Could you please explain me how, you would 'save' trees and connections like that, i mean design-whise AND java-whise, to be able to iterate it in a previously calculated manner? I would prefer, designing a pain in the *** node system, that i could then update properly, but i didnt get my head around it :P
I love the idea to work with nodes though, it gives me something visual, and actually, a graph would be a great feature to expand upon this.

Thank you very very much for your time, I'm looking forward for your tips :P

Btw, i might have to investigate your technique for thrusting and torque calculation on tile based space ships later on :P
Offline Grunnt

JGO Kernel


Medals: 143
Projects: 8
Exp: 5 years


Complex != complicated


« Reply #12 - Posted 2014-10-27 19:05:21 »

I haven't 100% worked it out yet, so it may be a little time until I got a system working. The idea of creating a seperate model for the energy (/ electricity) network is that you can make it much simpler by removing all non-functional blocks in between producers and consumers and directly link those. Then I'll go from consumer to producer, moving energy one step (node) at a time.

Unfortunately, I haven't figured it out in enough detail yet to give you really helpful examples.

The idea is somewhat inspired by how Creeper World 3 transmits energy "pulses". A cool game, by the way.

Btw, i might have to investigate your technique for thrusting and torque calculation on tile based space ships later on Tongue

For the thrust and torque I just use Box2D (in LibGDX) with a little custom code for generating the Box2D shapes based on the ship tiles and for applying force on the location of the tiles that contain thrusters. The shape generation code is pretty simple, but works well (I go through the grid line by line and create square shapes basically, then add each square shape to the ship body).

Offline Phibedy

Senior Devvie


Medals: 9



« Reply #13 - Posted 2014-10-27 19:40:04 »

Havent read everything and maybe it's just me but I wouldn't use an array.
If you have only some little parts of your map powered by elec. you would have huge arrays for nothing and you would need to iterate over them. In addition, if you dont want the whole map to be loaded as it's to big, you would run into problems like minecraft has.
For small elec. I would go for some tree-map-structured object Smiley
Offline JJengineering
« Reply #14 - Posted 2014-10-27 22:16:32 »

I haven't 100% worked it out yet, so it may be a little time until I got a system working. The idea of creating a seperate model for the energy (/ electricity) network is that you can make it much simpler by removing all non-functional blocks in between producers and consumers and directly link those. Then I'll go from consumer to producer, moving energy one step (node) at a time.

You are definitely right about removing the non-functional blocks, should be hard to get there, but once it works, i think i'll be the easiest, especially performance-whise.
I'll work on it anyway, and maybe update you on what i got, since i pretty much need it to work yesterday ^^

I looked a little close into the 'industrial craf7t 2' mod for minecraft, actually seems to be something complex..... But i havent found information about how it works yet.
If one of you, knows where the mod is explained (for programmers, not just how the blocks work,), please let me know :P

Thank you again for the quick answer,  i'm always slower in answering :)

Concerning the thruster and torque, I actually wanted to do it the hard way, with SAT collision detection, but somehow i feel, i should really be using Box2D :)
Offline JJengineering
« Reply #15 - Posted 2014-10-27 22:36:42 »

If you have only some little parts of your map powered by elec. you would have huge arrays for nothing and you would need to iterate over them. In addition, if you dont want the whole map to be loaded as it's to big, you would run into problems like minecraft has.

If not many components are used, that is off course true, i would still need to buffer every used object instead of iterating everything blindly, thats why some kind of 'node map' would be great.
If you know any documentation (link to it) on mapping stuff like that, i.e. generating and using them, that would be reaaally helpfull :)
Somehow, i have a few pages on paper full of topics, techniques, programming, OpenGl, links ..... there is no end.
Programming a game,if you want to do it yourself, seems to be the biggest hole i ever fell in :P.
This is a topic, i can add to my list ^^

I remember the day i was able to get a sprite on screen, and i thought, 'YES, now i can finally programm a damn game' (i actually thought, i was at the end of the tunnel^^)

And also thank you for the answer :)
Offline Grunnt

JGO Kernel


Medals: 143
Projects: 8
Exp: 5 years


Complex != complicated


« Reply #16 - Posted 2014-10-28 11:14:32 »

There's topics that are easy and topics that are hard. I think physics is generally a pretty difficult topic to do yourself, and I guess making somewhat realistic simulations of electrical networks is also pretty hard stuff.

I have now settled on an even simpler system: each seperate network of generators, consumers, buffers and conduits is collectively an "EnergyNetwork". For simulation I do not take the structure of the network into account, I just simply calculate total production, consumption and buffering of the entire network. If there is enough energy generated or buffered then all consumers work at 100% effectiveness, if it is less, then effectiveness goes down. Effectiveness is a variable that I then use when calculating things like generated thrust or torque.

Updating the network is then quite simple:
1. add generated energy to buffer
2. calculate total energy needed by all consumers in the network (buffer capacity and production output is stable as long as the network does not change)
3. if energy-need <= buffered-energy then effectiveness = 1
   else effectiveness = buffererd-energy / energy-need (if energy-need > 0)
4. subtract consumed energy from buffered energy (check if buffer is not < 0 or > max capacity)

And that's basically it. It's not useable for things like switches etc, though.

Creating the network is done using a "flood fill", starting from each generator in the grid. Every grid tile has a "visited" boolean that I use in the flood fill. So:
1. Clear "visited" flag of all cells
2. Go through entire grid, add all generators to a stack (or LibGDX Array)
3. while stack is not empty
    - pop topmost generator from stack
    - if generator is not yet visited, buildnetwork(generator)

The buildnetwork(generator) function then does the following:
1. Create a stack of cells to visit (visitStack)
2. Add the generator to the visitStack
3. While visitStack is not empty
   - pop topmost cell from visitStack
   - is the current cell not visited yet and an energy cell? (i.e. conduit to energy, producer, consumer or buffer?)
   - if true
     - add all surrounding cells (not outside grid ofcourse) to visitStack
     - add energy production, buffer size to totals in EnergyNetwork
     - add consumer cells to a list of consumers to quickly calculate energy consumption (which is dynamic since thrusters, etc may be on or off)
   - mark cell as visited

You can find more about this if you look into "flood fill" as a search term. This may not be what you are looking for, but I thought I'd share what approach I'm taking now.

Offline JJengineering
« Reply #17 - Posted 2014-10-28 22:47:55 »

Hey Grunnt :P

Nice idea, (I like the way you approach the problem in a 'generalized' manner), and, if you dont need/want certain functionality, one does not need to work hard on something, that will probably never be needed :P
And thank you very much for sharing your techniques! Interesting stuff :P

I was grinding the internet the whole day, and i think i've come up with a very performant, simple technique, that will work for pretty much everything(power sources, switches etc).
It is basically a node tree, and when using recursion(allthough i still have to find out why recursion is told, to be such a 'bad' thing to do ? Oo ), the thing is updated very easily.
And then i think it is pretty simple to add functionality, so that only necessary updates are performed.

Actually, you put me on the node/tree thing, since i never considered it to be an option before :), so credits to you.

I'll be working on it tomorrow, and i'll let you know when i have some results, and since it is tile based, i have to come up with an 'extendable way', to code new components, and simply add them as such, and also map them to each other so that i get the full advantage of a node tree.

I worked with LibGDX for a while, but never used anything besides the sprite batcher, LibGDX seems to become quite fancy and really powerfull!?

Greetings and all the best, i'll try to post some results tomorrow :)
Offline Grunnt

JGO Kernel


Medals: 143
Projects: 8
Exp: 5 years


Complex != complicated


« Reply #18 - Posted 2014-10-29 09:59:13 »

I was grinding the internet the whole day, and i think i've come up with a very performant, simple technique, that will work for pretty much everything(power sources, switches etc).
It is basically a node tree, and when using recursion(allthough i still have to find out why recursion is told, to be such a 'bad' thing to do ? Oo )

There is nothing wrong with recursion in itself, it can be a quite elegant solution to many problems. However, the issue with recursion is that for each recursive call, some things get stored on the stack (a piece of memory where local variables are stored). So if you do many recursive calls (e.g. because you are parsing a large tiled grid using this approach) you may run out of stack memory and get exceptions.

So if you want to use recursion, you should be aware of this and ensure that there is an acceptable maximum "depth" of recursion. This means that the size of electricity networks must be limited somehow.

Offline Springrbua
« Reply #19 - Posted 2014-10-29 10:24:36 »

I followed this thread since its beginning cause i am interested in this system to. 
I have seen your node tree solution and i found a possible problem (maybe i only missunderstood the solution...): 
What if the Network looks something like this: 

            Generator(1)
                 |     Generator(2)
                / \        |       
               /   \____/\
    Consumer(1)        \
                          Consumer(2)


Will the Generator(2) affect the Consumer(1)? For example if the Consumer(1) does consume more, then the Generator(1) produces, will it take some power of the Generator(2)? 
Will the Generator(1) affect the Consumer(2)? For example if the Consumer(2) does consume more, then the Generator(2) produces, will it take some power of the Generator(1)?

If both questions are true, the Connection between Generator(1) and Generator(2) will be bi-directional, is that possible with the Node-Tree-Solution?
Offline Grunnt

JGO Kernel


Medals: 143
Projects: 8
Exp: 5 years


Complex != complicated


« Reply #20 - Posted 2014-10-29 11:53:15 »

I have seen your node tree solution and i found a possible problem

Good point. I think it just depends on how you process the node tree. My plan was originally (before I thought of using a much simplified model) to go through the tree from consumers to producers ("upstream" if you like). Each move up the tree I would check the incoming energy (which may be from multiple sources/blocks) and outgoing energy (also possibly from multiple sources/blocks), and make some "smart" decision about that.

Will the Generator(2) affect the Consumer(1)? For example if the Consumer(1) does consume more, then the Generator(1) produces, will it take some power of the Generator(2)?

If consumer(1) knows about both Generator(1) and Generator(2) then a rule could for example be that it will take 50% from generator (1) and 50% from generator(2), or more if any of the generators is unable to supply 50%.

Will the Generator(1) affect the Consumer(2)? For example if the Consumer(2) does consume more, then the Generator(2) produces, will it take some power of the Generator(1)?

Same as the above. I was thinking of doing this by moving all energy one "step" from generators to consumers during one update of the network. The interval between updates would then influence how fast energy would move. With electricity, however, this is pretty much instant, so maybe it will not work well then.

Offline Springrbua
« Reply #21 - Posted 2014-10-29 12:41:05 »

But when you step from consumer to producer, the consumer does not know how much power the generator produces. Also the nodes between the generator and the consumer don't know the "power-level" of the network, except the node right next to the generator and the generator itself. 
Also, as you are processing backwards, you only know about the next (or previous as it is up or backstream) nodes power-level, but not about other nodes, which may consume from that node, so you don't know the exact power you will receive. 

A posible solution i had in mind, before reading the tree-node solution, had more or less the same problem: 
You have the electricity layer, as the op said. If you add or change an electric element, check all its neighbors on the electricity layer and if there is any other electric component (generator, consumer, switch etc.) and update them. Do the same for all those nodes. 
So if you add a generator (for example) check its neighbor tiles. 
If there is one or more connection or consumer, add the generators "power level" (or part of its "power level") to the connection/consumers "power level". If the neighbor is a consumer, you can stop, as a consumer does not affect other nodes. If it is a connection, update its neighbors with the new power level.
Offline matheus23

JGO Kernel


Medals: 138
Projects: 3


You think about my Avatar right now!


« Reply #22 - Posted 2014-10-29 12:47:13 »

Just think of it this way:
One node system has energy storage that is the energy storage of all things connected to this system combined.
A consumer can request energy from the system, and if it does, the system has to decide how: There are a couple of possible options. (We'll get to this in the example)
A producer simply produces energy and stores that energy in it's local energy storage.

So for example, you have consumer 1 and consumer 2, as well as producer 1 and 2 connected to the same network.
producer 1 and 2 have a 20k energy storage. So the system has 40k energy storage in total.
When one of the consumers request 40 energy, the system could do 2 different things: It could drain the energy storage of producer 1 by 40 energy, or split the energy request to all the energy sources and take 20 energy of each, though this might be harder since you can't always drain all the generators (if one is a little empty for example). (Like Grunnt sugessted).

You could also make this configureable for the user. So they tell you which energy sources should be drained first, etc.


I wouldn't implement that with any node-tree system. My system would simply be implemented with two arrays containing the Consumers and Producers:
1  
2  
3  
4  
public class EnergySystem {
  private final ArrayList<Consumer> consumers;
  private final ArrayList<Producer> producers;
}


And if you build a wire that is not connected to anything, that creates a new EnergySystem.
If you connect a wire to a wire, that wire is going to take the EnergySystem of the wire it's connected to.
If you connect a wire to two or more wires, that wire merges the EnergySystem of all the wires it was connected to.
If you connect a consumer or producer to a wire, it's added to the array of the EnergySystem.
If you remove a wire, you need to split the Energy system. Thats the only thing that might be a little tricky Smiley

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline Grunnt

JGO Kernel


Medals: 143
Projects: 8
Exp: 5 years


Complex != complicated


« Reply #23 - Posted 2014-10-29 13:07:21 »

I wouldn't implement that with any node-tree system. My system would simply be implemented with two arrays containing the Consumers and Producers:
1  
2  
3  
4  
public class EnergySystem {
  private final ArrayList<Consumer> consumers;
  private final ArrayList<Producer> producers;
}


And if you build a wire that is not connected to anything, that creates a new EnergySystem.
If you connect a wire to a wire, that wire is going to take the EnergySystem of the wire it's connected to.
If you connect a wire to two or more wires, that wire merges the EnergySystem of all the wires it was connected to.
If you connect a consumer or producer to a wire, it's added to the array of the EnergySystem.
If you remove a wire, you need to split the Energy system. Thats the only thing that might be a little tricky Smiley

Yeah that's precisely what I'm doing. Splitting energy systems is indeed a bit of an issue, but it's pretty easy to update the networks using a flood fill search.

Offline Springrbua
« Reply #24 - Posted 2014-10-29 13:33:58 »

Wow a real simple approach, but it is not applicable in the situation, where you want to have energy-loss over the way.
So lets say every 5 tiles the enery-level falls by 1, the way the energy takes would matter and therefore you cannot have a network with energy produced and consumed, but you need to store the energy for every part of that network. 
Also with this simple approach it wouldn't be possible (or at least not easy) to have a network with diodes (or One-Way cables), which would allow the network part of one side to affect the networkpart at the other side, but not vice versa.

Anyways, i really like this approach, it will be working for many (or even most) energysystems. The splitting of the network will need some calculations (worst case: recalculate the whole network), but i guess it is stil easier then implementing a tree-node system Tongue
Offline JJengineering
« Reply #25 - Posted 2014-10-29 14:41:05 »

Wow you guys put some thought into that :P

Edit:Could someone please tell me how to put code snippets in my posts, i tried some html tags (code, pre), but none worked :/
I want my posts to look cleaner.

Quote
There is nothing wrong with recursion in itself, it can be a quite elegant solution to many problems. However, the issue with recursion is that for each recursive call, some things get stored on the stack (a piece of memory where local variables are stored). So if you do many recursive calls (e.g. because you are parsing a large tiled grid using this approach) you may run out of stack memory and get exceptions.

So if you want to use recursion, you should be aware of this and ensure that there is an acceptable maximum "depth" of recursion. This means that the size of electricity networks must be limited somehow.

I heard of the stack issue but never thought that i would be an actual issue, as i thought it would be very hard to actually run out of memory. Do you know some numbers, or a way to check how much is possible?
Also, a node tree is of what i understood, An object (parent), that contains (one, two, or more) children, and the children have children again etc.
To me it seems like composition of objects.

So if i had an interface which every electric component implements, let's say with the method impulse(): To run through the components i just had to call =>

Battery-> impulse child -> impulse child -> and so on, it would be the same method name, but not really recursion(it would be the implemented method of another object), since in fact i would just run through the objects in a direct manner, and the method in the Battery component would not be calling itself again.
In this case, this seems like the most optimal way to 'flood-fill' the circuit. There would be basically no wasted method calls at all, depending on how it is done.

And this way I could easily implement an internal mapping/rules, of where the impulse should flow to, based on states etc.
So it would be easy to add new features, and even a bit more complex stuff like 'internal circuits'(ic's);
Is there any issue with the stack memory then? (Like in the next example)
Edit: I read a little about heap,stack etc: If there are no local variables (which I avoid 99.999% in methods), there would/should be no problem in in recursive methods, even if they run thousands of times. Or am i wrong?(Memory, is still totally alien for me :/ )

(Please excuse my pseudo code)
Update circuit => Battery.emitImpulse() -> Battery.cableNode.impulse() -> Cable.switchNode.impulse() -> Switch.ConsumerNode.impulse() -> etc

I dont know how it could be more efficient, plus, it could easily be saved until the next iteration, and only had to be overwritten while passing impulses around.(if desired)
                  
I like the idea of all your methods, (and btw thank you for sharing it and beeing patient ^^), especially that you keep track of the differrent objects in different arrays.
I will also implement a method to acces/save different object/component types in different arrays, because i will eventually need to order them by type.

And what i havent understood, or simply didnt see it in all your answers(excuse me if that is the case), how do you actually iterate your components, as you said a flood-fill, since you would use array, are you connecting it via meta-objects(like nodes) or by index or something ? :P

In this case i though a tilemap would make it easier, but as it seems, for once, a tile map actually makes it harder :P (At least for me)

Thank you guys again very, very much for the help and suggestions! <3
(Including answering some of my noob questions => going to read up some java memory/stack stuff)
Offline Springrbua
« Reply #26 - Posted 2014-10-29 15:08:55 »

Well, as i take a look at the solutions we came up with here, i see, that some of them face different kinds of electricity networks (at least 2). 

Think about minecrafts redstone, which is some kind of electricity. The signal strength goes down every block, until it reaches zero. 
With @matheus23 energysystem method that wouldn't be possible. 

Now instead think about a lossless system, where every generator/producer feeds the whole network and every consumer takes energy from the network. 
This is not possible with @JJengineering mehtod, as the tree is monodirectional. Take the case i wrote before:
Quote
            Generator(1)
                 |     Generator(2)
                / \        |       
               /   \____/\ (*)
    Consumer(1)        \
                          Consumer(2)

There the Consumer(1) one would not know about the Generator(2), as it is connected to a childnode of Consumer(1)s parent and you iterate from parent to child. 
So this network would result in  something like: 
Generator(1) feeds Consumer(1)
Generator(1) feeds Consumer(2) if the connection (*) allowes it (is it a child or a parent of the previous connection?) 
Generator(2) feeds Consumer(2) only.
Offline Riven
Administrator

« JGO Overlord »


Medals: 1370
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #27 - Posted 2014-10-29 15:38:53 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
public class Wire {
   public final Node a, b;

   public Wire(Node a, Node b) {
      this.a = a;
      this.b = b;
      a.wires.add(this);
      b.wires.add(this);
   }

   public void cut() {
      a.wires.remove(this);
      b.wires.remove(this);
   }
}

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
import java.util.ArrayList;
import java.util.List;

public class Node {
   public int energy;
   public int capacity;

   public List<Wire> wires = new ArrayList<>();

   public void tick() {
      if (energy == 0 || wires.isEmpty())
         return;

      while (true) {
         Node target = null;
         for (Wire wire : wires) {
            Node remote = (wire.a != this) ? wire.a : wire.b;
            if (remote.energy == remote.capacity)
               continue; // remote node is full
            if (remote.energy >= this.energy)
               continue; // cannot spread against a voltage potential
            if (target == null || remote.energy < target.energy)
               target = remote; // we found a new target
         }
         if (target == null)
            return;

         this.energy -= 1;
         target.energy += 1;
      }
   }
}


A generator is a Node:
1  
2  
3  
4  
5  
6  
7  
8  
9  
public class Generator extends Node {
   public int production = 100;

   public void tick() {
      energy = Math.min(energy + production, capacity);

      super.tick();
   }
}


A consumer is a Node:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
public class Consumer extends Node {
   public int demand = 33;

   public void tick() {
      int taken = Math.min(demand, energy);
      energy -= taken;
      if(taken < demand) {
         // make something crash and burn
      }

      super.tick();
}


Generate, spread & consume electricity:
1  
2  
3  
for(Node node: world.nodes) {
   node.tick();
}

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline JJengineering
« Reply #28 - Posted 2014-10-29 15:42:00 »

@Springrbua I see what issue you are pointing out.

You are certainly right about that, and what i would do about it is a little more complex than a simple iteration from Parent to child on each node.

I think of each component, to have inputs and outputs. (which is the part of the hole thing im trying to figure out atm)
Also, i'll have to limit impulses in case where for instance: a generator is connected to another generator over a cable.
I'll map a generator's output to a cable and then define that cable node as 'input' and the other side as output as needed, if the outputs of two generators are connected through one cable, thats is for instance a case where nothing should happen, or some sort of event (fire, breaking components etc).

When other people play my game, they cant know what works and what doesnt, that makes it all even worse.

So i will need a mapping of inputs and outputs.

So you are absolutely right, these are some issues aswell (pretty big ones even), but i think when one has the right data structure of classes and mapping of the components and all the different cases, that should be doable.( I wich i could brainstorm and just throw an adjsuted technique in here, but for that i need some hours with a pen and paper :P )
Offline Riven
Administrator

« JGO Overlord »


Medals: 1370
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #29 - Posted 2014-10-29 15:44:09 »

The 'beauty' of my design is that it models reality (although in reality it converges to a solution much quicker), is trivial, and just works, no matter how complex your scene.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Pages: [1] 2
  ignore  |  Print  
 
 

 
Riven (183 views)
2019-09-04 15:33:17

hadezbladez (4859 views)
2018-11-16 13:46:03

hadezbladez (1783 views)
2018-11-16 13:41:33

hadezbladez (5131 views)
2018-11-16 13:35:35

hadezbladez (1013 views)
2018-11-16 13:32:03

EgonOlsen (4365 views)
2018-06-10 19:43:48

EgonOlsen (5213 views)
2018-06-10 19:43:44

EgonOlsen (2940 views)
2018-06-10 19:43:20

DesertCoockie (3865 views)
2018-05-13 18:23:11

nelsongames (4290 views)
2018-04-24 18:15:36
Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08

Deployment and Packaging
by gouessej
2018-08-22 08:03:45
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!