• Categories
  • Recent
  • Tags
  • Popular
  • Solved
  • Unsolved
  • Users
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (Darkly)
  • No Skin
Collapse
brainCloud Forums
J

JasonL

@JasonL
bitHeads
About
Posts
118
Topics
0
Groups
3
Followers
0
Following
0

Posts

Recent Best Controversial

    Question about CloudCode API Hook and Global Property read costs / usage count
  • J JasonL

    Hi @gyutaelee,

    Thanks for the follow-up. Based on the current behavior, the “first 2 API calls are free” allowance is applied across the whole request chain, not separately for the Pre-hook and the original CloudCode script. In other words, internal bridge.callAPI() usage from both executions shares the same allowance for that request/session.

    So if the Pre-hook makes 1 internal API call and the original script makes 3 more, the first 2 total internal calls are free, and the remaining 2 are billed according to the normal post-free rate.

    For your current version-gate use case, this does not change anything because bridge.getGlobalProperty() is not counted as an API call. But if either the Pre-hook or the original script starts using bridge.callAPI() later, the calls will pool under the same request-level allowance.


  • Question about CloudCode API Hook and Global Property read costs / usage count
  • J JasonL

    Hi @gyutaelee ,

    Based on the current brainCloud's implementation, here are the answers to your questions:

    Q1: Does the Pre-hook count as a separate CloudCode execution / API count?**

    Yes. The Pre-hook counts as both a separate API call and a separate CloudCode script invocation. After running, the server publishes its own analytics event with operation "RUN_HOOK-Pre_VersionGate" that increments both counts.

    Q2: Does bridge.getGlobalProperty() count as an API call?**

    No. bridge.getGlobalProperty() is completely free. It reads directly from the cached Game object in memory and bypasses the API call tracking pipeline entirely.

    Q3: Does the "first 3 free, then 0.5 each" rule apply to hook CloudCode scripts?**

    Yes, the discount applies to internal calls from any script or hook within the session.

    Q4: Pass-through case: usage count breakdown

    • Client calls script.RUN: +1 API call
    • Pre-hook executes: +1 API call
    • bridge.getGlobalProperty() inside hook: free
    • Original CloudCode script: +0 (covered by the original script.RUN request)

    Total external API count: 2

    Q5: Blocked case: usage count breakdown

    • Client calls script.RUN: +1 API call
    • Pre-hook executes: +1 API call
    • bridge.getGlobalProperty() inside hook: 0 (free)
    • Original script: +0 (does not run, server throws before invoking it when hook returns non-200)

    Total external API count: 2

    The blocked case costs the same as pass-through from an API-count perspective. The only savings is that the original script's internal bridge.callAPI() calls are avoided.

    Q6: Could reading a Global Property on every script.RUN become a performance or cost concern?

    Performance: No. getGlobalProperty() reads from an in-memory cached Game object (ConcurrentHashMap per node) with no DB query or network call.

    Cost: The hook itself adds +1 API count to every script.RUN call that has the hook attached.

    Q7: Recommended caching approach for frequently-read, rarely-changed property?

    The cache is already in place, no additional caching needed. brainCloud stores the Game object (including all global properties) in an in-memory cache for each server node. Cross-node invalidation is handled automatically when a global property is updated in the portal. Using bridge.getGlobalProperty() is already the optimal pattern.

    Q8: Portal metrics: what can be broken down separately?

    • API Hook execution count: Partially available. Hooks appear within the CC script invocation counter; no hook-only counter exists.
    • CloudCode script execution count: Available as CC Script Invocations, but includes hooks in the same counter.
    • CloudCode internal API call count: Available as CC API Calls in the Monitoring dashboard.
    • Global Property read count: Not tracked. No metric exists for this.

  • Segment Code Bug Report
  • J JasonL

    Hi @LEE-JONG-GUN,

    Good news: the fix for the Segment code field clone bug has been deployed.

    What changed

    • When you clone a Segment now, the code field is automatically appended with _copy (e.g., myCode becomes myCode_copy).
    • The cloned segment's code field is editable, so you can change it to any unique value and save the clone successfully.

    This resolves the duplicate-code issue that was preventing clones from being saved. Thanks again for the report.


  • Segment Code Bug Report
  • J JasonL

    Good catch! Thanks for bringing this to our attention. We’ll fix it so that cloning a segment doesn’t copy and inactivate the code field, avoiding the duplicate-code issue and allowing the clone to be saved.


  • Integration with .NET server
  • J JasonL

    The SDK is just a plain C# source library you can drop into any .NET project (not Unity-only). You can find usage examples and the source in our GitHub repositories at https://github.com/getbraincloud.


  • Question about using unique indexes for Custom Entities
  • J JasonL

    Hi @gyutaelee, have you tried calling the sysListIndexes method from the API Explorer to verify the index, as mentioned earlier? The Portal’s Custom Indexes UI may not always reflect the underlying MongoDB index options correctly for manually adjusted indexes like unique, so sysListIndexes is the more reliable way to confirm what’s actually on the collection. So run CustomEntity > SysListIndexes in API Explorer and check the returned index list for followerId_followingId and its unique flag.


  • Question about using unique indexes for Custom Entities
  • J JasonL

    Hi @gyutaelee, thanks for the detailed request. We will add a unique compound index for your FOLLOW Custom Entity.

    About Your Questions:

    1. Will this unique index auto-deploy to Staging/Production?
      No. Because brainCloud's API blocks unique indexes at the code level (to prevent sharding issues), the deployer does not know about manually added indexes.

    2. Does this need to be applied per app/environment manually?
      Yes. Each brainCloud app (Dev/Staging/Prod) is a separate appId with its own physical MongoDB collection.

    3. Can we provide appIds for Dev/Staging/Prod so you can add the index to each?
      Yes, absolutely. Please reply with the App IDs for your Staging and Production environments. Once we have them, we'll apply the same unique index to all three environments.

    4. Are manually added Custom Entity indexes included in deploy/migrate/export-import workflows?
      No. The deploy pipeline is config-driven. Any index added directly via MongoDB (outside the Portal/API) is invisible to ImportExportService.

    5. If there are existing duplicate rows, will unique index creation fail?
      Yes. MongoDB returns duplicate key error and aborts the entire index build. Since you mentioned the feature isn't in production yet, you can safely reset/clean up FOLLOW data before we apply the index to avoid this. We may need to check for duplicates first.

    6. Is there expected downtime, lock, write failure, or performance impact?
      No hard downtime Index builds are non-blocking: reads and writes continue during the build.

    7. How to verify the unique index exists after application?
      You can verify it from the Indexes tab of app/design/cloud-data/custom-entities/FOLLOW from portal, or call the method sysListIndexes() via API Explorer.


  • Questions about brainCloud Friends and Social Leaderboard behavior
  • J JasonL

    Hi @gyutaelee ,

    Thanks for the detailed questions.

    1. Friend Relationship Direction - Yes, bidirectional

    • AddFriends: When user A calls AddFriends([B]), both A and B see each other in ListFriends("brainCloud")
    • Both A and B will appear in each other's GetSocialLeaderboard results (if they have scores)
    • RemoveFriends: Removes the relationship from both users atomically

    2. Idempotency - Yes, both are idempotent

    • Calling AddFriends([B]) when already friends: No-op, no error thrown (skips DB write)
    • Calling RemoveFriends([B]) when not friends: No-op, no error thrown

    3. Consistency and Caching - Immediate

    • Friend changes are persisted immediately to the database (no write-behind caching)
    • ListFriends("brainCloud") and GetSocialLeaderboard reflect changes immediately after AddFriends/RemoveFriends
    • No eventual consistency or caching delay

    4. Friend Count Limits - No hard cap

    • No code-enforced limit on brainCloud friends per user
    • Practical consideration: Friend IDs stored as array on UserProfile; very large arrays (>10K) may impact read/write performance

    5. GetSocialLeaderboard Behavior - Returns all friends + self + pacers, no limit

    • Returns all recognized friends + self + pacers
    • No hidden maximum result count
    • Pacers are included (if leaderboard has pacers configured)
    • Warning: Response payload grows linearly with friend count

    6. Recommended API for Top-N - Yes, use GetMultiSocialLeaderboard

    • GetMultiSocialLeaderboard with a single leaderboard ID is a correct approach for top-N results
    • leaderboardResultCount is applied after social filtering and score sorting
    • leaderboardResultCount is capped by maxMultipleLeaderboardScoreLimit app property (default 10, can be raised in app-basis)
    • Preferred over GetSocialLeaderboard for top-N because it has built-in truncation

    7. Social Leaderboard Pagination - Not supported

    • No GetSocialLeaderboardPage API exists (only GetGlobalLeaderboardPage for global leaderboards)
    • Social leaderboards always return the full friend set (potentially truncated by leaderboardResultCount only in the multi variant)
    • I will forward your pagination request for team review

    8. Billing and API Counts - 1 API call per request

    • GetSocialLeaderboard = 1 API call regardless of friends/entries returned
    • GetMultiSocialLeaderboard = 1 API call even with multiple leaderboards
    • AddFriends/RemoveFriends = 1 API call even though they modify both users' profiles

    9. Recommended Usage - Yes, your design aligns perfectly


  • Question about using unique indexes for Custom Entities
  • J JasonL

    Hi @gyutaelee,
    Currently, brainCloud blocks unique indexes on all custom collections as a blanket safeguard. The check happens unconditionally before the system even evaluates whether your collection is owned or sharded, so it rejects the unique option with that error.

    We can manually add the unique index for your FOLLOW collection on our end. Please send us a request with:

    1. Your appId
    2. The entityType (is it FOLLOW only?)
    3. The field name(s) that need uniqueness
    4. The desired index name (e.g., test_index)

    Once we receive your request, we'll add the uniqueness constraint for you directly.


  • Admin Billing API request
  • J JasonL

    I’ll forward your request to the team for review...


  • Automated Promotion not associated for users already in target segment
  • J JasonL

    Yes, the behavior you’re describing is expected with the current implementation. RefreshMySegments, RefreshPromotions, and login will not attach the promotion to users who are already in the segment, because the system is designed to only grant automated promotions when the user enters the segment (i.e., when it shows up in enteredIds). The fact that Reset Segments or Re‑evaluate All Segments fixes it is also expected, because those actions force the user back through the segment‑entry logic.

    We’re working on a fix to make this smoother. The practical effect going forward will be that, when a new automated promotion is created or attached to an existing segment, the next segment refresh will automatically apply it to all currently‑eligible users in the background, without you needing to reset or re‑evaluate segments manually. This should make the behavior more predictable, especially when you have a large number of existing users already in that segment.


  • Question about timing for newly deployed Automated Promotions
  • J JasonL

    Our automated promotions were designed to pull members of a segment into a promotion, which is why they can trigger notifications. When an automated promotion fires for a user, they can be notified, and that notification is intended to draw them back into the game. So startTime is effectively the wall‑clock time when the batch job processes that user, not when the user logs in. A user who never logs in will have their promotion silently expire in the background.

    I’ve forwarded your request to our team to see if we can look at adding a flag that lets developers specify that an automated promotion should only trigger on login, which would likely align well with the kind of “starter‑package” use case you described.


  • [Feature Request] Add "Open in New Window" option for Owner ID in Custom Entity view
  • J JasonL

    Thanks for the suggestion and the explanation of the workflow benefit. I’ll bring this request to our team for review and follow up here...


  • New users are never counted — all users appear as Returning Users after launch
  • J JasonL

    @noah The team is working on this, and we’ll share any progress here once there’s something concrete to report.


  • Feature Request / Question: Selective Promotion Exclusion During App Deployment
  • J JasonL

    Hi, thanks for the detailed report. At the moment, there isn’t a per-promotion exclusion toggle for deployments; the currently recommended way is to keep Preserve Products+Pricing & Promotions in the target environment. Your request for selective promotion exclusion makes sense. I’ll pass this along as a feature request for the team to consider.


  • Two Questions: Follow System & Referral Rewards
  • J JasonL

    Hi @gyutaelee,

    1. For one-way follow: brainCloud doesn’t have a built-in one-way “follow” graph, so you’ll need to implement your own follower/following system using one of the user data mechanisms (e.g. global or entity data) to track who follows whom. This keeps it independent of the Friends API, which is designed around mutual relationships. GetPresenceOfUsers() works with any valid profile IDs, it does not require a Friend relationship between the players to return presence info.

    2. For the referral rewards question: I’m going to forward this to our team to review the best server-side approach for triggering rewards for both the referrer and referee once the milestone (like reaching level 3) is reached.

    Thanks for the detailed explanation of your use cases.


  • Automated Promotions with no discount — "Not for Sale" workaround and purchase count tracking
  • J JasonL

    Did you call CachePurchasePayloadContext() with the promotionId before calling verifyPurchase() ? That’s the piece that passes the promotion ID through and should trigger an increase in the maxPurchases counter.


  • Automated Promotions with no discount — "Not for Sale" workaround and purchase count tracking
  • J JasonL

    If your promotion is for a cash product and the promotional product is set to Not for Sale, you need to complete the flow by calling verifyPurchase in brainCloud with the purchasePayload from the store.

    As long as that payload contains the promotionId you received from GetEligiblePromotions, the promotion will be correctly attributed and the server-side flow will reach the counter increment logic.

    Also make sure you set maxPurchases on the promotion configuration page so the system knows when to stop returning that promotion for the user.

    As for your feature request to allow promotions without requiring a discount, I will forward this to our team for review.


  • Does GetEligiblePromotions trigger Automated Promotions in real-time after XP level update?
  • J JasonL

    Hi, GetEligiblePromotions is snapshot-driven, not fully real-time. It relies on a cached promotion-eligibility snapshot stored on the UserProfile, which is only refreshed at specific points.

    • GetEligiblePromotions does not reevaluate Automated Promotion segment conditions (like experienceLevel >= 4) against the latest player state on every call. Instead, it uses the last calculated promotion snapshot that was written to the UserProfile. That snapshot is normally refreshed at login, or when you explicitly call the RefreshPromotions CAPI.

    • Because of that, the “delay” you are seeing is essentially “until the next snapshot refresh.” In your current flow, that refresh happens on the next login, which is why restarting the app makes the promotion suddenly appear. There is no fixed time-based delay; it is purely tied to when the snapshot is updated.

    • To make the promotion available immediately mid-session, add an explicit refresh step to your flow. After your CloudCode call to incrementExperiencePoints (once the player has reached level 4), call RefreshPromotions on the client, and then call GetEligiblePromotions. That will force an immediate refresh of the promotion snapshot so the level-4 promotion is returned without requiring a new session.

    API details for RefreshPromotions:
    https://docs.braincloudservers.com/api/capi/appstore/refreshpromotions.


  • missing features
  • J JasonL

    Thanks for the suggestions, we will look into it...

  • Login

  • Login or register to search.
  • First post
    Last post
0
  • Categories
  • Recent
  • Tags
  • Popular
  • Solved
  • Unsolved
  • Users