Free Hero Mesh [Puzzle Game Engine]

Free Hero Mesh [Puzzle Game Engine]

Postby zzo38 » 07 Jul 2022, 19:30

About: This project is a puzzle game engine for turn-based grid-based puzzle games, involving objects moving around (e.g. Sokoban, Hero Hearts). It was made originally as a clone of Everett Kaser's MESH:Hero Hearts, but now has many new features too that the original game engine does not have, too. It is in a usable state (I often use it to play Hero Hearts puzzles, and I have made up some of my own puzzles too), although many further improvements are still possible.

Contributions: Any kind of contributions will be wanted, e.g. code patches, bug reports, feature suggestions, documentation, community, promotion, packaging/distribution, etc. Please use the NNTP and/or IRC for discussion.

Project page: http://zzo38computer.org/freeheromesh/

Code license: Public domain.

Assets license: N/A.

Note: I am using fossil and not git to manage this project. (I think that fossil is much less confusing than git.)
zzo38
 
Posts: 26
Joined: 07 Jul 2022, 19:04

Re: Free Hero Mesh [Puzzle Game Engine]

Postby glitchapp » 11 Jul 2022, 17:07

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
glitchapp
 
Posts: 15
Joined: 05 Mar 2022, 10:00

Re: Free Hero Mesh [Puzzle Game Engine]

Postby zzo38 » 11 Jul 2022, 20:14

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
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.

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 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.

(EDIT) I have made some improvements to the README and compile script now; hopefully this is an improvement.
zzo38
 
Posts: 26
Joined: 07 Jul 2022, 19:04

Re: Free Hero Mesh [Puzzle Game Engine]

Postby bzt » 12 Jul 2022, 08:42

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.
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}: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.
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.

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).

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 ;-)

Cheers,
bzt
Attachments
mirror.png
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Free Hero Mesh [Puzzle Game Engine]

Postby zzo38 » 12 Jul 2022, 19:44

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 ;-)
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.)

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.
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.

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).
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.

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 ;-)
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).)
zzo38
 
Posts: 26
Joined: 07 Jul 2022, 19:04

Re: Free Hero Mesh [Puzzle Game Engine]

Postby bzt » 13 Jul 2022, 14:45

zzo38 {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
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 example
{l Code}: {l Select All Code}
# 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

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).
Yes, it is working now, thanks! The mirrors are still having that (obviously), but your local webrepo doesn't.

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.
It is painfully slow now (takes about 40-50 secs to load), but at least it does not time out.

zzo38 {l Wrote}:I will not use GitLab, because it will not display anything if JavaScripts are disabled.
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 intend to keep these files unencrypted. The program running for one local user should not try to prevent them from accessing them
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}:If you want to, you can prevent other local users from accessing the file by use of chmod.
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 verify scores, there is another way; you could send them to a server
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}:or to another program on the same computer, for local multiuser scoring
Won't solve the issue either, it would just replace one unencrypted file with another on the same local machine.

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.

Cheers,
bzt
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Free Hero Mesh [Puzzle Game Engine]

Postby zzo38 » 14 Jul 2022, 00:11

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.)
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.)

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
But then they can mess with it and fake high-scores, unlock levels etc. Maybe that's not something you want to allow.
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.)

A puzzle set normally includes the solutions (and it is then possible for a player to replay them, or to copy them and try to make a better score by changing some moves; the solution file also can be used as test cases). A solution file is required, although it may be empty if you do not want to publish the solutions. Your own move lists also can be published if desired, or you can keep them private if wanted. However, if you want someone else to verify your scores then they will need a copy of the move lists as well as a copy of the puzzle set.

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 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.

zzo38 {l Wrote}:If you want to verify scores, there is another way; you could send them to a server
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.)
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).

Servers (if a player wishes to use them) could be configured to publish the move lists or to keep them private, or they could reveal the move lists after some specified amount of time has passed. A server could also be configured only to make puzzle sets available for download (identified by their hash, perhaps) without storing any scores, if this is preferred. Whether or not others can submit puzzle set files, also can be configurable.

