Results of requests

Every Pulse plugin answers a request (unlock a skill, add an item, craft, join a session) with an FPulseResult: did it work, and if not, why, as a gameplay tag with a text for the player and details of the plugin. A Blueprint or an interface reads the result of any plugin the same way.

Field What it holds
bSuccess True if the request was done
Reason Why it failed: a Pulse.Result.Failure tag or one of the plugin (Pulse.Skill.Failure.Requirement)
Message Text for the player; empty shows the last part of the reason as words (“Not Found”)
Details An instanced struct of the plugin: the item that did not fit, the missing cost, an online error id

Blueprint: Make Pulse Success, Make Pulse Failure, Is Success, Failed For (a reason and its children), Get Display Text. C++: FPulseResult::Success(Details), FPulseResult::Failure(Reason, Message, Details), IsSuccess, GetDetails<T>(), ToString for logs.

Common reasons

Tag Meaning
Pulse.Result.Failure.Authority Only the server may do this
Pulse.Result.Failure.Invalid The request makes no sense (missing or wrong values)
Pulse.Result.Failure.NotFound What the request names does not exist
Pulse.Result.Failure.Conditions Conditions did not pass
Pulse.Result.Failure.Costs The costs could not be paid
Pulse.Result.Failure.NoSpace There is no room (inventory, slots)
Pulse.Result.Failure.Busy Something else runs and must finish first
Pulse.Result.Failure.Cancelled The request was cancelled
Pulse.Result.Failure.Timeout No answer came in time

Plugins add their own reasons below their plugin tag and use the common ones where they fit.

The answer reaches the client

A client asks the server through a server RPC; the result is decided on the server. The common way back:

  1. The client starts the request: UPulseRequestSubsystem::Get(this)->BeginRequest(Callback) (Blueprint Begin Pulse Request) gives an FPulseRequestId. The client sends it with its own server RPC.
  2. The server answers: Pulse::Requests::Reply(AnyActorOfThePlayer, RequestId, Result).
  3. The client’s callback gets the result. A failure is also broadcast on Pulse.Message.Request.Failed (payload FPulseRequestFailedMessage, the reason in the context tags), so one interface can show the reason of every plugin.
// Client
const FPulseRequestId id = UPulseRequestSubsystem::Get(this)->BeginRequest(
	FPulseRequestCallback::CreateUObject(this, &UMyCraftingWidget::HandleCraftResult));
Crafting->ServerCraft(Recipe, id);

// Server, in the implementation of ServerCraft
Pulse::Requests::Reply(GetOwner(), InRequestId, FPulseResult::Failure(Pulse::Foundation::Tags::Result_Failure_Costs));

The server adds a UPulseRequestComponent to every player controller at login (and on the first answer if a controller has none); nothing to set up. A request without an answer fails with Timeout after its timeout (30 real seconds by default, 0 waits forever); Cancel Pulse Request forgets one. The player of the server (listen server, single player) gets its answer directly. A request id of 0 means “no answer wanted”.

Debugging

PulseRequestTest [fail] sends a test request to the server and prints the answer (Console).


PulseFoundation plugin documentation.

This site uses Just the Docs, a documentation theme for Jekyll.