Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String Variables #3051

Merged
merged 47 commits into from
Oct 23, 2023
Merged

String Variables #3051

merged 47 commits into from
Oct 23, 2023

Conversation

enewey
Copy link
Contributor

@enewey enewey commented Jul 5, 2023

implements all major maniacs string variable operations and modifiers, with the exception of the .sjis and .utf8 encoding modifiers for file reading/writing.

.asg & .cat
t[..]
v[..]
s[..]
.actor [a] .name
.skill [a] .name
.item [a] .name
.enemy [a] .name
.troop [a] .name
.terrain [a] .name
.element [a] .name
.state [a] .name
.anim [a] .name
.tileset [a] .name
.s [a] .name
.v [a] .name
.t [a] .name
.cev [a] .name
.class [a] .name
.anim2 [a] .name
.map [a] .name
.mev [a] .name
.member [a] .name
.actor [a] .desc
.skill [a] .desc
.item [a] .desc
.member [a] .desc
.cat
.ins
.rem
.rep
.exrep
.subs
.join
.file

.toNum
.getLen
.inStr
.exInStr
.exMatch
.split
.toFile
.popLine

also adds support for string comparators in conditional statements
.eq
.neq
.contains
.notContains

2k3 test project used for developing these features:
https://rpgmaker.net/users/narcodis/locker/easyrpg_testing.zip
proper unit testing could be added 😓


Web Player test: https://easyrpg.org/play/pr3051/?game=string-var

@Ghabry
Copy link
Member

Ghabry commented Jul 5, 2023

Jenkins: test this please <3

Thanks for this huge contribution!

You received an invite for the "Player Team". This whitelists you for the pull request builder (will auto-build your stuff).

Also add yourself and all other authors that contributed to this to the Authors.md if you havn't done already.

src/filefinder.cpp Outdated Show resolved Hide resolved
@Ghabry
Copy link
Member

Ghabry commented Jul 5, 2023

Not going to review this right now as is a bit too long xD.

But one remark already: I don't like the commit text. Could you prefix all of them with something like StringVar: to make it clear what the context is?

The easiest way to do this should be:

git rebase -i HEAD~23

Then change all the pick to reword.

After save and quit git will open a text editor for every single commit (so 23 times). Here prefix all the commits with something like StringVar: .

Then push: git push --force-with-lease origin.

Is a bit tedious but shouldn't take more than a few minutes.

@Ghabry
Copy link
Member

Ghabry commented Jul 5, 2023

Uploaded the string var test project to the web player: https://easyrpg.org/play/pr3051/?game=string-var (note that txt file loading won't work as the code for "async asset fetching" is not implemented currently)

@enewey
Copy link
Contributor Author

enewey commented Jul 5, 2023

Looks like String vars in a string pic isn't fully supported -- while you can display a stringvar through message codes (e.g. @pic[1].strpic { "\t[1]", ... } ), you cannot just plug in the string variable directly (e.g. @pic[1].strpic { t[1], ... }). Need to update string pics, and any command that takes a string parameter (like a filename).

@Ghabry
Copy link
Member

Ghabry commented Jul 5, 2023

except for StringPics (where this appears to be used alot(?)) I would prefer to have support for string-vars in the other commands as another PR.

Adding support to all other commands is alot of additional complexity and lots of more testing that nothing breaks. So not required for the MVP. ;)

@enewey
Copy link
Contributor Author

enewey commented Jul 5, 2023

I agree -- don't want to explode the scope of this. Isolating to supporting string pics sounds reasonable.

Copy link
Member

@Ghabry Ghabry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only quickly looked through the code and these are the largest issues I'm currently seeing.

Sorry but text processing and encodings is tricky so we must think here of all the edge-cases as we are multi-platform, multi-language and Unicode aware, so a "lol, works in Japan for me" is not good enough.

All in all for your first PR (which solves a complex problem) this is already pretty good work :).

src/game_interpreter.cpp Show resolved Hide resolved
src/game_interpreter.cpp Outdated Show resolved Hide resolved
src/game_strings.h Show resolved Hide resolved
int len = static_cast<std::string>(Get(params.string_id)).length();
Main_Data::game_variables->Set(var_id, len);
return len;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This must be checked (same for index returned by InStr):

What kind of encoding is Maniac Patch using here?