zzo38 {l Wrote}:or to another program on the same computer, for local multiuser scoring
Won't solve the issue either, it would just replace one unencrypted file with another on the same local machine.
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.)

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.
I agree it is not worth it like you say. The end user should have full control over their own files and programs.

There is actually two files; the database file and the puzzle set file. Both file formats are documented.

The database file is meant to be private; it is not meant to be transferred to anyone else (and it is not very useful to do so). A user tampers with this file only at their own risk. If there are segfaults or other security problems, this is not considered to be a major bug, although you may report it anyways if you want to (but it isn't a high priority).

The puzzle set files are meant to be distributed, and there are checks done in the program; malformed puzzle set files should never cause segfaults, arbitrary code execution, etc. If it does cause segfaults or other security problems, this is considered to be a major bug; please report them (and if you know how, provide a patch to fix them), because this one is a high priority.

Avoiding encrypting the files also makes the program simpler, and the source codes are available anyways so it won't really stop you from tampering with them if you really want to do so.
zzo38
 
Posts: 26
Joined: 07 Jul 2022, 19:04

Re: Free Hero Mesh [Puzzle Game Engine]

Postby bzt » 14 Jul 2022, 09:35

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.
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}: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.
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 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
Good!

zzo38 {l Wrote}:Actually it does help, as long as the system administrator does not tamper with 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}:Encrypting them would not prevent the system administrator from altering the program to report incorrect scores, though.
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}:There is actually two files; the database file and the puzzle set file. Both file formats are documented.
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}:Avoiding encrypting the files also makes the program simpler,
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.

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. 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.

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!

Cheers,
bzt
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Free Hero Mesh [Puzzle Game Engine]

Postby zzo38 » 14 Jul 2022, 21:13

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.
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.)

I do have an account on GitHub (I needed to create the account on another computer but then I could access it on this computer), which I did that I might be able to write issues on other projects. Although some features of GitHub require JavaScripts, some don't; reading the file lists and files, and reading the API documentation, does not require JavaScripts. I do not use it for my own projects (although mirrors on GitHub and other services would still be possible, which I might do in future; currently the only mirror is on Chisel).

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.
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.

(This is especially the problem in web browsers that do not let end users do what you want to do, and tries to override your decisions and hides things from you. This is why I still use a very old version (and I still need to heavily customize it to make it being reasonable, and still many things aren't working reasonably); the new ones are bad in many ways. They keep removing good features and adding bad ones instead.)

(I have game "amoebax" (also FOSS) and the configuration menu does not allow to set the same keys for both players. Nevertheless that is what I wanted to do, but fortunately, I found the configuration file and edited that and that did what I wanted it to do.)

zzo38 {l Wrote}:Actually it does help, as long as the system administrator does not tamper with 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).
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.

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.)
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.

zzo38 {l Wrote}:There is actually two files; the database file and the puzzle set file. Both file formats are documented.
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.
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.)

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).
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.

(There are also many virtual tables and temporary tables which are exposed to the end user (this is documented). It is intended that the user can use them if they are believed to be useful to you. I have found them useful a few times, although non-advanced users might not have any use for them, which is also OK.)

I agree that the program must not segfault during normal operation and that it is a bug if it does.

zzo38 {l Wrote}:Avoiding encrypting the files also makes the program simpler,
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.
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.

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 used valgrind for testing; it is very good. Sometimes this helped me to find some bugs.

Which other compile time and runtime checks do you suggest? (Please be specific. "Check the file" is not specific enough.)

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.
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.

I also wrote a PORTING file, with notes in case anyone wishes to port it to anything or include it in any kind of distributions, and some of the considerations about doing so. Probably exec.c will be used as is or nearly as is, and other files might need more modifications or being replaced entirely (possibly copying some code from them).

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!
Good.

Another comment: The database is not related to the game logic. This means that an alternative implementation which uses the same game logic can use an entirely different database (or none at all), different user interfaces, etc, and still be compatible with the same puzzle set files and same games.

