Economy Component#
Several multiplayer games require the ability to transfer ownership of an item from one user to another. The Economy Component tracks and catalogs those transactions:
Table of Contents#
The Central Bank#
The Central Bank is a Persona Object. All transactions begin at the Central Bank. Once a Resource Object is created, a corresponding PersonaResource Object is generated owned by the Central Bank. Only an Admin User can perform Transactions with the Central Bank.
The example below demonstrates retrieving the Central Bank Persona Object:
1try
2{
3 auto& personaService = CoreSDK->GetServiceFactory()->GetService<services::PersonaService>();
4 std::map<utility::string_t, Variant> searchParams{ { _XPLATSTR("name"), _XPLATSTR("central_bank") } };
5 personaService->FindAll(&searchParams).then([](pplx::task<std::vector<std::shared_ptr<Persona>>> task)
6 {
7 try
8 {
9 std::vector<std::shared_ptr<Persona>> personas = task.get();
10 std::shared_ptr<Persona> centralBank = personas[0];
11 }
12 catch (const xbe::sdk::Exception& e)
13 {
14 // Handle error here
15 }
16 }).wait();
17}
18catch (const xbe::sdk::Exception& e)
19{
20 // Handle error here
21}
22catch (const std::exception& e)
23{
24 // Handle error here
25}
1try
2{
3 PersonaService personaService = CoreSDK.ServiceFactory.GetService<PersonaService>();
4 Dictionary<string, string> resourceDict = new() {{ "name", "central_bank" }};
5 List<Persona> personas = await personaService.FindAll(centralBankDict);
6 Persona centralBank = personas[0];
7}
8catch (Exception ex)
9{
10 // Handle error here
11}
1try
2{
3 const personaService:PersonaService = coreSDK.serviceFactory.getService(PersonaService);
4 var personas: Persona[] | undefined = await personaService.findAll({name: "central_bank"});
5 var Persona:Persona centralBank = personas[0];
6}
7catch(error: any)
8{
9 // Handle Error Here
10}
A reference to the Central Bank Persona Object will enable transactions with the bank, when logged in with an Admin User account.
Resources#
A Resource Object is a Non-Transferable Object that represents data required for a Transferable Object. For Example:
A shop keeper has an inventory; every item in that inventory requires data. The Resource Object is the data for that item; not the item itself.
Data Structure
Name |
Description |
|---|---|
Name |
The unique name of the resource. |
Cost |
The costs associated with the resource. |
Data |
An arbitrary map of additional data about the resource. |
Defaults |
The defaults to use when creating new instances of the resource. |
Description |
Description of the resource |
ParentUid |
The UUID of the parent resource to inherit stats, description, etc |
Stackable |
Indicates if the resource can be copied and stacked or if each instance is considered unique. |
Stats |
The list of stat definitions for the resource. |
Title |
The name to display to the user. |
Only Admin Users can create a Resource Object. The following example illustrates how to create a Resource Object:
1try
2{
3 auto& resourceService = CoreSDK->GetServiceFactory()->GetService<services::ResourceService>();
4 std::shared_ptr<Resource> resource = std::make_shared<Resource>(Resource());
5
6 resource->SetName(_XPLATSTR("Sonic Screwdriver"));
7 resourceService->Create(resource).then([resourceService](pplx::task<std::shared_ptr<Resource>> task)
8 {
9 try
10 {
11 std::shared_ptr<Resource> resource = task.get();
12 }
13 catch (const xbe::sdk::Exception& e)
14 {
15 // Handle error here
16 }
17 catch (const std::exception& e)
18 {
19 // Handle error here
20 }
21 }).wait();
22}
23catch (const xbe::sdk::Exception& e)
24{
25 // Handle error here
26}
27catch (const std::exception& e)
28{
29 // Handle error here
30}
1try
2{
3 ResourceService resourceService = CoreSDK.ServiceFactory.GetService<ResourceService>();
4 Resource resource = new()
5 {
6 Name = "Sonic Screwdriver"
7 };
8 resource = await resourceService.Create(resource);
9}
10catch (Exception ex)
11{
12 // Handle error here
13}
1try
2{
3 var resourceService:ResourceService = coreSDK.serviceFactory.getService(ResourceService);
4 var resource:any = new Resource({
5 name: "Sonic Screwdriver NodeJS"
6 });
7 resource = await resourceService.create(resource);
8}
9catch(error: any)
10{
11 // Handle Error Here
12}
Persona Resources#
A PersonaResource Object is a Transferable Object defining Ownership. For Example: A shop keeper has an inventory; every item in that inventory is owned by the shop keeper. The Ownership of an item must be transferred from the shop keeper to another player. The object representing that Ownership is the PersonaResource Object.
Data Structure
Name |
Description |
|---|---|
PersonaUid |
The unique identifier of the persona or user that this resource belongs to. |
ResourceUid |
The UUID of the resource definition |
Quantity |
The number of resources in the inventory. A negative value indicates an unlimited quantity. A positive value indicates a finite quantity. |
Data |
An arbitrary map of additional data about the instance of the resource for the persona. |
Stats |
The list of unique stats for the resource. Stats are not applicable on stackable resources. |
A PersonaResource Object can not be created, destroyed or edited, managed by the Server. The code below exemplifies how a PersonaResource Object can be retrieved by PersonaResource.uid, for use in Transactions:
1try
2{
3 auto personaResourceService = CoreSDK->GetServiceFactory()->GetService<services::PersonaResourceService>();
4 personaResourceService->FindById(Persona_Resource_ID).then([](pplx::task<std::shared_ptr<PersonaResource>> task)
5 {
6 try
7 {
8 std::shared_ptr<PersonaResource> resource = task.get();
9 }
10 catch (const xbe::sdk::Exception& e)
11 {
12 // Handle error here
13 }
14 }).wait();
15}
16catch (const xbe::sdk::Exception& e)
17{
18 // Handle error here
19}
20catch (const std::exception& e)
21{
22 // Handle error here
23}
1try
2{
3 PersonaResourceService personaResourceService = CoreSDK.ServiceFactory.GetService<PersonaResourceService>();
4 PersonaResource resource = await personaResourceService.FindById(Persona_Resource_ID);
5}
6catch (Exception ex)
7{
8 // Handle error here
9}
1try
2{
3 var personaResourceService:PersonaResourceService = coreSDK.serviceFactory.getService(PersonaResourceService);
4 var resource:any = await personaResourceService.findById(Persona_Resource_ID);
5}
6catch(error: any)
7{
8 // Handle Error Here
9}
Secondly, how a list of PersonaResource Objects can be retrieved by Resource.Uid:
1try
2{
3 auto personaResourceService = CoreSDK->GetServiceFactory()->GetService<services::PersonaResourceService>();
4 std::map<utility::string_t, Variant> searchParams{
5 { _XPLATSTR("resourceUid"), Resource_ID }
6 };
7
8 personaResourceService->FindAll(&searchParams).then([](pplx::task<std::vector<std::shared_ptr<PersonaResource>>> task)
9 {
10 try
11 {
12 std::vector<std::shared_ptr<PersonaResource>> resources = task.get();
13 }
14 catch (const xbe::sdk::Exception& e)
15 {
16 // Handle error here
17 }
18 }).wait();
19}
20catch (const xbe::sdk::Exception& e)
21{
22 // Handle error here
23}
24catch (const std::exception& e)
25{
26 // Handle error here
27}
1try
2{
3 PersonaResourceService personaResourceService = CoreSDK.ServiceFactory.GetService<PersonaResourceService>();
4 Dictionary<string, string> resourceDict = new() {{ "resourceUid", Resource_ID }};
5 List<PersonaResource> resources = await personaResourceService.FindAll(resourceDict);
6}
7catch (Exception ex)
8{
9 // Handle error here
10}
1try
2{
3 const personaResourceService:PersonaResourceService = coreSDK.serviceFactory.getService(PersonaResourceService);
4 var resources:any = await personaResourceService.findAll({
5 resourceUid: Resource_ID
6 });
7}
8catch(error: any)
9{
10 // Handle Error Here
11}
Lastly, how a list of PersonaResource Objects can be retrieved by Persona.Uid:
1try
2{
3 auto personaResourceService = CoreSDK->GetServiceFactory()->GetService<services::PersonaResourceService>();
4 std::map<utility::string_t, Variant> searchParams{ { _XPLATSTR("personaUid"), Persona_ID } };
5
6 personaResourceService->FindAll(&searchParams).then([](pplx::task<std::vector<std::shared_ptr<PersonaResource>>> task)
7 {
8 try
9 {
10 std::vector<std::shared_ptr<PersonaResource>> resources = task.get();
11 }
12 catch (const xbe::sdk::Exception& e)
13 {
14 // Handle error here
15 }
16 }).wait();
17}
18catch (const xbe::sdk::Exception& e)
19{
20 // Handle error here
21}
22catch (const std::exception& e)
23{
24 // Handle error here
25}
1try
2{
3 PersonaResourceService personaResourceService = CoreSDK.ServiceFactory.GetService<PersonaResourceService>();
4 Dictionary<string, string> resourceDict = new() {{ "personaUid", Persona_ID }};
5 List<PersonaResource> resources = await personaResourceService.FindAll(personaDict);
6}
7catch (Exception ex)
8{
9 // Handle error here
10}
1try
2{
3 var personaResourceService: PersonaResourceService = coreSDK.serviceFactory.getService(PersonaResourceService);
4 var resources = await personaResourceService.findAll({personaUid: Persona_ID});
5}
6catch(error: any)
7{
8 // Handle Error Here
9}
Creating A Transaction#
A Transaction is the act of transferring a PersonaResource Object from one Persona Object to another. This is performed with a Transaction Object. Transaction Objects represent data required for a transaction to occur.
Data Structure
Name |
Description |
|---|---|
Status |
The current status of the transaction. |
From |
The unique identifier of the persona that is sending resources to a recipient persona. If |
To |
The unique identifier of the persona is receiving the resources from the sender. If |
Resources |
The list of resources involved in the transaction. If one or more resource(s) are specified belonging to the recipient then it will be transferred to the sender upon execution. |
Approval |
The transaction’s current approval status for each party. |
The code below demonstrates how to create a Transaction:
1try
2{
3 auto personaResourceService = CoreSDK->GetServiceFactory()->GetService<services::PersonaResourceService>();
4
5 personaResourceService->FindById(Persona_Resource_ID).then([CoreSDK, Banker_ID, Persona_ID](pplx::task<std::shared_ptr<PersonaResource>> task)
6 {
7 try
8 {
9 auto transactionService = CoreSDK->GetServiceFactory()->GetService<services::TransactionService>();
10 auto resource = task.get();
11 std::vector<std::shared_ptr<PersonaResource>> resources = { resource };
12
13 std::shared_ptr<Transaction> transaction = std::make_shared<Transaction>(Transaction()
14 .SetStatus(Transaction::Status::PENDING)
15 .SetFrom(Banker_ID)
16 .SetTo(Persona_ID)
17 .SetResources(resources)
18 .SetApproval(std::make_shared<Transaction::TransactionApproval>(Transaction::TransactionApproval()
19 .SetFrom(true)
20 .SetTo(false)
21 ))
22 );
23
24 transactionService->Create(transaction).then([](pplx::task<std::shared_ptr<Transaction>> task)
25 {
26 try
27 {
28 std::shared_ptr<Transaction> transaction = task.get();
29
30 }
31 catch (const xbe::sdk::Exception& e)
32 {
33 // Handle error here
34 }
35 }).wait();
36 }
37 catch (const xbe::sdk::Exception& e)
38 {
39 // Handle error here
40 }
41 }).wait();
42}
43catch (const xbe::sdk::Exception& e)
44{
45 // Handle error here
46}
47catch (const std::exception& e)
48{
49 // Handle error here
50}
1try
2{
3 TransactionService transactionService = CoreSDK.ServiceFactory.GetService<TransactionService>();
4 PersonaResourceService personaResourceService = CoreSDK.ServiceFactory.GetService<PersonaResourceService>();
5
6 List<PersonaResource> resources = new()
7 {
8 await personaResourceService.FindById(Persona_Resource_ID)
9 };
10
11 Transaction transaction = new()
12 {
13 Status = TransactionStatus.PENDING,
14 From = Persona_1_ID,
15 To = Persona_2_ID,
16 Resources = resources,
17 Approval = new TransactionApproval()
18 {
19 From = true,
20 To = false
21 }
22 };
23
24 transaction = await transactionService.Create(transaction);
25}
26catch (Exception ex)
27{
28 // Handle error here
29}
1try
2{
3 const transactionService:TransactionService = coreSDK.serviceFactory.getService(TransactionService);
4 const personaResourceService:PersonaResourceService = coreSDK.serviceFactory.getService(PersonaResourceService);
5
6 var resource:any = await personaResourceService.findById(Persona_Resource_ID);
7 var resources:any = [resource];
8
9 var transaction:any = new Transaction(
10 {
11 status: TransactionStatus.PENDING,
12 from: Banker_ID,
13 to: Persona_ID,
14 resources: resources,
15 approval: {
16 from: true,
17 to: false
18 }
19 });
20
21 transaction = await transactionService.create(transaction);
22}
23catch(error: any)
24{
25 // Handle Error Here
26}
The returning Transaction Object will return with its Transaction.Status property set to “PENDING”, if the transaction creation is successful.
Approving A Transaction#
For a Transaction to complete the Receiver must agree to the transaction, using the Transaction.Approval property. The code below illustrates how to approve a Transaction:
1try
2{
3 auto transactionService = CoreSDK->GetServiceFactory()->GetService<services::TransactionService>();
4 transactionService->FindById(Transaction_ID).then([transactionService](pplx::task<std::shared_ptr<Transaction>> task)
5 {
6 try
7 {
8 std::shared_ptr<Transaction> transaction = task.get();
9 std::shared_ptr<Transaction::TransactionApproval> approval = transaction->GetApproval();
10 approval->SetTo(true);
11
12 transaction->SetApproval(approval);
13 _transactionId = transaction->GetUid();
14
15 transactionService->Update(_transactionId, transaction).then([](pplx::task<std::shared_ptr<Transaction>> task)
16 {
17 try
18 {
19 std::shared_ptr<Transaction> transaction = task.get();
20
21 }
22 catch (const xbe::sdk::Exception& e)
23 {
24 // Handle error here
25 }
26 }).wait();
27 }
28 catch (const xbe::sdk::Exception& e)
29 {
30 // Handle error here
31 }
32 }).wait();
33}
34catch (const xbe::sdk::Exception& e)
35{
36 // Handle error here
37}
38catch (const std::exception& e)
39{
40 // Handle error here
41}
1try
2{
3 TransactionService transactionService = CoreSDK.ServiceFactory.GetService<TransactionService>();
4 Transaction transaction = await transactionService.FindById(Transaction_ID);
5
6 transaction.Approval.To = true;
7 transaction = await transactionService.Update(transaction.Uid.ToString(), transaction);
8}
9catch(Exception ex)
10{
11 // Handle error here
12}
1try
2{
3 const transactionService:TransactionService = coreSDK.serviceFactory.getService(TransactionService);
4 var transaction:any = await transactionService.findById(Transaction_ID);
5
6 transaction.approval.to = true;
7 transaction = await transactionService.update(Transaction_ID, transaction);
8}
9catch(error: any)
10{
11 // Handle Error Here
12}
The returning Transaction Object will return with its Transaction.Status property set to “APPROVED”, if the transaction approval is successful.
Retrieving Transactions#
To Update A Transaction, a reference to the Transaction Object can be helpful. The code below exemplifies retrieving all Transaction Objects sent from a Persona Object:
1try
2{
3 auto transactionService = CoreSDK->GetServiceFactory()->GetService<services::TransactionService>();
4 std::map<utility::string_t, Variant> searchParams{ {_XPLATSTR("from"), Persona_ID } };
5
6 transactionService->FindAll(&searchParams).then([](pplx::task<std::vector<std::shared_ptr<Transaction>>> task)
7 {
8 try
9 {
10 std::vector<std::shared_ptr<Transaction>> transactions = task.get();
11
12 }
13 catch (const xbe::sdk::Exception& e)
14 {
15 // Handle error here
16 }
17 }).wait();
18}
19catch (const xbe::sdk::Exception& e)
20{
21 // Handle error here
22}
23catch (const std::exception& e)
24{
25 // Handle error here
26}
1try
2{
3 TransactionService transactionService = CoreSDK.ServiceFactory.GetService<TransactionService>();
4 List<Transaction> transactions = await transactionService.FindAll(
5 new Dictionary<string, string>()
6 {
7 { "from", Persona_ID }
8 }
9 );
10}
11catch (Exception ex)
12{
13 // Handle error here
14}
1try
2{
3 const transactionService:TransactionService = coreSDK.serviceFactory.getService(TransactionService);
4 var transactions:any = await transactionService.findAll({"from": Banker_ID});
5}
6catch(error: any)
7{
8 // Handle Error Here
9}
Auto-Approved Transactions#
In some instances it may become necessary for both parties to agree to a transaction upon request. For Example:
The Central Bank is not a Persona associated with a user. To transact with the bank, it would be helpful if the transaction was approved by both the bank and the other party. This is possible but only from an Admin User.
The code below demonstrates how to auto-approve a Transaction Object, as an Admin User:
1try
2{
3 auto transactionService = CoreSDK->GetServiceFactory()->GetService<services::TransactionService>();
4 auto personaResourceService = CoreSDK->GetServiceFactory()->GetService<services::PersonaResourceService>();
5
6 personaResourceService->FindById(Persona_Resource_ID).then([transactionService, CENTRAL_BANK_Persona_ID, Banker_ID](pplx::task<std::shared_ptr<PersonaResource>> task)
7 {
8 try
9 {
10 std::shared_ptr<PersonaResource> resource = task.get();
11 std::vector<std::shared_ptr<PersonaResource>> resources = { resource };
12
13 std::shared_ptr<Transaction> transaction = std::make_shared<Transaction>(Transaction()
14 .SetStatus(Transaction::Status::PENDING)
15 .SetFrom(CENTRAL_BANK_Persona_ID)
16 .SetTo(Banker_ID)
17 .SetResources(resources)
18 .SetApproval(std::make_shared<Transaction::TransactionApproval>(Transaction::TransactionApproval()
19 .SetFrom(true)
20 .SetTo(true)
21 ))
22 );
23
24 transactionService->Create(transaction).then([](pplx::task<std::shared_ptr<Transaction>> task)
25 {
26 try
27 {
28 std::shared_ptr<Transaction> transaction = task.get();
29 }
30 catch (const xbe::sdk::Exception& e)
31 {
32 // Handle error here
33 }
34 }).wait();
35 }
36 catch (const xbe::sdk::Exception& e)
37 {
38 // Handle error here
39 }
40 }).wait();
41}
42catch (const xbe::sdk::Exception& e)
43{
44 // Handle error here
45}
46catch (const std::exception& e)
47{
48 // Handle error here
49}
1try
2{
3 TransactionService transactionService = CoreSDK.ServiceFactory.GetService<TransactionService>();
4 PersonaResourceService personaResourceService = CoreSDK.ServiceFactory.GetService<PersonaResourceService>();
5 PersonaResource resource = await personaResourceService.FindById(Persona_Resource_ID);
6 List<PersonaResource> resources = new(){ resource };
7
8 Transaction transaction = new()
9 {
10 From = CENTRAL_BANK_PERSONA_ID,
11 To = Persona_ID,
12 Resources = resources,
13 Status = TransactionStatus.PENDING,
14 Approval = new TransactionApproval()
15 {
16 From = true,
17 To = true
18 }
19 };
20 transaction = await transactionService.Create(transaction);
21}
22catch (Exception ex)
23{
24 // Handle error here
25}
1try
2{
3 const transactionService:TransactionService = coreSDK.serviceFactory.getService(TransactionService);
4 const personaResourceService:PersonaResourceService = coreSDK.serviceFactory.getService(PersonaResourceService);
5
6 const resource:any = await personaResourceService.findById(Persona_Resource_ID);
7 var resources: any = [ resource ];
8
9 var transaction:any = new Transaction(
10 {
11 from: CENTRAL_BANK_Persona_ID,
12 to: Banker_ID,
13 resources: resources,
14 status: TransactionStatus.PENDING,
15 approval:
16 {
17 from: true,
18 to: true
19 }
20 });
21 transaction = await transactionService.create(transaction);
22}
23catch(error: any)
24{
25 // Handle Error Here
26}