Skip to content

Feature/custom epochs and eras#331

Open
quipsol wants to merge 5 commits into
Alchyr:masterfrom
quipsol:feature/custom-epochs-and-eras
Open

Feature/custom epochs and eras#331
quipsol wants to merge 5 commits into
Alchyr:masterfrom
quipsol:feature/custom-epochs-and-eras

Conversation

@quipsol

@quipsol quipsol commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Adds CustomEpochModel, CustomStoryModel and CustomEpochEra models.

  • Custom epochs can be inserted into the timeline.
  • Support for Character specific epochs that match how the base game epochs unlock.
  • Custom Eras can be inserted to the Timeline.

Custom Epoch

With these it is possible to add custom Epochs to the Timeline. Important for that are the patches that change the position value for epochs that have duplicate values with other epochs in the same Era. As well as fixing the Timeline Screen when epoch count in an era grows over 5, as they would appear out of bound.

Custom Story

Stories cross reference themselves with their respective Epochs. Some information of them is shown in the Timeline.

Character Specific Epochs

Character specific epochs are nullable EpochModel properties. Default to null and leaving them empty will keep the CustomCharacterModel to behave as previously. Any number of them can be overwritten with a CustomEpoch and BaseLib will take care of the unlock logic for it.

A special mention goes to the first epoch which unlocks the character. If the value is not null the character will be locked by default. When the character unlocks depends on the UnlocksAfterRunAs property.
null or Ironclad will result in the character to unlock after obtaining the NeowEpoch. This is how Silents unlock works as well (Silent does say "play a game as Ironclad" but it technically unlocks after doing a run with any character).
Choosing other characters will unlock after a run with them has been finished.
Since mods are usually added later, during main menu load a check is run to see if any required epoch is already unlocked. If it is, set the character unlock epoch state to obtained.

Custom Eras

The game uses the EpochEra enum value for ordering in the Timeline (and a few other minor things). This does not work for us. While a [CustomEnum] EpochEra is still required, it is only used for insertion in a Dictionary and set in the EpochModel.
During Timeline initialization, all epochs that belong to custom eras are removed from the list. At a later point in the initialization a transpiler will call a method that will handle re inserting these Epochs and creates the Eras along the way.

Eras are inserted as follows:
A reference base game Era used as an insertion reference point.
A direction in which to insert the Era.
A number to declare the order in which they are displayed. (larger -> further away from reference)

Since eras only exist if at least one epoch from it will be shown, there is some logic that will find an alternative entry point which keeps the expected display position the same.

Custom Eras have these extra features:

  • Disable forced resizing -> displays the icon with its original resolution
  • Disable tinting -> Removes the games self modulate which turns the icon textures from white to their gold yellow

issues/notes

If a custom era had to find an alternative entry point, and the game inserts new eras during unlocking, the custom era might not be in the correct spot. -> Fixes itself when exiting and entering the Timeline.

If multiple characters are unlocked at once, only one character will get the unlock animation when entering the choose a character menu. (they are still all unlocked)

As before, many patches skip the original epoch unlock methods. If someone wants to forgo this system and implement their own, they still need to patch around that. (its not difficult to do but should still be mentioned)

Since EpochModel and StoryModel are not in ModelDb, the default PrefixId patch does not work. I have tried to find good places to implement prefixing but couldn't find any. So currently the mod prefix must be added manually to them.

While they haven't touched the Timeline/Epoch system in a while, there are minor changes in the newest beta branch update. Possible that this currently only works for beta branch.

One of the commits is just a squashed commit of all the master branch changes. I needed those due to the game updating.


CustomEras are a bit more complicated to set up. If this gets merged I will write an Entry on the Wiki for all of this.

Custom Era code:

public class MyCustomEras
{
    public static CustomEpochEra TestEra => new CustomTestEra();
    
    private class CustomTestEra : CustomEpochEra
    {
        [CustomEnum] public static EpochEra TestEpochEra;
        public override EpochEra CustomEra => TestEpochEra;
        public override EpochEra ReferenceEra => EpochEra.FarFuture0;
        public override RelativeEraDirection Direction => RelativeEraDirection.After;
        public override int DirectionDepth => 42;
        public override string EraIconPath => $"{MainFile.ResPath}/images/eras/{StringHelper.Slugify(GetType().Name).ToLowerInvariant()}.png";
        public override bool UseOriginalImageSize => true;
        public override bool DisableTinting => true;
    }

for use in a CustomEpochModel:

public override EpochEra Era =>  CustomEra.CustomEra;
public override CustomEpochEra CustomEra => MyCustomEras.TestEra;

quipsol added 5 commits July 3, 2026 12:37
custom epochs are fully supported now
commit c95f0ec
Merge: a569501 fc58de3
Author: Alchyr <39511935+Alchyr@users.noreply.github.com>
Date:   Fri Jul 3 09:59:09 2026 +0000

