When I was doing this for Latin, I took my list of singular monster names (I excluded the unique bosses since they never need plural forms), sorted it right-to-left so that I had all the same suffixes grouped together, wrote out the correct plural form for each name, did some extra Latin-specific stuff you won't need to deal with for English, and then wrote out the singular -> plural transformation rules I needed. Once I had that, writing the code was fairly straightforward; it's a little bit long and boring, but the individual sections are pretty simple. This is an oversimplification (particularly for CMP, which does multiple other things simultaneously), but for the purposes of this exercise
, you can treat CMP #$hex as "check if A is #$hex", BEQ $addr as "if it is, go to $addr", and BNE $addr as "if it isn't, go to $addr".
As with script editing, I recommend writing code as code rather than typing things in to a hex editor, so you'll want to grab an assembler (anything that works for 65816 should also work for 6502, so pick your favourite SNES or NES assembler; I was actually using Asar
, but I've been meaning to give xkas-plus
a try), and if you haven't done any ASM before, you'll also want some reference material (I like the handy instruction descriptions in chapter 18 of Programming the 65816
, but feel free to consult other resources if that one doesn't suit your style).
Also, if you get the chance to be clever, take it! E.g. if you only have one monster name that ends in "r" and you're writing the code to handle names that end in "r", you don't have to check that the 2nd-last letter is "a" or the 3rd-last letter is "W" or anything else, you can immediately just change the 9th-last letter to "e" to get "Man o' War" pluralized to "Men o' War".
By expanding the Battle Command window, I realized I could display full names at the top of the window now, but strangely any unused character spaces still "cover" the top bar of the window. That's a real shame, otherwise it's neat! I'm thinking of keeping the change.
Check out the screenshots from my translation - I also added some code for changing trailing spaces in hero names to top borders when the names are displayed as part of a border
Edit: So as brought to my attention by laser lambert, apparently the special [(s)] (F2) doesn't work the same way as DW1. If used for "points", whenever there's 1, it just cuts off the string (experience) or doesn't display the whole window at all (points of damage in battle). Don't want to be a bother (I really really don't I swear! ^^'') But even if I used the Trace Logger/Debugger to find the routine I wouldn't know what to look for, I'm mostly just curious, but is there any way to fix that?
Much like the [name] control code, [(s)] just tests the 16-bit value at $8F; the code for that is actually right before the pluralization code:
; data -> code
; if $8F-$90 == #$0001, print "s" + [end-FA] to $60F1 and SEC, else print [end-FA] and CLC
; indirect control flow target
; from $02:$BE37 via $8006
0x01C7E8|$07:$87D8:A5 90 LDA $90
0x01C7EA|$07:$87DA:D0 05 BNE $87E1 ; if $90 > 0, add "s"
0x01C7EC|$07:$87DC:A4 8F LDY $8F
0x01C7EF|$07:$87DF:F0 0C BEQ $87ED ; if $90 == 0 and $8F - 1 == 0 (i.e. $8F == 1), do not add "s"
; control flow target (from $87DA)
0x01C7F1|$07:$87E1:A9 1C LDA #$1C ; "s"
0x01C7F3|$07:$87E3:8D F1 60 STA $60F1
0x01C7F6|$07:$87E6:A9 FA LDA #$FA ; [end-FA]
0x01C7F8|$07:$87E8:8D F2 60 STA $60F2
; control flow target (from $87DF)
0x01C7FD|$07:$87ED:A9 FA LDA #$FA ; [end-FA]
The [number] control code, which is used for both experience and gold gains, also uses $8F-$90, so I would have expected [(s)] to work for both of those situations.