Note that any puzzle set that includes solutions are also test cases for the game logic; you can run "heromesh -a" to automatically test them (and report any errors that occur). This means that in case of porting or changes (either to the puzzle set's class definitions or to the game engine implementation) can be tested that they do not break the existing game logic.
zzo38
 
Posts: 26
Joined: 07 Jul 2022, 19:04

Re: Free Hero Mesh [Puzzle Game Engine]

Postby bzt » 15 Jul 2022, 10:09

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.
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}:I do have an account on GitHub
git != github

Forget github. No FOSS projects should use that. 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 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 (you should not worry about your secondary mirror requiring JS if your primary mirror doesn't need it.)

zzo38 {l Wrote}:If the user wants to assign them strangely, the program should not stop it.
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}: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, 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}:SQLite has integrity checks in case the database is inconsistent.
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}:I agree that the program must not segfault during normal operation and that it is a bug if it does.
Good, I'm glad we agree.

zzo38 {l Wrote}:Which other compile time and runtime checks do you suggest? (Please be specific. "Check the file" is not specific enough.)
(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).

But that's just one example. In general I can only give you examples. Take a look at my TirNanoG Editor for example. I allow users to edit the project files with third party tools for example (these are plain text files). Therefore I do check everything I could think of, for example does the line end in '\r\n'? Fine, then '\r' must not cause trouble. But in more general, I set all values to be read from the file to a valid, known-to-be good state on file open, and only change those if the value actually read from the file is indeed valid. Loading the grid's size of a sprite layout for example looks like this:
{l Code}: {l Select All Code}
s = project_getint(s, &newsprite_gridw, 0, 1024);
s = project_getint(s, &newsprite_gridh, 0, 1024);
This project_getint() function verifies that s isn't NULL, *s isn't 0, and it does not simply do an atoi() on it, but also checks if the parsed integer is indeed in the given range (0 - 1024 in this case). If not, then the default newsprite_gridw (or gridh) won't be changed. Reading in sprite category looks like this:
{l Code}: {l Select All Code}
    for(i = 0; i < 5; i++)
        if(!memcmp(s, project_dirs[PROJDIRS_SPRITES + i], 2)) { sprites_cat = i; break; }
It does not blindly do an sscanf("%s"), no. It iterates on the possible values, and if the string in the file isn't one of them, then the sprites_cat variable left unchanged (remember it was initialized to a known-to-be good value).
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.

zzo38 {l Wrote}:I have looked at SDL2, and I think there are some advantages and disadvantages compared with SDL1.
Agree, but for portability it's better to use SDL2 these days. But it's up to you.

zzo38 {l Wrote}:Another comment: The database is not related to the game logic.
Yes it is. You store game variables, keybindings and other things in the db which directly influence the game.

Please don't get me wrong. By reading your code I can tell a lot of thinking was put into, and I can see that you have written it in a way to be bullet-proof. Not many developers think that way, which definitely makes you a good programmer. All I'm trying to say is, think a bit more, try fuzzing your code with multiple bad inputs, and your code will be perfect. To be clear I wouldn't say these advice if I weren't see the potential in you, and your code is really good, and I think it just needs a little bit of push to be really great.

Cheers,
bzt
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Free Hero Mesh [Puzzle Game Engine]

Postby dulsi » 15 Jul 2022, 17:33

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 disagree. If we had all the time in the world, I agree we should handle any anomaly. If a file (sqlite, text, etc.) shouldn't be modified by hand and cannot cause random code to be executed, adding checks are a low priority. This might not be true for all programs but for games it is not a big deal. (Some exceptions could exist like if it could cause flashing which can be problematic for some or maybe induce nausea in VR display.) If you have a choice of making the code "perfect" or polishing the game/starting a new code, spending the time to make the code "perfect" might not be worth it.
dulsi
 
Posts: 570
Joined: 18 Feb 2016, 15:24

Re: Free Hero Mesh [Puzzle Game Engine]

Postby zzo38 » 15 Jul 2022, 23:53

bzt {l Wrote}:Forget github. No FOSS projects should use that.
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.)

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 know that, but I don't care if attribution is or is not given for my code.

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
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.

(you should not worry about your secondary mirror requiring JS if your primary mirror doesn't need it.)
Yes, that is a valid point; it is not the only one, so it is OK if some of the mirrors do use JS.

zzo38 {l Wrote}:If the user wants to assign them strangely, the program should not stop it.
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}: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, 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.
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).