    Merge pull request Alchyr#321 from Alchyr/develop

    3.3.4

commit fc58de3
Author: Alchyr <isithalchyr@gmail.com>
Date:   Fri Jul 3 02:55:37 2026 -0700

    3.3.4

commit b9e0308
Author: Alchyr <isithalchyr@gmail.com>
Date:   Fri Jul 3 02:53:59 2026 -0700

    fix for main branch temporary powers when compiling against beta branch

commit a569501
Merge: 323fbcb 3ee7fc3
Author: Alchyr <39511935+Alchyr@users.noreply.github.com>
Date:   Fri Jul 3 06:50:08 2026 +0000

    Merge pull request Alchyr#319 from Alchyr/develop

    v3.3.3

commit 3ee7fc3
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 23:39:38 2026 -0700

    3.3.3

commit d0c71ea
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 23:30:06 2026 -0700

    update notes

commit 0378af1
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 23:29:36 2026 -0700

    base damage modification patches (wip)

commit 8adccdc
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 23:29:21 2026 -0700

    ArgIndex extension method

commit 47dee1e
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 23:28:57 2026 -0700

    update card modifier class

commit 978d665
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 23:28:50 2026 -0700

    temporarily disable card reward serialization patch

commit ac5a874
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 23:28:32 2026 -0700

    avoid referencing inequality operator (breaks main)

commit e8ed28b
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 23:28:20 2026 -0700

    beta compatibility

commit bb743c9
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 23:28:08 2026 -0700

    more detailed fail patch comment

commit 8fe11cd
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 23:27:58 2026 -0700

    fix extra tooltip patches

commit f13d27c
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 23:27:47 2026 -0700

    allow null owner for dynamic var source

commit 8e0b40c
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 23:27:31 2026 -0700

    make patch slightly more generic

commit a9dec68
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 22:52:10 2026 -0700

    adjustments to patch util

commit 44f4d3e
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 22:32:29 2026 -0700

    fix play destination patches for beta

commit 8860cbd
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 22:32:01 2026 -0700

    fix calculated var usage in CardBlock

commit f7a5711
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 22:31:46 2026 -0700

    update ModInterop for beta compatibility

commit 8ca14a7
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 15:32:07 2026 -0700

    beta compat cleanup

commit 5a236a4
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 15:31:52 2026 -0700

    small adjust

commit 7e16b83
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 15:28:30 2026 -0700

    beta compat cleanup

commit 64235fd
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 15:27:26 2026 -0700

    adjustment

commit f78a625
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 14:46:52 2026 -0700

    surround manually called patches in a try block

commit c31efb1
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 14:46:36 2026 -0700

    additional tips for relics and powers, and allow card mods to add tips

commit 8a3ede7
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 14:44:29 2026 -0700

    beta compat cleanup

commit e8e8da8
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 14:43:14 2026 -0700

    small comment adjustment

commit d13b235
Author: Alchyr <isithalchyr@gmail.com>
Date:   Thu Jul 2 14:43:00 2026 -0700

    clean up old beta compatibility

commit 424de34
Merge: a111f1f 3197610
Author: Alchyr <isithalchyr@gmail.com>
Date:   Wed Jul 1 14:13:37 2026 -0700

    Merge remote-tracking branch 'origin/develop' into develop

commit a111f1f
Author: Alchyr <isithalchyr@gmail.com>
Date:   Wed Jul 1 14:13:28 2026 -0700

    disable log window on steam deck

commit 3197610
Merge: 77f6954 5e65533
Author: Alchyr <39511935+Alchyr@users.noreply.github.com>
Date:   Wed Jul 1 15:09:59 2026 +0000

    Merge pull request Alchyr#318 from 1939323749/loc/complete-zhs

    Complete Chinese (zhs) localization

commit 5e65533
Author: snowlie <1939323749@qq.com>
Date:   Wed Jul 1 14:33:03 2026 +0800

