I'm creating a grid based game in Java and I want to implement game recording and playback. I'm not sure how to do this, although I've considered 2 ideas:
Several times every second, I'd record the entire game state. To play it back, I write a renderer to read the states and try to create a visual representation. With this, however, I'd likely have a large save file, and any playback attempts would likely have noticeable lag.
I could also write every key press and mouse click into the save file. This would give me a smaller file, and could play back with less lag. However, the slightest error at the start of the game (For example, shooting 1 millisecond later) would result in a vastly different game state several minutes into the game.
What, then, is the best way to implement game playback?
Edit- I'm not sure exactly how deterministic my game is, so I'm not sure the entire game can be pieced together exactly by recording only keystrokes and mouse clicks.
A good playback mechanism is not something that can be simply added to a game without major difiiculties. The best would be do design the game infrastructure with it in mind. The command pattern can be used to achieve such a game infrastructure.
For example:
public interface Command{
void execute();
}
public class MoveRightCommand implements Command {
private Grid theGrid;
private Player thePlayer;
public MoveRightCommand(Player player, Grid grid){
this.theGrid = grid;
this.thePlayer = player;
}
public void execute(){
player.modifyPosition(0, 1, 0, 0);
}
}
And then the command can be pushed in an execution queue both when the user presses a keyboard button, moves the mouse or without a trigger with the playback mechanism. The command object can have a time-stamp value (relative to the beginning of the playback) for precise playback...
Shawn Hargreaves had a recent post on his blog about how they implemented replay in MotoGP. Goes over several different approaches and their pros and cons.
http://blogs.msdn.com/shawnhar/archive/2009/03/20/motogp-replays.aspx
Assuming that your game is deterministic, it might be sufficient if you recorded the inputs of the users (option 2). However, you would need to make sure that you are recognizing the correct and consistent times for these events, such as when it was recognized by the server. I'm not sure how you handle events in the grid.
My worry is that if you don't have a mechanism that can uniformly reference timed events, there might be a problem with the way your code handles distributed users.
Consider a game like Halo 3 on the XBOX 360 for example - each client records his view of the game, including server-based corrections.
Why not record several times a second and then compress your output, or perhaps do this:
recordInitialState();
...
runs 30 times a second:
recordChangeInState(previousState, currentState);
...
If you only record the change in state with a timestamp(and each change is small, and if there is no change, then record nothing), you should end up with reasonable file sizes.
There is no need to save everything in the scene for every frame. Save changes incrementally and use some good interpolation techniques. I would not really use a command pattern based approach, but rather make checks at a fixed rate for every game object and see if it has changed any attribute. If there is a change that change is recorded in some good encoding and the replay won't even become that big.
How you approach this will depend greatly on the language you are using for your game, but in general terms there are many approaches, depending on if you want to use a lot of storage or want some delay. It would be helpful if you could give some thoughts as to what sacrifices you are willing to make.
But, it would seem the best approach may be to just save the input from the user, as was mentioned, and either store the positions of all the actors/sprites in the game at the same time, which is as simple as just saving direction, velocity and tile x,y, or, if everything can be deterministic then ignore the actors/sprites as you can get their information.
How non-deterministic your game is would also be useful to give a better suggestion.
If there is a great deal of dynamic motion, such as a crash derby, then you may want to save information each frame, as you should be updating the players/actors at a certain framerate.
I would simply say that the best way to record a replay of a game depends entirely on the nature of the game. Being grid based isn't the issue; the issue is how predictable behaviour is following a state change, how often there are new inputs to the system, whether there is random data being injected at any point, etc, You can store an entire chess game just by recording each move in turn, but that wouldn't work for a first person shooter where there are no clear turns. You could store a first person shooter by noting the exact time of each input, but that won't work for an RPG where the result of an input might be modified by the result of a random dice roll. Even the seemingly foolproof idea of taking a snapshot as often as possible isn't good enough if important information appears instantaneously and doesn't persist in any capturable form.
Interestingly this is very similar to the problem you get with networking. How does one computer ensure that another computer is made aware of the game state, without having to send that entire game state at an impractically high frequency? The typical approach ends up being a bespoke mixture of event notifications and state updates, which is probably what you'll need here.
I did this once by borrowing an idea from video compression: keyframes and intermediate frames. Basically, every few seconds you save the complete state of the world. Then, once per game update, you save all the changes to the world state that have happened since the last game update. The details (how often do you save keyframes? What exactly counts as a 'change to the world state'?) will depend on what sort of game information you need to preserve.
In our case, the world consisted of many, many game objects, most of which were holding still at any given time, so this approach saved us a lot of time and memory in recording the positions of objects that weren't moving. In yours the tradeoffs might be different.
Related
Concept: A database contains the signal strength values of several access points in a building. The values have been collected after a walk through the corridors of the building. Now I want to visualize this route on a floor map with the changes of the signal strength.
So I need to implement a visualization/simulation mechanism in Java for this. What do you suggest? From where should I start? Any help? I am not looking for something professional..
example
One place to start is really simple: create a 2D canvas, and at each x,y where signal was measured, put a colored circle that indicates signal strength. This will allow you to distinguish a dozen levels of strength. If you need more info you can then put a mouse event handler so if you hover over a circle you can get strength value. After that, you'll probably realize other capabilities you need and this will guide your next set of features. This will lead to organic growth of your app, which will eventually make it unmaintainable. ;) At that point you will have gained significant understanding of your requirements (visualization, edit, etc), so you'll be able to start fresh with a clear set of requirements, a more robust design, and the added features that were too difficult to implement before the re-design :)
I'm trying to write multiplayer game for Android with java back-end using sockets, but I don't know how to do some things.
For example, I have to players. First player pushed "UP" button and his avatar moving up. How can I tell about it to all other players?
I can send message, that user with some ID changed his coordinates to new X and Y, but I will need to do that for every millisecond while he moving. Is that right?
Or I can send message that user with some ID pushed UP button and after that new message that user released UP button. Using time difference between this two events and movement speed I can calculate new coordinates of user, but in this case will be problems with latency (time difference calculation will be not enough accurate)
How I can do that?
You can do it in lot of ways and all will have drawbacks like you already found. I guess there is no "best" way to do that.
A common way for games is to have a "game server". The server recieves input from all clients and decides about the resulting state.
Clients could for example just transmit the keypresses and the server tells them about their location and location of other clients that need to be drawn. Clients do the same math locally and display this state while waiting for confirmation from the server. But that's just a prediction.
When it lags you can observe yourself jumping between positions in a lot of games because actual server calculated position and your prediction got out of sync.
The other advantage of server-side state decisions is that clients can't cheat that easily. It's no foolproof way to prevent every cheat. Aim-bots for example simply simulate a perfectly aiming user by moving the mouse for them and that's basically not detectable. Map hacks / wall hacks (anything where you can see things that you would not see) on the other hand can be prevented by simply not telling the client about currently invisible things. Only the server needs to know the full state.
The server approach can also be used without a dedicated game server. Instead, one of the clients will have the role of the server and decide about the game state. That responsibility can in some games even switch between clients if the original host drops out. A smooth handover if that happens is rather tricky though.
If there is no server and all clients are equally responsible you will have to think about schema which defines which client is responsible for validating which action. For example in a shooter, A shoots in a certain direction, and thinks B is still there but B already moved a bit further and now A thinks "B was hit" and B thinks "shot missed" -> Either the one shooting or the one being hit should decide what happens.
A schema with multiple decision making parties might not work for every game and it is a very complicated task. Not just for games but distributed computing in general
Java and Sockets are just tools here. The actual problem is one where you should take pen and paper and think about a schema that works for your scenario.
Regarding coordinates every milisecond: you could also send messages like "I will be at point X,Y at time Z" and other clients interpolate the path of that player so you don't have to transmit every position.
I have written a few 2D games in the past using libraries such as LWJGL (with a Slick2D wrapper) and the XNA framework, but one thing i have never been able to grasp (or have the need to) is how the user input is kept constant, eq not dependent on FPS.
I'm looking for a more generic answer rather than framework specific. I understand it has something to do with time measured between frame updates ?
Thank you
I can't speak for some of those other frameworks, but I know that XNA basically lets you poll the current input state (are the buttons up or down?) whenever you like. You usually do it each frame.
What this means is, if your player happens to be a ninja and can hit keys faster than 60FPS, it is possible that they may hit a key (or mouse button) between pollings and you miss it. In practice it is almost never an issue.
If it does bother you, the solution to this problem is to hook the Windows message pump and receive keyboard up/down events.
For general gameplay it is really not worth the effort. Usually the only time where you really must capture every keystroke is when the user is typing text. So rather than capture key up/down events, you capture character events (WM_CHAR). This means you won't miss a keypress. But the more important problem that this solves is that it offloads key-to-character translation to Windows - allowing it to handle key-repeat, keyboard layout, shifted characters, etc, for you - allowing your game to behave like any other Windows application.
(Of course, if you can get away with just using the polling-based framework input stuff - go with that - it's much easier to implement and less platform-specific.)
The above only matters when you are detecting distinct key presses (eg: tap to fire this gun), as opposed to holding keys down (eg: accelerate this vehicle).
The alternate interpretation of your question is you are suggesting that a key may come up half way through a frame - how do you account for that, in a game with a discrete time-step?
Generally you don't worry about it. Just as 60 frames per second is fast enough to discretely calculate your game state and appear smooth and continuous to a human, it's fast enough to accept input.
But what happens if you're not running at 60FPS? If you're running at 30FPS (as you might on a mobile platform), then it can make your inputs - particularly analogue inputs - feel much smoother if you poll them at 60FPS. The easiest way to do this is to simply do two Updates for each Draw - if your Update is not too taxing on the CPU.
I'm creating an organism simulator for Android, so I guess the algorithm would ideally be in Java. I realize that there is a whole Stanford course on Machine Learning available on youtube, but I simply don't have the time to sit through the whole thing, and I think for my purposes the solution could be very simple.
The organism will be interacted with by the touchscreen primarily, or even if it's interacted with through the mic or accelerometer the inputs in the algorithm will mostly amount to coordinate positions for the different limbs. I think it will be inelegant to have a 'scolding' or 'rewarding' mechanism for random behaviors, so I would like to avoid that. So tracking general directions or patterns in movements and being able to repeat them when they have a high enough frequency would be the goal.
To be honest I'm not really sure how hard this is to accomplish, but I'd like to hear any feedback to know how much more I have to research before I can implement it.
EDIT: Is this a genetic algorithm? The problem is I have no idea how to measure a successful or non successful evolution.
EDIT 2: Okay, I'll try to add as much detail as possible. The application is still in concept stage at the moment, but I just wanted to know how difficult the algorithm would be to put it. So I'm building it in Processing, which is really just Java. The organism would be comprised of limbs that have a fixed distance between them, but are allowed to move independently from the center piece. The limbs move around freely and would find random points periodically to ease to. The organism would have a center appendage that has x and y coordinates as well, and each of the outer limbs would move in relation to that. The user could interact with the organism by manually moving the appendages or the center piece with drags on the touch screen. When the organism is being interacted with is where the algorithm would be used, because there's no point in learning from just random numbers. So I guess the algorithm would take the x and y coordinates of the center piece into consideration, and each appendage would have its own version of the algorithm that learns independently from the others. For instance, if the user continually dragged the organism to the right side of the touch screen, it might be more attracted to that place when it isn't being interacted with. I hope that clarifies a little bit.
I think that for your case, you should try to sit down and write down what are the variables that you can observe and what are the variables that you want to predict
Observable variables: position of the appendage, how many times a specific one is interacted with, for how long, ...
Variables you want to predict: which appendage will be interacted with next time, ...
Once you have the input variables and output variables, you can try to go through the list of standard machine learning algorithms. There are Weka(Java), Rapidminer, KNIME ... which are both libraries and standalone tools. Try to throw your problem at the available tools and see if you are doing better than chance.
If you are, tune its parameters. If you are not performing better than chance, you should ask your Data Mining/Machine Learning friends. They will know best what will work for your problem.
Other things that might affect your choice of algorithms:
Are there hidden states?
Are the variables independence?
The way I see it, all you'd need to do is have an array of, for example, the appendage coordinates, then just average them out and have it move towards that point on the screen
I'm trying to write a painting app for a mobile device (Android) that will have a bit more functionality than MS Paint (e.g. various brushes and brush settings, selections, layers) but won't be as complex as Photoshop. I need my app to have a decent undo/redo feature. Unlimited undo/redo is probably not possible. I'd be happy with being able to undo about the last minute worth of user actions (maybe about 20 actions).
The main approaches I know of for undo/redo is:
save the whole state or just the bits that changed after each operation. Undoing involves updating the state by restoring snapshots. Pros: simple to implement Cons: memory intensive.
use the command pattern where each command has a "do action" and "undo action" method. To undo, you just call the undo action of the previous commands. Pros: memory efficient, Cons: much more complex to implement.
My pathological undo/redo scenarios I have to consider is:
the user paints over the whole canvas in one go, where you would want this whole operation to be undone when the user clicks undo. With option 1, we'd need to store a bitmap the size of the whole canvas.
the user draws something, imports image 1.jpg onto the canvas, does some more drawing, 1.jpg is then deleted/modified at some point by another application and then the user wants to undo then redo all their actions in the paint application. I'm really not sure how to undo correctly here without saving a copy of any imported image while it's on the undo stack.
Can anyone give any recommendations about how best to implement undo/redo on a mobile device where memory and processor speed are low? I like the simplicity of 1 and 3 but it seems like the only realistic option is 2. I'm not sure how to cope with my second pathological example with this option though.
On the iPhone, Core Data has built in support for undo and redo. Just make your data model reflect the objects drawn and you can easily roll it back and forward between saves. Usually you would save the procedures and objects used to create the graphic instead of the graphic itself.
Edit:
OK, but this is just a little API
support for implementing number 2 and
won't help with the examples I gave.
The key idea to making this work is that you don't configure your data model to modal and persist the graphical output of the program, you configure it to modal and persist the process of creating the graphical output.
The naive way of creating a graphical program would be to set up the data flow like:
Input_UI-->Display_UI-->Data_Model
The user manipulates the Input_UI which directly alters the onscreen graphics of the Display_UI. Only when the user saved would the Data_Model come into play. This type of data flow makes undo/redo (and other things) very hard to implement especially in a painting e.g. compositing program. Every single operation has to know how to undo itself and has to be able operate on the altered graphic.
The better way is to set up a data flow like this:
Input_UI-->Data_Model-->Display_UI
The user manipulates the Input_UI which communicates to the Data_Model which manipulations the user chose. The Data_Model records the process e.g. "add file jpg.1 at rect {0,0,100,100}". A change to the Data_Model sends a notification to the Display_UI which reads the changed data and implements the process described.
The Data_Model rolls itself back and the Display_UI simply draws what the Data_Model tells it to. The Display_UI doesn't have to understand the undo process at all.
In a drawing program you would create logical layers of individual graphical objects so that redoing is just a matter of removing layers in the reverse order they were added. For painting/composition programs, you have to start at the last save point and recreate the graphic going forward until the last-1 step.
So, in your examples for a compositing program:
The Data_Model stores the coordinates of the selected area (the entire canvas) which is still just "rect {0,0,canvas.width,canvas.height}" and then the operation "fill with black". For undo, the Display_UI whips the image back to the last save point and then invisibly applies the changes made up to last-1.
You just need to save a cache of the image up until the next save. At that point, the Data_Modal commits all the changes and exports the composition to a file. The next time the app starts, it begins with the image from the last time. If you want infinite undo, then yes you have to save the imported image permanently.
The way to approach this is to ignore the GUI and instead think about how you would design an app to be run from the command line with out any GUI input or output. The Data_Modal would work just the same. It would save the text commands and the data (e.g. imported images) for creating the output image, not just a snapshot of the image on screen.
I like the simplicity of 1 and 3 but
it seems like the only realistic
option is 2.
I'm not sure what "3" is, since you only appear to have two options in your question.
With respect to the memory consumption of #1, it's only an issue if you use memory. Only hold onto history in memory for as long as it takes an AsyncTask (or possibly a regular background thread working off a LinkedBlockingQueue) to write them to the SD card. No SD card -- no undo/redo. On an undo, if your history has already written it to disk, reload it from disk. Just be sure to clean up the SD card (delete history on a clean exit, delete all lingering files on next startup).
Bear in mind that I have never written a painting application, let alone on Android, and so there may yet be performance problems (e.g., undo may take a second to load the bitmap off of the SD card).