• Advertisement


  • Content count

  • Joined

  • Last visited

Community Reputation

253 Neutral

About nullbear

  • Rank

Personal Information

  • Interests
  1. As part of one of my projects, there is a /chemistry/ simulator. It's not intended to be exact to real-life chemistry, but is still a fair bit more complex than just "A + B = C" This is being done in an Object-Oriented programming language similar to java and c#. Some background:  Before I started working on the project: The container was an instantiated object. It contained a variable, with an array of instantiated chemicals that *existed in the container*. The chemicals themselves were instantiated objects, with a reference to their container, and a volume. Whenever the container was interacted with, (such as a new chemical added), the function would instantiate a new chemical, add linking references, and update the volume of the chemical. Then it would iterate through *EVERY* chemical in the container to check for possible reactions using a lookup table, and if a match was found, it would run the reaction, and restart. This included a potential for infinitely 'reacting' chemicals, but the workaround was just careful implementation of recipes to prevent infinite loops. ---------------------------------- Now i saw this, and was absolutely disgusted. And changed it to something more akin to:   In this model, the container has a 2D array of the chemical, and it's volume inside of the container. The chemical is only ever instantiated ONCE, and if a chemical is accessed, the properties of the master chemical are read. (Each unique chemical has static properties in both models, and the only dynamic variable was *volume*) Then when the contents of the container are modified, it is *flagged* to receive an update, iterates through the contents, performs all currently possible reactions unless that reaction was already performed during this update. If any reactions occured, it would flag the container to be updated *next* process. This removed the potential for problems caused be recursive reactions, but prevented instantaneous consecutive reactions. ----------------- The problem! NOW, i want to add some more realism and complexity to the system, as well as make it more efficient if possible. I want to iterate as infrequently as possible. containers now store the following variables and properties regarding its chemical contents: Quantity - The quantity of a chemical within. Equivalent to moles. Thermal Energy - The total thermal energy of chemicals within. Equivalent to joules. Volume - The volume of the container. This is the *SAME* as the total volume of the container's contents. But the volume of each chemical should also be tracked separately. ie. 50 unit container contains 30 units of AIR and 1 unit of OIL and 19 units of WATER. This should be calculated based on the quantity of each substance in the container, the temperature, and the total volume of the container. As well as some data based on the individual chemical's properties. Temperature - This is calculated based on the thermal energy, and the chemical properties of the chemicals within. (IE. Temperature = Total thermal energy / Total specific heat capacity of chemicals.) Pressure - This is calculated based on volume, temperature, quantity, and some chemical properties. ---------- What is the most efficient way for me to *add* or *remove* a chemical from the container? For example "I add 30 units of water. This displaces the gas in the container, and modifies the specific heat and thermal energy of the container. As a result, modifying the temperature, volume, and pressure of the container contents."  How can i adjust all relevant container values using *just* the values before the water is added, and the properties of the water? What additional information might i need to store?  The volume of the contents of the container is *ALWAYS* equal to the volume of the container. This means that if the container is sealed, and contains 30 units of water @ standard temperature, but the volume of the container is *larger* than the volume of liquid water. How do i find the equilibrium point for the volume of *liquid* water and water *vapour* using only temperature, quantity, total volume, and a single extra variable/coefficient for vapour pressure? How do i quickly and efficiently calculate that, when there are say, n other chemicals inside the container with different properties, that also need to be in equilibrium? --- Are there any faster and more efficient methods i can use to look-up all possible reaction matches, and perform the reactions, so that the reactions are in equilibrium? IE if i have : "1 water + 1 agent A = volatile acid" and "1 water + 1 agent B = volatile explosive" in the recipe list, and i have: "1 water, 1 agent A, and 1 agent B" in the container, How can i make sure that i end up with 25% acid, 25% explosive, 25% A, 25% B, instead of 50% acid, 50% agent B, with as few iterations as possible? In the case that "acid" and "explosive" react together to form 3 parts agent C and 1 part water, How can i make the reaction find equilibrium in only one update, with as few iterations as possible? 
  2. New to Pixel Animation Need Critique

    The pixel art looks pretty decent, and the animation itself is decent as well. It's much better than *most*  all beginners i've seen take their shot at it. dbaumgart has good advice. I can see a jump in animation from what i assume is the end of the animation, and where it loops back to the start. I recommend using software that allows for onion-skinning between the first and last frames of the animation. A core value of animation is *keyframes*. You can probably just google that to find better suited tutorials on what it is and how to do it, but i'll summarize: Start by focussing on the important parts of the animation. For walking, you've got: "Standing" "Raising First foot" "First step."  "Raising Second foot" "Second Step" "Intermediate Loop" "Last Step / Transition to Standing" In your animation i can see that your character is using your base *standing* frame as part of the animation. But people do not *take a step* then stand still before taking another step. You must transition into walking, walk, and then finally transition into standing when you are NO LONGER WALKING, in order for the animation to look more natural. If this is for a game, this makes up 3 animations in total, two of them being a transition between walking and standing. Your key poses do not need to *flow* very well. The goal is for the FRAME to look like they are taking a step. Not the animation as a whole. At the same time it should not be a hugely jarring change from the keyframe before it. Once you have your keyframes, add a few frames in between each of them *as needed* in order to make for a smooth transition between each keyframe. If my keyframes are: || and =, and the two lines are rotating, i would add // in between the two. Feel free to adjust your keyframes and transition frames as needed to make them look more natural. For a walk cycle, timing is important.  It's good to see that you are animating the entire body, many people fail to do that, and animate only the legs.  But you still seem to be animating the body separately from the legs. Think about anatomy, and how your limbs are connected, and center of gravity shifts as you walk. Your legs should not 'get longer' when stepping, and 'get shorter' when standing.   
  3. Exit to main menu after cinematic. Unlock bonus levels / content / challenges. Ithe cinematic and quit-to-menu is a tried-and-true method of telling the player that the game has been completed. Bonus content/levels offers some replayability to the game, and can allow for new mechanics to be added that may not have fit in the original game. A *time race* or *death count* scoreboard showing the players fastest completion of the standard levels. This is probably the simplest way to add replayability without actually adding any new content to the game. New levels, or harder optional levels that are unlocked after completing the game. If you show these as an inaccessible option on the menu, it actually incentivizes completion of the game. Alternatively, options for changing the mechanics of the original game. Such as 'low gravity' or 'the floor is lava', or 'you can shoot the hazards' etcetera. make sure that the game is still completeable with the modifications of course. Bonus content. Again, showing, but not allowing access to this, can incentivize completion of the game to players. If your game is artistically focused, or story focused, this bonus content could be as simple as *here's some related drawings and storyline or lore* Bonus content to A DIFFERENT GAME. This can incentivize players to complete the game, and *ALSO* incentivizes them to play other games you have made. For example, if completing one game gives you a 'code' to unlock a new campaign in your other game, players are more likely to play that other game so that they can use the content they unlocked. As well, players of the *other* game are also more likely to play *this* game so that they can unlock the additional content. This is free exposure and advertisement of your other products, and more revenue if they are paid games. Don't abuse this though, the bonus content should actually be something the players look forward to and enjoy, not tricking them into playing your other game, only to be disappointed by the content.
  4. Flanking. Focus on flanking. If the player runs, his back is turned, and he will take extra damage from the enemy. This could alternatively be *the enemy uses a different attack when the players back is turned*, such as a cinematic nearly/completely instakilling backstab. This alternative punishes the player for running, and helps lead them towards understanding that they are intended to face the enemy head-on, and find an alternative, non-kiting, non-fleeing, method of taking it on. If the player runs towards (and behind) the enemy, he will be able to *AVOID* being hit, and also deal more damage to the enemy. If the enemy turns slowly, this gives the player a bigger advantage to flanking, and it is easier to flank. Placing a high-contrast element on the back of the enemy will make a very clear *this is my weak spot*. The weak spot will not be apparant to first-encounter players because the back is likely hidden to the player unless the player runs to the other side of them (towards, but behind.) This fixes your unintentional *autocombat* issue. As the player must be repeatedly actively moving in order to be able to avoid being hit, and hit the enemy in return. Facing the enemy head-on reduces damage, as opposed to running away from them (and being stabbed in the back.) This encourages players to fight the enemy in a certain way, and punishes running. Depending on what you would like, the enemy can either take reduced damage, or be completely immune to damage, when attacked head-on. If feedback is provided to the player that the enemy takes damage when attacked head-on, it will likely take longer for them to figure out that they need to attack the enemy from behind. On the contrary, if feedback is provided to the player that makes it clear that the enemy is *immune* to being injured by the player, this encourages the player to find other ways of attacking the enemy, and tells the player that there is a *trick* to it, or a *weak spot* that must be targetted.  
  5. There are 3 common accuracy/dodge mechanics i often see in games, electronic, tabletop, or otherwise. 1. The simplest to understand from a laymans perspective: Accuracy/Dodge %. The percent chance to hit is equal to accuracy %. You roll a 'random' and then you either hit, or you miss. Dodge is usually factored into this.The net/total accuracy is equal to a factor of base accuracy and target's dodge. this can be either a sum: "90A - 10D = 80% chance" or a multiplication: "90A * 0.9(dodge coefficient is 10%) = 81% chance to hit." In both instances there can be an issue of scaling. As in 0% chance to hit, ever. As in "my dodge chance is 100% so no matter how accurate you are you will never hit me". or "my accuracy is over 100% so no matter your dodge i will always hit you". Many games get around this by setting limits. But this limits player customizeation and specialization. IE. *i wanted a character really good at dodging, but the game limits my build". The limit can be a form of "maximum dodge % is 90%" or "there is always a minimum of 10% chance to hit, or 1% chance to dodge". In my experience, the latter is more enjoyable limit. Even assuming that you do not implement a limit, the limit is implicit, and will always be *anyone with more than X accuracy over you will always hit, and anyone with X dodge over you will always dodge* An example of which is *critical hit/critical miss* rolls in a game, where even if you would normally have 0% chance to hit, if you score a critical hit, you are guaranteed to hit. 2. Simple to implement, but a little less user-friendly: DND style AC/to-hit. Whether or not this system is easy for players to understand or not depends on the player. How DnD handles armor, and accuracy, is You have a number that represents your ability to avoid being hit and taking damage: AC This number is compared against the attacker's "to-hit" number, and a dice roll. Usually the attacker has a base to-hit, and then a random factor to it. If your attacker has a base to-hit of 10, and you have an ac of 15, the attacker needs to roll a 5 or more in order to hit you. DnD uses a 20 sided die, and so increments in amounts of 5%. This means that if the attacker rolls between 1 and 5, they will *miss*, and if they roll between 5 and 20, they will *hit*. 1 being an automatic miss, 20 being grounds for a critical hit. In this system, it scales linearly. If your AC is equal or greater than 20 points higher than the attackers base-to-hit, they will miss 95% of the time. Any AC *above* this number is redundant. And on the contrary, any base to-hit above your target's AC, is redundant, as you will always hit anyways. This system allows for reasonably fair linear scaling in a way that you do not become invincible, and higher stat characters have an advantage over lower ones, but they are still susceptable to being injured by higher-level enemies. 3. Infinitely Scaling Accuracy/Dodge. In this system, your *chance to hit* is your "accuracy" divided by the target's dodge. (A/D) = H% This system is intuitive, scaleable, and simple to implement. In this situation, if your accuracy is equal to or more than your target's dodge, you have a 100% chance to hit them. The higher your dodge is, the less likely you are to become hit, but unless the enemies accuracy is zero, there will *always* be a chance for them to hit, however small. If you have 40 dodge, and the attacker has 10 accuracy, they have a 25% chance to hit. If you have 100000 dodge, and they have a meager 1 accuracy, they still have a 1 in 100 thousand chance to hit you.  The problem with this design is that if an enemy has a high enough accuracy, they will *always* be able to hit you, and your dodge ability will be worthless. To remedy this a good method is to use a hybrid system with one or more of the above, or a critical hit/fail for dodging and hitting. My personal favourite is: A/D  = H% WITH A MIN and MAX OF: "0% + 1/(D-A)" and "100% - 1/(A-D)" (i think?) so that even if you have 10000 dodge, and your enemy has 10000 accuracy, your investment into dodge is not wasted, and increasing your dodge / accuracy never becomes redundant, there are just diminishing returns. The formulas i've provided are probably inefficient or nonsimplified etc. I know that, im just too lazy and my brain is too tired to fix it.
  6. Sorry, it would probably be more efficient to say, having a cached/precalculated list of 'crossed tile' coords, for a given SIN/COS/TAN value. So it's more to do with optimizing trigonometric functions than raycasting.   I am casting ~200 rays per update, per raycasting object, of which there are many (honestly haven't counted it yet. But at least one thousand.). My grid is 51x51 tiles, and the object is always centered  at 26, 26 in the grid, so i only need to have 1 octant cached. (or angles from 0 degrees to 45 degrees/tan <= 1) Updates occur 10 times per second. So yeah, the question is moreso: Is using a cached lookup table of the possible values given x, for trigonometric functions faster than calling those functions >200k times per update?  
  7. @lawnjelly the graphics calculations aren't a concern at all. The intensive bit is the mixing and equalizing of data between cells. It's called about twice per second. (it is a 'passive' fluid simulation for a game, though typically gasses as opposed to liquids.) @norman barrows: Yes, i know what it is. I'm just not sure how to quickly and efficiently do it on a potentially large scale. I've explained that it's for fluid simulation, typically of gasses. Here is an example of what you might see:   21 moles of oxygen, 80 moles of nitrogen, at 20 degrees celsius in 'group A' 100 moles of carbon dioxide, at 1000 degrees celsius, in 'group B' Not only are we spreading the molar count evenly between the tiles, but also the temperature (which affects the pressure of the fluid, and thus the rate at which it disperses)
  8. AH! Maybe a better idea:   Keep the spreading logic, but not only superconduct a small amount with your own inactive cells, but with the other inactive cells as well.
  9. there are about a million cells, though only a relatively tiny amount of those are typically 'active' at any given time (1000-10000) Each cell is able to store a LOT of data (specifically, there are at least 150 different variables which need to be 'equalized' between cells) By more accurate, i mean stuff like: A X X X X X X X X B  Where X is the active group, it instantly teleports the contents of A to B, and vice versa, without any care as to the distance that they actually are. A and B could be extremely different cells, and could be extremely far away from eachother as well. So the 'superconductive' inactive cells are fine for small groups, but in larger or more extreme groups it can be a lot more jarring. The 'most' accurate method would be to calculate everything on a cell-by-cell basis, but that seems both slow for the purpose of equalizing things, as well as intensive. Another concern is that i don't necessarily want things to equalize instantly. IE If the values are: 9, 9, 9, 9, 9, 5 I want it to become: 9, 9, 9, 9, 6| 9, 9, 9, 9, 7| 9, 9, 9, 9, 8| 8, 8, 8, 8, 8| Or something similar. (rounded estimated numbers for laziness) so again, the ideal for accuracy would be: 5, 7, 7, 7, 9 | 6, 6, 7, 8, 8 | 6, 6.5, 7, 7.5, 8 | 6.5, 7, 7, 7, 7.5 | 7, 7, 7, 7, 7 Where it does not equalize instantly through itself. But this is intensive and slow, and can potentially be redundantly recursive if they are only operating on a cell by cell basis. How i'm currently handling it, is to only superconduct a small fraction of the delta through the inactive group at a time. 
  10. I'm attempting to rework the flow-mechanics of my system to be faster, more accurate, and more efficient. See the image below for an example of what i'm doing.     So the object stores a 'volume' and spreads its data to the cardinally adjacent tiles, losing a proportional amount of its volume in the process, until all accessible tiles have an equal volume. Simple enough. I'm trying to find different and ideally more efficient ways to implement this. Keep in mind that there can be more than one 'hotspot' at once, and the collision of different 'hotspots' needs to be taken into consideration.     What are your ideas for handling this? ----------------------------------------------------------------------- My current idea: Have a main 'hotspot' controller object which stores both 'active' and 'inactive' tiles in two separate arrays/lists. Active tiles are 'tiles adjacent to tiles of innequal volume' Inactive tiles are 'tiles adjacent to tiles of equal volume OR black/wall tiles.' For each process of the controller: active tiles equalize with their adjacent tiles, and adjust their volume by (total adjacent tiles / total hotspot tiles * hotspot volume) active tiles become inactive tiles, and adjacent tiles become active tiles. inactive tiles adjust their volume by the same amount, but negative. Upon collision with another hotspot, if the other hotspot is 'newer' it ignores it, and treats it as a wall. Otherwise it overtakes it as a normal 'adjacent' tile. If overtaking it splits the previous hotspot, it creates a new hotspot where it was split (for a total of 3 active hotspots) When there are no more active tiles, the hotspot dies. HOWEVER i still have the issue where the 'volume' of the inactive tiles changes even when it wouldn't make sense to change instantly.      The biggest issue i have right now is when it 'cuts' another active group into two, because as i understand, i have two options: Allow it to keep processing as though it's a single group. (BAD) or recalculate the group EVERY single time it's overtaken by another active group (ALSO BAD)
  11. 2.5D Dynamic LOD Voxel Renderer

    I've seen the euclidean thing, And as far as i can tell, It doesnt really support dynamic lighting. I dont neccessarily need the engine to run in real-time, but closer to something like a beefed up blender "cycles" As well, a huge part of this is expected to be working on the hardware side, as well as the soft side.
  12. 2.5D Dynamic LOD Voxel Renderer

      I don't understand this. What is BDRF?  I expect that to fully realise this idea, it'll be required to have a "super-computer" built designed to specialize in running the engine (renderer, and other)     A lot of the world-modelling is hoped to be highly dependent on proc. gen., dealing with each independent brick, tree, leaf, etc.  
  13. 2.5D Dynamic LOD Voxel Renderer

    Well on the consumer side, it would seem cheaper to just purchase a machine that communicates with your computer, Than to purchase a highly specialized "console" designed to run "games" and simulations using this engine.   But then again, I'm also considering beefing it up even more, without taking the consumer into consideration. And making it into a sort of next-gen arcade machine, where you pay to use it for a while, rather than owning your own.   And yes, I suppose its similar to minecraft, On steroids, or something. Since its intended to have maybe 10k Voxels for every 1m. (Or as few as 1 Voxel for 1km) and with a severely beefed up lighting system.
  14. 2.5D Dynamic LOD Voxel Renderer

    Oh, And to boot, Throw in physics-based lighting.   What you see is completely dependent on Light (probably best simulated as a color, position, and "energy" value.), Viewpoint (Mostly just simulated as a position, but might have some fancy stuff added like seeing colors differently, seeing things a bit lighter than others, etc.), and Material properties, which have yet to be determined. But, in essence, It should be possible to create a scene like the one above, using only a light source, a viewpoint, and an array of voxels with material properties that affect the way the light is reflected, refracted, lost, etc. But only in relation to the viewpoint. (This would be tricky, since a lot of this would rely on having light "bounce" off the stone, part of it returning to the viewpoint, part of it lighting other areas, and returning to the viewpoint with less "energy" etc.)   Oh yeah, and one more 'impossible' thing to add. Make it an MMO, or at least with a client-server style infrastructure. While it would be possible to just say that all the rendering is handled client-side, How would all those "infinitely detailed" voxels be dealt with? Constant file-streaming, perhaps? Would it be faster to just stream the rendered images to the client, rather than stream the world/area, and wait for the client to render it? I feel like the latter option would be less intensive on the client, making it possible for the "machine" to be cheaper for a consumer, at the cost of a much more expensive server.
  • Advertisement