Puzzle set files are considered to be untrusted code (since they are meant to be published, rather than private), so checking them is more careful, and cannot execute arbitrary native code, etc. If you can find some segfault or other security problem with this, then you should report it. (Unfortunately, the stack protection does not currently work properly. I tried to implement this because I considered it to be important, but it doesn't seem to work; sorry. If you can fix it, then you can please do so.)

zzo38 {l Wrote}:SQLite has integrity checks in case the database is inconsistent.
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.
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.

zzo38 {l Wrote}:Which other compile time and runtime checks do you suggest? (Please be specific. "Check the file" is not specific enough.)
(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).
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.)

Nevertheless, I could fix some of these things: check that the number of columns is correct (it will only be wrong if the user deliberately alters the number of columns at run time), and that the return value of sqlite3_column_text is not null (I think snprintf already checks anyways, but I can check anyways in case some implementations don't). SQLite checks if *st is valid (this is documented); I do not need to do so in my own code. A buffer overflow is not caused because the type of dc->width is Uint8 and buf is 256 bytes long, and snprintf is used (and a below code that uses memcpy also checks that the number is in range). Even though a comment says "This implementation does not check that the format is necessarily valid", it is harmless if it is not valid; it will simply result in an empty column in the level menu.

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.
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.

zzo38 {l Wrote}:I have looked at SDL2, and I think there are some advantages and disadvantages compared with SDL1.
Agree, but for portability it's better to use SDL2 these days. But it's up to you.
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.

zzo38 {l Wrote}:Another comment: The database is not related to the game logic.
Yes it is. You store game variables, keybindings and other things in the db which directly influence the game.
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.
zzo38
 
Posts: 26
Joined: 07 Jul 2022, 19:04

Re: Free Hero Mesh [Puzzle Game Engine]

Postby glitchapp » 16 Jul 2022, 07:39

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?
glitchapp
 
Posts: 15
Joined: 05 Mar 2022, 10:00

Re: Free Hero Mesh [Puzzle Game Engine]

Postby bzt » 16 Jul 2022, 09:21

zzo38 {l Wrote}:Yes, but this is a trusted file and so does not try to assume that the user is wrong, if possible.
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}: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.
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 think that SDL2-based programs do not work on SDL1-based systems.
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.

You can keep SDL-1 of course, but I think it really worth thinking about migrating to SDL-2. (Truth to be told, I too have a project which is still using SDL-1, and I was also hesitant to migrate it until now, but since my distro removed SDL-1 support I left with no other options, I must do it sooner than later, no escape. So I understand your hesitance very well. On the bright side, zooming was a bit slow with CPU generated surfaces, and it will get a lot more performant using GPU rendering, and I'm sure you can find similar silver lining with SDL-2 in your project too.)

glitchapp {l Wrote}:complicated compilation process prevents me from discovering and testing software
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}:Have you considered creating a package? Appimage, flatpak or deb for example?
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.

Cheers,
bzt
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Free Hero Mesh [Puzzle Game Engine]

Postby glitchapp » 16 Jul 2022, 11:04

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.

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 for a tool with which you can program games without a single line of code. Congratulations!
glitchapp
 
Posts: 15
Joined: 05 Mar 2022, 10:00

Re: Free Hero Mesh [Puzzle Game Engine]

Postby bzt » 16 Jul 2022, 11:24

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.
Don't you worry, I knew :-) My advice to you "try running compile" is about the Puzzle game Engine.

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!
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.

Cheers,
bzt
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Free Hero Mesh [Puzzle Game Engine]

Postby dulsi » 16 Jul 2022, 13:11

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.

What distro are you using? SDL1 was removed from Fedora but they added in a SDL1 compatibility like what zz038 mentioned using. I will say the compatibility is not perfect. I tried Icebreaker on Fedora 35 and could not get it running. I haven't had a chance to try again to see if it is fixed.

I would recommend porting to SDL2. SDL1 can still be used now but SDL2 is a safer bet for the future. Upgrading from old libraries is one of the things I often have to do to get old games running.
dulsi
 
Posts: 570
Joined: 18 Feb 2016, 15:24