    Complete Chinese (zhs) localization

    Adds the missing zhs tables (card_keywords, card_selection, gameplay_ui) and the remaining settings_ui keys, matching the game's official Chinese terminology (e.g. Transform=变化, Deck=牌组, pile names).

commit 77f6954
Merge: 716a530 01f53c2
Author: Alchyr <39511935+Alchyr@users.noreply.github.com>
Date:   Wed Jul 1 06:23:15 2026 +0000

    Merge pull request Alchyr#317 from SpaD-Overolls/patch-1

    change Purge description's "deck" to (gold) "Deck"

commit 8c92469
Author: Alchyr <isithalchyr@gmail.com>
Date:   Tue Jun 30 22:56:05 2026 -0700

    add type safe generic extension method to retrieve dynamic vars

commit 01f53c2
Author: SpaD-Overolls <142741667+SpaD-Overolls@users.noreply.github.com>
Date:   Wed Jul 1 12:01:04 2026 +0800

    change (white) "deck" to (gold) "Deck"

    change "deck" to "[gold]Deck[/gold]" to stay consistent with the basegame's usage of the term

commit 7538bf9
Merge: f6569af 716a530
Author: Alchyr <isithalchyr@gmail.com>
Date:   Tue Jun 30 03:47:03 2026 -0700

    Merge remote-tracking branch 'origin/develop' into develop

commit 716a530
Merge: d058d65 4805ee5
Author: Alchyr <39511935+Alchyr@users.noreply.github.com>
Date:   Tue Jun 30 10:46:54 2026 +0000

    Merge pull request Alchyr#316 from 1939323749/fix/autoplay-custom-target

    Add CardCmd.AutoPlay fallback for custom single-target types

commit 4805ee5
Author: snowlie <1939323749@qq.com>
Date:   Tue Jun 30 13:17:57 2026 +0800

    Add CardCmd.AutoPlay fallback for custom single-target types

    AutoPlay only randomized a target for AnyEnemy/AnyAlly, so an auto-played custom single-target card with no target was played with null and errored (Alchyr#312). Adds a defensive prefix that picks a random valid target via the registered predicate; any problem leaves the target untouched so the original logic runs unchanged.

commit f6569af
Author: Alchyr <isithalchyr@gmail.com>
Date:   Sat Jun 27 15:49:01 2026 -0700

    small cleanup

commit fb570b5
Author: Alchyr <isithalchyr@gmail.com>
Date:   Sat Jun 27 15:48:43 2026 -0700

    update WithTip comments

commit d058d65
Merge: 69e9ba9 b47e1d4
Author: Alchyr <39511935+Alchyr@users.noreply.github.com>
Date:   Fri Jun 26 23:12:14 2026 +0000

    Merge pull request Alchyr#310 from lamali292/german-loc

    Add German localization for gameplay_ui.json

commit b47e1d4
Author: lamali <lamali292@gmail.com>
Date:   Fri Jun 26 23:32:24 2026 +0200

    Add German localization for gameplay_ui.json

commit 69e9ba9
Author: Alchyr <isithalchyr@gmail.com>
Date:   Tue Jun 23 11:51:30 2026 -0700

    fix audio play overloads

commit 46041ec
Author: Alchyr <isithalchyr@gmail.com>
Date:   Tue Jun 23 01:27:08 2026 -0700

    adjust csproj to copy to workshop workspace

commit d753eae
Merge: 3533fe9 8df7063
Author: Alchyr <isithalchyr@gmail.com>
Date:   Tue Jun 23 01:11:55 2026 -0700

    Merge remote-tracking branch 'origin/develop' into develop

commit 3533fe9
Author: Alchyr <isithalchyr@gmail.com>
Date:   Tue Jun 23 01:11:26 2026 -0700

    add cloning option to spirefields on models

commit 8df7063
Merge: 8d52d02 91a78e6
Author: Alchyr <39511935+Alchyr@users.noreply.github.com>
Date:   Sun Jun 21 22:13:12 2026 +0000

    Merge pull request Alchyr#305 from exscape/modconfig-buttons-only

    Mod config: allow configs with only buttons

commit 91a78e6
Author: Aeluwas <serenity@exscape.org>
Date:   Sun Jun 21 23:43:33 2026 +0200

    Mod config: allow configs with only buttons
now not only checks for neowepoch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant