Get desktop application:
View/edit binary Protocol Buffers messages
Used in:
Unlike "InventorySlot", "BattleEquipment" has no varying state during a battle
Used in:
Used in:
,It's not trivial to handle damage after the following sequence 1. Pick up damageDelta=+10 for 600 frames 2. Pick up damageDeltaByPercentage=+10% for 600 frames 3. Buff "damageDelta=+10" expires 4. Buff "damageDeltaByPercentage=+10%" expires Pick a deterministic way :)
[WARNING] The following field previously had type "repeated DebuffConfig" and the reason given was "to reduce the count of heap-RAM access when stepping battle dynamics", it was not a bad reason yet such complicated type imposed a heavy burden on serialization/deserialization of "RoomDownsyncFrame" which would be used frequently when we use "backend forceResync" for "active slow ticker" or "recovery upon reconnection". See "ConcerningEdgeCases.md" for details.
Used in:
,Would be calculated in number of renderFrames, not actual time in seconds or milliseconds
Used in:
Jargon reference https://www.thegamer.com/fighting-games-frame-data-explained/ ALL lengths are in world coordinate
Copied from the first bullet for all subsequent bullets
Copied to favor collision handling of the dispatched bullet
[WARNING] Currently we can use "trapLocalId" to directly access "RoomDownsyncFrame.trapsArr" just like "joinIndex" in "calcHardPushbacksNormsForCharacter" -- because memory in "RoomDownsyncFrame.trapsArr" is never truely reused when a trap is destroyed -- yet this approach should be avoided whenever possible; kindly note that even "joinIndex" can be reused for "RoomDownsyncFrame.npcsArr" by carefully tuning "_leftShiftDeadNpcs(...)"
[WARNING] Assignment to this field MUST BE order-insensitive w.r.t. collider traversal order!
Not using quaternion yet because this is a 2D game.
To be used after applying "dirX (used for mirroring)"
To be used after applying "dirX (used for mirroring)"
for the convenience of selecting the correct next bullet for multihit fireball (where the offender's "activeSkillHit" might've already been reset)
for the convenience of selecting the correct next bullet for multihit fireball (where the offender's "activeSkillId" might've already been reset); also for reverse lookup in multihit transition, in the most extreme case, a same "BulletConfig" instance is to be shared across different "Skill"s, thus we put "skillId" in "BulletBattleAttr" instead.
Used in:
For fireball, this SpeciesId specifies both the active animation and the explosion animation (if "explosionSpeciesId" not explicitly assigned), for melee it specifies the explosion animation
marks how many simultaneous bullets are left, default to 0 indicating that the current bullet is the only one to fire
For speed varying bullets, this is the initial speed
the initial direction indicator for X-axis
the initial direction indicator for Y-axis
patternId -> skillId
for long lasting bullet, applicable for "mhType == (FromPrevHitActual | FromPrevHitAnyway)"
currently only support 1 vfx config when active
currently only support 1 vfx config when exploding
acceleration perpendicular to instantaneous velocity per frame
if true, "selfLockVelX" & "selfLockVelY" would only be applied when bullet is active
Only used for melee bullets
Change of hitboxSizeX per frame
Change of hitboxSizeY per frame
For attenuation
For attenuation
Default is false, multihit bullets will inherit (originatedVirtualGridX, originatedVirtualGridY) from the previous bullet
If true, both collision & rendering of the bullet will respect (originatedVirtualGridX, originatedVirtualGridY) -> (virtualGridX, virtualGridY)
collision space translation from the original anchor of unrotated polygon
collision space translation from the original anchor of unrotated polygon
Only applicable to "bType == GroundWave"
Only applicable to "bType == Melee"
Only applicable to "bType == Melee"
Only applicable to "true == groundImpactMeleeCollision"
currently only support 1 vfx config when starting up
[WARNING] Always implies "beamCollision" and must be used together with "beamCollision".
e.g. a bomb, a ground-wave
Sfx configs
Used in:
Used in:
Used in:
by default using "(ed-st)" rotated around "z-axis at st" toward upper y-axis and length 0.25*|ed-st| as an intermediate relay
Used in:
"velX" and "velY" is used to record the accumulated effect by inertia and accelerations (including gravity)
this is the instantaneous scalar attribute of a character, different from but will be accounted in "velX" and "velY"
For evolution during battle
number of frames elapsed in the current character state
by design a standalone field only inferred by the collision result of "Step" instead of "characterState", because we need check the transition for "characterState" from this field, i.e. "inAir (prev -> curr)"
like "inAir", it’s by design a standalone field only inferred by the collision result of "Step" instead of "characterState", because we need check the transition for "characterState" from this field, i.e. "onWall (prev -> curr)"
Mostly from a dynamic trap
like "inAir", it’s by design a standalone field only inferred by the collision result of "Step" instead of "characterState", because we need check the transition for "characterState" from this field, i.e. "forcedCrouching (prev -> curr)"
like "inAir", it’s by design a standalone field only inferred by the calc result of "Battle.Step" instead of "characterState"
Mostly from a dynamic trap
Should be cleared whenever entering a non-attacked chState
TODO: change to 1-based in code and uint32
Kindly note that "collisionTypeMask" is NOT GRANULAR ENOUGH for inter-character collision configuration, e.g. same team omission, thus we'd still need the fields "bulletTeamId" and "chCollisionTeamId" here
including both forward-kinematics and inverse-kinematics
Used in:
the k-th subcycle tick corresponds to speciesIdList[k]
Used in:
,Pre-activated state for evtsub-based NPC
When at this state, the character has already completed transform, i.e. in new speciesId
When at this state, the character has already completed transform, i.e. in new speciesId
Debuff recovery
Used in:
A redundancy of "debuffConfig" for easy termination detection
"Acc" here means "acceleration"
Used in:
[WARNING] On the use of unsigned int. RdfId (as well as all configured "frames"), xxxLocalId, skillHit offset and joinIndex will be used as array index which doesn't support "uint", just use 0 as their TERMINATING value to save bandwidth. We should reduce runtime typecasting as much as possible!
Used in:
,Sound effect basis
Used in:
, ,Indexed by "joinIndex", we try to compress the "single player input" into 1 word (64-bit for 64-bit Golang runtime) because atomic compare-and-swap only works on 1 word. Although CAS on custom struct is possible in C# https://learn.microsoft.com/en-us/dotnet/api/system.threading.interlocked?view=netstandard-2.1, using a single word is still faster whenever possible.
Indexed by "joinIndex", same compression concern as above
[WARNING] Only used by frontend, i.e. on backend this field can be always zero because backend sets "InputFrameDownsync.ConfirmedList" by UDP packets too while frontend shouldn't.
Used in:
Used in:
Used in:
Used in:
For "slot D", just skip everything for this type
For "slot D", reserved for pickables
Reusable after cooldown
Has certain quotas before required to cooldown
NOT IMPLEMENTED!
Used in:
* [WARN] Multihit of a fireball (determined in turn by the "BulletType bType" field) is more difficult to handle than that of melee, because we have to count from the fireball's first hit; the situation becomes even more complicated when a multihit fireball is in a crowd -- remains to be designed Types of fireball multihit-singlebullet a. References the emission frame b. References the first hit only when actually hit c. References the first hit even if blocked d. References the prev hit only when actually hit e. References the prev hit even if blocked
Used in:
Used in:
,"input when colliding from the left side"
"input when colliding from the right side"
"input when colliding from the down side"
"input when colliding from the up side"
[COLLISION_NPC_PATROL_CUE_INDEX_PREFIX, COLLISION_TRAP_PATROL_CUE_INDEX_PREFIX]
Used in:
,Used in:
Used in:
If "MAGIC_EVTSUB_ID_NONE != subscriptionId", then this field represents the "firstShowRdfId" after subscriptionId is fulfilled
Only meaningful when "pickupType == PutIntoInventory"
Always use pixelated vfx
Used in:
the k-th subcycle tick corresponds to speciesIdList[k]
Used in:
Used in:
,Used in:
Any level can be in a state of "partially unlocked", if a record exists in "PlayerStoryProgress.levelProgressDict" with non-empty "remainingDependencies", then it's locked but visible
Used in:
Any region can be in a state of "partially unlocked"
Used in:
Including just unlocked regions with 0 progress
Including just unlocked levels with 0 progress
Used in:
, ,Indexed by "joinIndex", same compression concern as stated in InputFrameDownsync
Used in:
, , ,Used in:
"collisionTypeMask" is contained here
Used in:
"TrapColliderAttr.collisionTypeMask" is a little peculiar, it can be a composite of different COLLISION_*_INDEX_PREFIX, thus often NOT taken care of by the COLLIDABLE_PAIRS set
Used in:
"collisionTypeMask" can be derived from here
Used in:
Used in:
[WARNING] Only applicable to Melee. When transitting from "boundChState" to "boundChStateOnHit", keep "framesInChState" but "framesToRecover += (recoveryFramesOnHit - recoveryFrames)".
Usually used as "mp consumption"
Hits within a "Skill" are automatically triggered
Used in:
Used in:
not taking over control if true
null for no cut scene
Used in:
[WARNING] Only one of "narratorJoinIndex" and "narratorSpeciesId" should be available for each "StoryPointDialogLine".
true is "down"
Used in:
What distinguished "Trap" and "Npc(typed CharacterDownsync)" is that a "Trap" often has much simpler skillset, vision/patrol reaction -- yet more complicated boundaries and hard/soft pushback config.
Used in:
[WARNING] Used to look up proper "List<TrapColliderAttr>" which is configured in Tiled Editor and remained static during the whole battle!
[WARNING] Here "virtualGridX" and "virtualGridY" denotes the point in virtual grid for local (0, 0) of a trap, then each "colliderAttr" carries "hitboxOffsetX", "hitboxOffsetY", "hitboxSizeX" and "hitboxSizeY" also in virtual grid! It's bit embarrassing that in Tiled Editor - if we draw a rectangle in an Object Layer by the rectangle tool, its local (0, 0) is the bottom-left corner, but - if we put an image object in an Object Layer, its local (0, 0) is the upper-left corner such a frustrating default so we'll use a uniformed local (0, 0) -- the center of rectangle.
To be used after applying "dirX (used for mirroring)"
To be used after applying "dirX (used for mirroring)"
Used in:
,In the case of a trap, it might own multiple hitboxes and each hitbox is drawn in Tiled and assigned after parsing the tmx file, thus not put in static config.
Redundancy for referencing "TrapConfig"
ref-back upon collision, for damage handling, hardPushback moving and effPushbacks recording (if the trap provides softPushback)
Used in:
For accurate positioning
[WARNING] For a single "Trap", all of its "TrapColliderAttrs" respect the shared spin anchor & angular velocity.
collision space translation from the original anchor of unrotated polygon
collision space translation from the original anchor of unrotated polygon
Used in:
By the time of writing, I am not yet very confident on what should be completely hardcoded constant in C# and what should be flexibly configured from Tiled Editor. The simple mindset ruling here - we couldn't make configurable items infinitely granular, at least not at this early stage of development - for a "completely static trap" (not moving & not changing appearance even if destroyed), both its appearance and hitbox can be drawn in Tiled Editor - for a "dynamic trap" (either moving or changing appearance anyway), both its appearance and hitbox can be drawn in Tiled TSX Editor, put onto an Object Layer in Tiled Editor for preview -- however the object on the Object Layer will be removed immediately and replaced by a Trap object in "RoomDownsyncFrame.trapsArr" for dynamic management
Will be used for the "dynamic trap" to locate its Prefab for animating, and used for all types of traps to locate their explosion animations.
For speed varying bullets, this is the initial speed
the initial direction indicator for X-axis
the initial direction indicator for Y-axis
[WARNING] This is a "trigger editor id", I don't want to overcomplicated the config of traps, use an additional Trigger to bridge complicated subscription combination between other triggers and a trap
[WARNING] For boss door only, couldn't coexist with "subscribesToIdAfterInitialFire"
[WARNING] For elevator only, couldn't coexist with "subscribesToIdAfterInitialFire"
Used in:
Used in:
if TRIGGER_MASK_BY_CYCLIC_TIMER, resets whenever "0 < subCycleQuotaLeft" and itself becomes 0
the initial value is from static config, but decreases upon use
resets whenever "framesToRecover" becomes 0; for TRIGGER_MASK_BY_WAVE, this field is repurposed as the "remaining NPC count of current wave"
Even the "demandedEvtMask" changes with time/battle progress
For fast reverse-referencing
For fast reverse-referencing
Used in:
ref-back upon collision, most (actually by now ALL) triggers are static, we use this "TriggerColliderAttr.triggerLocalId" to save the need of dynamically inserting and deleting colliders of each trigger while still being able to be rollback-compatible for "trigger.framesToFire & trigger.framesToRecover"!
:repeats "quota" times |<-------------------------------------- recoveryFrames ----------------------------->|<-----------------recoveryFrames ---------->|....... :repeats "subCycleQuota" times :repeats "subCycleQuota" times |<-delayedFrames->|<-subCycleTriggerFrames->|<-subCycleTriggerFrames->|<-subCycleTriggerFrames->| |....... |TReady |TCoolingDown |TCoolingDown(replay) |TCoolingDown(replay) |TReady |.......
of this trigger
Used in:
[WARNING] In virtual grid coordinates
[WARNING] In virtual grid coordinates
MUST Be configured by increasing "cutoffRdfFrameId"!
MUST Be configured by increasing "cutoffRdfFrameId"!
When set to "true", will (a.) remove all NPCs activated before current rdfId (b.) remove all traps/pickables/barriers whose collision boxes not fully contained in this trigger's box
Used in:
Used in:
Just by "demandedEvtMask == fulfilledEvtMask" without any other timer or collision requirement
Used in:
Used in: