Download

Please bring back the automatic generation of RPC.

As of 4.7 'The automatic generation of _Implementation and _Validate function declarations" has been deprecated.
We really don’t understand why Epic would do this, when you want to make the engine **easier **for everyone, not harder.

Right now all RPC functions have to be split into three separated functions, a very confusing task for beginners and ridiculous task for programmers who have already used your automation in the past. Take our example, we already have over 500+ RPC functions and splitting/debugging them all will be very cumbersome.

SO, please really consider bringing back the RPC automation in 4.8. In the end, I’m sure that ‘making your Engine human-friendly’ will give a bigger benefit in the long run.

I agree on this, mainly because I don’t really understand why the change was made, and it made our lives a LOT easier not having to type all those functions in. If there’s a limitation caused by the old method, then fair enough.

One thing worth noting, if you use GENERATED_UCLASS_BODY() instead of GENERATED_BODY(), the implementation and validate functions will still be declared for you. I imagine that GENERATED_UCLASS_BODY() will be sticking around for some time yet.

I would also like the auto generation back, if there are no other reasons than style issues.

Updating to 4.7 was the most horrific code change yet, I had to go through hundreds of files and thousands of generated methods to make the project work again and since I tested it out every couple of 4.7 preview iterations I did it more than once.

greetings,
FTC

After going through my project and adding these declarations I long to have the old system back as well, I don’t see why the change was made, macros are used all over the place to save time and improve QOL so it’s kinda odd to go back on that :confused:

If we can’t get the old way back an explanation for the change would be nice.

I mean if it’s working really well now, why take it out?

I totally agree that we deserve some explanation/discussion with users for any big code change like this.

Bumping this, would like to hear official feedback.

Hate to be a troll, but I’m going to keep bumping this until we get some response from Epic.

so bump

I support this, my headers are a huge wall of formerly auto-generated methods :confused:

I don’t know! But I’m asking the network team to jump in and respond…

This change was part of a bigger effort to make UObject workflow more clear to the user and make UObjects feel more like normal C++ classes. Many people were complaining that it’s strange they need to write method bodies for methods they didn’t declare (as the declarations were auto-declared by UnrealHeaderTool). We did a similar thing with UObject constructors, although I imagine it was less painful as the constructors are fully optional.

UnrealHeaderTool should still allow you to not declare those methods until 4.8 but it will emit a warning.

It’s getting a bit out of control for us though.

We abstract our code away, such that when a player wants to pass the ball, he will just has to call Pass(); without worrying about being a server or client. On top of that, for good measure, we also want to emit an OnPass RPC to let everybody know that somebody has passed the ball. The amount of overhead is insane, and we need to declare 7 functions (!) of which only 1 actually performs the ball pass. For good measure, here’s a snippet of the method declarations in the header file:



    /**
     * Pass the ball to the currently locked target.
     * If no target is locked, it becomes a normal dump shot.
     */
    UFUNCTION(BlueprintCallable, Category = "Supraball")
    virtual bool Pass();

    /** @copydoc AWeapon::Pass() */
    UFUNCTION(Reliable, Server, WithValidation)
    virtual void Server_Pass(AActor* Target);
    virtual bool Server_Pass_Validate(AActor* Target);
    virtual void Server_Pass_Implementation(AActor* Target);
    /** @copydoc AWeapon::Pass() */
    virtual void DoPass();
    /** RPC event called when the weapon performed a pass. */
    UFUNCTION(Unreliable, NetMulticast)
    void OnPass(); SEPERATE_EVENT_HEADER(OnPass);
    void OnPass_Implementation();


There’s even a SEPERATE_EVENT_HEADER(OnPass); macro we wrote to split RPC behaviour into Server only, Client only and Both. Apart from passing a ball, we have around 7 to 8 other of such actions. The amount of boilerplate code is just insane. The header is getting quite big and complex, without adding much value at all.

