Dragon Star
Build Dragon Star, a Gacha RPC game!
Table of Contents
New Project
This is a example showing how to use our SDK to create a RPC game called Dragon Star with the Gacha game design.
First of all, use the CLI to quickly scaffold the project structure: python3 he-cli.py

Then let's navigate into the newly-created directory and see what do we have in the repository

The "models" folder is where your data class, data model, and data items will be.
The "sdk" folder contains a set of tools and models that you can easily use.
Create Dragons
The center of the Gacha RPG game is drawing items and using them to compete with other players. In Dragon Start, players can obtain dragons of five tiers (denoted by 'C' 'U' 'R' 'SR' and 'SSR'), and couple dragons with riders or equip with items to enhance their power. Let's see how to develop the backend of this game using Hyperedge' SDK.
Data Class
First of all let's create the data class for the dragon that stores all the necessary static attributes:
python3 he-admin.py create-dataclass dragon --fields "name:str; shortDescription:str; Description:str; Affinity:typing.Optional[DataRef[AffinityData]]; Element:typing.Optional[DataRef[ElementData]]; Tier:DataRef[TierData]; EquipSlots:typing.List[DragonEquipSlotData] = list(); Clonable:typing.Optional[bool] = False; RetirementReward:typing.Optional[Reward]"
Here, we define these fields for the dragon data class:
name
shortDescription
Description
Affinity, which can be 'Elemental', 'Bio', 'Techno', 'Psycho', and 'Aether'
Element, can be 'Fire', 'Geo', 'Water', 'Electro', and 'Metal'
Tier, which can be 'C', 'U', 'R', 'SR', and 'SSR'
EquipSlots, which defines a list of slots that player can place different types of items, such as element stone and weapons
Clonable, which set the permission of cloning a dragon
Retirement, which defines the reward when player decides to retire a dragon
Data Model
We will create the dataclasses referenced by Dragon later. Now, let's continue and create the dragon data model, where we want to put in more dynamic attributes that can change during gameplay, using:
python3 he-admin.py create-model Dragon dragon --fields "level: int; exp: int"
Data Items
Now we're ready to create some concrete dragons, of different tier, affinity, and element. Gasp!
Let's start with creating some tier C dragons.
Let's define five kinds of pretty basic Tier C dragons :
BASIC_DRAGONS = ('Drake', 'Dragon', 'Wyvern', 'Wyrm', 'Lindwurm')
and create a script to dynamically assign them the "C" tier and an experience ladder, using Hyperedge's define() function (which performs field and id validation for you):
from dragon_star.models.data.dragons.dragon import *
from dragon_star.models.dragons import *
from dragon_star.sdk.utils import to_underscore
################################################################################
# Tier 1 Basic Dragons
################################################################################
for dragon_type in BASIC_DRAGONS:
DragonData.define(
id=to_underscore(dragon_type),
Name=dragon_type,
ShortDescription='',
Description='',
EquipSlots=[],
Tier=TIER_C)
BasicDragonCommonLadder = DragonLadder.new_ladder('BasicDragonCommonLadder')
#assert False, str(BasicDragonCommonLadder)
exp = 100
step = 100
for lvl in range(1, 40):
#FIXME
level_data = DragonLadder.ladder_level_data_class(id=f'xx{lvl}', Exp=exp, Data=DragonLadderLevelData(id=f'xx{lvl}'))
BasicDragonCommonLadder.add_level(level_data)
exp += step
step += 100
Here's the DragonLadder stores the experience ladder of the dragon. It's created using the ProgressionLadder class from Hyperedge's SDK.
from dragon_star.sdk.models import BaseData, DataModel
from dragon_star.sdk.models.progression import ProgressionLadder
class DragonLadderLevelData(BaseData):
pass
DragonLadder = ProgressionLadder(
Entity=Dragon,
IsExperienceBased=True,
LadderLevelData=DragonLadderLevelData)
Want to add something more interesting? Let's create some Tier U dragons with weapon slots and magic stone slots on them:
from dragon_star.models.data.dragons import *
from dragon_star.models.data.tier import *
from dragon_star.models.data.slots.equip_slots.weapon_slots import *
################################################################################
# Tier 2 Warrior Dragons
################################################################################
D_WARRIOR_DRAKE = DragonData.define(
id='warrior_drake',
Name='Warrior Drake',
ShortDescription='',
Description='',
Tier=TIER_U,
EquipSlots=[DE_TURRET_WEAPON]
)
D_WARRIOR_VYWERN = DragonData.define(
id='warrior_vywern',
Name='Warrior Vywern',
ShortDescription='',
Description='',
Tier=TIER_U,
EquipSlots=[DE_AERIAL_WEAPON]
)
D_WARRIOR_DRAGON = DragonData.define(
id='warrior_dragon',
Name='Warrior Dragon',
ShortDescription='',
Description='',
Tier=TIER_U,
EquipSlots=[DE_AERIAL_WEAPON]
)
################################################################################
# Tier 2 Warrior Heavy Dragons
################################################################################
D_WARRIOR_HEAVY_DRAKE = DragonData.define(
id='warrior_drake_heavy',
Name='Warrior Drake',
ShortDescription='',
Description='',
Tier=TIER_U,
EquipSlots=[DE_TURRET_WEAPON, DE_TURRET_WEAPON]
)
D_WARRIOR_HEAVY_VYWERN = DragonData.define(
id='warrior_vywern_heavy',
Name='Warrior Vywern',
ShortDescription='',
Description='',
Tier=TIER_U,
EquipSlots=[DE_AERIAL_WEAPON, DE_AERIAL_WEAPON]
)
D_WARRIOR_HEAVY_DRAGON = DragonData.define(
id='warrior_dragon_heavy',
Name='Warrior Dragon',
ShortDescription='',
Description='',
Tier=TIER_U,
EquipSlots=[DE_AERIAL_WEAPON, DE_AERIAL_WEAPON]
)
from dragon_star.models.data.dragons.dragon import *
from dragon_star.models.data.slots.equip_slots.element_slots import *
from dragon_star.sdk.utils import to_underscore
################################################################################
# Tier 2 Elemental Dragons
################################################################################
for el_data in ElementData.instances():
for dr_type in BASIC_DRAGONS:
DragonData.define(
id=f'dragon_elem_{el_data.id}_{to_underscore(dr_type)}',
Name=f'{el_data.Name} {dr_type}',
ShortDescription='',
Description='',
Tier=TIER_U,
EquipSlots=[DE_ELEMENT_STONE],
Affinity=AFFINITY_ELEMENTS)
D_SKYHIGH_DRAGON = DragonData.define(
id='skyhigh_dragon',
Name='Skyhigh Dragon',
ShortDescription='',
Description='',
Tier=TIER_U,
Affinity=AFFINITY_ELEMENTS)
Refer to the dragon star repo to see all our full example and how other dragon items are created.
(TL;DR:
tier C: basic dragons
tier U: metal dragon, engineered dragons, elemental dragon, Bubble Dragon, Skull Dragon, Future Dragon ...
tier S: 9 sons
tier SR: Chinese dragon, legendary dragon tier
tier SSR: Conceptual Dragon)
Create Auxiliary Items
Now let's create more dataclasses that are referenced in the Dragon data class -- AffinityData, ElementData, TierData, and DragonEquipSlotData. They're all static data. Having ElementData and DragonEquipSlotData, we can also create Equippable items eventually.
Let's get started. Using the same approach as how we created Dragon, use:
python3 he-admin.py create-dataclass Affinity --fields "id: str; Name: str; description: str"
python3 he-admin.py create-dataclass Element --fields "Name: str; HasStone: typing.Optional[bool] = False"
python3 he-admin.py create-dataclass DragonEquipSlot --fields "description: str"
python3 he-admin.py create-dataclass Tier --fields "name: str; symbol: str"
As they're all static data, we don't need to create any data models. And from here, we can use the define() method from Hyperedge's CLI to create data class items as such:
Affinity
from dragon_star.sdk.models import BaseData
class AffinityData(BaseData):
Name: str
Description: str
AFFINITY_ELEMENTS = AffinityData.define(
Name='Elemental',
Description='')
AFFINITY_BIO = AffinityData.define(
Name='Bio',
Description='')
AFFINITY_TECHNO = AffinityData.define(
Name='Techno',
Description='')
AFFINITY_PSYCHO = AffinityData.define(
Name='Psycho',
Description='')
AFFINITY_AETHER = AffinityData.define(
Name='Aether',
Description='')
Element
import pydantic
import typing
from dragon_star.sdk.models import BaseData, DataRef, optional_field
class ElementData(BaseData):
Name: str
HasStone: bool = optional_field(False)
ELEMENT_FIRE = ElementData.define(
Name='Fire',
HasStone=True
)
ELEMENT_WIND = ElementData.define(
Name='Wind'
)
ELEMENT_GEO = ElementData.define(
Name='Geo',
HasStone=True
)
ELEMENT_WATER = ElementData.define(
Name='Water',
HasStone=True
)
ELEMENT_ELECTRO = ElementData.define(
Name='Electro'
)
ELEMENT_METAL = ElementData.define(
Name='Metal'
)
Tier
import typing
from dragon_star.sdk.models import BaseData
class TierData(BaseData):
Name: str
Symbol: str
TIER_C = TierData.define(id='common', Symbol='C', Name='Common')
TIER_U = TierData.define(id='uncommon', Symbol='U', Name='Uncommon')
TIER_R = TierData.define(id='rare', Symbol='R', Name='Rare')
TIER_SR = TierData.define(id='super_rare', Symbol='SR', Name='SuperRare')
TIER_SSR = TierData.define(id='ultra_rare', Symbol='SSR', Name='UltraRare')
ALL_TIERS = TierData.instances()
def prev_tier(tier: TierData) -> typing.Optional[TierData]:
for jj, t in enumerate(ALL_TIERS[1:]):
if t == tier:
return ALL_TIERS[jj]
return None
def next_tier(tier: TierData) -> typing.Optional[TierData]:
for jj, t in enumerate(ALL_TIERS[:-1]):
if t == tier:
return ALL_TIERS[jj+1]
return None
Equipment slots
from dragon_star.sdk.models import BaseData, DataRef
from dragon_star.models.data.tier import *
class DragonEquipSlotData(BaseData):
Description: str
# Weapon slots
DE_AERIAL_WEAPON = DragonEquipSlotData.define(id='de_aerial_stone', Description='')
DE_TURRET_WEAPON = DragonEquipSlotData.define(id='de_turret_stone', Description='')
# Element stone slots
DE_ELEMENT_STONE = DragonEquipSlotData.define(id='de_elem_stone', Description='')
Equippable items
Now we can use create equippable items that can be equipped on the dragons, including element stones and weapons:
python3 he-admin.py create-dataclass DragonEquippable --fields "name:str; shortDescription:str; Description:str; slot:DataRef[DragonEquipSlotData]; Tier: DataRef[TierData]; RecycleReward: Reward"
python3 he-admin.py create-model dragonEquippable dragonEquippable --fields "level: int; exp: int"
And let's create some element stone items using what we've just made, with a craft rule that player can craft a higher level magic stone with three lower levels ones. You can implement this using the CraftRule class provided by Hyperedge's SDK.
from dragon_star.sdk.models import BaseData, DataRef
from dragon_star.sdk.models.crafting import CraftRule
from dragon_star.models.data.slots.equip_slots.element_slots import *
from dragon_star.models.data.equips.equippables.equippable import DragonEquippableData
from dragon_star.models.data.element import ElementData
from dragon_star.models.data.tier import *
################################################################################
# Element stones for elemental dragons
################################################################################
STONES_BY_ELEMENT = {el_data: dict() for el_data in ElementData.instances()}
for ti, tier_data in enumerate(ALL_TIERS):
for el_data in ElementData.instances():
if tier_data == TIER_C:
continue
stone_data = DragonEquippableData.define(
Name=f'{tier_data.Name} {el_data.Name} Stone',
Description='',
Slot=DE_ELEMENT_STONE,
Tier=tier_data)
#
STONES_BY_ELEMENT[el_data][tier_data] = stone_data
minor_tier = prev_tier(tier_data)
if minor_tier and minor_tier != TIER_C:
req_stone = STONES_BY_ELEMENT[el_data][minor_tier]
craft_rule = CraftRule(f'craft_rule_{stone_data.id}')
craft_rule.require(req_stone, 3)
craft_rule.produce(stone_data, 1)
DE_ELEMENT_STONE = DragonEquippableData.define(
Name=f'Elements Stone',
Description='',
Slot=DE_ELEMENT_STONE,
Tier=TIER_SSR
)
DE_ELEMENT_STONE_CRAFT = CraftRule(f'craft_rule_{DE_ELEMENT_STONE.id}')
for el_data in ElementData.instances():
DE_ELEMENT_STONE_CRAFT.require(STONES_BY_ELEMENT[el_data][TIER_SSR])
DE_ELEMENT_STONE_CRAFT.produce(DE_ELEMENT_STONE)
Create Riders and Buildings
Two more key entities in Dragon Star are riders and buildings.
Riders
Riders are character to couple with dragon, follow the same approach to create rider data class and data model.
python3 he-admin.py create-dataclass rider --fields "name:str; shortDescription:str; Description:str; Affinity:typing.Optional[DataRef[AffinityData]]; Tier:DataRef[TierData]; EquipSlots:typing.List[DragonEquipSlotData] = list(); RetirementReward:"typing.Optional[Reward]"
python3 he-admin.py create-model rider rider
Buildings
Buildings are places that can produce resources and unlock new functionalities, for example mine is basically an energy system that produces gold/iron over time; incubator is where dragon is raised; and market is where players can purchase resourcse. As there's only one slot for each type of building, let's do it in this way
python3 he-admin.py create-dataclass CityBuildingSlotData --fields "name:str; Description:str;
python3 he-admin.py create-model building
And then create building items as:
from dragon_star.sdk.models import DataModel
class BuildingBase(DataModel):
Level: int = 0
class BuildingCastle(BuildingBase):
pass
class BuildingMine(BuildingBase):
pass
class BuildingIncubator(BuildingBase):
pass
class BuildingAcademy(BuildingBase):
pass
class BuildingForgery(BuildingBase):
pass
class BuildingNest(BuildingBase):
pass
from dragon_star.sdk.models import BaseData, DataRef
from dragon_star.models.data.tier import *
class CityBuildingSlotData(BaseData):
Name: str
Description: str
BUILDING_SLOT_CASTLE = CityBuildingSlotData.define(
Name='Castle',
Description='')
BUILDING_SLOT_MINE = CityBuildingSlotData.define(
Name='Mine',
Description='')
BUILDING_SLOT_INCUBATOR = CityBuildingSlotData.define(
Name='Incubator',
Description='')
BUILDING_SLOT_NEST = CityBuildingSlotData.define(
Name='Nest',
Description='')
BUILDING_SLOT_MARKET = CityBuildingSlotData.define(
Name='Market',
Description='')
BUILDING_SLOT_ACADEMY = CityBuildingSlotData.define(
Name='Academy',
Description='')
BUILDING_SLOT_FORGERY = CityBuildingSlotData.define(
Name='Forgery',
Description='')
BUILDING_SLOT_DEPOT = CityBuildingSlotData.define(
Name='Depot',
Description='')
BUILDING_SLOT_HUB = CityBuildingSlotData.define(
Name='Hub',
Description='')
Create Game Mechanics and Logic
Now we've defined most of the data models that construct this game and added a couple of items, let's create a few more classes for game mechanics, including currency, experience, and achievement. Then we'll fill in some of the concrete game logic, include upgrading and claiming achievement etc.
Currency
One system that most games have is the currency system, and it's common for Gacha games to have multiple currencies used for purchasing different resources. As an example, let's try to create two currencies in Dragon Star:
python3 he-admin.py create-dataclass Currency --fields "Name: str; Symbol:str; Tier: DataRef[TierData]"
from dragon_star.sdk.models import BaseData, DataRef
from dragon_star.models.data.tier import *
class CurrencyData(BaseData):
Name: str
Symbol: str
Tier: DataRef[TierData]
CURR_DRAX = CurrencyData.define(
Name='Drax',
Symbol='DRX',
Tier=TIER_U
)
CURR_GOLD = CurrencyData.define(
Name='Gold',
Symbol='GLD',
Tier=TIER_R
)
Experience
Our previous code indicates that rider, dragon, and equipments have a experience attribute and can be upgraded. Now let's create the data classes used for storing the experience levels.
python3 he-admin.py create-dataclass DragonExpMaterial --fields "name: str; Description: str; Value: int; Tier: DataRef[TierData]; Affinity: DataRef[AffinityData]; DraxPerValue: typing.Optional[int] = 0"
python3 he-admin.py create-dataclass DragonEquippableExpMaterial --fields "name: str; Description: str; Value: int; Tier: DataRef[TierData]; Affinity: DataRef[AffinityData]; DraxPerValue: int = optional_field(0)"
python3 he-admin.py create-dataclass RiderExpMaterial --fields "name: str; Description: str; Value: int; Tier: DataRef[TierData]; Affinity: DataRef[AffinityData]; DraxPerValue: typing.Optional[int] = 0"
Now we can create some Dragon Experience Material Items of different tiers and affinities that can increment a dragon's experience.
from dragon_star.sdk.models import BaseData, DataRef
from dragon_star.models.data.element import *
from dragon_star.models.data.affinity import *
from dragon_star.models.data.tier import *
class DragonExpMaterialData(BaseData):
Name: str
Description: str
Value: int
Tier: DataRef[TierData]
Affinity: DataRef[AffinityData]
DraxPerValue: typing.Optional[int] = 0
_AFFINITY_TO_CORENAME = {
AFFINITY_ELEMENTS.id: "Elemental",
AFFINITY_TECHNO.id: "NanoMachine",
AFFINITY_BIO.id: "Life",
AFFINITY_PSYCHO.id: "Mind",
AFFINITY_AETHER.id: "Void"
}
################################################################################
for a_idx, affinity_data in enumerate(AffinityData.instances()):
for tier_data in [TIER_R, TIER_SR, TIER_SSR]:
DragonExpMaterialData.define(
id=f'dragon_exp_mat_{affinity_data.id}_{tier_data.id}',
Name=f'{_AFFINITY_TO_CORENAME[affinity_data.id]} Core',
Description='',
Tier=tier_data,
Value=100,
Affinity=affinity_data,
DraxPerValue=1 if a_idx == 0 else a_idx*2
)
In this same way, we can create Experience Material Items for equippments and riders:
from dragon_star.sdk.models import BaseData, DataRef
from dragon_star.models.data.element import *
from dragon_star.models.data.affinity import *
from dragon_star.models.data.tier import *
class DragonEquippableExpMaterialData(BaseData):
Name: str
Description: str
Value: int
Tier: DataRef[TierData]
Affinity: DataRef[AffinityData]
DraxPerValue: int = optional_field(0)
################################################################################
# Elemental-based equippable upgrades
################################################################################
for el_data in ElementData.instances():
for tier_data in [TIER_R, TIER_SR, TIER_SSR]:
DragonEquippableExpMaterialData.define(
id=f'dragon_equip_exp_mat_elem_{el_data.id}_{tier_data.id}',
Name='Elemental Essence Crystal',
Description='',
Tier=tier_data,
Value=100,
Affinity=AFFINITY_ELEMENTS,
DraxPerValue=0
)
_AFFINITY_TO_CRYSTAL_NAME = {
AFFINITY_ELEMENTS.id: "Elemental Essences",
AFFINITY_TECHNO.id: "NanoMachine",
AFFINITY_BIO.id: "Life",
AFFINITY_PSYCHO.id: "Mind",
AFFINITY_AETHER.id: "Void"
}
################################################################################
for a_idx, affinity_data in enumerate(AffinityData.instances()):
for tier_data in [TIER_R, TIER_SR, TIER_SSR]:
DragonEquippableExpMaterialData.define(
id=f'dragon_equip_exp_mat_{affinity_data.id}_{tier_data.id}',
Name=f'{_AFFINITY_TO_CRYSTAL_NAME[affinity_data.id]} Crystal',
Description='',
Tier=tier_data,
Value=100,
Affinity=AFFINITY_TECHNO,
DraxPerValue=1 if a_idx == 0 else a_idx*2
)
from dragon_star.models.data.element import *
from dragon_star.models.data.affinity import *
from dragon_star.models.data.tier import *
class RiderExpMaterialData(BaseData):
Name: str
Description: str
Value: int
Tier: DataRef[TierData]
Affinity: DataRef[AffinityData]
DraxPerValue: typing.Optional[int] = 0
_AFFINITY_TO_KNOWLEDGE_DRIVE_NAME = {
AFFINITY_ELEMENTS.id: "Elemental Essences",
AFFINITY_TECHNO.id: "NanoMachine",
AFFINITY_BIO.id: "Life",
AFFINITY_PSYCHO.id: "Mind",
AFFINITY_AETHER.id: "Void"
}
################################################################################
for a_idx, affinity_data in enumerate(AffinityData.instances()):
for tier_data in [TIER_R, TIER_SR, TIER_SSR]:
RiderExpMaterialData.define(
id=f'rider_upgrade_{affinity_data.id}_{tier_data.id}',
Name=f'{_AFFINITY_TO_KNOWLEDGE_DRIVE_NAME[affinity_data.id]} Knowledge Drive',
Description='',
Tier=tier_data,
Value=100,
Affinity=AFFINITY_TECHNO,
DraxPerValue=1 if a_idx == 0 else a_idx*2
)
Achievement
Another important system we're missing right now is the achievement system. Let's create the achievement data class and data model first:
python3 he-admin create-dataclass achievement --fields "name: str; description: str; reward: Reward"
python3 he-admin create-model achievement achievement --fields "Claimed: bool"
More importantly, let's create the handler of claiming an achievement demonstrating how you can implement game logics using Hyperedge's SDK. Let's create another folder called "Logic", navigate into it, and create a function handler called ClaimAchievementReward, using Hyperedge's Handler class (which enforces a consistent formating).
import typing
from dragon_star.sdk.models.types import Ulid
from dragon_star.sdk.models.base import _BaseModel
from dragon_star.sdk.models.handler import Handler
class ClaimAchievementRewardReq(_BaseModel):
AchievementId: Ulid
class ClaimAchievementRewardResp(_BaseModel):
Success: bool
ClaimAchievementRewardHandler = Handler(
Name='ClaimAchievementReward',
RequestClass=ClaimAchievementRewardReq,
ResponseClass=ClaimAchievementRewardResp)
ClaimAchievementRewardHandler.Code = """
var failResp = new ClaimAchievementRewardResp { Success = false };
var user = await GameContext.GetUserAsync(GameContext.CurrentUserId);
var achievement = user.GetAchievement(req.AchievementId);
if (achievement.Claimed)
{
return failResp;
}
var achievementData = GameDb.GetAchievementData(achievement.Data);
if (!GameContext.GiveReward(user, achievementData.Reward))
{
return failResp;
}
achievement.Claimed = true;
user.UpdateAchievement(achievement);
return new ClaimAchievementRewardResp { Success = true };
"""
In the function body, we checked whether user has unlocked a given achievement that hasn't been claimed it before. If so, we grant the achievement to the user.
Upgrading
Following the same approach, we can create handlers for upgrading dragons, equipments, and buildings:
import typing
from dragon_star.sdk.models.types import *
from dragon_star.sdk.models.base import _BaseModel
from dragon_star.sdk.models.handler import Handler
class UpgradeDragonReq(_BaseModel):
DragonId: Ulid
MaterialIds: typing.List[int]
MaterialAmounts: typing.List[UInt64]
class UpgradeDragonResp(_BaseModel):
Success: bool
UpgradeDragonHandler = Handler(
Name='UpgradeDragon',
RequestClass=UpgradeDragonReq,
ResponseClass=UpgradeDragonResp)
UpgradeDragonHandler.Code = """
return new UpgradeDragonResp { Success = false };
"""
_UpgradeDragonHandler_FIXME = """
var failResp = new UpgradeDragonResp { Success = false };
var user = await GameContext.GetUserAsync(GameContext.CurrentUserId);
var dragon = user.GetDragon(req.DragonId);
ulong addExp = 0;
var itemsToUse = new Dictionary<Ulid, ulong>();
for (int i = 0; i < req.MaterialIds.Count; i++)
{
var matData = GameDb.GetDragonExpMaterialData((DragonExpMaterialData.Types)req.MaterialIds[i]);
if ((matData is null) || !user.HasItems(matData.Uid, req.MaterialAmounts[i]))
{
return failResp;
}
itemsToUse.Add(matData.Uid, (ulong)req.MaterialAmounts[i]);
addExp += (ulong)matData.Value * req.MaterialAmounts[i];
}
if (!user.RemoveItems(itemsToUse))
{
return failResp;
}
var dragonData = GameDb.GetDragonData(dragon.Data);
var dragonLadderData = GameDb.GetDragonLadderData((int)dragonData.Ladder);
dragon.Exp += (int)addExp;
var (newLevel, newExp) = dragonLadderData.GetLevel(dragon.Level, dragon.Exp);
dragon.Level = newLevel;
dragon.Exp = newExp;
user.UpdateDragon(dragon);
return new UpgradeDragonResp { Success = true };
"""
class UpgradeDragonEquipmentReq(_BaseModel):
DragonId: Ulid
MaterialIds: typing.List[int]
MaterialAmounts: typing.List[UInt64]
class UpgradeDragonEquipmentResp(_BaseModel):
Success: bool
UpgradeDragonEquipmentHandler = Handler(
Name='UpgradeDragonEquipment',
RequestClass=UpgradeDragonEquipmentReq,
ResponseClass=UpgradeDragonEquipmentResp)
UpgradeDragonEquipmentHandler.Code = """
return new UpgradeDragonEquipmentResp { Success = true };
"""
class UpgradeBuildingReq(_BaseModel):
BuildingId: Ulid
MaterialIds: typing.List[int]
MaterialAmounts: typing.List[UInt64]
class UpgradeBuildingResp(_BaseModel):
Success: bool
UpgradeBuildingHandler = Handler(
Name='UpgradeBuilding',
RequestClass=UpgradeBuildingReq,
ResponseClass=UpgradeBuildingResp)
UpgradeBuildingHandler.Code = """
return new UpgradeBuildingResp { Success = true };
"""
#FIXME
_FIXME_IMPL = """
var failResp = new UpgradeBuildingResp { Success = false };
var user = await GameContext.GetUserAsync(GameContext.CurrentUserId);
var building = user.GetBuilding(req.BuildingId);
var buildingData = GameDb.GetBuildingData(building.Data);
var buildingLevelLadderData = GameDb.GetBuildingLevelLadderData(buildingData.Ladder);
//???
if (!UpgradeService.DoUpgrade(building))
{
return failResp;
}
return new UpgradeBuildingResp { Success = true };
"""
Refer to the dragon star repo to see all our full example and other game logics are implemented, including crafting equipments, equipping the dragon, claiming quest and battlepass rewards, cloning and retiring dragon.
Export and Run Server
Last but not least, let's talk about how to deploy all of your code to Hyperedge's servers and get it running.
First of all, run
python3 he-admin.py collect
to see all the created data classes and models you've created.
[screenshot of terminal ... ]
And then please use these commands sequentially to export, release, build, and run the app!
python3 he-admin.py export
python3 he-admin.py release 1.0.0
python3 he-admin.py build 1.0.0
python3 he-admin.py run 1.0.0
Using the version number, we've provided you a version management system for your releases and builds. Please make sure the version numbers you supply here match.
[screenshot of running app .. ]
Last words
Congratulations and Thank You for following this tutorial all the way to the end. We hope it helps you understand Hyperedge's tool, and will make game development process easier and more enjoyable.
If you have any questions or need further assistance, please feel free to contact us at [email protected] or visit our support page at HyperEdgeLabs.
Last updated