I tried to make clear in the README and FAQ. You must get the latest version of SQLite amalgamation and compile it as sqlite3.o in the same directory of the source files (and also sqlite3.h), due to often the version of SQLite included with the system is a old version.glitchapp {l Wrote}:Hi, very interesting project. I think it would help to provide better instructions to compile it. I try to compile it and become the following error: gcc: error: sqlite3.o
If sqlite3.o is missing, then the compile script should compile it. If sqlite3.c is also missing, then it should either explain the error, or, even better, execute wget/curl/whatever to get the latest amalgamation ;-)zzo38 {l Wrote}:Possibly I should include the SQLite amalgamation with it, or possibly I could change the compile script to check that sqlite3.o is missing and explain it in that case.
I've wanted to take a look, but the link "Sources" / "Main" timed out for me. The "Mirror" and "Mirror (HTTPS)" links were working, but I couldn't check the source on them. I've clicked the "Branches" on the menu, and I got an error message ("no hyperlinks without login", wait, why?), and it showed nothing, but throw a bunch of JavaScript errors. I wasn't able to click anywhere, the checkbox next to "trunk" wasn't working for example.zzo38 {l Wrote}:I will also accept contributions for optionally compiling with other build systems if this is desired, or for improving the current build scripts and/or documents.
Yesterday I had thought of that, but had not yet implemented it. (Another alternative would be to include a copy of the SQLite amalgamation in this source repository. If I do have it download the file, I do not want it to just automatically compile it without verifying it first (or at least asking the user); automatically downloading third-party software without verifying it (or asking the user, if verification fails or is not possible) just doesn't seem very good to me.)bzt {l Wrote}:If sqlite3.o is missing, then the compile script should compile it. If sqlite3.c is also missing, then it should either explain the error, or, even better, execute wget/curl/whatever to get the latest amalgamation ;-)
Hopefully I fixed the "no hyperlinks without login" error now (that might be due to a misconfiguration, which I have hopefully fixed now). I don't know why the "Main" link timed out, since it is the same server as the web page that contains that link.zzo38 {l Wrote}:I've wanted to take a look, but the link "Sources" / "Main" timed out for me. The "Mirror" and "Mirror (HTTPS)" links were working, but I couldn't check the source on them. I've clicked the "Branches" on the menu, and I got an error message ("no hyperlinks without login", wait, why?), and it showed nothing, but throw a bunch of JavaScript errors. I wasn't able to click anywhere, the checkbox next to "trunk" wasn't working for example.
The "Mirror" and "Mirror (HTTPS)" links are on Chisel which is a remote site for fossil; "Main" is my own computer. If additional mirrors are made that is OK with me too (and it is possible to mirror a fossil repository in git format too; SQLite and also Fossil itself do this). I will not use GitLab, because it will not display anything if JavaScripts are disabled.I'd recommend to use a codehosting instead, which is known to work (if you don't like github, which I can totally understand, use notabug.org or something similar). If you insist to keep the source on your machine, the use a software that generates a working website for the code. Now I don't know what alternatives fossil has, but for git there are lots of FOSS web frontends (gitea, gittree, gitlab etc., you can install those on your own server).
I intend to keep these files unencrypted. The program running for one local user should not try to prevent them from accessing them, and the SQL is exposed to the end user anyways in this program (many users probably will not need it, but for advanced batch operations, customizing key bindings, and some other things, some users may find it useful). If you want to, you can prevent other local users from accessing the file by use of chmod. If you want to verify scores, there is another way; you could send them to a server (or to another program on the same computer, for local multiuser scoring) which will receive and verify that the scores are valid (this is only possible if the puzzle set files are readable by the scoring verification server). (If solutions are recorded with the puzzle set file, or your move lists are otherwise published, then they can be verified by the end user, by the use of the "-a" switch (this can also be used for regression testing, in case you modify the rules of a puzzle set and want to verify that you have not broken the existing puzzles in the puzzle set, or even modifying Free Hero Mesh itself and want to ensure it hasn't broken existing puzzles).)Just for fun, if you want to stop hackers from messing with the game state, you could encrypt the database file. The FOSS version of sqlite3 can't do that (only the paid SQLite SEE), however I've implemented an Open Source alternative for that, sqlite3aes. It is a drop-in replacement for the proprietary SEE, uses military grade AES for encryption and works with the sqlite3 amalgamation out-of-the-box ;-)
That's why you should use GNU make and a Makefile. It will check if the sqlite3.o is missing or if the sqlite3.c is newer than the .o file, and it will only compile if so. It can even automatically download and verify sqlite3.c if that's missing (if you decide not to ship sqlite3.c with your source, that is). Or it could just inform the user that they should download it, for examplezzo38 {l Wrote}:Yesterday I had thought of that, but had not yet implemented it. (Another alternative would be to include a copy of the SQLite amalgamation in this source repository. If I do have it download the file, I do not want it to just automatically compile it
# executes if sqlite3.c is missing
sqlite3.c:
@echo Please download sqlite3.c from https://www.sqlite.org/download.html
@false
# verifies the existence of sqlite3.c and if exists then executes if sqlite3.o is missing or if sqlite3.c is newer
sqlite3.o: sqlite3.c
gcc sqlite3.c -c -o sqlite3.o
Yes, it is working now, thanks! The mirrors are still having that (obviously), but your local webrepo doesn't.zzo38 {l Wrote}:Hopefully I fixed the "no hyperlinks without login" error now (that might be due to a misconfiguration, which I have hopefully fixed now).
It is painfully slow now (takes about 40-50 secs to load), but at least it does not time out.zzo38 {l Wrote}:I don't know why the "Main" link timed out, since it is the same server as the web page that contains that link.
Then maybe take a look at gitweb, it is as simple as possible, truly the simplest of the simplest, works perfectly without JS of course. It's just my personal opinion, but it's lot more usable IMHO than your current fossil webpage. (But again, this is just my humble opinion, my personal preference.)zzo38 {l Wrote}:I will not use GitLab, because it will not display anything if JavaScripts are disabled.
But then they can mess with it and fake high-scores, unlock levels etc. Maybe that's not something you want to allow.zzo38 {l Wrote}:I intend to keep these files unencrypted. The program running for one local user should not try to prevent them from accessing them
I wasn't thinking about preventing other users, rather preventing the local user from accessing the data outside from the game where the consistency and logic cannot be forced. You'll have to implement a lot of security and sanity checks and input verification if you deliberately allow users to set any arbitrary value in any field outside of your control.zzo38 {l Wrote}:If you want to, you can prevent other local users from accessing the file by use of chmod.
But then you'd have to have a working internet connection to play the game. I personally would hate that. (It is only okay if having a score server is optional, and users can opt-out.)zzo38 {l Wrote}:If you want to verify scores, there is another way; you could send them to a server
Won't solve the issue either, it would just replace one unencrypted file with another on the same local machine.zzo38 {l Wrote}:or to another program on the same computer, for local multiuser scoring
Maybe it is, although I find that the file format, protocol, command-line interface, etc of Fossil is much less confusing than Git, even if the web interface isn't. Nevertheless, in future I could add mirrors if needed, including using different formats if wanted. (I don't know if anyone else has made alternative web interfaces for Fossil (either by use of libfossil or by copying the raw artifacts into their own database), but it would be possible, too.)bzt {l Wrote}:It's just my personal opinion, but it's lot more usable IMHO than your current fossil webpage. (But again, this is just my humble opinion, my personal preference.)
Free Hero Mesh does not allow levels to be locked, and I do not intend to add that feature. You can play levels in any order, without needing to unlock them first. While you can add fake scores, doing so is not helpful; if you try to verify such fake scores (which you must tell it to do explicitly, and it might take approximately one second, depending on the puzzle set, number of moves, and computer speed), then the verification will fail if the recorded move list is not a solution to the puzzle. (Verifying a score simply involves replaying the move list and checking that that sequence of moves results in a win with the specified score.)But then they can mess with it and fake high-scores, unlock levels etc. Maybe that's not something you want to allow.zzo38 {l Wrote}:I intend to keep these files unencrypted. The program running for one local user should not try to prevent them from accessing them
I know that, but consider:I wasn't thinking about preventing other users, rather preventing the local user from accessing the data outside from the game where the consistency and logic cannot be forced. You'll have to implement a lot of security and sanity checks and input verification if you deliberately allow users to set any arbitrary value in any field outside of your control.
I also hate having to have a working internet connection; fortunately, you don't. Even if a score server is implemented, it would be opt-in (and you could configure which server to use, and the protocol would be documented), not opt-out; by default it would not access the internet at all (by default it would run by itself only, without needing any servers). The server does not necessarily have to be on another computer; you can also use a server on the same computer (e.g. for local multiuser scoring). But you can also verify scores without needing a server; Free Hero Mesh has this capability built-in (as I explained above).But then you'd have to have a working internet connection to play the game. I personally would hate that. (It is only okay if having a score server is optional, and users can opt-out.)zzo38 {l Wrote}:If you want to verify scores, there is another way; you could send them to a server
Actually it does help, as long as the system administrator does not tamper with the scores. (Encrypting them would not prevent the system administrator from altering the program to report incorrect scores, though.)Won't solve the issue either, it would just replace one unencrypted file with another on the same local machine.zzo38 {l Wrote}:or to another program on the same computer, for local multiuser scoring
I agree it is not worth it like you say. The end user should have full control over their own files and programs.But it's okay, you can say that you don't care about security (what harm can messing with the high-score of a puzzle game do, after all? Maybe it just does not worth the effort of protecting.) But if you allow editing the database outside of the game, then be prepared to add lots of sanity checks in your code, you can't get away without the checks.
Well, I don't know about fossil, but I've used CVS, SVN and Hg for a long time, and technically speaking git is far more superior to all of them. About the command line I agree, git has terrible and impossible to remember switches, but luckily Linux has command aliases. That's what I do. About the mirror I agree too. Maybe it's the best if you keep the fossil for yourself, and you create a git mirror with gitweb too?zzo38 {l Wrote}:Maybe it is, although I find that the file format, protocol, command-line interface, etc of Fossil is much less confusing than Git, even if the web interface isn't. Nevertheless, in future I could add mirrors if needed, including using different formats if wanted.
Considering SQL injection is important, but that's not what I meant here. For example, you've said keyboard assignments are also stored in SQL. What if someone sets the key to left movement "Left" and right movement "Funky"+"Left"? Obviously there's no such key as "Funky", but with a trivial verification and invalid key removal now you'll end up having both left and right keys set to "Left". I meant things like that when I said you have to do a lot of sanity checks if you allow modifications outside of your game.zzo38 {l Wrote}:I know that, but consider:
- The SQLite database is only used for user data; puzzle sets use a different format.
- Checks are done on puzzle set files, and some checks are also done on the SQL files.
- Puzzle sets cannot contain SQL codes.
Good!zzo38 {l Wrote}:I also hate having to have a working internet connection; fortunately, you don't. Even if a score server is implemented, it would be opt-in
You see, that's exactly the problem. For a typical end user they are the system administrator too. There's no difference between a user tampering with the files and the system administrator tempering with the files because the machine owner, who is the player user, also has root privileges (or sudo).zzo38 {l Wrote}:Actually it does help, as long as the system administrator does not tamper with the scores.
Yes it would, because then you would need to have a software that can modify encrypted sqlite databases. To have such a software, you'd have to patch and compile the sqlite REPL, which is not something an average user can (or willing) to do. (There's no protection from experts, anything can be hacked. In the security industry we say a data is considered to be protected and safe not if the encryption is unbreakable (which could never be), rather when the price of hacking is higher than the value of the encrypted data.)zzo38 {l Wrote}:Encrypting them would not prevent the system administrator from altering the program to report incorrect scores, though.
Right, and that is a wise separation. What I'm trying to say is with the necessity of checks is, while the puzzle set file has a custom format, so it can only be modified through your program, where you can enforce the logic and consistency, but with a database file you allow modification through 3rd party software (the sqlite3 REPL), which will not enforce your logic at all. You must be prepared that you'll read inconsistent garbage from the database (hopefully you won't) You see, the difference is, using a custom format makes tempering with the puzzle files not part of normal operation, however by your own admission tempering with the database through 3rd party software is normal and allowed. And your program must not segfault during normal operation, no matter what (that's always a bug if it does).zzo38 {l Wrote}:There is actually two files; the database file and the puzzle set file. Both file formats are documented.
Actually in your case it won't, using encryption would be simpler (sqlite3aes is totally transparent to your application. You have to make one additional call after opening the database, but that's it). But I don't want to pressure you to use encryption, all I want to do is, make you aware what you must check everything you read from the database if you allow db access outside the game.zzo38 {l Wrote}:Avoiding encrypting the files also makes the program simpler,
I cannot judge CVS, SVN, Hg, since I have not read the documentation of them, but probably you are correct. (Fossil isn't perfect either, but their object formats and protocols are less confusing than git, and the command-line interface is also less confusing than git. I had made up (but not implemented, yet) "Generalized Fossil" which is slightly a variant of fossil, to improve what I consider are the problems; it is compatible enough anyways that an implementation of Generalized Fossil could reconstruct a deconstructed Fossil repository and all of the same structures will be present.)bzt {l Wrote}:Well, I don't know about fossil, but I've used CVS, SVN and Hg for a long time, and technically speaking git is far more superior to all of them.
If the user wants to assign them strangely, the program should not stop it. The software should not try to believe that what the user deliberately entered is wrong and that you really want something else; too many modern designs do that and I do not like that. A better design is that you have enough ropes to hang yourself and also a few more just in case; that is the UNIX philosophy, and it is better than Microsoft, Google, etc.Considering SQL injection is important, but that's not what I meant here. For example, you've said keyboard assignments are also stored in SQL. What if someone sets the key to left movement "Left" and right movement "Funky"+"Left"? Obviously there's no such key as "Funky", but with a trivial verification and invalid key removal now you'll end up having both left and right keys set to "Left". I meant things like that when I said you have to do a lot of sanity checks if you allow modifications outside of your game.
Yes, although I meant the situation in which case a local server is used; for a single user system, probably no server will be used. The user is only cheating themself, and as I explained, verification of scores is possible anyways. Even if you are on a multiuser system, it could use a server which is configured to expose move lists and puzzle sets, in which case the system administrator cannot effectively cheat because any user can verify the scores.You see, that's exactly the problem. For a typical end user they are the system administrator too. There's no difference between a user tampering with the files and the system administrator tempering with the files because the machine owner, who is the player user, also has root privileges (or sudo).zzo38 {l Wrote}:Actually it does help, as long as the system administrator does not tamper with the scores.
The data belongs to the end user so they can do what they want to do with it. Being able to access and modify the database is useful, even if it is not normally needed; a user can do so at their own risk.Yes it would, because then you would need to have a software that can modify encrypted sqlite databases. To have such a software, you'd have to patch and compile the sqlite REPL, which is not something an average user can (or willing) to do. (There's no protection from experts, anything can be hacked. In the security industry we say a data is considered to be protected and safe not if the encryption is unbreakable (which could never be), rather when the price of hacking is higher than the value of the encrypted data.)
It is not quite true. A non-composite puzzle set is four files, three of which are Hamster archive files, and one of which is a plain text file (which is expected to be read and altered using a text editor). A composite puzzle set is a Hamster archive file containing the other four (and is considered to be read-only; you must split them into separate files if you want to be able to edit them). Hamster archive format is not a common format, but this repository does contain a program (misc/har.c) for dealing with them; the UNLUMP and RELUMP programs included with OHRRPGCE can also deal with them (although they have less capabilities than har). (I had been trying to see if 7z, libarchive, etc could also implement Hamster archive format, but they have not done so at this time.)Right, and that is a wise separation. What I'm trying to say is with the necessity of checks is, while the puzzle set file has a custom format, so it can only be modified through your program, where you can enforce the logic and consistency, but with a database file you allow modification through 3rd party software (the sqlite3 REPL), which will not enforce your logic at all.zzo38 {l Wrote}:There is actually two files; the database file and the puzzle set file. Both file formats are documented.
SQLite has integrity checks in case the database is inconsistent. Regardless of the file formats, and regardless of whether or not any external programs support editing these formats, what is important is that untrusted files (in this case, the puzzle set files) do not cause security problems or other undesired operations. Trusted files (the database) is private and it is assumed that whatever the user puts in there is desired.You must be prepared that you'll read inconsistent garbage from the database (hopefully you won't) You see, the difference is, using a custom format makes tempering with the puzzle files not part of normal operation, however by your own admission tempering with the database through 3rd party software is normal and allowed. And your program must not segfault during normal operation, no matter what (that's always a bug if it does).
I believe it is best to allow you to have enough ropes to hang yourself and also a few more just in case; it should not try to hide things from the user or try to outguess you.Actually in your case it won't, using encryption would be simpler (sqlite3aes is totally transparent to your application. You have to make one additional call after opening the database, but that's it). But I don't want to pressure you to use encryption, all I want to do is, make you aware what you must check everything you read from the database if you allow db access outside the game.zzo38 {l Wrote}:Avoiding encrypting the files also makes the program simpler,
I have used valgrind for testing; it is very good. Sometimes this helped me to find some bugs.I've checked your code. Not bad at all, but it definitely lacks some more compile time and runtime checks. Have you tried to run it through valgrind for example? I suggest that you do, it has very very useful reports.
I have looked at SDL2, and I think there are some advantages and disadvantages compared with SDL1. If you want to run it on a computer with SDL2 but is not compatible with SDL1 (maybe Wayland, but I don't actually know), you may consider using the SDL compatibility layer (I have seen at least two such compatibility layers). If some feature does not work with the compatibility layer, you can report this, and I can consider whether to either fix it in my program or to forward the report to the authors of the compatibility layer for them to fix it instead.And also if I were you, I'd consider rewriting it for SDL2 (the render interface instead of the surface interface). Looking at your code I think it shouldn't be too hard, with surfaces you lock the surface to get the pixel buffer pointer and then you modify the buffer directly (mostly). This is pretty much the same with render, you lock the texture to get the pixel buffer's address, and then you can modify the buffer directly. This means the main logic and most parts of your game can be left untouched, you'll only have to replace the locking/unlocking part to make it SDL2 compatible.
Good.Anyway, well done, your project looks good! I like puzzles, I like the idea that you can create puzzles, and also it is written in C, one of the most bullet-proof and powerful languages in the world! Nice job!
As I've said the file format and the protocol is better. About the command line I agree, git has impossible switches, but you can use command aliases like with any other commands, that's what I do.zzo38 {l Wrote}:Fossil isn't perfect either, but their object formats and protocols are less confusing than git, and the command-line interface is also less confusing than git.
git != githubzzo38 {l Wrote}:I do have an account on GitHub
You are mistaken here. This is totally out of your control. Your program not just "should not", but literally "cannot" stop misbehaving users if you use sqlite, that's why you must assume your database is tempered with.zzo38 {l Wrote}:If the user wants to assign them strangely, the program should not stop it.
Yes, but your program should not crash nor segfault or misbehave in any other way on bad input either. All I'm saying is, if you allow users to edit the database, then your program must be prepared that it will receive bad input.zzo38 {l Wrote}:Being able to access and modify the database is useful, even if it is not normally needed; a user can do so at their own risk.
This isn't what I'm talking about. I mean when the database file is consistent, passes all sqlite validations, but stores values which are inconsistent with YOUR game. For example a negative value in the variables table for a variable which should be positive, things like that. You might be able to express some of your logic as sql constraints, but not all. Your program must not misbehave if invalid values (from your game's point of view) stored in a valid (from sqlite's point of view) database file.zzo38 {l Wrote}:SQLite has integrity checks in case the database is inconsistent.
Good, I'm glad we agree.zzo38 {l Wrote}:I agree that the program must not segfault during normal operation and that it is a bug if it does.
(Yeah, I cannot link a line to your fossil code...) In levels_column for example you do not check if n is valid, or if it does cause an out of bound reference, no check if *st is valid, or if it's returning a valid column value. You just pass a binary blob to sprintf without verification! sqlite3_column_text(st,nc) could return a NULL pointer if the database is invalid (that's not the same as the field type being an SQL NULL).zzo38 {l Wrote}:Which other compile time and runtime checks do you suggest? (Please be specific. "Check the file" is not specific enough.)
s = project_getint(s, &newsprite_gridw, 0, 1024);
s = project_getint(s, &newsprite_gridh, 0, 1024);
for(i = 0; i < 5; i++)
if(!memcmp(s, project_dirs[PROJDIRS_SPRITES + i], 2)) { sprites_cat = i; break; }
Agree, but for portability it's better to use SDL2 these days. But it's up to you.zzo38 {l Wrote}:I have looked at SDL2, and I think there are some advantages and disadvantages compared with SDL1.
Yes it is. You store game variables, keybindings and other things in the db which directly influence the game.zzo38 {l Wrote}:Another comment: The database is not related to the game logic.
bzt {l Wrote}:You are mistaken here. This is totally out of your control. Your program not just "should not", but literally "cannot" stop misbehaving users if you use sqlite, that's why you must assume your database is tempered with.
I made up a GitHub accout to write issues on projects that do use GitHub, though; I can't make those projects to use or not use GitHub. I do not use GitHub for my own projects, although since I have a account anyways making it a possible mirror will still be possible (e.g. if someone who is using GitHub for their own projects, intends to fork it); it need not be the only mirror. (SQLite uses fossil on their own server but also has a mirror on GitHub, too.)bzt {l Wrote}:Forget github. No FOSS projects should use that.
I know that, but I don't care if attribution is or is not given for my code.M$ is admittedly stealing source codes (via Co-pilot). It doesn't matter how much they pay to lawyers to say otherwise, it IS stealing, and not attributing the source IS in violation of GPL.
I already have fossil and I think I do not need to run git also (although I could add the git protocol in case someone will try to clone it using git, maybe). I may consider notabug.org, possibly.I was talking about having your own git repo, and running your own gitweb or gitea instance. For remote you can use notabug.org for example, but I believe it's even okay to have a gitlab mirror
Yes, that is a valid point; it is not the only one, so it is OK if some of the mirrors do use JS.(you should not worry about your secondary mirror requiring JS if your primary mirror doesn't need it.)
Yes, but this is a trusted file and so does not try to assume that the user is wrong, if possible. Keybindings/configurations can execute arbitrary code and this is by design. Still, some checks are performed, and if you can still cause a segfault (without doing something like loading a defective extension), then you should mention it so that it can be fixed (in either Free Hero Mesh or SQLite, whichever the bug is in).You are mistaken here. This is totally out of your control. Your program not just "should not", but literally "cannot" stop misbehaving users if you use sqlite, that's why you must assume your database is tempered with.zzo38 {l Wrote}:If the user wants to assign them strangely, the program should not stop it.Yes, but your program should not crash nor segfault or misbehave in any other way on bad input either. All I'm saying is, if you allow users to edit the database, then your program must be prepared that it will receive bad input.zzo38 {l Wrote}:Being able to access and modify the database is useful, even if it is not normally needed; a user can do so at their own risk.
There are actually three kind of tables: disk tables, temporary tables, and virtual tables. (Only disk tables can be accessed by external programs; the others do not exist outside of Free Hero Mesh.) Values are checked for all three kind of tables, where necessary, though.This isn't what I'm talking about. I mean when the database file is consistent, passes all sqlite validations, but stores values which are inconsistent with YOUR game. For example a negative value in the variables table for a variable which should be positive, things like that. You might be able to express some of your logic as sql constraints, but not all. Your program must not misbehave if invalid values (from your game's point of view) stored in a valid (from sqlite's point of view) database file.zzo38 {l Wrote}:SQLite has integrity checks in case the database is inconsistent.
This is a temporary table, and I use snprintf (not sprintf). Furthermore, it is guaranteed to be null terminated because sqlite3_column_text guarantees that (this is documented in the SQLite documentation), and that is the only thing which is relevant here. (In future, if I add support for multibyte character encodings (such as EUC-JP), then it will be necessary to also check that the width is correct, but that can be implemented in future.)(Yeah, I cannot link a line to your fossil code...) In levels_column for example you do not check if n is valid, or if it does cause an out of bound reference, no check if *st is valid, or if it's returning a valid column value. You just pass a binary blob to sprintf without verification! sqlite3_column_text(st,nc) could return a NULL pointer if the database is invalid (that's not the same as the field type being an SQL NULL).zzo38 {l Wrote}:Which other compile time and runtime checks do you suggest? (Please be specific. "Check the file" is not specific enough.)
I agree; it makes sense for your program to work even if it is not a format that Tiled can save, if the format is valid.Another example: my editor is capable of reading Tiled TMX files. Even though Tiled always saves TMX files like that, yet I do not assume that both firstgid and name is given for a tileset and that they appear in this order in the file. I do check for all valid encodings (csv, gzip, zlib, zstd etc.) too, and my code does not misbehave if the encoding is something that Tiled can't even save. I mean things like that.
By using the SDL compatibility layer, you can run programs using SDL1 with SDL2 instead, so I would expect that SDL1-based programs will run on both SDL1-based systems and on SDL2-based systems (although possibly lacking some features), but I think that SDL2-based programs do not work on SDL1-based systems.Agree, but for portability it's better to use SDL2 these days. But it's up to you.zzo38 {l Wrote}:I have looked at SDL2, and I think there are some advantages and disadvantages compared with SDL1.
There is a separation between the game state (exec.c) and the input/output (game.c). The game state itself is exposed as virtual tables, but these are read-only during the game (it enforces this; the game engine can modify the contents of this table but SQL code cannot do so); however, they are writable in the level editor (which is deliberate, in order to allow user-defined batch operations to be performed). Saved game data is stored on disk, and it does check this too.Yes it is. You store game variables, keybindings and other things in the db which directly influence the game.zzo38 {l Wrote}:Another comment: The database is not related to the game logic.
But if you allow the user to alter the database outside of your control, then you simply cannot trust the values in that file. Simple as that. Be paranoid, check everything, that's all I'm saying (you already have plenty of checks, which is good, just make sure you have every necessary checks.)zzo38 {l Wrote}:Yes, but this is a trusted file and so does not try to assume that the user is wrong, if possible.
Nope, only formats that Tiled can save considered valid, but the point is, my code does not misbehave when it encounters an invalid file.zzo38 {l Wrote}:I agree; it makes sense for your program to work even if it is not a format that Tiled can save, if the format is valid.
Yep, but SDL-1 is EOL, the number of systems supporting SDL-1 is rapidly shrinking, and at the same time SDL-2 gets supported on more and more systems. My Linux distro has removed SDL-1 support entirely just a few days ago. Under emscripten (if you ever want to port your game into a webbrowser) SDL-1 works for now, but very limited, missing features and admittedly unmaintained, so no way of knowing for how long it will be an option at all. They say everyone is expected to use the SDL-2 port only, because the SDL project itself expects everyone to upgrade to SDL-2 ("right away" they have said in 2013). The last release of SDL-1 was 9 years ago, unmaintained ever since, only SDL-2 was updated in the past nearly one decade.zzo38 {l Wrote}:I think that SDL2-based programs do not work on SDL1-based systems.
Try running compile, otherwise I agree, it would be more fortunate to use GNU make, and the well known make all install should work with it.glitchapp {l Wrote}:complicated compilation process prevents me from discovering and testing software
Providing up-to-date binaries for your code in different package formats and for different systems is not an easy task. It would be great if they could do it of course, but please understand that it is a lot to ask so you simply cannot expect having binaries.glitchapp {l Wrote}:Have you considered creating a package? Appimage, flatpak or deb for example?
Don't you worry, I knew :-) My advice to you "try running compile" is about the Puzzle game Engine.glitchapp {l Wrote}:Hi bzt, sorry for the confusion, I'm not used to this forum and I've replied to the last post which was yours, but I was talking about the Puzzle game Engine.
Thank you! Yeah, I wanted to make it simple and easy to learn, but I know I have failed on that department. I'm planning a refactor a bit to make the UI more intuitive, but until then maybe the manual can help.glitchapp {l Wrote}:Your tool is awesome and I did not have any problem to make it run, so what I said does not apply to you. The only thing I can say is that it has its learning curve, but that's to be expected with a tool with which you can program games without a single line of code. Congratulations!
bzt {l Wrote}:Yep, but SDL-1 is EOL, the number of systems supporting SDL-1 is rapidly shrinking, and at the same time SDL-2 gets supported on more and more systems. My Linux distro has removed SDL-1 support entirely just a few days ago. Under emscripten (if you ever want to port your game into a webbrowser) SDL-1 works for now, but very limited, missing features and admittedly unmaintained, so no way of knowing for how long it will be an option at all. They say everyone is expected to use the SDL-2 port only, because the SDL project itself expects everyone to upgrade to SDL-2 ("right away" they have said in 2013). The last release of SDL-1 was 9 years ago, unmaintained ever since, only SDL-2 was updated in the past nearly one decade.
I tried to improve the compilation process, but some things might need to be configured manually. I tried to make the documentation clear and will continue to improve it as needed; the compile script may also be improved if needed (I had recently added some things due to suggestions on this forum, too).glitchapp {l Wrote}:I hope the developer of this great tool don't take this wrong, but complicated compilation process prevents me from discovering and testing software. This is honest. Have you considered creating a package? Appimage, flatpak or deb for example?
Yes, this is the difficulty and is the main reason why I did not do it. This does not mean that nobody can do it; different people who work with different package management systems and different operating systems, computers, etc, can do it if wanted, and I can help to answer questions, add patches if needed, etc, to ensure that it can work properly.bzt {l Wrote}:Providing up-to-date binaries for your code in different package formats and for different systems is not an easy task. It would be great if they could do it of course, but please understand that it is a lot to ask so you simply cannot expect having binaries.
Actually, all package manager expects desktop integration, AppImage is no exception. The example parameters you provided are the means of desktop integration :-) Normally that text will be saved under /usr/share/applications/*.desktop, and all desktop environments (like GNOME, Mate, KDE, LXDE etc.) are parsing that directory to figure out what applications are installed, this way the list is independent to the distro and the actual package manager (could it be apt, rpm, emerge, pacman etc. doesn't matter).glitchapp {l Wrote}:The only type of package I ever created is AppImage, and all you need is an icon, no need for desktop integration or anything, as an example these are all the parameters you need to edit:
Should be no problem. I haven't used AppImage myself, but I know it works this way: it creates a SquashFS archive out of a directory, and appends that archive to a (not so) small code which is then distributed as a single file (called AppImage). On execution, that preambule runtime unpacks the attached archive into a temporary directory and then executes the freshly unpacked game's binary called "AppRun".glitchapp {l Wrote}:how to communicate outside the package (save etc).
I don't think that's necessary. The ld-linux.so parses the ELF binary looking for the required shared libraries, and it will print a verbose, meaningful error message if one of those is missing. I've seen some debian and bugbuntu distros that are even making suggestions what package to install to get that library. (BTW, you can list those needed shared library records yourself with the ldd heromesh command, the shorter that list is, the more portable your code is).glitchapp {l Wrote}:Another solution is to create a custom script that checks if all the required libraries are meet and if not try to install them or show in the terminal the possible commands to do it.
application/x-free-hero-mesh fhm
[Desktop Entry]
Version=1.0
Type=Application
Name=Free Hero Mesh
Exec=/usr/bin/heromesh
Icon=heromesh
Terminal=false
StartupNotify=false
Categories=Application;Game;
MimeType=application/x-free-hero-mesh;
Actions=View
[Desktop Action View]
Name=Play with Free Hero Mesh
Exec=/usr/bin/heromesh %F
This can be done easily enough, at least if sandbox capabilities are not used. (AppImage does not use sandbox capabilities, but Flatpak does.)glitchapp {l Wrote}:how to communicate outside the package (save etc).
Having read the AppImage documentation (but I had not actually used it), I mostly agree; I also looked at the source code you mentioned. It will only set the HOME variable if there is a writable directory with the same name as the AppImage file but with ".home" added on the end.bzt {l Wrote}:Should be no problem. I haven't used AppImage myself, but I know it works this way: it creates a SquashFS archive out of a directory, and appends that archive to a (not so) small code which is then distributed as a single file (called AppImage). On execution, that preambule runtime unpacks the attached archive into a temporary directory and then executes the freshly unpacked game's binary called "AppRun".
Truth to be told, by a quick look I haven't seen anything in that runtime that would prevent you from accessing files outside of the temporary directory. It does some nasty and dirty hacks to hide the paths (like messing with the HOME variable), but no "chroot" or any similar security feature used as far as I can tell. Absolute paths should work as-is.
On my computer, I get the list:bzt {l Wrote}:The ld-linux.so parses the ELF binary looking for the required shared libraries, and it will print a verbose, meaningful error message if one of those is missing. I've seen some debian and bugbuntu distros that are even making suggestions what package to install to get that library. (BTW, you can list those needed shared library records yourself with the ldd heromesh command, the shorter that list is, the more portable your code is).
linux-vdso.so.1 => (0x00007ffe382db000)
libSDL-1.2.so.0 => /usr/lib/x86_64-linux-gnu/libSDL-1.2.so.0 (0x00007f5724981000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f572477d000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f572455f000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5724263000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5723ea2000)
libasound.so.2 => /usr/lib/x86_64-linux-gnu/libasound.so.2 (0x00007f5723bb4000)
libpulse-simple.so.0 => /usr/lib/x86_64-linux-gnu/libpulse-simple.so.0 (0x00007f57239b0000)
libpulse.so.0 => /usr/lib/x86_64-linux-gnu/libpulse.so.0 (0x00007f5723768000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f5723432000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f5723221000)
libcaca.so.0 => /usr/lib/x86_64-linux-gnu/libcaca.so.0 (0x00007f5722f56000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5724c33000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f5722d4d000)
libpulsecommon-1.1.so => /usr/lib/x86_64-linux-gnu/libpulsecommon-1.1.so (0x00007f5722aef000)
libjson.so.0 => /usr/lib/x86_64-linux-gnu/libjson.so.0 (0x00007f57228e7000)
libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3 (0x00007f57226a2000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f572247d000)
libslang.so.2 => /lib/x86_64-linux-gnu/libslang.so.2 (0x00007f572210c000)
libncursesw.so.5 => /lib/x86_64-linux-gnu/libncursesw.so.5 (0x00007f5721ede000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f5721cb7000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f5721aa0000)
libwrap.so.0 => /lib/x86_64-linux-gnu/libwrap.so.0 (0x00007f5721896000)
libsndfile.so.1 => /usr/lib/x86_64-linux-gnu/libsndfile.so.1 (0x00007f5721630000)
libasyncns.so.0 => /usr/lib/x86_64-linux-gnu/libasyncns.so.0 (0x00007f572142a000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f5721226000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f5721020000)
libnsl.so.1 => /lib/x86_64-linux-gnu/libnsl.so.1 (0x00007f5720e06000)
libFLAC.so.8 => /usr/lib/x86_64-linux-gnu/libFLAC.so.8 (0x00007f5720bbb000)
libvorbisenc.so.2 => /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2 (0x00007f57206ec000)
libvorbis.so.0 => /usr/lib/x86_64-linux-gnu/libvorbis.so.0 (0x00007f57204c0000)
libogg.so.0 => /usr/lib/x86_64-linux-gnu/libogg.so.0 (0x00007f57202b8000)
libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f572009c000)
bzt {l Wrote}:@zzo38: Anyway, here are my two cents on packaging, if you decide to provide binaries:
Do not use /bin/heromesh as target, that violates File Hierarchy Standard. Use /usr/bin/heromesh or /usr/local/bin/heromesh instead. (Rationale: according to FHS, /bin is reserved for system management and essential tools. Applications like games are considered to be User Sharable Resources, therefore should be placed under /usr/bin.)
OK, I can consider this possibility, then.bzt {l Wrote}:Even better, simply output heromesh, and use sudo install to copy that to its final place under /usr/bin (the install tool is very similar to cp, but it also sets file permissions and safe to execute as root.)
Nevertheless, there are reasons why I cannot. Why should every program need to have a icon, anyways (even if you do not have a desktop environment; I do not use a desktop environment on my own computer)?bzt {l Wrote}:Having an icon and a .desktop file as @glitchapp suggested, is a VERY good advice. You should add those.
The MIME type of a Free Hero Mesh composite puzzle set (which is mentioned in the documentation) is "application/freeheromesh.composite+hamarc" (there is no MIME type for non-composite puzzle sets). Currently no file name extension is defined, but ".fhm" can work, so I can use that. (UTI and unordered-labels-file-format-identification are also defined. My opinion is that unordered-labels-file-format-identification is clearly better, but it is not really in use, so MIME and UTI are also specified.)bzt {l Wrote}:
- You could name your puzzle files with a unique extension (fhm looks fine), and add that extension and an unofficial mime type to /etc/mime.types, for example
- {l Code}: {l Select All Code}
application/x-free-hero-mesh fhm
- If you have an associated mime type, then you can write the desktop file in a way to automatically open the puzzle game files with your app
I do intend also to make Debian/Ubuntu packages (and possibly others). I had read the package management documentation, and it doesn't seem to be quite so simple; the PORTING file has some notes I made about this.bzt {l Wrote}:
- You should consider .deb archives, as those are easy to create (just standard compilation tools, no 3rd party application required, here's an example), and you can specify SDL as a dependency, so apt will install libsdl on its own (either it's SDL1.2 or the SDL2 compatibility), therefore you don't have to worry about the libs.
- Same goes for all the other packaging formats, but .deb is the most widespread thanks to ubuntu and the other "user-friendly" distros.
Nevertheless, there are reasons why I cannot. Why should every program need to have a icon, anyways (even if you do not have a desktop environment; I do not use a desktop environment on my own computer)?
Free Hero Mesh will not run without command-line arguments; the puzzle set name MUST be specified.
The last line probably should be "Exec=/usr/bin/heromesh -z %f"; the -z switch is required for loading composite puzzle sets, and it cannot load multiple puzzle sets at once, and the specification says "%F" is for multiple files and "%f" is for a single file.
And here's the TirNanoG Editor. Note, I'm a very experienced C programmer, and I did lots of tricks (including configuring and compiling SDL myself) to achieve this:zzo38 {l Wrote}:On my computer, I get the list:
$ ldd /usr/bin/tnge
linux-vdso.so.1 (0x00007fff2973c000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f2c74c6c000)
libmvec.so.1 => /usr/lib/libmvec.so.1 (0x00007f2c6cb04000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f2c6c800000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f2c74d6c000)
The magic with SDL_mixer is configuring with --disable-shared and if you want other formats, with --enable-music-ogg-shared for example. This will not link with the shared libraries, rather it will compile a code that tries to link in run-time (using dlopen). The only difference from your code's perspective, that if for example libogg and libvorbis cannot be loaded, then Mix_Open(MIX_INIT_OGG) will return an error, instead of Linux complaining and refusing to run your app. But WAV is always supported, it does not need any libraries in the first place.zzo38 {l Wrote}:does not use any sound file formats other than WAV
Yes, you can, and you should. Just two small files in your repo (a .desktop and a .png), not a big deal. You might not use a desktop environment (me neither), but rest assured, your average users do.zzo38 {l Wrote}:Nevertheless, there are reasons why I cannot. Why should every program need to have a icon, anyways (even if you do not have a desktop environment; I do not use a desktop environment on my own computer)?
Feel free to tweak it to your needs. I gave it just as an example and a skeleton you can mess with.zzo38 {l Wrote}:The desktop file you wrote seems to be mostly good enough, except:
Yep, you can't use that. Only IANA can assign such official mime types. For unofficial types, you must start it with "x-".zzo38 {l Wrote}:The MIME type of a Free Hero Mesh composite puzzle set (which is mentioned in the documentation) is "application/freeheromesh.composite+hamarc"
Excellent news!zzo38 {l Wrote}:I do intend also to make Debian/Ubuntu packages (and possibly others).
Don't let the doc fool you, it is really simple. Take a look at the Makefile I have linked.zzo38 {l Wrote}:I had read the package management documentation, and it doesn't seem to be quite so simple
That's a very good idea too. Also the only way if you want to port to Android for example (which is simply not capable of handling program arguments... yeah, really. Sad, but true).glitchapp {l Wrote}:Create a starting menu where you can input or select the puzzle set name.
The problem is that I do not have a icon.glitchapp {l Wrote}:Nevertheless, there are reasons why I cannot. Why should every program need to have a icon, anyways (even if you do not have a desktop environment; I do not use a desktop environment on my own computer)?
Not every program should have an icon but icons help identify programs and in a tool like yours I think would be very useful. The original tool in which your tool is based have an icon.
In future, a separate "launcher" program might be written which will do this (and possibly some other things too). This is not my highest priority at this time, although itis something that I intend.Free Hero Mesh will not run without command-line arguments; the puzzle set name MUST be specified.
Create a starting menu where you can input or select the puzzle set name. Developers and players are different. I love the terminal and parameters but players usually do not like complicated commands and the terminal, they just want to play the game and they like interfaces.
If you tell it to start with a specific puzzle set, then it should do so, isn't it? (So that you do not need to go through the menus, etc)The package should not start the game with an specific puzzle, it should start an interface or a menu or input screen, no matter how rudimentary or sophisticated, where you can select which level you want to play.
MESH:Hero Hearts does have a icon, and starts with the previously loaded puzzle set (and you can select different puzzle sets at runtime); you cannot specify which puzzle set or level to start by command-line arguments. I decided that specifying by command-line arguments is better, but I am willing to accept patches to allow it to work both ways.I did not buy the original tool but I'm pretty sure it does all the things I mentioned above.
I did look at that. I do not really intend to do this (at this time), but someone else might do so. Maybe someone can figure out how to avoid the dependencies that I do not use, somehow. (Maybe I used the wrong linker settings; I don't know.)bzt {l Wrote}:And here's the TirNanoG Editor. Note, I'm a very experienced C programmer, and I did lots of tricks (including configuring and compiling SDL myself) to achieve this: ... If you want to get some pointers, and looking for hints how I did it, check out my Makefile. Also read the README.md in the directories, because I had to patch some libraries manually for this.zzo38 {l Wrote}:On my computer, I get the list:
My program does not use SDL_mixer; it only uses SDL_LoadWAV_RW, and the other built-in SDL sound-oriented functions. (I don't know why it lists dependencies for dealing with other file formats, which are not used.)The magic with SDL_mixer is configuring with --disable-shared and if you want other formats, with --enable-music-ogg-shared for example. This will not link with the shared libraries, rather it will compile a code that tries to link in run-time (using dlopen). The only difference from your code's perspective, that if for example libogg and libvorbis cannot be loaded, then Mix_Open(MIX_INIT_OGG) will return an error, instead of Linux complaining and refusing to run your app. But WAV is always supported, it does not need any libraries in the first place.zzo38 {l Wrote}:does not use any sound file formats other than WAV
OK I will put a desktop file, but I do not have a icon, to put.Yes, you can, and you should. Just two small files in your repo (a .desktop and a .png), not a big deal. You might not use a desktop environment (me neither), but rest assured, your average users do.zzo38 {l Wrote}:Nevertheless, there are reasons why I cannot. Why should every program need to have a icon, anyways (even if you do not have a desktop environment; I do not use a desktop environment on my own computer)?
The use of "X-" is deprecated. I will use it without "x-"; this is also the case for some other formats, such as "text/gemini" also is not in the official list of MIME types. Sometimes some people still use "x-" and to me (and some others), we will use it when it is something that there is no point to be standardized (such as "X-Clacks-Overhead" or other similar ideas), or for something that is already using it.Yep, you can't use that. Only IANA can assign such official mime types. For unofficial types, you must start it with "x-".zzo38 {l Wrote}:The MIME type of a Free Hero Mesh composite puzzle set (which is mentioned in the documentation) is "application/freeheromesh.composite+hamarc"
Yes, although there are the Debian policies, etc. Although I statically link SQLite, I think that on Debian it is supposed to use the dependencies instead, but it must be ensured that it is the correct version of SQLite and sometimes the version included in the package manager is too old. Also, the "har" program probably should be put into a separate package (which will be Recommended or Suggested by this one). It might also want to Recommend or Suggest a virtual package for farbfeld (I do not know if there is such a virtual package, although the latest version of ImageMagick is suitable, as are some other programs which do not involve ImageMagick). There is also source packages, documentation, etc.Don't let the doc fool you, it is really simple. Take a look at the Makefile I have linked.zzo38 {l Wrote}:I had read the package management documentation, and it doesn't seem to be quite so simple
Basically a .deb file is nothing more than an "ar" archive ...
A port to Android will probably need many more changes than only that (see the PORTING file for some notes about this).bzt {l Wrote}:That's a very good idea too. Also the only way if you want to port to Android for example (which is simply not capable of handling program arguments... yeah, really. Sad, but true).glitchapp {l Wrote}:Create a starting menu where you can input or select the puzzle set name.
(Some of the things mentioned in this thread suggest being written by people who have not read the documentation (which answers some of the questions that you may have).)
The problem is that I do not have a icon.
I decided that specifying by command-line arguments is better
In future, a separate "launcher" program might be written which will do this (and possibly some other things too). This is not my highest priority at this time, although itis something that I intend.
I can accept any patches if anyone wants to contribute any; this way it can get done faster, I suppose..
Users browsing this forum: No registered users and 1 guest