Jump to content

The Lion Throne (Fangame and Engine)


rainlash
 Share

Recommended Posts

Hey rainlash, I recently downloaded the engine and started messing around with trying to make my own level. When I did, I got this error:

Quote

*** Lex Talionis Engine Version 0.9.3.19 ***
Main Crash 'NoneType' object has no attribute 'items'
Traceback (most recent call last):
  File "C:\Users\Kevin\Desktop\Games\Projects\Lex Talionis\lex-talionis\main.py", line 122, in <module>
    main()
  File "C:\Users\Kevin\Desktop\Games\Projects\Lex Talionis\lex-talionis\main.py", line 44, in main
    run(gameStateObj, metaDataObj)
  File "C:\Users\Kevin\Desktop\Games\Projects\Lex Talionis\lex-talionis\main.py", line 62, in run
    mapSurf, repeat = gameStateObj.stateMachine.update(eventList, gameStateObj, metaDataObj)
  File "C:\Users\Kevin\Desktop\Games\Projects\Lex Talionis\lex-talionis\Code\StateMachine.py", line 196, in update
    input_output = self.state[-1].take_input(eventList, gameStateObj, metaDataObj)
  File "C:\Users\Kevin\Desktop\Games\Projects\Lex Talionis\lex-talionis\Code\Transitions.py", line 577, in take_input
    self.build_new_game(preloaded_level, gameStateObj, metaDataObj)
  File "C:\Users\Kevin\Desktop\Games\Projects\Lex Talionis\lex-talionis\Code\Transitions.py", line 631, in build_new_game
    for item in reversed(unit.items):
AttributeError: 'NoneType' object has no attribute 'items'
=== === === === === ===
Damn. Another bug 😞
Quick! Copy this error log and send it to rainlash!
Or send the file "Saves/debug.log.1" to rainlash!
Thank you!
=== === === === === ===

Is this something I messed up? I'm gonna look at the code, but I'm a bit confused.
 

Link to comment
Share on other sites

  • Replies 459
  • Created
  • Last Reply

Top Posters In This Topic

12 hours ago, kdports said:

Is this something I messed up? I'm gonna look at the code, but I'm a bit confused.

Likely a problem with the unit id. What's happening is the preloaded level you are using has some unit_id defined that is no longer defined in the "Data/units.xml". So the engine fails to find a unit matching that id. Make sure all the unit "names" in the preload_levels.xml (they're really the unit ids) are defined in the units.xml. 

Link to comment
Share on other sites

This looks like a really neat project!

I stumbled upon this thread yesterday and it's really great how much work you've put, and are continuing to put into this. I'm just starting with the GitLab tutorial, and I wanted to let you know that for a Git cloned installation, PIL is missing as a dependency for the Level Editor. On one hand, most people using the Git installation method can probably figure it out from the error dialog, but it would probably help some beginners who are trying it out and unable to make it past the first page of Getting Started.

image.png

 