Is this the length in bytes or in codepoints? When it is the length in bytes is it in local encoding or in UTF-8?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When testing the string My name is Đức:
Assigned to a string directly, length is 14.
When read from a file specified as utf8, length is 14.
When read from a file specified as ansi, length is 17.
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the PR as it is, the player does not behave the same way.
With files read as utf8, we are saying its length is 17
With files read as ansi, we are saying its length is 17
And when assigned directly to a string, we are saying its length is 15... I believe this is because tpc doesn't allow the character (either due to my computer's locale or tpc itself, no idea).
image
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like BingShan recently released an update to tpc on his private discord that does not encode the text-editor as shift-jis, so I may be able to test this a little more comprehensively... I'll check this out.

if (params.hex)
num = std::stoi(str, 0, 16);
else
num = std::stoi(str);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::stoi is problematic because it throws an exception when conversion fails and we have exceptions disabled = crash

If you need no error checking (error is 0, if this matches Maniac Patch???) use atoi and if you need error checking and different bases use std::strtoimax https://en.cppreference.com/w/cpp/string/byte/strtoimax

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did not know this about std::stoi, good note! I will look into the alternatives suggested.

src/game_strings.cpp Show resolved Hide resolved
src/game_strings.cpp Show resolved Hide resolved
src/game_interpreter.cpp Outdated Show resolved Hide resolved
src/game_interpreter.cpp Show resolved Hide resolved
src/game_interpreter.cpp Outdated Show resolved Hide resolved
@jetrotal
Copy link
Contributor

jetrotal commented Jul 8, 2023

Ghabry asked to list the issues pointed at rm2k3 channel:

discord issue 1:
image


discord issue 2:
image

t[1] .asg s[1]


discord issue 3:
image


discord issue 4:
image image

@loop 20 {
    v[1] += 1
    t[2] .asg v[1]
    t[1] .asg  .cat t[2], "
", t[1]
    
}

@pic[1].strpic {
    "\t[1]"
    .pos 160, 120 .center
    .size 0, 0    .chromakey 1
    .scale 100
    .trans 0
    .rgbs 100, 100, 100, 100
    .font "", 12
    .spacing 0, 4
    .skin "" .stretch
    .mapLayer 7
    .eraseWhenTransfer
    .affectedByFlash
    .affectedByShake
}

this last one may have been fixed already.

@enewey enewey force-pushed the master branch 2 times, most recently from a09f033 to 7e6e982 Compare July 12, 2023 23:09
Copy link
Member

@Ghabry Ghabry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good, I think we are 98% there :)

src/filefinder.cpp Show resolved Hide resolved
src/filefinder.cpp Show resolved Hide resolved
src/game_strings.cpp Show resolved Hide resolved
src/game_interpreter.cpp Show resolved Hide resolved
src/game_variables.h Outdated Show resolved Hide resolved
src/maniac_patch.cpp Show resolved Hide resolved
@fdelapena fdelapena added the Awaiting Rebase Pull requests with conflicting files due to former merge label Sep 19, 2023
@Ghabry
Copy link
Member

Ghabry commented Sep 30, 2023

I rebased the PR but I cannot push to the branch (because it is master I guess?).

Will likely close this PR later and create my own to resolve the last pending issues.

Oh and thanks again for figuring this all out. This looked like a huge afford, the stuff I have to fix is simple compared to it ^^

@enewey
Copy link
Contributor Author

enewey commented Oct 13, 2023

Have resolved most issues, still a couple hanging threads to resolve.

An issue has cropped up with displaying string pictures, though. Seems to be related to some code changes I had to accommodate on rebase in the PendingMessage class. It appears when a string is assigned a string containing a string param (i.e. t[1] .asg "\t[2]"), it will strip out all newline characters from the original string. Not sure what else it might be stripping out.

Maniacs rpg_rt:
image

EasyRPG player:
image

Player also appears to incorrectly(?) color text when maniacs does not, but I don't know how concerned I am about that particular thing.

For the newline stripping piece, I will try to find time to dig into the PendingMessage class in more depth to deduce why this is happening.

some related code changed during the rebase and this no longer appears to be necessary
@Ghabry Ghabry removed the Awaiting Rebase Pull requests with conflicting files due to former merge label Oct 13, 2023
@Ghabry
Copy link
Member

Ghabry commented Oct 21, 2023

I have a hard time going through the tests because I'm already stuck for a long time at the first one: Bottom left. Just this bottom left test took me already 90 minutes to check what is going in...

First discovery: Maniac changed how unknown command codes are parsed. E.g. a message with \A[0] \B[1] \e[2] is rendered as [0] [1] [2] by the Player. This is also what RPG_RT does, Maniac changed this and it renders \A[0] \B[1] \e[2] instead. I believed for 45 minutes that this is a player bug until I finally started an original RPG_RT to notice that it is a Maniac change -_-


