-
Notifications
You must be signed in to change notification settings - Fork 43
Auditions: random cast generation #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
EmoGarbage404
merged 44 commits into
EphemeralSpace:master
from
Just-a-Unity-Dev:crewgen
Jun 15, 2025
Merged
Changes from all commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
c2419a7
basic auditions
Just-a-Unity-Dev c91d4cf
Add producer singleton
Just-a-Unity-Dev 9b7ea00
view variables
Just-a-Unity-Dev 7fb4ed9
server auditions system
Just-a-Unity-Dev f76b05d
relationship prototype
Just-a-Unity-Dev 188fe46
Merge branch 'master' of github.com:EphemeralSpace/ephemeral-space in…
Just-a-Unity-Dev 1ce5015
basic relationships
Just-a-Unity-Dev cefef47
doccomment
Just-a-Unity-Dev 0747606
integrate relationships
Just-a-Unity-Dev 6b42858
Integrate relationships
Just-a-Unity-Dev 0f3e3bc
cast generation
Just-a-Unity-Dev 501cc9b
make producer an argument
Just-a-Unity-Dev d306263
cast generation
Just-a-Unity-Dev eaab942
documentation
Just-a-Unity-Dev 4e0b962
doc comments
Just-a-Unity-Dev a8af9b3
unified -> mutual refactor
Just-a-Unity-Dev 2b51c39
datafield+networked comp
Just-a-Unity-Dev 4a269a5
[ForbidLiteral] these prototypes
Just-a-Unity-Dev ca011db
oops lol
Just-a-Unity-Dev 9251998
protoyptpye
Just-a-Unity-Dev 82a715d
remove stupid params
Just-a-Unity-Dev fc76ad2
datafielded
Just-a-Unity-Dev 3899640
PARTING THE RED SEA
Just-a-Unity-Dev 03eacee
datadef
Just-a-Unity-Dev b3ee772
dirty clean
Just-a-Unity-Dev c8065a1
make the api better
Just-a-Unity-Dev 2929547
events for systems to integrate with
Just-a-Unity-Dev 35e3896
sosyal groups
Just-a-Unity-Dev d7c3476
decrewization
Just-a-Unity-Dev b3de2c5
clean up events
Just-a-Unity-Dev e5bce22
doc comments
Just-a-Unity-Dev b20f08c
randomized date of birtghs
Just-a-Unity-Dev 3e4f83e
force mutual oopsies!
Just-a-Unity-Dev c7f3db8
fix date time test fail
Just-a-Unity-Dev c69fe8a
tidy
Just-a-Unity-Dev 045176c
fix test fail
Just-a-Unity-Dev b966c99
backgrounds
Just-a-Unity-Dev 6b14668
command for casting
Just-a-Unity-Dev 4adf9bf
default command argunebnts
Just-a-Unity-Dev f58f3ff
toolshed descriptior
Just-a-Unity-Dev 6c9306f
dont integrate groups that have already been integrated
Just-a-Unity-Dev e1aef29
oops integration
Just-a-Unity-Dev 740f0ea
it8jdhbiuksfxhrs
Just-a-Unity-Dev f2c597e
make exes rarer
Just-a-Unity-Dev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,158 @@ | ||
| using System.Diagnostics; | ||
| using System.Linq; | ||
| using Content.Server.Administration; | ||
| using Content.Shared._ES.Auditions; | ||
| using Content.Shared.Administration; | ||
| using Robust.Shared.Random; | ||
| using Robust.Shared.Toolshed; | ||
|
|
||
| namespace Content.Server._ES.Auditions; | ||
|
|
||
| /// <summary> | ||
| /// This handles the server-side of auditioning! | ||
| /// </summary> | ||
| public sealed class AuditionsSystem : SharedAuditionsSystem | ||
| { | ||
| [Dependency] private readonly IRobustRandom _random = default!; | ||
|
|
||
| /// <summary> | ||
| /// Hires a cast, and integrates relationships between all of the characters. | ||
| /// </summary> | ||
| public void GenerateCast( | ||
| int captainCount = 26, | ||
| int crewCount = 10, | ||
| ProducerComponent? producer = null | ||
| ) | ||
| { | ||
| if (!TryGetProducer(ref producer)) | ||
| throw new Exception("Could not get ProducerComponent!"); | ||
|
|
||
| var preEvt = new PreCastGenerateEvent(producer); | ||
| RaiseLocalEvent(ref preEvt); | ||
|
|
||
| var captains = GenerateEmptySocialGroup(); | ||
| captains.Comp.RelativeContext = producer.CaptainContext; | ||
|
|
||
| var newCharacters = new List<EntityUid>(); | ||
|
|
||
| for (var i = 0; i < captainCount; i++) | ||
| { | ||
| var newCrew = GenerateRandomCrew(crewCount); | ||
| captains.Comp.Members.Add(newCrew.Comp.Members[0]); | ||
| newCharacters.AddRange(newCrew.Comp.Members); | ||
| } | ||
|
|
||
| var psgEvt = new PostShipGenerateEvent(producer); | ||
| RaiseLocalEvent(ref psgEvt); | ||
|
|
||
| foreach (var group in producer.SocialGroups) | ||
| { | ||
| var comp = EnsureComp<SocialGroupComponent>(group); | ||
| if (comp.Integrated) | ||
| continue; | ||
|
|
||
| var ent = (group, comp); | ||
|
|
||
| var pre = new SocialGroupPreIntegrationEvent(ent); | ||
| RaiseLocalEvent(ref pre); | ||
|
|
||
| IntegrateRelationshipGroup(comp.RelativeContext, comp.Members); | ||
| comp.Integrated = true; | ||
|
|
||
| var post = new SocialGroupPostIntegrationEvent(ent); | ||
| RaiseLocalEvent(ref post); | ||
| } | ||
|
|
||
| IntegrateRelationshipGroup(producer.IntercrewContext, newCharacters); | ||
| producer.Characters.AddRange(newCharacters); | ||
|
|
||
| var postEvt = new PostCastGenerateEvent(producer); | ||
| RaiseLocalEvent(ref postEvt); | ||
| } | ||
|
|
||
| public void GenerateCast( | ||
| int captainCount = 26, | ||
| int minimumCrew = 5, | ||
| int maximumCrew = 12, | ||
| ProducerComponent? producer = null | ||
| ) | ||
| { | ||
| GenerateCast(captainCount, _random.Next(minimumCrew, maximumCrew), producer); | ||
| } | ||
| } | ||
|
|
||
| [ToolshedCommand, AdminCommand(AdminFlags.Round)] | ||
| public sealed class CastCommand : ToolshedCommand | ||
| { | ||
| private AuditionsSystem? _auditions; | ||
|
|
||
| [CommandImplementation("generate")] | ||
| public IEnumerable<string> Generate(int captainCount = 26, int crewSize = 10) | ||
| { | ||
| _auditions ??= GetSys<AuditionsSystem>(); | ||
|
|
||
| var stopwatch = new Stopwatch(); | ||
| stopwatch.Start(); | ||
|
|
||
| _auditions.GenerateCast(captainCount, crewSize, null); | ||
|
|
||
| yield return $"Generated cast in {stopwatch.Elapsed.TotalMilliseconds} ms."; | ||
| } | ||
|
|
||
| [CommandImplementation("view")] | ||
| public IEnumerable<string> View([PipedArgument] EntityUid castMember) | ||
| { | ||
| _auditions ??= GetSys<AuditionsSystem>(); | ||
| if (!EntityManager.TryGetComponent<CharacterComponent>(castMember, out var character)) | ||
| { | ||
| yield return "Invalid cast member object (did not have CharacterComponent)!"; | ||
| } | ||
| else | ||
| { | ||
| yield return $"{character.Name}, {character.Age} years old ({character.DateOfBirth.ToShortDateString()})\nBackground: {character.Background}\nRelationships\n"; | ||
| Dictionary<string, List<string>> relationships = new(); | ||
| foreach (var relationship in character.Relationships) | ||
| { | ||
| if (relationships.ContainsKey(relationship.Value)) | ||
| relationships[relationship.Value].Add(relationship.Key); | ||
| else | ||
| relationships[relationship.Value] = [relationship.Key]; | ||
| } | ||
|
|
||
| foreach (var relationship in relationships) | ||
| { | ||
| yield return $"{relationship.Key} ({relationship.Value.Count}): {string.Join(", ", relationship.Value.ToArray())}"; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Fires prior to this social group's relationships being integrated. | ||
| /// </summary> | ||
| [ByRefEvent] | ||
| public readonly record struct SocialGroupPreIntegrationEvent(Entity<SocialGroupComponent> Group); | ||
|
|
||
| /// <summary> | ||
| /// Fires after this social group's relationships have been integrated. | ||
| /// </summary> | ||
| [ByRefEvent] | ||
| public readonly record struct SocialGroupPostIntegrationEvent(Entity<SocialGroupComponent> Group); | ||
|
|
||
| /// <summary> | ||
| /// Fires prior to any generation events (captain group, crew groups, etc). | ||
| /// </summary> | ||
| [ByRefEvent] | ||
| public readonly record struct PreCastGenerateEvent(ProducerComponent Producer); | ||
|
|
||
| /// <summary> | ||
| /// Fires after the primary generation events (captain group, crew group, etc) but before integration of relationships. | ||
| /// </summary> | ||
| [ByRefEvent] | ||
| public readonly record struct PostShipGenerateEvent(ProducerComponent Producer); | ||
|
|
||
| /// <summary> | ||
| /// Fires after all relationships have been integrated. | ||
| /// </summary> | ||
| [ByRefEvent] | ||
| public readonly record struct PostCastGenerateEvent(ProducerComponent Producer); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| using Robust.Shared.Prototypes; | ||
|
|
||
| namespace Content.Shared._ES.Auditions; | ||
|
|
||
| /// <summary> | ||
| /// This is a prototype for marking backgrounds | ||
| /// </summary> | ||
| [Prototype] | ||
| public sealed partial class BackgroundPrototype : IPrototype | ||
| { | ||
| /// <inheritdoc/> | ||
| [IdDataField] | ||
| public string ID { get; } = default!; | ||
|
|
||
| /// <summary> | ||
| /// Name of this relationship. | ||
| /// </summary> | ||
| [DataField, ViewVariables] | ||
| public LocId Name; | ||
|
|
||
| /// <summary> | ||
| /// Description of this relationship. | ||
| /// </summary> | ||
| [DataField, ViewVariables] | ||
| public LocId Description; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| using Content.Shared.Humanoid; | ||
| using Robust.Shared.Enums; | ||
| using Robust.Shared.GameStates; | ||
| using Robust.Shared.Prototypes; | ||
| using Robust.Shared.Serialization; | ||
|
|
||
| namespace Content.Shared._ES.Auditions; | ||
|
|
||
| /// <summary> | ||
| /// This is used for marking the character of components. | ||
| /// </summary> | ||
| [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] | ||
| public sealed partial class CharacterComponent : Component | ||
| { | ||
| [DataField, AutoNetworkedField] | ||
| public string Name = "Rain Miskovitch"; | ||
|
|
||
| [DataField, AutoNetworkedField] | ||
| public int Age = 25; | ||
|
|
||
| [DataField, AutoNetworkedField] | ||
| public Gender Gender = Gender.Neuter; | ||
|
|
||
| [DataField, AutoNetworkedField] | ||
| public HumanoidCharacterAppearance Appearance = default!; | ||
|
|
||
| [DataField, AutoNetworkedField] | ||
| public DateTime DateOfBirth = new(2025, 1, 1); | ||
|
|
||
| [DataField, AutoNetworkedField] | ||
| public Dictionary<string, ProtoId<RelationshipPrototype>> Relationships = new (); | ||
|
|
||
| [DataField, AutoNetworkedField] | ||
| public ProtoId<BackgroundPrototype> Background = "Colonist"; | ||
|
|
||
| [DataField, AutoNetworkedField] | ||
| public List<EntityUid> Memories = new (); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| using Content.Shared.Random; | ||
| using Robust.Shared.Prototypes; | ||
| using Robust.Shared.Serialization; | ||
|
|
||
| namespace Content.Shared._ES.Auditions; | ||
|
|
||
| /// <summary> | ||
| /// This is the cast component placed onto the producer entity. | ||
| /// </summary> | ||
| [RegisterComponent] | ||
| public sealed partial class ProducerComponent : Component | ||
Just-a-Unity-Dev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| /// <summary> | ||
| /// All the characters in the cast. | ||
| /// </summary> | ||
| [DataField] | ||
| public List<EntityUid> Characters = new (); | ||
|
|
||
| /// <summary> | ||
| /// List of all active social groups. | ||
| /// </summary> | ||
| [DataField] | ||
| public List<EntityUid> SocialGroups = new (); | ||
|
|
||
| [DataField] | ||
| public RelationshipContext CrewContext = new ("RelationshipPoolCrew", 0.75f); | ||
|
|
||
| [DataField] | ||
| public RelationshipContext CaptainContext = new ("RelationshipPoolCaptains", 0.5f); | ||
|
|
||
| [DataField] | ||
| public RelationshipContext IntercrewContext = new ("RelationshipPoolIntercrew", 0.1f); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Configuration for integrating relationships. | ||
| /// </summary> | ||
| [Serializable, NetSerializable, DataDefinition] | ||
| public partial struct RelationshipContext | ||
| { | ||
| /// <summary> | ||
| /// List of possible relationships. | ||
| /// </summary> | ||
| [DataField] | ||
| public ProtoId<WeightedRandomPrototype> PoolPrototype; | ||
|
|
||
| /// <summary> | ||
| /// How likely is a relationship to spark in this context? | ||
| /// </summary> | ||
| [DataField] | ||
| public float RelationshipProbability = 0.5f; | ||
|
|
||
| /// <summary> | ||
| /// How likely is a relationship to be mutual (both sides have the same relationship)? | ||
| /// </summary> | ||
| [DataField] | ||
| public float UnificationProbability = 1f; | ||
|
|
||
| /// <summary> | ||
| /// If the relationship isnt mutual, what are other possible relationships to give? If null, no relationship is assigned. | ||
| /// </summary> | ||
| [DataField] | ||
| public ProtoId<WeightedRandomPrototype>? SeperatePoolPrototype; | ||
|
|
||
| public RelationshipContext() | ||
| { | ||
| } | ||
|
|
||
| public RelationshipContext(string prototype, float probability) | ||
| { | ||
| RelationshipProbability = probability; | ||
| PoolPrototype = prototype; | ||
| UnificationProbability = 1f; | ||
| SeperatePoolPrototype = null; | ||
| } | ||
|
|
||
| public RelationshipContext(string prototype, float probability, float unificationProbability, string? seperatePrototype) | ||
| { | ||
| RelationshipProbability = probability; | ||
| PoolPrototype = prototype; | ||
| UnificationProbability = unificationProbability; | ||
| SeperatePoolPrototype = seperatePrototype; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| using Robust.Shared.Prototypes; | ||
|
|
||
| namespace Content.Shared._ES.Auditions; | ||
|
|
||
| /// <summary> | ||
| /// This is a prototype for marking relationships | ||
| /// </summary> | ||
| [Prototype] | ||
| public sealed partial class RelationshipPrototype : IPrototype | ||
Just-a-Unity-Dev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| /// <inheritdoc/> | ||
| [IdDataField] | ||
| public string ID { get; } = default!; | ||
|
|
||
| /// <summary> | ||
| /// Name of this relationship. | ||
| /// </summary> | ||
| [DataField, ViewVariables] | ||
| public LocId Name; | ||
|
|
||
| /// <summary> | ||
| /// Color of this relationship. | ||
| /// </summary> | ||
| [DataField, ViewVariables] | ||
| public Color Color; | ||
|
|
||
| /// <summary> | ||
| /// Whether or not this relationship must be mutual. Family members, ex-lovers, etc, all fall under this. | ||
| /// </summary> | ||
| [DataField, ViewVariables] | ||
| public bool ForceMutual; | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.