I'm making a UHC plugin, I need to pregenerate the world before teleporting a user so I load all the chunks. I found that this is ineffective as these chunks will unload when there is no one on them. One of my friends suggested I use this:
Map<Pair<Integer, Integer>, Object> map = CacheBuilder.newBuilder().expireAfterWrite(500, TimeUnit.MILLISECONDS).build(new CacheLoader<Key, Graph>() {
#Override
public Graph load(Key key) { // no checked exception
return createExpensiveGraph(key);
}
});
teleport(Location, Player) {
map.put(new Pair(location,getChunk.getX, location.getChunk.getZ));
location.getChunk().load;
Bukkit.getScheduler.runTaskLater(plugin, () -> player.teleport(location), 5L);
}
Also else where I would have an eventhandler handling the chunk unload event for the time that the chunk is in the Mapping. My problem is I have little to no experience with this google API which I am refrencing to here CacheBuilder and I'm not completely sure what I am doing wrong with this. I realize that createExpensiveGraph is a method but I don't know if it should be within the guava api or I need to make my own. I was wondering if someone might have a better way to solve my problem of pregening the world or help explain what I'm doing wrong when creating a new instance of chacheloader. Any input would be great, thanks!
You could keep the chunks in a list during the time that they should not be unloaded (before the player has been teleported there) and listen to the ChunkUnloadEvent, canceling it if it tries to unload one of the chunks in the list (and of course removing the chunks from the list again after the player has been teleported). A BukkitRunnable that loads all the chunks, waits for them to be finished and then teleports the player might be a good approach for this.
I assume you want this to work mostly for chunks that haven't been generated yet, because teleporting a player to a chunk that has been generated but simply isn't loaded into memory yet shouldn't cause too much trouble since loading of generated chunks often takes less than a tick (the delay seen on clients is just because of the rendering of chunks/sending of packets).
The OnChunkLoad event is called after the chunk is finished generating the basic terrain (and thus cannot be cancelled) which fortunately means that the isLoaded() boolean can be used as an indicator that the simple terrain in a chunk has been generated.
One last thing: Loaded chunks do not unload for at least a few seconds if no player is nearby (although I'm not positive whether this delay decreases if the server has more players/is using more resources) so while delaying the teleport for 5 ticks allows time for new chunks to be generated, I doubt they would already start unloading before those 5 ticks have elapsed, especially if you're only pre-loading one single chunk (in fact, when I tested this, my server never unloaded the single chunk, only once I started preloading multiple chunks were they unloaded after 15-30 seconds, but maybe this is different on a larger or different server)
I have code written for this that I used to test my ideas, although hopefully this is enough information to help you out (posting my code would make this post too long), but let me know if you need any more specific help with this!
To give some background information, I'm currently working on a Java coded pinball game. I'm keeping it in an MVC design model. It has a fairly realistic physics system that allows it to work collisions, gravity, friction etc. The system runs on a 20 FPS system right now.
The problem I'm having is that the physics loop that checks for collisions in the system works by running a method that using the current velocity of the ball calculates the time until the next collision. The most effective way for this to work would obviously be to keep running the check to account for the movement of the ball between checks to get it as accurate as possible, and if the time until collision is less than the time until the next check, then carry out the collision.
However, right now the system I am working with can only run the loop 20 times per second, which does not provide as accurate results as I would like, particularly during times of high acceleration, such as at ball launch.
The timer loop that I use is in the controller section of the MVC, and places a call to the physics section, located within the model. I can pass in the time remaining at the time the method is called in the controller, which the physics system can use, however I don't know how to run the loop multiple times while still tracking the remaining time before the next screen refresh?
Ideally I would like to run this at least 10 times per screen refresh. If anybody needs any more information please just ask.
Thanks for any help.
So the actual problem is that you do not know when the the collision will happen and when the next frame update is?
Shouldnt these be seperate running tasks? One thread that manages the collision detection and one that does the updating? each thread can run on its own interval (Timer.addTask(...)) and they should propebly be synchronized so colission/location updates are not performed when the render thread is executed.
Hope this answers your question.
Regards, Rob.
I've been working on a little proof of concept game that has a rolling environment in the background (2D). I have a custom class object called roadTile, which basically is a 200px tall block with a picture to paint on and some physics. I'm storing the tiles in a LinkedList 5 at a time. I have a main loop that is responsible for moving everything and checking for collisions. The loop is supposed to be performed every 50ms (controlled by a timer) and it keeps the rate fixed by measuring the length of the last run and then taking deducting it from the sleep-time.
This usually runs fine and the loops run in less than a millisecond, but when I start the program, it "chokes" after the first 2-7 times. I removed the old tile and put a new one on the bottom of the list. On calling the add (new roadTile()), the program halts for 20-400ms which is a millenium in computer time, and to top this off, the behavior isn't consistent. Sometimes it works fine some times not.
I'm pretty clueless how to eliminate this, any thoughts?
Make sure that you cache everything before you start working with graphics. This might be the cause of your delay.
I am creating an android game where enemies are generated randomly and there can be multiple at once.
Is it better to create the enemies at a random time from a timer (so 5s, then 4s, then 6s... etc), or through the game loop (count to 50, create enemy, count to 64, create enemy).
If the phone the person used was slow at rendering the game loop, the timer could create too many enemies, but if it used the game loop, they would not get enemies very quickly. There appear to be pro's and con's for each.
Also, which is better for saving processing power so it can render images faster?
Thanks in advance
Tom
ALSO, if I used a timer for each "group" of enemies, there would be 3 timers running.
I recommend a combination: The engine should be driven by "ticks" that in itself don't represent a specific duration. All engine decisions should be done based on time calculations independent of the ticks (e.g. System.currentTimeMillis subtractions). This way when there is high load on the machine you get lower frames per second but the distance of movements is not influenced. When there is lower load you get smoother graphics and movements. You should check for FPS and if they get to high you should even set the thread to sleep or you can generate more enemies. If it gets too low you can lower graphic details or prevent generation of new enemies to adapt to the situation. So I wouldn't start timers but store times for events that you precalculate to occur in the future and check in the game loop if it is time for them to happen (not with exact comparision, of course, but eventtime < now).
I'm developing a real time strategy game clone on the Java platform and I have some conceptional questions about where to put and how to manage the game state. The game uses Swing/Java2D as rendering. In the current development phase, no simulation and no AI is present and only the user is able to change the state of the game (for example, build/demolish a building, add-remove production lines, assemble fleets and equipment). Therefore, the game state manipulation can be performed in the event dispatch thread without any rendering lookup. The game state is also used to display various aggregated information to the user.
However, as I need to introduce simulation (for example, building progress, population changes, fleet movements, manufacturing process, etc.), changing the game state in a Timer and EDT will surely slow down the rendering.
Lets say the simulation/AI operation is performed in every 500ms and I use SwingWorker for the computation of about 250ms in length. How can I ensure, that there is no race condition regarding the game state reads between the simulation and the possible user interaction?
I know that the result of the simulation (which is small amount of data) can be efficiently moved back to the EDT via the SwingUtilities.invokeLater() call.
The game state model seems to be too complex to be infeasible for just using immutable value classes everywhere.
Is there a relatively correct approach to eliminate this read race condition? Perhaps doing a full/partial game state cloning on every timer tick or change the living space of the game state from EDT into some other thread?
Update: (from the comments I gave)
The game operates with 13 AI controlled players, 1 human player and has about 10000 game objects (planets, buildings, equipment, research, etc.). A game object for example has the following attributes:
World (Planets, Players, Fleets, ...)
Planet (location, owner, population, type,
map, buildings, taxation, allocation, ...)
Building (location, enabled, energy, worker, health, ...)
In a scenario, the user builds a new building onto this planet. This is performed in EDT as the map and buildings collection needs to be changed. Parallel to this, a simulation is run on every 500ms to compute the energy allocation to the buildings on all game planets, which needs to traverse the buildings collection for statistics gathering. If the allocation is computed, it is submitted to the EDT and each building's energy field gets assigned.
Only human player interactions have this property, because the results of the AI computation are applied to the structures in EDT anyway.
In general, 75% of the object attributes are static and used only for rendering. The rest of it is changeable either via user interaction or simulation/AI decision. It is also ensured, that no new simulation/AI step is started until the previous one has written back all changes.
My objectives are:
Avoid delaying the user interaction, e.g. user places the building onto the planet and only after 0.5s gets the visual feedback
Avoid blocking the EDT with computation, lock wait, etc.
Avoid concurrency issues with collection traversal and modification, attribute changes
Options:
Fine grained object locking
Immutable collections
Volatile fields
Partial snapshot
All of these have advantages, disadvantages and causes to the model and the game.
Update 2: I'm talking about this game. My clone is here. The screenshots might help to imagine the rendering and data model interactions.
Update 3:
I'll try to give a small code sample for clarify my problem as it seems from the comments it is misunderstood:
List<GameObject> largeListOfGameObjects = ...
List<Building> preFilteredListOfBuildings = ...
// In EDT
public void onAddBuildingClicked() {
Building b = new Building(100 /* kW */);
largeListOfGameObjects.add(b);
preFilteredListOfBuildings.add(b);
}
// In EDT
public void paint(Graphics g) {
int y = 0;
for (Building b : preFilteredListOfBuildings) {
g.drawString(Integer.toString(b.powerAssigned), 0, y);
y += 20;
}
}
// In EDT
public void assignPowerTo(Building b, int amount) {
b.powerAssigned = amount;
}
// In simulation thread
public void distributePower() {
int sum = 0;
for (Building b : preFilteredListOfBuildings) {
sum += b.powerRequired;
}
final int alloc = sum / (preFilteredListOfBuildings.size() + 1);
for (final Building b : preFilteredListOfBuildings) {
SwingUtilities.invokeLater(=> assignPowerTo(b, alloc));
}
}
So the overlapping is between the onAddBuildingClicked() and distributePower(). Now imagine the case where you have 50 of these kind of overlappings between various parts of the game model.
This sounds like it could benefit from a client/server approach:
The player is a client - interactivity and rendering happen on that end. So the player presses a button, the request goes to the server. The reply from the server comes back, and the player's state is updated. At any point between these things happening, the screen can be re-painted, and it reflects the state of the game as the client currently knows it.
The AI is likewise a client - it's the equivalent of a bot.
The simulation is the server. It gets updates from its clients at various times and updates the state of the world, then sends out these updates to everyone as appropriate. Here's where it ties in with your situation: The simulation/AI requires a static world, and many things are happening at once. The server can simply queue up change requests and apply them before sending the updates back to the client(s). So as far as the server's concerned, the game world isn't actually changing in real time, it's changing whenever the server darn well decides it is.
Finally, on the client side, you can prevent the delay between pressing the button and seeing a result by doing some quick approximate calculations and displaying a result (so the immediate need is met) and then displaying the more correct result when the server gets around to talking to you.
Note that this does not actually have to be implemented in a TCP/IP over-the-internet sort of way, just that it helps to think of it in those terms.
Alternately, you can place the responsibility for keeping the data coherent during the simulation on a database, as they're already built with locking and coherency in mind. Something like sqlite could work as part of a non-networked solution.
Not sure I fully understand the behavior you are looking for, but it sounds like you need something like a state change thread/queue so all state changes are handled by a single thread.
Create an api, maybe like SwingUtilities.invokeLater() and/or SwingUtilities.invokeAndWait() for your state change queue to handle your state change requests.
How that is reflected in the gui I think depends on the behavior you are looking for. i.e. Can't withdraw money because current state is $0, or pop back to the user that the account was empty when the withdraw request was processed. (probably not with that terminology ;-) )
The easiest approach is to make the simulation fast enough to run in the EDT. Prefer programs that work!
For the two-thread model, what I suggest is synchronise the domain model with a rendering model. The render model should keep data on what came from the domain model.
For an update: In the simulation thread lock the render model. Traverse the render model updating where things are different from what is expected update the render model. When finished traversing, unlock the render model and schedule a repaint. Note that in this approach you don't need a bazillion listeners.
The render model can have different depths. At one extreme it might be an image and the update operation is just to replace a single reference with the new image object (this wont handle, for instance, resizing or other superficial interaction very well). You might not bother checking whether an item has change and just update eveything.
If changing the game state is fast (once you know what to change it to) you can treat the game state like other Swing models and only change or view the state in the EDT. If changing the game state is not fast, then you can either synchronize state change and do it in swing worker/timer (but not the EDT) or you can do it in separate thread that you treat similarly to the EDT (at which point you look at using a BlockingQueue to handle change requests). The last is more useful if the UI never has to retrieve information from the game state but instead has the rendering changes sent via listeners or observers.
Is it possible to incrementally update the game state and still have a model that is consistent? For example recalculate for a subset of planet/player/fleet objects in between renders/user updates.
If so, you could run incremental updates in the EDT that only calculate a small part of the state before allowing the EDT to process user inputs and render.
Following each incremental update in the EDT you would need to remember how much of the model remains to be updated and schedule a new SwingWorker on the EDT to continue this processing after any pending user inputs and rendering has been performed.
This should allow you to avoid copying or locking the game model while still keeping the user interactions responsive.
I think you shouldn't have World store any data or make changes to any objects itself, it should only be used to maintain a reference to an object and when that object needs to be changed, have the Player making the change change it directly. In this event, the only thing you need to do is synchronize each object in the game world so that when a Player is making a change, no other Player can do so. Here's an example of what I'm thinking:
Player A needs to know about a Planet, so it asks World for that Planet (how is dependent upon your implementation). World returns a reference to the Planet object Player A asked for. Player A decides to make a change, so it does so. Let's say it adds a building. The method to add a building to the Planet is synchronized so only one player can do so at a time. The building will keep track of its own construction time (if any) so the Planet's add building method would be freed up almost immediately. This way multiple players can ask for information on the same planet at the same time without affecting each other and players can add buildings almost simultaneously without much appearance of lag. If two players are looking for a place to put the building (if that is part of your game), then checking the suitability of a location will be a query not a change.
I'm sorry if this doesn't answer you're question, I'm not sure if I understood it correctly.
How about implementing a pipes and filters architecture. Pipes connect filters together and queue requests if the filter is not fast enough. Processing happens inside filters. The first filter is the AI engine while the rendering engine is implemented by a set of subsequent filters.
On every timer tick, the new dynamic world state is computed based on all the inputs (Time is also an input) and a copy inserted into the first pipe.
In the simplest case your rendering engine is implemented as a single filter. It just takes the state snapshots from the input pipe and renders it together with the static state. In a live game, the rendering engine may want to skip states if there are more than one in the pipe while if you're doing a benchmark or outputting a video you'll want to render every one.
The more filters you can decompose your rendering engine into, the better the parallelism will be. Maybe it is even possible to decompose the AI engine, e.g. you may want to separate dynamic state into fast changing and slow changing state.
This architecture gives you good parallelism without a lot of synchronization.
A problem with this architecture is that garbage collection is going to run frequently freezing all the threads every time, possible killing any advantage gained from multi-threading.
It looks like you need a priorityqueue to put the updates to the model on, in which updates frmo the user have priority over the updates from the simulation and other inputs. What I hear you saying is that the user always needs immediate feedback over his actions wheras the other inputs (simulation, otherwise) could have workers that may take longer than one simulation step.
Then synchronize on the priorityqueue.