Getting Started with the Load Simulator #
This Getting Started Guide provides an example scenario and how to run locally.
Example #
The generated file: [game]-load-simulator/src/main/kotlin/LoadSimulatorMain.kt comes with a working scenario.
- Start the run-pragmarun configuration in IntelliJ
- Start the run-load-simulatorrun configuration in IntelliJ
[game]-load-simulator/src/main/kotlin/LoadSimulatorMain.kt
package pragma.loadsimulator
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import pragma.party.PartyRpc.CreateV1Request
import pragma.party.PartyRpc.CreateV1Response
import pragma.party.PartyRpc.JoinWithInviteCodeV1Request
import pragma.party.PartyRpc.JoinWithInviteCodeV1Response
import pragma.utils.toUUID
@ExperimentalCoroutinesApi
fun main() {
    // Initialize your config. Override values as desired, later you can parse a config file passed
    // in as an argument.
    val config = LoadSimulatorConfig(totalPlayerCount = 3)
    // Run within a coroutine scope to initialize and start the scenario.
    runBlocking {
        // Build the runner with a list of phases, the building blocks of your scenario
        val runner = LoadSimulatorRunner.build(config, this, ::generatePhases)
        runner.runScenario()
    }
}
fun generatePhases(context: LoadSimulatorContext): List<Phase> {
    return listOf(
        // This builder accepts a list of steps to run sequentially
        Phase.buildWithSteps(
            "ExamplePhase",
            context,
            listOf(
                // Scenario code lives within steps. The specified player count will be passed to
                // each step execution.
                ExampleStep(context, playerCount = 3),
            ),
            // Run the phase a specified number of times.
            runCount = 1,
        ),
    )
}
class ExampleStep(context: LoadSimulatorContext, playerCount: Int) :
    Step("ExampleStep", context, playerCount) {
    override suspend fun runStep(
        players: List<ClientWrapper>,
        tracker: ICustomStepTracker
    ) {
        // The runner will pass in the correct number of players guaranteed.
        val leader = players[0]
        val buddies = players.subList(1, players.size)
        // sendOrThrow will return the response object or throw an exception in the event of an rpc
        // error or application error.
        val party =
            leader.game
                .sendOrThrowV2(
                    CreateV1Request.getDefaultInstance(),
                    CreateV1Response::class,
                    tracker
                )
                .party
        println("Your partyId is: ${party.partyId.toUUID()}")
        val joinRequest =
            JoinWithInviteCodeV1Request.newBuilder()
                .setInviteCode(party.inviteCode)
                .build()
        buddies.forEach { buddy ->
            // send will invoke an error callback and return null on error
            val result =
                buddy.game.send(
                    joinRequest,
                    JoinWithInviteCodeV1Response::class,
                    tracker
                ) { f ->
                    println("oh no, an error! ${f.failure.error.name}")
                }
            if (result != null) {
                val partySnapshot = result.party
                println(
                    "Your party includes: ${partySnapshot.partyMembersList.joinToString { it.displayName.displayName }}"
                )
            }
        }
    }
}