最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Simulating virtual worlds: continuous or discrete steps? - Stack Overflow

programmeradmin1浏览0评论

I'm making something similar to Polyworld, which means I will be simulating virtual worlds where little creepers run around, eat, and evolve. I'm making that with Node.js, and I plan to use physics and neural networks, but I'm not sure what's the best way to update the world, more specifically, should the update functions be recieving delta time as an argument, or do the same thing each time, independent of when they were last called? What are the benefits of both ways?

Edit: A point that I have against continous updates is that I want to implement some kind of intervals, for example, each 20 simulation seconds a food block spawns. If the dt gets different than 1 (or a fraction of 1), this will never work precisely.

Then again, if I go with discrete updates, where updates don't care about how much time has passed, I won't be able to "slow time down". As I made this to work on a powerful server and render in the browser, I figure that the updates will happen pretty often, and I need a way of slowing time down without affecting the simulation, so I can see what's happening.

I'm making something similar to Polyworld, which means I will be simulating virtual worlds where little creepers run around, eat, and evolve. I'm making that with Node.js, and I plan to use physics and neural networks, but I'm not sure what's the best way to update the world, more specifically, should the update functions be recieving delta time as an argument, or do the same thing each time, independent of when they were last called? What are the benefits of both ways?

Edit: A point that I have against continous updates is that I want to implement some kind of intervals, for example, each 20 simulation seconds a food block spawns. If the dt gets different than 1 (or a fraction of 1), this will never work precisely.

Then again, if I go with discrete updates, where updates don't care about how much time has passed, I won't be able to "slow time down". As I made this to work on a powerful server and render in the browser, I figure that the updates will happen pretty often, and I need a way of slowing time down without affecting the simulation, so I can see what's happening.

Share Improve this question edited Aug 25, 2012 at 10:42 corazza asked Aug 22, 2012 at 20:43 corazzacorazza 32.4k39 gold badges122 silver badges191 bronze badges
Add a ment  | 

6 Answers 6

Reset to default 2 +100

If your don't have multiple agents (each with its own thread) that have to collaborate and that you dont have to deal with synchronization/events of process flow problems I reend you to use continuous simulation. Using fixed time step and change the state of your world in each step. Each world piece change its state using a funcion like:

newState = f(oldState, deltaSteps)

About the speed problem you mention, do not directly map your iterations to time. Define a intermediate time unit (step), and them map this unit time to ms, iterations or what you prefer. So if you what to increase or reduce your simulation speed, just change the factor used to conver from step to time/iterations. If you need to change speed just change your constant.

Check this page with some insight about simulation techniques.

Each time you invoke updating function you can calculate how much time elapsed since animation start. Then you pass this time to updating function and having that, even though frame may not be updated precisely at 20th second, you may make all your calculations according to actual time.

Example: Car starts its movement at 20th second with speed 3units/s. Assume that update function is triggered at following times: ..., 19.35s, 20.67s, ... When updating at 19.35s you know what it should not yet be moved so nothing happens, but when update function is triggered with time value 20.67s then you know that car has already been moving for 0.67s, therefore you calculate its position (time*speed) 0.67*3 = 2.01 and do all other calculations/draw as if it was already 2.01 units moved. This way you don't need to worry about not precise time measurements, lags, updating function taking more time than usually etc.

I think you not exceed a certain frequency (like 50 Hz). That would waste CPU time on unneeded precision.

If the user's device cannot provide that update rate, you an either

  1. Keep the same physics frequency and slow down wall-clock speed
  2. Lower the physics frequency with higher delta T

I'd go with 2 if the frequency is still above 20Hz. If it goes lower you probably should switch to strategy 1 in order to maintain precision.

So you probably want a deltaT based solution so you can adjust the update frequency.

Your update functions should do the same thing every time step.

There are drawbacks to both approaches, but passing a delta that represents the time elapsed since the last update bees difficult to manage when simulating many-to-many interactions within a population. This is because it is time-consuming to predict the points in time (the deltas) at which interactions will happen. If these points in time are missed, the simulation is not accurate.

A drawback to the approach that updates all the elements at every time-step is that it will do unneeded work. However, the cost of this unneeded work will probably be less than the amount of work it would take to accurately predict which points in time need to be evaluated, especially given a plex interacting environment.

I think you are going to want your animation to be continuous and based on some elapsed time or clock (that you might be able to speed up or slow down). So some update functions you would want to be based on a delta.

But that doesn't mean that you can't for example use a setInterval to spawn food blocks. It also doesn't mean that everything else needs or should be based on that delta.

For example, you could check after your position update for creatures that are near each other or whatever condition is required for procreation, and then generate the offspring as a discrete step that isn't dependent on the current clock. You would want to record what the clock was when that happened though.

I would do this with constant timestep. It's by far more easy to code. Each update function does one step according to environement. You don't have to update the browser each step. You can pute 10 or 100 steps and then send results to browser.

It will be much more accurate this way. Lot of small simple steps are much easier to code than delta time depending functions (a nightmare).

If you are using variable time steps. When time step is big, you could have scenario where an ant is on point A at t0 and point B at t+delta. You update the ant first, it ends in point B. The you update a food respawn point between A and B that should have respawn at t0+ 1/3 delta. The ant passed by without seening the food. The simulation is wrong.

Other things you'll probably need :

  • To be really accurate you must check collision between segments [previous position - new position] rather than points. Otherwise ants may cross themselve without colliding. Check physics engines.
  • Avoid to send all objects to your browser. Use Octrees or quadtrees to quickly determine wich subset of your data correspond to the area displayed by browsers.

Strange choice to do this in Node.js, I would use a Java or a real oop language.

You'll find lot of useful help on game developer forums.

发布评论

评论列表(0)

  1. 暂无评论