This is somewhat of an open question.
I'm in the process of developing a simple game for android and I've gotten to the point where I'm trying to enable thee user to save their progress and return later.
As i'm a beginner, I'm not exactly sure where to start, so I was hoping some of you might have at least some suggestions.
A little info on the setup of the game:
All animation is done in a thread through a canvas and alternation of stored bitmap frames based on a 30 ms loop.
Everything is an object, the characters, the background is simply a 2d array of objects. and each object is generally referenced and created dynamically through a hashmap.
Now how to save? I know I could brute force it, and simply save coordinates and current actions blah blah etc. etc. for each object in each map.
But is there a better way to do this? I've briefly read that in python there's a method of sterilizing objects called "pickle," and there is something similar called "kryo." Am I looking in the right direction?
You should look into Java serialization. It's not perfect, it has problems, but it's the safest, quickest way to turn a complex tree of objects into something that you can save to a file or a db, and load it back when you need.
Else, there's always the possibility to use your own specific serialization using INSERT SQL queries, etc. But be very careful, it's easy to miss parts of what you want to save / restore. One example of that would be to turn your objects tree into XML and save that XML as a file. There are very good 3rd-party libs to map objects to XML and back in Java.
Well.. That's not STERILIZATION, but SERIALIZATION.. Which is a programming technique. And serialization is also the technique you want to use.
Doesn't matter if you use a predefined method or something you write on your own, but the only thing that matters is to loop across the objects and write to the file (or saving structure) the date you need to be later reloaded.
Anyway yes, you're looking the right way.
The best way to do it is implementing a serialization interface. Each object for which the serialize() method is called must save it's data and then call the serialize() method for each child object it owns.
Related
I'm currently working on a training plugin, where every player would get his own region, to learn bridge for example. So when a player joins, the plugin should automatically generate a new area for this player and delete it when he leaves.
I've created a SetupCommand where you have to set the start and end of the region that should be copied.
Now the only thing to do is copy the region and teleport the player to it, however, I couldn't find any good ways to do that. The only solution I found so far is to loop through all blocks and copy them one by one. But I can imagine that this is not the best solution and would cause lag, not only server-side but also client-side.
Are there better ways to clone a region than that?
I've read you should use Schematics but they weren't going into detail.
If you are experienced with java and feel comfortable about your skills you can try to get the blocks in the list as List and save it as base64 into your database or whatelse. You can parse it everytime back into a list of blocks and replace it. I would rather recommend you to make a custom block class with implements Serializeable and then add some values like Location, Material and BlockData to it.
Use FAWE or WorldEdit to copy/paste sections
If you use Block#setType, performance will be very slow, so if you don't want to use the API, you should use NMS, but using NMS is not a good practice.
Disadvantages of NMS:
Most nms methods are obfuscated. In one version the method is called f(), in the next version maybe c().
How to copy/paste with FAWE:
https://www.spigotmc.org/threads/how-to-paste-a-schematic-with-fawe.402950/
How to copy/paste with worldedit:
https://www.spigotmc.org/threads/worldedit-api-schematic-copy-save-load-and-paste.498476/
In conclusion, it is recommended to use the API
Is there a way to make a collection of class files/objects and then have them used in an interactive main file? So let's say I want to make a program to store information interactively where different classes are designed to hold different information. Then I would have an interactive main file where I made instances of these classes which would collectively hold the information I want stored. And then any changes or anything I do in this interactive main file is then saved.
I understand that this might be a very odd inquiry and maybe some other program might be useful for this. If so, feel free to point me in the right direction.
Here are two solutions that are good for the purpose you mentioned in your comment.
The first one is called Serialization. This let's you save your java object to your hard drive, and retrieve it later.
The second, (and in this case, more preferable option in my opinion), is using a Database.
A database is a compliment to your program, that stores data. You can then use "Queries" to access this data, and update it. Almost every database software is compatible with java.
I would look into MySQL
The reason I think a database would be better for your purpose is that they are already highly optimized, and are designed to have multiple people accessing and writing to them at once. If you wanted just want one person to use this program at a time however, serialization might be easier to implement.
Absolutely! Your main class would use the standard input (perhaps Scanner input = new Scanner(System.in);) and output (System.out.println()). To interact with your other classes, most simply, just put them in the same folder (if you are interested take a look at Java packages). If you have a Dog class in the same folder as your main class, you can freely create Dog objects in your main class. I hope this helps!
As a side note, because you mentioned storing information with different classes, you might be interested in the Java Collections Framework.
I am doing a java project and have several methods. Would like to know if its possible to quit the programme after the 3rd method for example and then when resuming the programme it continues from there? Any information regarding this would be helpful
THank you
Not without some kind of external persistence mechanism, no.
Once the process is done, it's done.
Why do you want to do this? There may be a better solution.
Otherwise, it would be along the lines of saving data in some particular format (JSON, YAML, etc..) and then have a parser that could determine where the last program left off. It's somewhat vague, so it also depends on what you're attempting to "save".
Potentially could do something hacky if you ran the program with a wrapper.
Edit:
You could serialize your classes, which in turn would allow you to be able to save the fields of any objects you have, however everything you have would need to implement Serializable and be saved to a file.
So after a little bit of googling, I found that there is also the XStream library, which serializes objects to XML without needing to implement an interface. In that sense, you could serialize objects themselves, but wouldn't be able to, say, continue from the middle of a method. (Having a string you can parse to start in different locations could be one option).
I have written a math game in Java, and have distributed some copies to a few beta-testers. The problem is that the version I have given them is saving the GameData via object serialization, which I found out is mainly for sending Objects, or in this case, ArrayLists of GameData, over a network. It is NOT persistance; that is what a relational database is for. Knowing this, I would like to know if it would be better to create a database on the beta-tester's machine (and rewrite the game), or continue with the Object serialization version of the game, and then retrieve the Objects when they are ready to send the data?
My guess would be to just move their data to a database that is created on their computer, and then give them the database version of the game. That way, the data can be persisted and be much easier to manipulate. What turns me away from that idea is the question of how am I going to write their database into mine (in the future)?
Although relatively rare, there are still lots of applications that use serialization for storage and retrieval of objects. It's not wrong to do this, just slightly unusual. If it's working for you, stick with it because DB's are a heavyweight solution. What you found out, about serialization, is only an opinion and an ill-formed one at that.
In terms of using an embedded database, two options to consider are SQLite and HyperSQL. However, serialization is also an option, and in my opinion it should be your default option if you've already implemented it. Some considerations:
With serialization you've generally got to retrieve the entire object, which is slow if you've got an object with several dozen fields and you only want to read one of them. If you're making queries like these, then use a database. I suspect that you're just reading in all of your serialized objects at startup and serializing them back out to disk at shutdown, in which case there's no reason to use a database instead of serialization.
Java's default serialization mechanism is fairly slow. You may want to consider another serialization mechanism, such as Kryo or Jackson, but only if you're not happy with your program's serialization performance.
It is difficult to advise on the best choice of technology without knowing what you are persisting and why.
If the state is simply a snapshot of your game state (i.e. a save file) or a "best scores" table, then you don't need a database. Serializing using JSON, XML or ... Java Object serialization is sufficient.
If the state needs to be read or updated incrementally or shared with other applications ... or users on other machines ... then a database is more appropriate.
Serialization mechanisms are problematic if the requirements include incremental changes, etcetera. You end up building a database-like layer over the top of the serialization.
As to whether you should stick with Java serialization ... or switch to JSON or XML or something like that:
Object serialization is simple, but it can be fragile if you change the classes that you are serializing. This fragility can be mitigated, but it is messy and you lose the simplicity. (You need to write custom readObject and writeObject methods that know how to read "old versions" of the serialized objects.)
JSON and XML are a bit more complicated, but still relatively simple if you use an object binding mechanism.
It is worth noting that changes to the persisted object classes (or the database schemas) are potentially problematic no matter what you do. There is no easy universal solution to this problem.
UPDATE
Given the additional information that you provided in your first comment (below), it seems like you don't need a database in the game itself. All you need is something that can read and analyse the session state save files that your beta testers provide for you. Indeed, it doesn't even seem like the actual app needs to be able read the files. (But that's unclear, because you've not said what the real purpose of these files is ... or at least, not what the entire purpose is.)
It is also worth noting that you are probably saving the wrong information if your aim is to tune the sets of questions. What you really need to do is record the length of time and whether the user got the right or wrong answer and the time ... for each individual question. And you probably need to know what the actual answer given was ... so that you can spot cases where the user's answer was actually right and you "marked" it as wrong ... or vice versa.
"What turns me away from that idea is the question of how am I going to write their database into mine (in the future)?"
Exactly. If you hadn't prematurely "analysed" the data, you wouldn't have this problem.
But ignoring that, it seems like that a simple state saving mechanism is sufficient to meet your (still hypothetical / inferred) requirement of keeping a personal score board for the end user. Your "tuning" stuff would be better implemented using a custom log file. I cannot see any value in incorporating a database as part of the app itself.
I presume you are doing java serialisation, If so there is nothing wrong with it. Just be aware of its limitations - Different versions of java might not be able to retrieve the file.
Also If you change the Class, previous saved data can not be retrieved.
If you decide to change you could look at Xml, JSon, Protocol Buffers, Thrift, Avro etc as well as a DB.
Note:
Xml is builtin in to java
Java Db (Derby) is also in Java
Other serialisation schema's require a seperate library.
I'm working on building a custom Simulink block as a Matlab Toolbox. In order to avoid matlab's language to program the system, I'd like to make the system in Java as much as possible. I've researched the Matlab <-> Java interface, and it seems possible to do this. However, the one thing I couldn't find any information about was storing my custom Java object (holding the block's data) inside the Simulink block.
I conducted a quick test, and it seems storing a Java.lang.String instance is possible. However, that was a relatively simple test. Before jumping in head first, I wanted to check if this was even possible. Does anyone have experience with a similar setup? Does the object simply need to be Serializable to work?
For background information, I'm looking to implement the non-math part (GUI code, processing, etc) in Java. Math related elements would likely remain in matlab.
To store your Java object inside the block you should use its UserData block parameter. According to the documentation, you can put any data type in this parameter.
The only problems I can see with this are saving/loading and creation of new blocks. Saving/loading should be solved using serialization, but you will have to try it to see. If this doesn't work, then you could create a hidden mask parameter for your blocks, serialize your Java object to a string, and save the data in this mask during the PreSaveFcn callback. The data could be deserialized from the mask parameter in the LoadFcn callback.
For the creation of new blocks, you should set the PreCopyFcn callback of your library block and create your new Java object there. I have the feeling that if you don't do this, then MATLAB will copy the reference to your object from UserData (if one exists there already), which is probably not what you want.
You probably also want to override the OpenFcn callback since your aim is to use your Java object as a kind of souped-up mask, so that when a user double-clicks on the block you can show your custom UI.
For more information on block callback parameters, see this.