Thanks for the feedback so far. I agree on the boilerplate. Having to deal with header files is a pain with RPCs. :confused:

One of our goals with improving C++ usability is to avoid magically synthesizing function declarations. It’s weird to not have a declaration but to still have to implement the body. Jumping to the declaration of one of these magical functions would take you to a complicated macro. What’s worse, inexperienced developers would be treated to linker errors for method names they didn’t declare themselves, which most people at Epic thought was not a very good design. So we decided to try having users declare the functions themselves with the latest syntax.

Ideally, you’d even be able to configure the name of the function. I don’t particularly like that Unreal forces a naming convention on certain functions. But in this example, allowing the names to be configured would result in even more boilerplate code. (e.g., “UFUNCTION( WithValidation=ValidatePass)”)

We should keep discussing improvements we can make, and brainstorming ideas to reduce boilerplate while not introducing confusing things to new users. Also, it might not be difficult for us to continue to support the legacy syntax for users with existing large codebases. Robert would have a better idea about that.

We probably also we need to be more considerate and backwards compatible. We’ve discussed how we could possibly “version” Unreal C++ syntax changes. Alternatively, the idea has come up that we should “save up” a large number of syntax improvements and roll them out all together rather than trickling changes out with each version, which we initially hoped would be less disruptive.

–Mike

I think if you make large and wide cumulated changes its a worse nightmare to upgrade.

Maybe you can educate UnrealHeaderTool to have an option to generate a copy of a header with generated declarations to edit or fit in.

UnrealUpgradeTool :smiley:

Maybe it’s time to start writing some UE4-focused snippets or VS plugins to help write the boilerplate?

I’m a fan of smaller trickling changes (rather than huge save up), so far with my (admittedly small) c++ codebase, it only takes a few minutes ( and at most a couple hours) and i can update my codebase to latest version! Its a pretty nice feeling, and i don’t dread upgrading.

I could see with large changes, people just deciding its not worth upgrading (or plugin vendors) requiring much more time to update and test. I think it only took allegorithmic 5-6 day turn around after 4.7 to have a tested and ready version of substance out. I could see with huge changes it may take 3-6 weeks. I know github access help elevates this cause they get hand on code early like everyone else, but they will want to QA test for longer because of the larger changes. Thats my opinion anyway.

This is already in the master branch.

Yes, in a way we already do support the legacy syntax, hence a warning, not error.

I think we can restore the old behaviour as default and give people the option to ‘opt-in’ to the new syntax instead of enforcing it. I’m not sure though if that’s going to be possible through a hotfix but we’ll investigate.

One thing which could help reducing header file size would be to be able to include a class a header file with for example only the RPC function declarations.

something like:



class ACharacter
{
    virtual void Tick() override;

    #include "CharacterRPC.h"
};


CharacterRPC.h



UFUNCTION( Server, WithValidation )
void DoSomething();
virtual bool DoSomething_Validate();
virtual void DoSomething_Implementation();


The same could be done in implementation files.

It would not reduce the global amount of lines of code, but still it would make managing the classes maybe easier.

I remember I tried that a few monthes back, but I got errors with UHT. I doubt it would work right now, but it might be a possible extension.

My 2 cents…

Unfortunately that won’t work with UnrealHeaderTool. It’s a simple parses, we don’t parse macros and in general there’s no preprocessor step. We’re working on making it more robust but it’s long way from being as good as the compiler.

I’m a supporter of having to declare the RPC functions yourself. A drawback previously was that IntelliSense would not recognize an function for which the declaration is generated until UHT has generated the auto-generated header files. I disliked that, since to make use of auto-complete while implementing an RPC you had to have compiled the code at least once after declaring the RPC. Declaring them yourself means IntelliSense is immediately up to date.

Ideally for me though we could have the old style RPC declaration, but still have IntelliSense recognize the _Implementation and _Validate functions without having to run UHT. I’m not sure if that can be achieved without resorting to plugins.

I think we still need to resolve this issue so I’m bumping this again…