EDIT: I'm currently on CH.3 and enjoying the game so far. I had a question about Aura skills, is the effective range marked in purple when hovered over? If so, what are the rules for how many tiles an Aura will effect? It doesn't seem to be either 3 tiles in all directions, or the equivalent of a 3-tile move (or else I'd expect the tiles N-E-E and W-S-S of the selected Shaman to be affected).

image.png.fcd2f3fb2ca703e5e5f4e9b31f7e8054.png

Edited by El Grillo
Link to comment
Share on other sites

Hi, I reached you on reddit the other day, asking a few things about the tutorial...

I'm still blown away at how good your level editor tool is. But I'm very new to the scene and I'm wondering what's the best way to make the graphical display of a new custom map. Since the level editor needs a pre made image file to start, I hope there's a relatively easy way to make these images.

Thanks for all the help!

Link to comment
Share on other sites

6 hours ago, Hibari Oozora said:

Hi, I reached you on reddit the other day, asking a few things about the tutorial...

I'm still blown away at how good your level editor tool is. But I'm very new to the scene and I'm wondering what's the best way to make the graphical display of a new custom map. Since the level editor needs a pre made image file to start, I hope there's a relatively easy way to make these images.

Thanks for all the help!

Are you asking about the map .png file the Editor asks for when making a new chapter?

For that, I personally just use FE Map Creator and then copy and paste the image into paint and save as a png.

Link to comment
Share on other sites

44 minutes ago, TheeBill said:

Are you asking about the map .png file the Editor asks for when making a new chapter?

For that, I personally just use FE Map Creator and then copy and paste the image into paint and save as a png.

Right, that's what I meant.

I did find FE Map Creator here by just digging around and I thought trying to recreate FE7's prologue map would be a good exercise to learn how to use it.

By just poking around, I realized that ok, you gotta choose FE7's Plain Tile Set and easily put the the gate and the village, the forest tiles and even the mountain and cliff tiles to be the same ones. It's the actual plains that are giving me trouble when trying to recreate the patterns on the ground, can't even seem to find those white patches of dirt tiles. 

I realize that trying to recreate the exact same grass tiles would be almost impossible but at least getting a hand at making some nice textures for the ground would be cool. Linking different tiles like the plains or the peak in a way that make sense seems to be giving me trouble. Doesn't help that the sprite tiles are so tiny on the tile set selector.

I'm guessing the tags are for when using this program to insert them directly into GBA hacks but I'm a bit of a loss at the 'Repair Map' command is used for and what the logic behind the randomization of 'Generate Map' is.

I may be too off topic since this isn't strictly about lex talonis, if it is, I can move this rant to a more appropriate thread.

0.png

Link to comment
Share on other sites

On 4/24/2020 at 12:54 PM, El Grillo said:

EDIT: I'm currently on CH.3 and enjoying the game so far. I had a question about Aura skills, is the effective range marked in purple when hovered over? If so, what are the rules for how many tiles an Aura will effect? It doesn't seem to be either 3 tiles in all directions, or the equivalent of a 3-tile move (or else I'd expect the tiles N-E-E and W-S-S of the selected Shaman to be affected).

All Auras in the Lion Throne are standardized to range 3 (3 tiles in all directions) to make it easier on the player to remember. But, like ranged attacks in the Lion Throne, Auras are affected by line-of-sight. So the wall is blocking the spread of the aura.

7 hours ago, Hibari Oozora said:

Since the level editor needs a pre made image file to start, I hope there's a relatively easy way to make these images.

I personally used the Tiled Map Editor https://www.mapeditor.org/ , along with a little bit of GIMP, to make the maps in the Lion Throne. You can download my collection of tilesets here: https://www.dropbox.com/s/e4h3by9pcrrhtr6/TileSets.zip?dl=0  . I would choose a tileset, make the map in Tiled, export it as an image, and then do any final touch-ups with GIMP.

Link to comment
Share on other sites

23 hours ago, rainlash said:

All Auras in the Lion Throne are standardized to range 3 (3 tiles in all directions) to make it easier on the player to remember. But, like ranged attacks in the Lion Throne, Auras are affected by line-of-sight. So the wall is blocking the spread of the aura.

I personally used the Tiled Map Editor https://www.mapeditor.org/ , along with a little bit of GIMP, to make the maps in the Lion Throne. You can download my collection of tilesets here: https://www.dropbox.com/s/e4h3by9pcrrhtr6/TileSets.zip?dl=0  . I would choose a tileset, make the map in Tiled, export it as an image, and then do any final touch-ups with GIMP.

Tiled works great! Thanks a ton.

I managed to recreate FE7 Prologue map well enough and figured I'd toy around with it to practice some scripting. 

I can't seem to find a directory of character sprites with the winks and mouth frames included like you provided in the tutorial... I'm sorry to be such a bother, but are they organized like that anywhere?

Edit: Nvm, found the FE Universe resource repo you linked.

Edited by Hibari Oozora
Link to comment
Share on other sites

So where can I check what's causing the engine to crash? There must be a crash log right?

I tried adding a Lyn unit to see how it would go. But I must've messed something up when either adding the sprites or the parameters since it's crashing. I ran the animation converter, and renamed the new files, recolored the portrait background, and added the unit and class parameters... Not sure where I might've messed up.

Link to comment
Share on other sites

2 hours ago, Hibari Oozora said:

So where can I check what's causing the engine to crash? There must be a crash log right?

I tried adding a Lyn unit to see how it would go. But I must've messed something up when either adding the sprites or the parameters since it's crashing. I ran the animation converter, and renamed the new files, recolored the portrait background, and added the unit and class parameters... Not sure where I might've messed up.

Try running main.py with the command prompt (aka cmd). This way when the program crashes, the window won't close so you can read the error message. The engine prints an error message to the prompt when it crashes so make sure to read what it says.

Link to comment
Share on other sites

3 hours ago, Hibari Oozora said:

So where can I check what's causing the engine to crash? There must be a crash log right?

The crash logs also appear in the Saves/ directory. The most recent one is always named "debug.log.1". You can scroll all the way to the bottom to see the error message that caused the crash.

Link to comment
Share on other sites

Found a bug with the LevelEditor. It crashes when I try to delete factions.

Spoiler

  File "C:\Users\anon\Github\lex-talionis\Editor\EditorCode\Faction.py", line 129, in remove_faction
    del self.unit_data.factions[self.unit_data.factions.key()[idx]]
AttributeError: 'collections.OrderedDict' object has no attribute 'key'

 

Edited by TheeBill
Link to comment
Share on other sites

Hey listen. I just wanted to say your engine seems kind of bulky at times but is sexy af. If you ever complete a full editor UI I will be proud as hell. You have no idea how long I wanted to see a python engine and then I found  there was one. I haven't messed with code yet but I do read over it as I mull over what to do but I do like to rearrange the data and make do with the methods you have and it so good. I have ideas too but I won't tell you how to make your engine.

Link to comment
Share on other sites

I've played some more levels and I think I'd like to try making a map with this engine. My ambitions quickly grew in scope and I started looking at the engine code. While much of it is beyond my current understanding, I do feel confident in making a few small changes to support some features I'd like to include.

I added another event listener to unit level-ups (which required passing gameStateObj to apply_levelup in Actions.py in order to call gameStateObj.message.append in UnitObject.py), which seems to be working without having broken anything. Testing this in the debug level produced satisfactory results.

giphy.gif

My question is, in the scripting file, does the engine support parsing variables into the in-game output? For example, here's the current script I'm using:

if;self.unit.name == 'Jane'
	u;Jane;Right
	if;self.unit.level == 2
		s;Jane;I'm level 2 now!
	elif;self.unit.level == 3
		s;Jane;I'm level 3 now!
	else
		s;Jane;I gained another level!
	end
	r;Jane
	wait;500
end

Does the engine support anything like %s formatting?

s;Jane;I'm level %s now! % (self.unit.level)

It would be neat to be able to have a character refer to their equipped weapon's name, for example, without needing a huge if-else section.

Edited by El Grillo
Link to comment
Share on other sites

On 5/1/2020 at 1:03 PM, TheeBill said:

Found a bug with the LevelEditor. It crashes when I try to delete factions.

Thanks for the bug report. I've fixed it in the git repo. When I have more changes, or just in a couple of weeks, I'll go through the whole build process.

8 hours ago, El Grillo said:

My question is, in the scripting file, does the engine support parsing variables into the in-game output? For example, here's the current script I'm using

Yes, it does. You can check out, for instance, the "Level0/attackScript.txt" that comes with the Lion Throne. Simply put, you can add  "s;Jane;I am level {eval: self.unit.level}." to display the unit's current level. Just wrap the python command you want to evaluate in a "{eval: my_python_command}" syntax.

Link to comment
Share on other sites

I don't know how to say it but, I want to make a petition: Could you add UTF-8 text char for dialogues and units?

I know that this engine is used by (like 95%) English speakers, but It could be great if we have special chars too like 'ñ', 'á', etc...!

Btw, Keep doing great rainlash!!!

Link to comment
Share on other sites

Ah thanks rainlash, I see now that evaluate_evals is only called for dialogue lines that start with s;. I'll have to do a deeper investigation to see if I can get it working with the new dialogue method I've created. That said, I'm pleased enough with my first attempt at adding a feature over the past few days, event-driven growth changes:

giphy.gif

With this I'm confident that I can leave the rest of the code alone and do everything that I have in mind for my levels with just the editor and the scripting files. I have to say again that this is a really nifty project that you've built from scratch.

Link to comment
Share on other sites

That's pretty awesome El Grillo, way to go. 

So rainlash, is it possible to have different map sprites for the same class other than male / female versions?

Like for example, having different weapons equipped or for an FE7 situation where Eliwood and Hector are both Lords.

Link to comment
Share on other sites

2 hours ago, Hibari Oozora said:

is it possible to have different map sprites for the same class other than male / female versions?

Yes. As you're probably aware, each character has a gender 0 - 9. You can give a class a unique set of map sprites for each gender by naming the map sprite images 'teamClassX' where X is a number 0 - 9. If a unit's gender matches the number at the end, they will use those mapsprites for their class instead of the default ones. If you're familiar with how unique combat animations work, it's extremely similar.

As an example, if you have the images 'playerSage6' and 'playerSage6_move' in the appropriate map sprites folder and a create a player Sage character with a gender of 6, that character will use the 'playerSage6' map sprites instead of the 'playerSageF' ones as they normally would.

You can have a lot of unique map sprites for each class using this. However, if you want a character's map sprite to change when they equip a different weapon type, that is not possible to my knowledge. Hope this was helpful!

Edited by ZessDynamite
Link to comment
Share on other sites

16 hours ago, ZessDynamite said:

Yes. As you're probably aware, each character has a gender 0 - 9. You can give a class a unique set of map sprites for each gender by naming the map sprite images 'teamClassX' where X is a number 0 - 9. If a unit's gender matches the number at the end, they will use those mapsprites for their class instead of the default ones. If you're familiar with how unique combat animations work, it's extremely similar.

As an example, if you have the images 'playerSage6' and 'playerSage6_move' in the appropriate map sprites folder and a create a player Sage character with a gender of 6, that character will use the 'playerSage6' map sprites instead of the 'playerSageF' ones as they normally would.

You can have a lot of unique map sprites for each class using this. However, if you want a character's map sprite to change when they equip a different weapon type, that is not possible to my knowledge. Hope this was helpful!

Ah perfect! I thought that might be it but I hadn't tried deleting the 'M' or 'F' from the name convention, so I was adding the number id on top of that.

Much appreciated!

Link to comment
Share on other sites

I think I'm a bit confused as to how to properly construct eval for if commands.

I'm recreating FE7's chapter 1 to just train on using the program and auxiliary tools.

I recreated the intro sequence, but I'm having a bit of trouble scripting the event fight properly.

This is what I put on the fightScript.txt

if;self.unit.name == 'Lyn'
    if;self.unit2.name == 'Batta'
        if;'BattaDefault' not in gameStateObj.level_constants
            u;Batta;Left
            s;Batta;Who do you think you are?{w}{br}You think you can stand up to Batta the Beast?
            r;Batta
            interact_unit;Lyn;Batta;Hit,Hit,Hit
            set_level_constant;BattaDefault
        end
    end
end

The dialogue is played (dialogue plays before the actual combat screen shows up though)  and the scripted combat plays out. But after that, the game crashes.

95640    INFO:        Dialogue: Script line to parse: ['set_level_constant', 'BattaDefault']
95641    INFO:       Turnwheel: Add Action 84: ChangeLevelConstant
95641   DEBUG:   GeneralStates: Ending dialogue state
95641    INFO:   GeneralStates: Repeat Dialogue State!
95641   DEBUG:    StateMachine: Temp State: ['pop']
95642   ERROR:            main: 'NoneType' object has no attribute 'update'
Traceback (most recent call last):
  File "main.py", line 122, in <module>
  File "main.py", line 44, in main
  File "main.py", line 65, in run
  File "Code\StateMachine.py", line 198, in update
    update_output = self.state[-1].update(gameStateObj, metaDataObj)
  File "Code\GeneralStates.py", line 2250, in update
    combatisover = gameStateObj.combatInstance.update(gameStateObj, metaDataObj, self.skip)
AttributeError: 'NoneType' object has no attribute 'update'
96687   DEBUG:          Engine: Created save point from ./Saves\LDEBUGT3.p

So I think there's an issue with the flag I'm trying to create, but I'm using the tutorial and the fight dialogue we set up with Braguet as the example to follow...

After that, Lyn should have a dialogue before the enemy phase starts. Should be easy, right? in enemyTurnChangeScript.txt, just check if the BattaDefault flag has been activated and do the dialogue

But I realized I don't know how to check this properly. I'm also not quite sure when the elif (else if, right?) command should be used.

I figured "if;gameStateObj.level_constants == 'BattaDefault'" would check if the flag is activated, but I'm not sure. Would that and the first example of checking if the flag is not there correctly typed? with the space separating the "==" sign?

Then the second round of combat should play out and I'm wondering if this would be right. In fightScript, following the first round

if;self.unit.name == 'Lyn'
	if;self.unit2.name == 'Batta'
	if;gameStateObj.level_constants == 'BattaDefault'
	interact_unit;Batta;Lyn;Miss,Crit
	end
	end
	end

Link to comment
Share on other sites

The engine is crashing because weird stuff happens when you use the 'interact_unit' command in a fightScript; when you do that it starts a round of combat in the middle of another round of combat. To my knowledge there's no way to have a regular, non-cutscene fight be scripted, so you'll probably have to go without the event combat for now and remove 'interact_unit' in the fightScript (though I'd wait for rainlash to get back to you on this).

45 minutes ago, Hibari Oozora said:

Should be easy, right? in enemyTurnChangeScript.txt, just check if the BattaDefault flag has been activated and do the dialogue

The proper way to check something like this would be:
if;'BattaDefault' in gameStateObj.level_constants
    u;Lyn;Right
    s;Lyn;Nice!
    r;Lyn

As for the elif command, it basically allows you to check for multiple things in one if statement in a more condensed and readable way. Bosses that have multiple special conversations with different characters are a good example of using elif statements in Lex Talionis:
 

Spoiler

#Boss Convo with Character 1
if;self.unit.name == 'Character1'
    if;self.unit2.name == 'Boss'
        if;'BossCharacter1' not in gameStateObj.level_constants
            u;Boss;Left;u;Character1;Right
            s;Boss;Hello Character 1!
            r;Boss;r;Character1
            set_level_constant;BossCharacter1
        end
    end
#Boss Convo with Character 2
elif;self.unit.name == 'Character2'
    if;self.unit2.name == 'Boss'
        if;'BossCharacter2' not in gameStateObj.level_constants
            u;Boss;Left;u;Character2;Right
            s;Boss;I've got you now, Character 2!
            r;Boss;r;Character2
            set_level_constant;BossCharacter2
        end
    end
#Default Boss Convo
else;
    if;self.unit2.name == 'Boss'
        if;'BossDefault' not in gameStateObj.level_constants
            u;Boss;Left
            s;Boss;I'm the boss!
            r;Boss
            set_level_constant;BossDefault
        end
    end
end

This boss has special dialogue with 2 characters and some default dialogue for everyone else. We check for the first character with 'if', the second character with 'elif', and 'else' handles the rest. Note that we DO NOT check for the second character with another 'if'. If we wanted to add more special dialogue with more characters, we would just add more elif checks. You could write this script without using elif pretty easily, but it would be harder to read and even more annoying to write. There are loads more reasons why you might want to check for multiple things in an if statement with elif rather than use another if, this was just a small example. Hope this was helpful!

Link to comment
Share on other sites

19 minutes ago, ZessDynamite said:

The engine is crashing because weird stuff happens when you use the 'interact_unit' command in a fightScript; when you do that it starts a round of combat in the middle of another round of combat. To my knowledge there's no way to have a regular, non-cutscene fight be scripted, so you'll probably have to go without the event combat for now and remove 'interact_unit' in the fightScript (though I'd wait for rainlash to get back to you on this).

The proper way to check something like this would be:
if;'BattaDefault' in gameStateObj.level_constants
    u;Lyn;Right
    s;Lyn;Nice!
    r;Lyn

As for the elif command, it basically allows you to check for multiple things in one if statement in a more condensed and readable way. Bosses that have multiple special conversations with different characters are a good example of using elif statements in Lex Talionis:

This boss has special dialogue with 2 characters and some default dialogue for everyone else. We check for the first character with 'if', the second character with 'elif', and 'else' handles the rest. Note that we DO NOT check for the second character with another 'if'. If we wanted to add more special dialogue with more characters, we would just add more elif checks. You could write this script without using elif pretty easily, but it would be harder to read and even more annoying to write. There are loads more reasons why you might want to check for multiple things in an if statement with elif rather than use another if, this was just a small example. Hope this was helpful!

I see, so checking for custom flags should always be formatted as if;'flag' (not) in gameStateObj.level_constants. 

I was borrowing the format for how the turn count flag was written, but I guess that only works when you can assign numeric values to the statement for turns or unit position in maps. 

And not being able to run scripted fights in the fight script makes sense. I'd imagine the game crashes because Batta is dead and can't initiate the regular combat phase after the script is done. 

A million thanks!

Oh but I'm also wondering why the Boss fight convo was had in the normal map instead of the actual battle screen. I just checked out if it would sort itself if I removed the scripted combat and still both the pre battle and the death quote is on the normal map screen.

Edited by Hibari Oozora
Link to comment
Share on other sites

1 hour ago, ZessDynamite said:

The engine is crashing because weird stuff happens when you use the 'interact_unit' command in a fightScript; when you do that it starts a round of combat in the middle of another round of combat. To my knowledge there's no way to have a regular, non-cutscene fight be scripted, so you'll probably have to go without the event combat for now and remove 'interact_unit' in the fightScript (though I'd wait for rainlash to get back to you on this).

Yes, this is correct. Thanks for helping out, ZessDynamite! Basically, you've put two combat states on the stack, but the engine can only have one combat instance at a time. So you overwrite the first combat instance (the natural, normal one) with a new combat instance (the event one), which is fine. But then, when that one ends, the state stack wants to go back to the previous combat state, but the old combat instance has been overwritten in the meantime, and so crash. 

The way I implemented scripted combats in the Lion Throne was kind of janky in retrospect (I only used it for the prologue), but here goes. If you don't use the Level Editor (because the Level Editor will likely overwrite this change), you can modify the UnitLevel.txt file for the associated level directly.

Here's an example of the first enemies' definitions in the Lion Throne

# First enemy
enemy;0;E1;Fighter;f1;eIron Axe;0,0;Pursue;Soldier;Maximum HP -5
# Second enemies
enemy;0;E2;Soldier;f1;eSlim Lance;0,0;Pursue;Soldier

You can see that their weapons have an "e" prepended? That means "event", and it will force all combatants in combat with them (and themselves as well) while their using that item, to Hit if at all possible.

1 hour ago, Hibari Oozora said:

Oh but I'm also wondering why the Boss fight convo was had in the normal map instead of the actual battle screen. I just checked out if it would sort itself if I removed the scripted combat and still both the pre battle and the death quote is on the normal map screen.

Boss fight convos are always done in the normal map instead of the battle screen. This is because conversations were added to the engine way before full combat animations, and I never bothered to go back in and modify when to do boss fight convos. I may consider adding it to the to-do list, but I don't honestly don't think it makes much of a difference...

 

On 5/4/2020 at 11:21 AM, FrankOfAltea said:

I don't know how to say it but, I want to make a petition: Could you add UTF-8 text char for dialogues and units?

I know that this engine is used by (like 95%) English speakers, but It could be great if we have special chars too like 'ñ', 'á', etc...!

I also want this. It's on the todo list, but would be made faster if someone could get me all the bitmaps for each of the new characters (both uppercase and lowercase, and for as many font types as possible). I'm not a good GBA hacker, so I don't know where I would look for the base font bitmaps. Once I have the bitmaps, its trivial to support UTF-8 for conversations and units, items, statuses, etc.

Link to comment
Share on other sites

Thank you for the feed back. I'm glad it wasn't all me just not understanding things correctly and it was only partially me not understanding things correctly. The map conversation isn't a big deal either, just wanted to make sure it wasn't me doing things wrong.

Now my next step is gonna be recreating the dynamic boss ai of FE7 ch 12. Should be an interesting excercise. Wish me luck!

Edited by Hibari Oozora
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...