-
Notifications
You must be signed in to change notification settings - Fork 178
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
Make characters (player avatars) moddable #2942
base: master
Are you sure you want to change the base?
Conversation
cc1adf1
to
196ce99
Compare
Regarding rorbot, I have these thoughts:
And that was only the part on visuals! Further on the simulation like movement:
TL;DR: Present rorbot is 100% hardcoded which prevents artists like Vido from really improving him. And while at it, it makes sense to make him 100% moddable. |
6e20061
to
ec69f42
Compare
1854d53
to
da0033e
Compare
I added support for bone blend masks, see https://ogrecave.github.io/ogre/api/1.11/class_ogre_1_1_animation_state.html#a06594a53335afbe8ccb67331e35a32fd Example for the stock character.mesh (disables all upper body animation when running, see above GIF):
|
da0033e
to
89fe15e
Compare
We have multiple formats with very similar syntax: rig def (truck), odef, tobj, character (see RigsOfRods#2942). This new parser supports all these formats and adds new features: - support for "quoted strings with spaces". I first implemented them in the new .character fileformat and I decided I want them everywhere, notably .tobj so that procedural roads can have custom names and descriptions for a GPS-like navigation system. - Editable memory representation. The document is a vector of Tokens (types: linebreak, comment, keyword, string, number, boolean.) which keeps the exact sequence as in the file. Tokens can be easily added/modified/removed without writing any extra custom code. - Serializability - saving the (possibly modified) file is as simple as looping through the Tokens array and writing them to a file. No custom code needs to be written for any file format. - Ease of binding to AngelScript: a single API can modify any fileformat. All the operations the user needs is 1. insert token 2. modify token 3. delete token. Code changes: - TObjFileFormat.h: replaced char[] with std::string; renamed TObjFile to TObjDocument, renamed TObjParser to TObjReader. - TObjFileFormat.cpp: replaced scanf() with the new Reader API. - TerrainObjectManager.h: replaced char* with std::string in function args. - TerrainObjectManager.cpp: using the new Document API.
We have multiple formats with very similar syntax: rig def (truck), odef, tobj, character (see RigsOfRods#2942). This new parser supports all these formats and adds new features: - support for "quoted strings with spaces". I first implemented them in the new .character fileformat and I decided I want them everywhere, notably .tobj so that procedural roads can have custom names and descriptions for a GPS-like navigation system. - Editable memory representation. The document is a vector of Tokens (types: linebreak, comment, keyword, string, number, boolean.) which keeps the exact sequence as in the file. Tokens can be easily added/modified/removed without writing any extra custom code. - Serializability - saving the (possibly modified) file is as simple as looping through the Tokens array and writing them to a file. No custom code needs to be written for any file format. - Ease of binding to AngelScript: a single API can modify any fileformat. All the operations the user needs is 1. insert token 2. modify token 3. delete token. Code changes: - TObjFileFormat.h: replaced char[] with std::string; renamed TObjFile to TObjDocument, renamed TObjParser to TObjReader. - TObjFileFormat.cpp: replaced scanf() with the new Reader API. - TerrainObjectManager.h: replaced char* with std::string in function args. - TerrainObjectManager.cpp: using the new Document API.
We have multiple formats with very similar syntax: rig def (truck), odef, tobj, character (see RigsOfRods#2942). This new parser supports all these formats and adds new features: - support for "quoted strings with spaces". I first implemented them in the new .character fileformat and I decided I want them everywhere, notably .tobj so that procedural roads can have custom names and descriptions for a GPS-like navigation system. - Editable memory representation. The document is a vector of Tokens (types: linebreak, comment, keyword, string, number, boolean.) which keeps the exact sequence as in the file. Tokens can be easily added/modified/removed without writing any extra custom code. - Serializability - saving the (possibly modified) file is as simple as looping through the Tokens array and writing them to a file. No custom code needs to be written for any file format. - Ease of binding to AngelScript: a single API can modify any fileformat. All the operations the user needs is 1. insert token 2. modify token 3. delete token. Code changes: - TObjFileFormat.h: replaced char[] with std::string; renamed TObjFile to TObjDocument, renamed TObjParser to TObjReader. - TObjFileFormat.cpp: replaced scanf() with the new Reader API. - TerrainObjectManager.h: replaced char* with std::string in function args. - TerrainObjectManager.cpp: using the new Document API.
We have multiple formats with very similar syntax: rig def (truck), odef, tobj, character (see RigsOfRods#2942). This new parser supports all these formats and adds new features: - support for "quoted strings with spaces". I first implemented them in the new .character fileformat and I decided I want them everywhere, notably .tobj so that procedural roads can have custom names and descriptions for a GPS-like navigation system. - Editable memory representation. The document is a vector of Tokens (types: linebreak, comment, keyword, string, number, boolean.) which keeps the exact sequence as in the file. Tokens can be easily added/modified/removed without writing any extra custom code. - Serializability - saving the (possibly modified) file is as simple as looping through the Tokens array and writing them to a file. No custom code needs to be written for any file format. - Ease of binding to AngelScript: a single API can modify any fileformat. All the operations the user needs is 1. insert token 2. modify token 3. delete token. Code changes: - TObjFileFormat.h: replaced char[] with std::string; renamed TObjFile to TObjDocument, renamed TObjParser to TObjReader. - TObjFileFormat.cpp: replaced scanf() with the new Reader API. - TerrainObjectManager.h: replaced char* with std::string in function args. - TerrainObjectManager.cpp: using the new Document API.
Purpose: to make the rorbot 100% moddable Estimate: 2 man days. The hard part is done, the character-def fileformat is proven to work by Vido using dev-build. Work to be done: ModCache needs to be updated to recognize rorbot mods. I've done this before, see ohlidalp@bf95ca9 |
dfa13be
to
b97e60d
Compare
@CuriousMike56 Thanks for the exhaustive testing and sorry about the confusion with the default rorbot. The game now loads rorbots exclusively from the mods directory, so the config/classic.character won't be found anymore - I need to delete it. Also the classic rorbot needs to be uploaded to the content repo (alongside agora bus and DAF semitruck). |
Adding the classic RoRBot zip to mods allows terrains to load now, but the character is giant and with no texture (same result as Tritonas on Discord). Loading your character mod crashes the game when loading the skeleton:
This brings me to the biggest problem I have with this PR, there's no fallback to the current hardcoded character. If that's not possible, then at the very least the default RoRBot absolutely should be kept in the With the current setup there's bound to be people who delete the character zip from the |
@CuriousMike56 Thanks for testing, sorry about the giant size glitch (I forgot to add EDIT: OK, I see that it's either me taking the hit of maintaining more code (the alternate codepath of loading rorbot from the resources), or you getting the hit of more idiots spamming #support. The problem is, the old rorbot code is gone - the game uses the .character definitions exclusively, and I did that to enable Vido to just extend the default rorbot without hassle. Hardcoding the defs would take that away. |
@CuriousMike56 I think I figured out a setup which will satisfy everyone:
|
Perfect, as long the default character lives in the resources directory I'm good with that 👍 Current (latest master) behavior: RoR_2022-11-15_11-12-38.mp4Now: RoR_2022-11-15_11-24-46.mp4It appears that its not playing any animation in both clips, just that latest master is defaulting to the idle pose instead of T-posing. |
Button now is too small, harder to catch. You could make
Also pressing Cancel in the character selector makes main menu visible What happens in MP with this? Like player A has character A, player B has character B and player A doesn't have character B installed for example. Will he be able to see the default character in this case? Or everyone see the character that they selected in settings? |
This obsoletes the separate "upper/lower" body anim system. * Character.cpp: no longer determines animations, only sets state & situation flags. * SimBuffers.h, Network.h: now transferring flags instead of anim+time. * GfxCharacter.cpp: determine animation from flags and other state info.
Top menubar => tools => Character pose util => tab "Game animations" It also wonderfully explains how the new animation definition system works. - Red flags block the animation. - Green flags let the animation run. - Yellow flags let the animation run, but some are missing or the animation is blocked. - Dark blue flags mean nothing blocks the animation.
The default character is defined in file "resources/skeleton/config/classic.character" and loaded at startup.
New hotkeys: * EV_CHARACTER_CUSTOM_ACTION_01 - 10 (F1 - F10) * EV_CHARACTER_CUSTOM_MODE_01 - 10 (Ctrl+1 - Ctrl+0)
Switches skeleton to `Ogre::SkeletonAnimationBlendMode::ANIMBLEND_[AVERAGE/CUMULATIVE]`
Example for the stock character.mesh (disables all upper body animation when running): ``` begin_bone_blend_mask anim_name "Run" bone_weight "hand.R" 0 bone_weight "hand.L" 0 bone_weight "forearm.R" 0 bone_weight "forearm.L" 0 bone_weight "upper_arm.R" 0 bone_weight "upper_arm.L" 0 bone_weight "shoulder.R" 0 bone_weight "shoulder.L" 0 bone_weight "head" 0 bone_weight "neck" 0 bone_weight "chest" 0 bone_weight "spine" 0 end_bone_blend_mask ```
The usage is equivalent to other mods: a ZIP/directory under 'ROR_HOMEDIR/mods' containing a '*.character' file. To select character, open Settings UI, go to Gameplay tab, scroll to "Player character:" at the bottom and press "Select" button - the standard Selector UI will appear. Character is always loaded with terrain. If the character fails to load, a "Cannot load terrain" messagebox appears and user remains in main menu. The classic character resources were deleted from /resources and will be added to /content (a Git submodule).
You need a rorbot mod to use this branch. Without one, you won't be able to load a terrain. Here is the classic rorbot remade as a mod (it will be uploaded to content repo later) and one test rorbot mod from a beginner tutorial: RigsOfRods#294
Improved looks of the Settings/Gameplay/Select button. Added fallback code to use default chracter if the configured custom mod isn't found. All default character media moved under new directory /resources/classic_character - the deleted mesh/skeleton/material files were reintroduced, missing textures were migrated, a .character definition file was added.
Goal: * to resolve ambiguity between "anim/animation" meaning either skeletal animation or game-defined animation. Ambiguity is bad. Changes:�* game animations (defined in the .character file) ale now called Actions. the `begin/end_animation` is now `begin/end_action`. * ACTION_ flags were renamed to CONTROL_ flags.� Recap of how the system works: * A skeletal animation is a named animation track in OGRE '*.skeleton' file, like "Walk", "Swim", "Side_step"... * User defines 'actions' via .character file, by specifying a skeletal anim name to play and game state flags which trigger/block it. * SITUATION_ flags tell you what circumstances the character is in (on ground, in deep water, driving...) * CONTROL_ flags tell you what controller input is the player giving (go forward, turn, sidestep...)
Fixed glitches in the classic character if player presses contradicting keys together. More internal renaming to the new "anim=skeletal, action=game" terminology, see comments in previous commit. Character net packets moved from Network.h to RoRnet.h, alongside the actor packet.
summary of changes: - the built-in character was renamed from "classic" to "default" - a new cvar 'mp_override_character' was added - configurable from MultiplayerSelector UI with buttons [select] [clear].
cvars: added sim_player_character_skin, mp_override_character_skin character format: removed 'material_override', added 'character_guid' -- deal with it rornet: added 'character_skinfile' (max 40 characters) to UserInfo GameSettingsUI: added skin info next to sim_player_character info. MultiplayerSelectorUI: added skin info next to mp_override_character info. MainSelectorUI: all spawning and skin-choosing logic moved from `MainSelector::Apply()` to `GameContext::OnLoaderGuiApply()` - all in one place. added guid to default.character in resources. character now supports multiple materials (= submeshes + subentities, because each can use only one material)
The `m_current_selection` selection wasn't properly cleared. Also LT_Character/LT_CharacterMP were detected wrong (`type` would be LT_Skin if skins were available).
I changed how player colors are applied - instead of relying on order of elements in .material file, there are names (aliases): ``` // The multiplayer colorization pass - must be named "ColorChange" pass ColorChange { scene_blend alpha_blend // The alpha mask texture unit - name doesn't matter. texture_unit { texture character-alpha.png } // The color texture unit - must be named "PlayerColor" texture_unit "PlayerColor" { colour_op_ex blend_current_alpha src_manual src_current 0 0 0 } } ```
One .skin file can define multiple skins, so skins must be described by full name, not filename. The fix applies to both cvars (local configuration) and RoRnet. Codechanges: - CacheSystem.h: added search method NAME_FULL and helper func `MatchExact()` - CacheSystem.cpp: more comments in `Query()` - RORnet: renamed skin field + constant to clarify filename vs. name. - Network.cpp - just reflect the renaming in rornet - CharacterFactory: added helper `fetchCharacterSkin()` using the correct lookup for both local+remote characters. - GameContext.cpp - `OnLoaderGuiApply()` - fixed configuration cvars to contain skin names instead of filenames
Problem 1: the arrays in GfxScene weren't updated correctly:� std::vector<GfxActor*> m_all_gfx_actors; std::vector<GfxActor*> m_live_gfx_actors; std::vector<GfxCharacter*> m_all_gfx_characters;�I was the person who introduced the arrays a long time ago (before message queue was estabilished) and they didn't exactly help, so now I dropped them again and I use the global arrays directly: App::GetGameContext()->GetActorManager()->GetActors() App::GetGameContext()->GetCharacterFactory()->getAllCharacters() Problem2: The debug states array in GUI_CharacterPoseUtil was interfering between actors. I fixed it by moving the array into GfxCharacter itself, and I updated the GUI to only manipulate player character. Minor change: dropped the 'initialized' state tracking from GfxActor:� bool m_initialized = false;� bool IsActorInitialized() const { return m_initialized; } //!< Temporary TODO: Remove once the spawn routine is fixed void InitializeActor() { m_initialized = true; } //!< Temporary TODO: Remove once the spawn routine is fixed�If there any visual glitches caused by this, they can be fixed later, especially since I noticed some existing singleplayer glitches to fix.
ba08564
to
e9adc5e
Compare
Needs updated rorserver: RigsOfRods/ror-server#153
Present rorbot is 100% hardcoded which prevents artists like Vido from really improving him. And while at it, it makes sense to make him 100% moddable.
The classic rorbot is now a mod as well, and lives in /resources/default_character.zip. If no other mod is installed, game falls back to this one.
I've created a detailed tutorial for complete beginners: https://forum.rigsofrods.org/threads/beginner-tutorial-character-rorbot-mod-from-scratch-in-blender.3761/ - it will guide you through modelling, animating and exporting with Blender and blender2ogre.
Example character mod (from the above tutorial):
rorbotmod-tut1-rev1.zip
To use it, just place it anywhere in your mods directory and enable it using Settings UI/Gameplay tab.