Top Maniac, Bottom Player:

I wouldn't say that we are wrong here. This is just how it worked in original RPG_RT. Also is an edge-case nobody will usually encounter. Notice the missing \ at the last line before the s[1]. The Maniac parser has some bug here and is inconsistent.

image

image

Imo test passed ✔️


Looks like what we need for \t in a message box is to evaluate the expression? Though enabling the evaluation will also enable it for the String Picture because they share the same code. Is this a problem? Where is the y in Maniac coming from?

image

image

Test failed ➖


Upon more testing there seems to be in general a difference in how the message box resolves codes:

When you call Hero 1 \n[2] and do in code \n[1] then Maniac will replace this with the name of the 2nd hero while RPG_RT and EasyRPG render [2].

@Ghabry
Copy link
Member

Ghabry commented Oct 21, 2023

The 2nd test at the bottom row is also completely different.

Left is Maniac, Right is Player. Am I using the wrong version of Maniac patch? I use the RPG_RT.exe provided in the ZIP archive of the test game.

image


Sorry I cannot continue this review under these circumstances. My time is limited and something is completely broken.

@Ghabry Ghabry added the Needs feedback Waiting for the issue author to give further information. label Oct 21, 2023
@jetrotal
Copy link
Contributor

jetrotal commented Oct 21, 2023

Some direct comparations EasyRPG x Maniacs_RT (bigger windows being maniacs).
I may repeat the reports you guys gave:

Read PNG:
image

Uncommon Characters:
image
image

var, name, string, switch:
image
image
image

Database stuff (error only on easyRPG - Seems correct?):
image

"\t[1]" fails to read new lines, but interprets \c sintaxes:
image

@Ghabry
Copy link
Member

Ghabry commented Oct 21, 2023

About the remaining issues according to the screenshots:

  • Read PNG: I guess the difference is that we read in "Binary mode" and Maniac_RT in "Text mode". Text mode is not portable across operating systems so I would suggest to ignore this edge case (actually with our implementation it should be possible to read a PNG in "utf-8" mode and write the PNG in "utf-8" mode and it should survive 😅)
  • Has Patch Uncommon Characters: I implemented this now locally and I get UTF-8 17 and ANSI 14, so the opposite of Maniac. The problem here is that our Player uses UTF-8 internally and Maniac_RT likely the local codepage (as the old RPG_RT). That an implementation detail and imo not worth to fix.
  • var, name, string, switch: This is a difference in how we evaluate variables in Messages and String Pics. Fixing this will break it in the other case though... So I would be fine with keeping this broken until a later PR.
  • "\t[1]" fails to read new lines, but interprets \c sintaxes: Another implementation difference of Messages vs. String Pics: String Pics evaluate \n while in Messages they don't.

The last two cannot be fully implemented because we use shared code for both messages and string pics compared to Maniacs which seems to use 2 implementations......

@Ghabry Ghabry removed the Needs feedback Waiting for the issue author to give further information. label Oct 21, 2023
@Ghabry
Copy link
Member

Ghabry commented Oct 21, 2023

@enewey I figured out solutions for most of the remaining problems. Just need to clean it up a bit. Will send you a patch on Sunday or Monday that will resolve them.

@jetrotal
Copy link
Contributor

one thing we forgot to take a look is loading text files with webplayer

@Ghabry
Copy link
Member

Ghabry commented Oct 22, 2023

@enewey Creating commits was easier than explaining but I cannot push to your master branch (permission denied).

Please grab my commits manually:

git remote add ghabry https://github.com/ghabry/easyrpg-player
git fetch ghabry
git rebase ghabry/strvar --autostash --committer-date-is-author-date

Now you have my commits and you can push.

@Ghabry
Copy link
Member

Ghabry commented Oct 22, 2023

@jetrotal In case you already want to retest here is an emscripten instance with my changes:

http://server.mastergk.de:8000/easyrpg-player.html

src/game_interpreter.cpp Outdated Show resolved Hide resolved
src/game_strings.cpp Outdated Show resolved Hide resolved
Copy link
Member

@Ghabry Ghabry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is already complex enough and it is a very solid implementation of String Vars. Thanks again for this huge contribution.

There is only nitpicky stuff left (e.g. lack of unit tests, lots of copying instead of string view, code formatting in some parts) but this can be all addressed later.

@Ghabry Ghabry merged commit f2c3c98 into EasyRPG:master Oct 23, 2023
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

5 participants