Re: Free Hero Mesh [Puzzle Game Engine]

Postby zzo38 » 16 Jul 2022, 22:45

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?
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).

I will accept contributions for optional compilation using other scripts (e.g. Makefile), although there are some things I did not like about it, such as the implicit rules (which can be disabled by command-line arguments, but I fail to see any way to completely disable them by codes within the Makefile). (I agree that make is easier to use, but there are a few problems to get it to work right. Note that some files are auto-generated, currently using JavaScript (with a small subset of Node.js functions), although I could later rewrite them in other programming languages such as C, maybe (or possibly AWK, or at least making it less specific to Node.js). However, JavaScript is not required if you are not modifying the instruction set; the auto-generated files only need to be regenerated if you are adding new instructions to the Free Hero Mesh programming language, otherwise the ones included in the repository are already suitable.)

Someone who has the proper system for making packages (and properly testing them) may try to do so; I can help if you have questions about it. I had intended that this will be possible, but have not done this yet. The PORTING file contains some details if you have questions about this, though. There are currently no "release" versions; if testing will be done on multiple systems then I can make some newer versions to be "release" versions.

Also, one file not included in the repository yet is compile-time configuration options; none are implemented yet (although I had written some notes about them), but may be helpful when packaging, e.g. to find the default user configuration file if none exists in the home directory, whether to force using portable or not portable mode, hash table sizes, BSD vs GNU functions, stack protection, x86 BMI2 extensions, multiuser scoring, video recording, etc.

Flatpak and AppImage are possible, but there are some considerations:
  • There are difficulties in making the package.
  • It seems to require desktop integrations and desktop icons. Free Hero Mesh cannot work this way; it will not work without any command-line arguments. It can run without a desktop environment (although the presence of a desktop environment should not prevent it from working; I did compile it on another computer with a different Linux distribution (and even a different instruction set) that does have a desktop environment, and it works there, too).
  • Portals for sandbox capabilities that are using D-bus cannot properly deal with non-Unicode text, especially file names. (This is a significant flaw in the design of D-bus.)
  • The sandbox capability does not seem to be usable with popen. Free Hero Mesh uses it for some features (mainly import/export features, and also clipboard access; you can configure it to be usable in some other circumstances too), with the command taken from two sources: from the user-specified configuration file, and interactively from the user at run time.
  • Some file access is needed for not only the requested file name but also other files whose name will be based on that one adding suffixes. This is needed for non-composite puzzle sets (composite puzzle sets are read-only, so you will need it to be non-composite when editing it; however, conversion between composite and non-composite formats (in either direction) is simple enough to do if needed), and also for SQLite journal files.

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.
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.

Modifications to the program, wrappers, conditional compilation, etc, can be added as needed to be appropriate for different kinds of packages. For example, a wrapper to check the environment variables of AppImage (and possibly, to check if command-line arguments should run separate programs such as the converter from MESH:Hero Hearts to Free Hero Mesh) could be used if AppImage format is used; built-in stuff could also be added to check this, e.g. to ensure that the configuration file is able to point to files within the AppImage regardless of its path. Another example is that the default configuration files, man pages, installation paths, etc, can also be set properly for the system being packaged for.
zzo38
 
Posts: 26
Joined: 07 Jul 2022, 19:04

Re: Free Hero Mesh [Puzzle Game Engine]

Postby glitchapp » 17 Jul 2022, 09:51

The only type of package I ever created is AppImage, and all you need is an icon, no need for desktop integration or anything.

The package can be created with a single command and the output is a standalone that do not require you to install anything because it has everything inside.

I'm not sure if that's the best solution to the problem because packages add many problems and challenges as you pointed out, one of them for me is how to update the game after creating the package but also how to communicate outside the package (save etc).

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.

In any case I'm just trying to help, I don't really know what the best solution to the compiling problems are, and I wrote to this post because I love puzzles and I like very much the idea and the original tool was very cool too.
glitchapp
 
Posts: 15
Joined: 05 Mar 2022, 10:00

Re: Free Hero Mesh [Puzzle Game Engine]

Postby bzt » 17 Jul 2022, 14:16

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:
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).

