FabulaDSL { // CodeSegment: evaluate, renderMarkdown CodeSegment = (Block | CompleteOperation | EmptyLines)* // identifier: identifier, operands, textValue identifier (an identifier) = identifierStart identifierContinue+ identifierStart = "_" | "$" | letter identifierContinue = identifierStart | digit newline = "\n" // EmptyLines: evaluate (empty), renderMarkdown (empty) EmptyLines = operationTerminator+ wordSep = ~newline space spaces := (wordSep|blockComment)* // target: operands target = "@" // source: operands source = "&" null = "-" colon = ":" // operand: operands operand (an operand) = identifier | target | source comma = spaces "," spaces // Operands: operands Operands (operands) = nonemptyListOf // segments: resource segments = caseInsensitive<"segments">|caseInsensitive<"sections"> |caseInsensitive<"segment">|caseInsensitive<"section"> |caseInsensitive<"ticks">|caseInsensitive<"tick"> |caseInsensitive<"steps">|caseInsensitive<"step"> SegmentResource = segments points = caseInsensitive<"points">|caseInsensitive<"pts">|caseInsensitive<"power"> experience = caseInsensitive<"experience"> xp = caseInsensitive<"XP">|caseInsensitive<"EXP"> ExperienceFull = experience points // XpResource: resource XpResource = ExperienceFull|experience|xp health = caseInsensitive<"health">|caseInsensitive<"life">|caseInsensitive<"hit"> HealthFull = health points hp = caseInsensitive<"HP"> // HpResource: resource HpResource = HealthFull|health|hp mind = caseInsensitive<"mind">|caseInsensitive<"magic">|caseInsensitive<"mana"> MindFull = mind points mp = caseInsensitive<"MP"> // MpResource: resource MpResource = MindFull|mind|mp item = caseInsensitive<"items">|caseInsensitive<"item">|caseInsensitive<"inventory"> ItemFull = item points ip = caseInsensitive<"IP"> // IpResource: resource IpResource = ItemFull|item|ip zero = caseInsensitive<"zero"> charge = points|caseInsensitive<"charge">|segments ZeroFull = zero charge zp = caseInsensitive<"ZP">|caseInsensitive<"ZC"> // ZpResource: resource ZpResource = ZeroFull|zero|zp blood = caseInsensitive<"blood">|caseInsensitive<"grave"> BloodFull = blood points bp = caseInsensitive<"BP"> // BpResource: resource BpResource = BloodFull|blood|bp turns = caseInsensitive<"turns">|caseInsensitive<"turn">|caseInsensitive<"actions">|caseInsensitive<"action"> TurnsFull = turns points tp = caseInsensitive<"TP">|caseInsensitive<"AP"> // TpResource: resource TpResource = TurnsFull|turns|tp // MeteredResource: resource MeteredResource (the name of a metered resource) = SegmentResource|XpResource|HpResource|MpResource |IpResource|ZpResource|BpResource|TpResource fabula = caseInsensitive<"Fabula"> ultima = caseInsensitive<"Ultima"> special = caseInsensitive<"Special"> fp = caseInsensitive<"FP"> up = caseInsensitive<"UP"> sp = caseInsensitive<"SP"> FabulaFull = fabula points UltimaFull = ultima points SpecialFull = special points // FabulaResource, UltimaResource, SpecialResource, SpResource: resource FabulaResource = FabulaFull|fabula|fp UltimaResource = UltimaFull|ultima|up SpecialResource = SpecialFull|special|sp SpResource = FabulaResource|UltimaResource|SpecialResource // LevelResource: resource LevelResource = caseInsensitive<"Level">|caseInsensitive<"lvl">|caseInsensitive<"lv"> money = caseInsensitive<"Zenit">|caseInsensitive<"z">|caseInsensitive<"gold">|caseInsensitive<"gil">|caseInsensitive<"gp"> // MoneyResource: resource MoneyResource = money materials = caseInsensitive<"materials">|caseInsensitive<"mats"> MaterialsFull = money #wordSep materials // MaterialsResource: resource MaterialsResource = MaterialsFull|materials // OrderResource: resource OrderResource = caseInsensitive<"order">|caseInsensitive<"index"> // UnmeteredResource: resource UnmeteredResource (the name of an unmetered resource) = SpResource|LevelResource|MaterialsResource|MoneyResource|OrderResource // Resource: resource Resource (the name of a resource) = MeteredResource|UnmeteredResource // plus, minus, deltaOperator: sign plus = "+" minus = "-" deltaOperator = plus|minus // integer: numberValue integer (an integer) = digit+ // delta: numberValue, sign Delta (a delta) = deltaOperator integer // elements: element fireElement = caseInsensitive<"fire">|caseInsensitive<"flame">|caseInsensitive<"burn"> waterElement = caseInsensitive<"water">|caseInsensitive<"poison">|caseInsensitive<"acid"> lightningElement = caseInsensitive<"lightning">|caseInsensitive<"zap">|caseInsensitive<"electricity"> |caseInsensitive<"electrical">|caseInsensitive<"electric">|caseInsensitive<"elec"> |caseInsensitive<"shock"> earthElement = caseInsensitive<"earth">|caseInsensitive<"rock"> iceElement = caseInsensitive<"ice">|caseInsensitive<"cold"> windElement = caseInsensitive<"wind">|caseInsensitive<"air"> lightElement = caseInsensitive<"light">|caseInsensitive<"holy"> darkElement = caseInsensitive<"dark">|caseInsensitive<"evil"> physicalElement = caseInsensitive<"physical">|caseInsensitive<"phys"> nonElement = caseInsensitive<"nonelemental">|caseInsensitive<"non-elemental">|caseInsensitive<"none">|caseInsensitive<"non"> healingElement = caseInsensitive<"healing">|caseInsensitive<"heal">|caseInsensitive<"cure"> elementalType (an element) = fireElement|waterElement |lightningElement|earthElement |iceElement|windElement |lightElement|darkElement |physicalElement|nonElement|healingElement // affinities: affinity absorbAffinity = "??"|caseInsensitive<"drained">|caseInsensitive<"drains">|caseInsensitive<"drain"> |caseInsensitive<"absorbed">|caseInsensitive<"absorbs">|caseInsensitive<"absorb"> immuneAffinity = "."|caseInsensitive<"immunity">|caseInsensitive<"blocked">|caseInsensitive<"blocks">|caseInsensitive<"immune">|caseInsensitive<"block"> resistAffinity = "..."|caseInsensitive<"resistance">|caseInsensitive<"resisted">|caseInsensitive<"resists">|caseInsensitive<"resist"> vulnerableAffinity = "!!"|caseInsensitive<"vulnerable">|caseInsensitive<"weakness">|caseInsensitive<"weak"> normalAffinity = caseInsensitive<"normal"> affinity (an affinity indicator) = vulnerableAffinity|resistAffinity|immuneAffinity|absorbAffinity|normalAffinity meteredSeparator = ~lineCommentStart ~blockCommentStart "/" // MaxValue: numberValue, maxValue MaxValue = meteredSeparator integer // MeteredValue: currentValue, maxValue MeteredValue = integer MaxValue // DeltaOperation/Alternate/Alternate2: operands, resource, numberValue, affinity, element, evaluate, renderMarkdown DeltaOperation = Operands #wordSep Resource colon Delta affinity? elementalType? DeltaOperationAlternate = Operands colon Delta affinity? Resource? elementalType? DeltaOperationAlternate2 = Operands colon Resource Delta affinity? elementalType? // SetMeteredOperation/Alternate/Alternate2: operands, resource, currentValue, maxValue, evaluate, renderMarkdown SetMeteredOperation = Operands #wordSep MeteredResource colon MeteredValue SetMeteredOperationAlternate = Operands colon MeteredValue MeteredResource SetMeteredOperationAlternate2 = Operands colon MeteredResource MeteredValue // SetValueOperation/Alternate/Alternate2: operands, resource, numberValue, currentValue, evaluate, renderMarkdown SetValueOperation = Operands #wordSep Resource colon integer SetValueOperationAlternate = Operands colon integer Resource SetValueOperationAlternate2 = Operands colon Resource integer // SetMaxOperation/Alternate/Alternate2: operands, resource, numberValue, maxValue, evaluate, renderMarkdown SetMaxOperation = Operands #wordSep MeteredResource colon MaxValue SetMaxOperationAlternate = Operands colon MaxValue MeteredResource SetMaxOperationAlternate2 = Operands colon MeteredResource MaxValue // ClearOperation/Alternate/Alternate2: operands, resource, evaluate, renderMarkdown ClearOperation = Operands #wordSep Resource colon null ClearOperationAlternate = Operands colon null Resource ClearOperationAlternate2 = Operands colon Resource null // TODO: continue implementation list from here StatusOrItemCounterUnwrapped = "x"? integer StatusOrItemCounterWrapped = "(" StatusOrItemCounterUnwrapped ")" StatusOrItemCounter = StatusOrItemCounterWrapped | StatusOrItemCounterUnwrapped StatusOrItemDeltaWrapped = "(" Delta ")" StatusOrItemDelta = StatusOrItemDeltaWrapped | Delta StatusOrItemAddOperation = Operands colon plus identifier StatusOrItemCounter? StatusOrItemRemoveOperation = Operands colon minus identifier StatusOrItemCounterDeltaOperation = Operands colon identifier Delta StatusOrItemCounterDeltaOperationAlternate = Operands colon Delta identifier StatusOrItemCounterSetOperation = Operands colon identifier StatusOrItemCounter? notNewlineOrComment = ~newline ~lineCommentStart ~blockCommentStart any textToEndOfLine = notNewlineOrComment+ SetTargetOperation = target (Operands | null) SetSourceOperation = source (Operands | null) avoid = caseInsensitive<"avoided">|caseInsensitive<"avoids">|caseInsensitive<"avoid"> dodge = caseInsensitive<"dodged">|caseInsensitive<"dodges">|caseInsensitive<"dodge"> immune = caseInsensitive<"immune"> miss = caseInsensitive<"missed">|caseInsensitive<"misses">|caseInsensitive<"miss"> resist = caseInsensitive<"resisted">|caseInsensitive<"resists">|caseInsensitive<"resist"> fail = caseInsensitive<"failed">|caseInsensitive<"fails">|caseInsensitive<"fail"> block = caseInsensitive<"blocked">|caseInsensitive<"blocks">|caseInsensitive<"block"> parry = caseInsensitive<"parried">|caseInsensitive<"parries">|caseInsensitive<"parry"> FailReason = avoid|dodge|immune|miss|resist|fail|block|parry FailOperation = Operands colon FailReason allySide = caseInsensitive<"allies">|caseInsensitive<"ally"> |caseInsensitive<"friendly">|caseInsensitive<"friends">|caseInsensitive<"friend"> |caseInsensitive<"party">|caseInsensitive<"pcs">|caseInsensitive<"pc"> |caseInsensitive<"heroes">|caseInsensitive<"hero"> enemySide = caseInsensitive<"villains">|caseInsensitive<"villain"> |caseInsensitive<"enemies">|caseInsensitive<"enemy"> |caseInsensitive<"npcs">|caseInsensitive<"npc"> |caseInsensitive<"opponents">|caseInsensitive<"opponent">|caseInsensitive<"opposed"> characterSide = allySide|enemySide AllyPrivacy = caseInsensitive<"ally">|caseInsensitive<"friendly">|caseInsensitive<"friend"> full = caseInsensitive<"fully">|caseInsensitive<"full"> average = caseInsensitive<"normally">|caseInsensitive<"average">|caseInsensitive<"normal"> light = caseInsensitive<"lightly">|caseInsensitive<"light"> scan = caseInsensitive<"scanned">|caseInsensitive<"scan"> notPrefix = caseInsensitive<"un">|caseInsensitive<"non">|caseInsensitive<"not"> secretive = caseInsensitive<"secretive">|caseInsensitive<"secret"> hidden = caseInsensitive<"hidden"> optionalDash = (space|"-")? FullScanPrivacy = full optionalDash scan ScanPrivacy = (average optionalDash)? scan LightScanPrivacy = light optionalDash scan NotScannedPrivacy = notPrefix optionalDash scan SecretPrivacy = secretive HiddenPrivacy = hidden Privacy = AllyPrivacy|FullScanPrivacy|ScanPrivacy|LightScanPrivacy|NotScannedPrivacy|SecretPrivacy|HiddenPrivacy count = caseInsensitive<"counting">|caseInsensitive<"count">|caseInsensitive<"ticking">|caseInsensitive<"tick"> upward = caseInsensitive<"up"> downward = caseInsensitive<"down"> stop = caseInsensitive<"stopped">|caseInsensitive<"stop"> CountUp = (count optionalDash)? upward CountDown = (count optionalDash)? downward StopCount = stop (optionalDash count)? TimerDirection = CountUp|CountDown|StopCount status = caseInsensitive<"status"> clock = caseInsensitive<"clock"> timer = caseInsensitive<"timer"> character = caseInsensitive<"character"> bgm = caseInsensitive<"bgm"> bg = caseInsensitive<"bg"> sfx = caseInsensitive<"sfx"> descriptionSeparator = "::" urlIndicator = "@" title = (~urlIndicator any)+ url = (~space any)+ StatusDefinitionOperation = identifier status colon title urlIndicator url textToEndOfLine? ClockFill = caseInsensitive<"fill"> ClockEmpty = caseInsensitive<"empty"> ClockDirection = ClockFill|ClockEmpty ClockDescription = descriptionSeparator textToEndOfLine ClockDefinitionOperation = identifier clock colon title urlIndicator MeteredValue ClockDirection? ClockDescription? hours = caseInsensitive<"hours">|caseInsensitive<"hr">|caseInsensitive<"h"> minutes = caseInsensitive<"minutes">|caseInsensitive<"min">|caseInsensitive<"m"> seconds = caseInsensitive<"seconds">|caseInsensitive<"sec">|caseInsensitive<"s"> HoursCounter = integer hours MinutesCounter = integer minutes SecondsCounter = integer seconds Time = integer colon integer colon integer -- HMSColonTime | colon? integer colon integer -- MSColonTime | colon? integer -- SColonTime | HoursCounter? MinutesCounter? SecondsCounter -- HMSLetterTime | HoursCounter? MinutesCounter -- HMLetterTime | HoursCounter -- HLetterTime TimerDescription = descriptionSeparator textToEndOfLine TimerDefinitionOperation = identifier timer colon title urlIndicator Time TimerDirection TimerDescription? CharacterDefinitionOperation = identifier character colon title urlIndicator url textToEndOfLine? BGMChangeOperation = bgm colon title urlIndicator url textToEndOfLine? BGMClearOperation = bgm colon null SFXPlayOperation = sfx colon title urlIndicator url textToEndOfLine? DestroyOperation = Operands colon null printOperator = ">" PrintOperation = printOperator textToEndOfLine PrintOperationWithOperands = Operands colon printOperator textToEndOfLine Operation = DeltaOperation | DeltaOperationAlternate | DeltaOperationAlternate2 | SetMeteredOperation | SetMeteredOperationAlternate | SetMeteredOperationAlternate2 | SetValueOperation | SetValueOperationAlternate | SetValueOperationAlternate2 | SetMaxOperation | SetMaxOperationAlternate | SetMaxOperationAlternate2 | ClearOperation | ClearOperationAlternate | ClearOperationAlternate2 | StatusOrItemAddOperation | StatusOrItemRemoveOperation | StatusOrItemCounterSetOperation | StatusOrItemCounterDeltaOperation | StatusOrItemCounterDeltaOperationAlternate | SetTargetOperation | SetSourceOperation | FailOperation | PrintOperationWithOperands | PrintOperation silentOperator = "~" lineCommentStart = "//" lineComment = lineCommentStart textToEndOfLine (newline | end) blockCommentStart = "/*" blockCommentEnd = "*/" blockCommentCharacter = ~blockCommentEnd any blockCommentText = blockCommentCharacter* blockComment = blockCommentStart blockCommentText blockCommentEnd operationTerminator = newline | lineComment operationTerminatorOrEnd = operationTerminator | end CompleteOperation = silentOperator? Operation operationTerminatorOrEnd beginKeyword = caseInsensitive<"begin"> endKeyword = caseInsensitive<"end"> BlockTitle = colon textToEndOfLine BlockStart = silentOperator? beginKeyword SetSourceOperation? SetTargetOperation? BlockTitle? BlockEnd = endKeyword textToEndOfLine? Block = BlockStart operationTerminator CodeSegment BlockEnd operationTerminatorOrEnd }