However...
glitchapp {l Wrote}:how to communicate outside the package (save etc).
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.

(Sidenote: AAAAARGH, I shouldn't have taken a look at AppIamge's runtime.c... I've seen at least 2 security holes and potential buffer overflow attack vectors just in 10 secs... yep, the whole technology is disgusting, problematic and full of security holes like an emmentaler)

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.
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).

@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.)
  • 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.)
  • Having an icon and a .desktop file as @glitchapp suggested, is a VERY good advice. You should add those.
  • 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, for an example something like
    {l Code}: {l Select All Code}
    [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
  • 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.

Hope this helps.
bzt
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Free Hero Mesh [Puzzle Game Engine]

Postby zzo38 » 18 Jul 2022, 01:14

glitchapp {l Wrote}:how to communicate outside the package (save etc).
This can be done easily enough, at least if sandbox capabilities are not used. (AppImage does not use sandbox capabilities, but Flatpak does.)

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.
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.

However, relative paths should be used to access stuff inside of the AppImage. But, it sets a environment variable so that you can find them. Therefore, it should need to properly tell it to find dependencies in there (the AppImage documentation links to the GNU documentation that mentions how to do this), and to fix the program to allow default configuration to load files from there (which I can probably do soon).

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).
On my computer, I get the list:
{l Code}: {l Select All Code}
        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)
My program does not use all of these as direct dependencies; presumably SDL depends on all of these either directly or indirectly (and different systems might have a version of SDL with different dependencies, e.g. Wayland, or SDL2 with the compatibility layer), even though most of them are not used. My program does not use JSON at all (SQLite has its own JSON capabilities (and does not need libjson to use them), which are also not needed by this program though), it does not use D-bus, does not use any sound file formats other than WAV (which is all that the SDL documentation says SDL supports, anyways), etc. Audio is an optional feature anyways; Free Hero Mesh can be used with or without audio.

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.)

I completely agree with you, and by default my compile script uses ~/bin/heromesh (although that requires that you have such a directory in your home directory), but you can change this. (Note: ~/bin/heromesh is not the same as /bin/heromesh) If you run ./compile p then it is installed in a subdirectory of the current directory instead (and will create it if it does not exist). If it is meant to be a system-wide installation then yes, /usr/bin/heromesh will be better (if you have permission to install the file there).

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.)
OK, I can consider this possibility, then.

bzt {l Wrote}:Having an icon and a .desktop file as @glitchapp suggested, is a VERY good advice. You should add those.
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 desktop file you wrote seems to be mostly good enough, except:
  • The terminal is used for tracing and for some warning messages. However, tracing is disabled by default (it is normally only needed for debugging when creating new puzzle sets), and the output could be redirected to a file. So, the terminal display will usually not be needed.
  • 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.

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
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 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.
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.
zzo38
 
Posts: 26
Joined: 07 Jul 2022, 19:04

Re: Free Hero Mesh [Puzzle Game Engine]

Postby glitchapp » 18 Jul 2022, 07:01

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.

The icon should not interfere when the tool is used without a desktop environment.

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.

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.


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.

It is your game and those are my advices, you could take them or not but I think that would help a lot to make more people play the tool.

I did not buy the original tool but I'm pretty sure it does all the things I mentioned above.
glitchapp
 
Posts: 15
Joined: 05 Mar 2022, 10:00

Re: Free Hero Mesh [Puzzle Game Engine]

Postby bzt » 18 Jul 2022, 10:08

zzo38 {l Wrote}:On my computer, I get the list:
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:
{l Code}: {l Select All Code}
$ 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)
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}:does not use any sound file formats other than WAV
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}: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)?
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}:The desktop file you wrote seems to be mostly good enough, except:
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 MIME type of a Free Hero Mesh composite puzzle set (which is mentioned in the documentation) is "application/freeheromesh.composite+hamarc"
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}:I do intend also to make Debian/Ubuntu packages (and possibly others).
Excellent news!

zzo38 {l Wrote}:I had read the package management documentation, and it doesn't seem to be quite so simple
Don't let the doc fool you, it is really simple. Take a look at the Makefile I have linked.

Basically a .deb file is nothing more than an "ar" archive always strictly containing these 3 files, in this exact order:
  • debian-binary - a plain text file, with the string "2.0"
  • control.tar.gz - a tar archive with the meta info (with just 3 plain text files for a simple package)
  • data.tar.gz - a tar archive with your app's files (with absolute paths, but without the leading '/'. For example, if you have usr/bin/heromesh in this archive, that will be installed to /usr/bin/heromesh, simple).
And control.tar.gz containing these (here the files and their order is flexible):
  • DEBIAN/control - a simple plain text file describing your package. For example, take a look at mine (note I use sed to replace VERSION, ARCH and SIZE strings with actual values. You don't have to do that, only calculating the "Installed-Size" field is mandatory, du -s *).
  • DEBIAN/copyright - your project's LICENSE file. Again, a simple plain text file, nothing to see here, please move on.
  • DEBIAN/md5sums - just a list of checksums for the files in data.tar.gz. You can use md5sum `find * -type f` >DEBIAN/md5sums to generate.
That's all. There are of course numerous other options too, but you won't need those for a simple package.

Also a trick: I create the directories DEBIAN and usr, and copy the files into these temporary directories. This way it's damn easy to create the tarballs with the required paths, and I can simply use du -s usr (calculates the size recursively with all the sub-directories included) and find usr -type f (does start the paths in the output with "usr/" and not with "./" so no further sed/cut/awk/etc. magic required).

glitchapp {l Wrote}:Create a starting menu where you can input or select the puzzle set name.
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).

Cheers,
bzt
User avatar
bzt
 
Posts: 332
Joined: 23 May 2021, 21:46

Re: Free Hero Mesh [Puzzle Game Engine]

Postby zzo38 » 19 Jul 2022, 00:52

(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).)

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.
The problem is that I do not have a icon.

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.
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.

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.
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)

I did not buy the original tool but I'm pretty sure it does all the things I mentioned above.
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.

bzt {l Wrote}:
zzo38 {l Wrote}:On my computer, I get the list:
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.
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.)

zzo38 {l Wrote}:does not use any sound file formats other than WAV
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.
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 only direct dependencies of my program (which are not included with it) are: the GNU C library, SQLite (which is statically compiled in), and SDL. It also uses libdl (required by SQLite and SDL).

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)?
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.
OK I will put a desktop file, but I do not have a icon, to put.

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"
Yep, you can't use that. Only IANA can assign such official mime types. For unofficial types, you must start it with "x-".
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.

zzo38 {l Wrote}:I had read the package management documentation, and it doesn't seem to be quite so simple
Don't let the doc fool you, it is really simple. Take a look at the Makefile I have linked.

Basically a .deb file is nothing more than an "ar" archive ...
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.

And then, I will have to tell them to put it into the package manager, somehow.

Nevertheless, I will take your advice for how to do it; thank you for mentioning them.

bzt {l Wrote}:
glitchapp {l Wrote}:Create a starting menu where you can input or select the puzzle set name.
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).
A port to Android will probably need many more changes than only that (see the PORTING file for some notes about this).
zzo38
 
Posts: 26
Joined: 07 Jul 2022, 19:04

Re: Free Hero Mesh [Puzzle Game Engine]

Postby glitchapp » 19 Jul 2022, 10:55

(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).)

Not sure who you refer to. Unless you have a very static idea for the software you are writting, constructive feedback could sometimes help make it even better. The things I think can improve does not require to read the documentation because I'm not talking about the code and no matter which parameters are required, you can always provide them with different methods and not just the terminal.

The problem is that I do not have a icon.

I've seen on other threads that someone have created severals for you, you can always improve them in the future.

I decided that specifying by command-line arguments is better

That's fine and that's your opinion. I think that the real question here is, is it better for who? If you want the tool to be played for a wide audience then I disagree with it, but that's my constructive opinion.

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..

If you intend to have a separate launcher even a menu written in bash script will do the work (at least till something more sophisticated is written).

I hope this feedback helps!
glitchapp
 
Posts: 15
Joined: 05 Mar 2022, 10:00

Who is online

Users browsing this forum: No registered users and 1 guest