├── Assets
├── README.md
├── snapshot.json
└── templates.json
├── GameLogic
├── BallCollisionSystem.cs
├── BallData.cs
├── BallSpawningData.cs
├── BallSpawningSystem.cs
├── GameLogic.csproj
├── MapBoundsData.cs
├── MovementData.cs
├── MovementSystem.cs
├── PaddleCollectionSystem.cs
├── PaddleData.cs
├── PositionData.cs
├── Properties
│ └── AssemblyInfo.cs
├── README.md
├── TemporaryData.cs
└── TemporarySystem.cs
├── README.md
├── Unity
├── MapBoundsRenderer.cs
├── MapBoundsRenderer.cs.meta
├── PositionRenderer.cs
├── PositionRenderer.cs.meta
├── Resources.meta
├── Resources
│ ├── BallPrefab.prefab
│ ├── BallPrefab.prefab.meta
│ ├── PaddlePrefab.prefab
│ ├── PaddlePrefab.prefab.meta
│ ├── WorldPrefab.prefab
│ └── WorldPrefab.prefab.meta
├── SystemProvider.cs
└── SystemProvider.cs.meta
├── XNA.sln
├── XNA
├── DLLs
│ ├── Forge.AllLibraries.dll
│ ├── Forge.AllLibraries.pdb
│ ├── Forge.Collections.dll
│ ├── Forge.Collections.pdb
│ ├── Forge.Collections.xml
│ ├── Forge.Entities.dll
│ ├── Forge.Entities.pdb
│ ├── Forge.Entities.xml
│ ├── Forge.Extensions.dll
│ ├── Forge.Extensions.pdb
│ ├── Forge.Extensions.xml
│ ├── Forge.Networking.dll
│ ├── Forge.Networking.pdb
│ ├── Forge.Networking.xml
│ ├── Forge.Utilities.dll
│ ├── Forge.Utilities.pdb
│ ├── Forge.Utilities.xml
│ ├── Lidgren.Network.dll
│ ├── Lidgren.Network.pdb
│ ├── Lidgren.Network.xml
│ ├── Newtonsoft.Json.dll
│ ├── Newtonsoft.Json.pdb
│ ├── Newtonsoft.Json.xml
│ ├── log4net.dll
│ └── log4net.xml
├── XNA
│ ├── ExtendedSpriteBatch.cs
│ ├── Forge
│ │ ├── DataRegistry.cs
│ │ ├── DataRenderer.cs
│ │ ├── EntityContainerEventMonitor.cs
│ │ ├── GameEngineManager.cs
│ │ ├── IEventMonitor.cs
│ │ ├── PrefabData.cs
│ │ ├── README.md
│ │ └── Visualizer.cs
│ ├── Game.ico
│ ├── GameThumbnail.png
│ ├── PositionRenderer.cs
│ ├── Program.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── XNA.csproj
│ ├── XNA.csproj.user
│ └── XnaGame.cs
└── XNAContent
│ └── XNAContent.contentproj
├── demo_unity.gif
└── demo_xna.gif
/Assets/README.md:
--------------------------------------------------------------------------------
1 | `snapshot.json` is a saved game that contains some interesting initial data, such as where the paddles are and the dimensions of the map. Currently the `PrefabData` instances are only used for the Unity version, but if the XNA version implemented more sophisticated rendering it would also be used.
2 |
3 | `templates.json` contains the definition of a ball. The data serialization format here is going to change slightly in an upcoming patch to mirror that of `snapshot.json` (you won't see "$type" anymore).
--------------------------------------------------------------------------------
/Assets/snapshot.json:
--------------------------------------------------------------------------------
1 | {
2 | "EntityIdGenerator": {
3 | "NextId": 4
4 | },
5 | "GlobalEntity": [
6 | {
7 | "UniqueId": 0,
8 | "PrettyName": "Global Entity",
9 | "Data": [
10 | {
11 | "WasAdded": true,
12 | "DataType": "Forge.PrefabData",
13 | "CurrentData": {
14 | "PrefabResourcePath": "WorldPrefab"
15 | }
16 | },
17 | {
18 | "WasAdded": true,
19 | "DataType": "GameSample.MapBoundsData",
20 | "CurrentData": {
21 | "Width": 13,
22 | "Height": 7
23 | }
24 | },
25 | {
26 | "WasAdded": true,
27 | "DataType": "GameSample.BallSpawningData",
28 | "CurrentData": {
29 | "MaxTicks": 25,
30 | "MinTicks": 10,
31 | "Remaining": 0,
32 | "Ball": {
33 | "ReferencedId": 10000,
34 | "ReferenceType": "TemplateReference"
35 | }
36 | }
37 | }
38 | ]
39 | }
40 | ],
41 | "AddedEntities": [
42 | {
43 | "UniqueId": 2,
44 | "PrettyName": "Paddle1",
45 | "Data": [
46 | {
47 | "WasAdded": true,
48 | "DataType": "Forge.PrefabData",
49 | "CurrentData": {
50 | "PrefabResourcePath": "PaddlePrefab"
51 | }
52 | },
53 | {
54 | "WasAdded": true,
55 | "DataType": "GameSample.PositionData",
56 | "CurrentData": {
57 | "Position": {
58 | "X": 5.0,
59 | "Z": 0.0,
60 | "Radius": 3.0
61 | }
62 | },
63 | "PreviousData": {
64 | "Position": {
65 | "X": 0.0,
66 | "Z": 0.0,
67 | "Radius": 0.0
68 | }
69 | }
70 | },
71 | {
72 | "WasAdded": true,
73 | "DataType": "GameSample.MovementData",
74 | "CurrentData": {
75 | "Velocity": {
76 | "X": 0.0,
77 | "Z": 0.100097656
78 | }
79 | },
80 | "PreviousData": {
81 | "Velocity": {
82 | "X": 0.0,
83 | "Z": 0.0
84 | }
85 | }
86 | },
87 | {
88 | "WasAdded": true,
89 | "DataType": "GameSample.PaddleData",
90 | "CurrentData": {}
91 | }
92 | ]
93 | },
94 | {
95 | "UniqueId": 3,
96 | "PrettyName": "Paddle2",
97 | "Data": [
98 | {
99 | "WasAdded": true,
100 | "DataType": "Forge.PrefabData",
101 | "CurrentData": {
102 | "PrefabResourcePath": "PaddlePrefab"
103 | }
104 | },
105 | {
106 | "WasAdded": true,
107 | "DataType": "GameSample.PositionData",
108 | "CurrentData": {
109 | "Position": {
110 | "X": -5.0,
111 | "Z": 0.0,
112 | "Radius": 3.0
113 | }
114 | },
115 | "PreviousData": {
116 | "Position": {
117 | "X": 0.0,
118 | "Z": 0.0,
119 | "Radius": 0.0
120 | }
121 | }
122 | },
123 | {
124 | "WasAdded": true,
125 | "DataType": "GameSample.MovementData",
126 | "CurrentData": {
127 | "Velocity": {
128 | "X": 0.0,
129 | "Z": -0.100097656
130 | }
131 | },
132 | "PreviousData": {
133 | "Velocity": {
134 | "X": 0.0,
135 | "Z": 0.0
136 | }
137 | }
138 | },
139 | {
140 | "WasAdded": true,
141 | "DataType": "GameSample.PaddleData",
142 | "CurrentData": {}
143 | }
144 | ]
145 | }
146 | ],
147 | "ActiveEntities": [],
148 | "RemovedEntities": [],
149 | "Systems": [
150 | {
151 | "Type": "GameSample.PaddleCollectionSystem",
152 | "System": {
153 | "$id": "1",
154 | "Paddles": []
155 | }
156 | },
157 | {
158 | "Type": "GameSample.BallCollisionSystem",
159 | "System": {
160 | "_paddles": {
161 | "$ref": "1"
162 | }
163 | }
164 | },
165 | {
166 | "Type": "GameSample.MovementSystem",
167 | "System": {}
168 | },
169 | {
170 | "Type": "GameSample.BallSpawningSystem",
171 | "System": {}
172 | },
173 | {
174 | "Type": "GameSample.TemporarySystem",
175 | "System": {}
176 | }
177 | ]
178 | }
--------------------------------------------------------------------------------
/Assets/templates.json:
--------------------------------------------------------------------------------
1 | {
2 | "Templates": [
3 | {
4 | "TemplateId": 10000,
5 | "PrettyName": "Ball",
6 | "DefaultDataInstances": [
7 | {
8 | "$type": "Forge.PrefabData",
9 | "PrefabResourcePath": "BallPrefab"
10 | },
11 | {
12 | "$type": "GameSample.PositionData",
13 | "Position": {
14 | "X": 0.0,
15 | "Z": 0.0,
16 | "Radius": 0.300048828
17 | }
18 | },
19 | {
20 | "$type": "GameSample.MovementData",
21 | "Velocity": {
22 | "X": 0.300048828,
23 | "Z": 0.199951172
24 | }
25 | },
26 | {
27 | "$type": "GameSample.BallData",
28 | "CollisionDisabled": 0
29 | },
30 | {
31 | "$type": "GameSample.TemporaryData",
32 | "TicksRemaining": 50
33 | }
34 | ]
35 | }
36 | ],
37 | "TemplateIdGenerator": {
38 | "NextId": 10001
39 | }
40 | }
--------------------------------------------------------------------------------
/GameLogic/BallCollisionSystem.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Forge.Utilities;
3 | using Newtonsoft.Json;
4 | using System;
5 |
6 | namespace GameSample {
7 | ///
8 | /// If a ball hits a paddle, then the ball reverses direction.
9 | ///
10 | [JsonObject(MemberSerialization.OptIn)]
11 | public class BallCollisionSystem : BaseSystem, Trigger.Update {
12 | ///
13 | /// The system that we get our paddles from.
14 | ///
15 | [JsonProperty]
16 | private PaddleCollectionSystem _paddles;
17 |
18 | public BallCollisionSystem(PaddleCollectionSystem paddles) {
19 | _paddles = paddles;
20 | }
21 |
22 | ///
23 | /// We want to ensure that our paddle system executes before us, as we are using data from
24 | /// it.
25 | ///
26 | protected override SystemExecutionOrdering GetExecutionOrdering(ISystem system) {
27 | if (system == _paddles) {
28 | return SystemExecutionOrdering.AfterOther;
29 | }
30 |
31 | return base.GetExecutionOrdering(system);
32 | }
33 |
34 | public void OnUpdate(IEntity ball) {
35 | // If we just modified the velocity of the ball, then don't modify it again until the
36 | // cooldown has finished.
37 | if (ball.Current().CollisionDisabled > 0) {
38 | ball.Modify().CollisionDisabled--;
39 | return;
40 | }
41 |
42 | foreach (IEntity paddle in _paddles.Paddles) {
43 | Bound paddlePosition = paddle.Current().Position;
44 | Bound ballPosition = ball.Current().Position;
45 |
46 | // change the direction of the ball if it's colliding with a paddle
47 | if (paddlePosition.Intersects(ballPosition)) {
48 | ball.Modify().MultVelocity(-1, 1);
49 | ball.Modify().CollisionDisabled = 5;
50 | break;
51 | }
52 | }
53 | }
54 |
55 | ///
56 | /// The ball collision system only cares about entities that have PongData, MovementData,
57 | /// and PositionData.
58 | ///
59 | public Type[] RequiredDataTypes {
60 | get {
61 | return new Type[] {
62 | typeof(BallData), typeof(MovementData), typeof(PositionData)
63 | };
64 | }
65 | }
66 | }
67 | }
--------------------------------------------------------------------------------
/GameLogic/BallData.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Newtonsoft.Json;
3 | using System;
4 | using System.Collections.Generic;
5 |
6 | namespace GameSample {
7 | ///
8 | /// Contains information specific to a ball.
9 | ///
10 | [JsonObject(MemberSerialization.OptIn)]
11 | public class BallData : Data.NonVersioned {
12 | ///
13 | /// How many game ticks is collision disabled for?
14 | ///
15 | [JsonProperty]
16 | public int CollisionDisabled;
17 | }
18 | }
--------------------------------------------------------------------------------
/GameLogic/BallSpawningData.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Newtonsoft.Json;
3 |
4 | namespace GameSample {
5 | [JsonObject(MemberSerialization.OptIn)]
6 | public class BallSpawningData : Data.NonVersioned {
7 | ///
8 | /// The maximum number of ticks before a spawn occurs.
9 | ///
10 | [JsonProperty]
11 | public int MaxTicks;
12 |
13 | ///
14 | /// The minimum number of ticks before a spawn occurs.
15 | ///
16 | [JsonProperty]
17 | public int MinTicks;
18 |
19 | ///
20 | /// The number of ticks remaining until the next spawn.
21 | ///
22 | [JsonProperty]
23 | public int Remaining;
24 |
25 | ///
26 | /// The ball template used to create new ball entities.
27 | ///
28 | [JsonProperty]
29 | public ITemplate Ball;
30 | }
31 | }
--------------------------------------------------------------------------------
/GameLogic/BallSpawningSystem.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Forge.Utilities;
3 | using System;
4 |
5 | namespace GameSample {
6 | ///
7 | /// Spawns balls every so often.
8 | ///
9 | public class BallSpawningSystem : BaseSystem, Trigger.GlobalPostUpdate {
10 | public void OnGlobalPostUpdate() {
11 | BallSpawningData spawningData = GlobalEntity.Current();
12 |
13 | // can we spawn?
14 | if (spawningData.Remaining <= 0) {
15 | // create a new ball
16 | IEntity spawned = spawningData.Ball.Instantiate();
17 |
18 | // it isn't necessary to set the position of the spawned object to zero, but it
19 | // demos how to initialize a newly created entity
20 | PositionData spawnedPosition = spawned.AddOrModify();
21 | spawnedPosition.Position = new Bound(0, 0, spawnedPosition.Position.Radius);
22 |
23 | // reset the ticks until the next spawn
24 | GlobalEntity.Modify().Remaining =
25 | GameRandom.Range(spawningData.MinTicks, spawningData.MaxTicks);
26 | }
27 |
28 | // can't spawn yet; decrement the number of ticks until we can spawn again
29 | else {
30 | GlobalEntity.Modify().Remaining--;
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/GameLogic/GameLogic.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {A0314C4B-6CBA-4D0F-B32F-24B450A0DDEF}
8 | Library
9 | Properties
10 | GameLogic
11 | GameLogic
12 | v4.0
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 | ..\XNA\DLLs\Forge.AllLibraries.dll
36 |
37 |
38 | ..\XNA\DLLs\Forge.Collections.dll
39 |
40 |
41 | ..\XNA\DLLs\Forge.Entities.dll
42 |
43 |
44 | ..\XNA\DLLs\Forge.Extensions.dll
45 |
46 |
47 | ..\XNA\DLLs\Forge.Networking.dll
48 |
49 |
50 | ..\XNA\DLLs\Forge.Utilities.dll
51 |
52 |
53 | ..\XNA\DLLs\Lidgren.Network.dll
54 |
55 |
56 | ..\XNA\DLLs\log4net.dll
57 |
58 |
59 | ..\XNA\DLLs\Newtonsoft.Json.dll
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
91 |
--------------------------------------------------------------------------------
/GameLogic/MapBoundsData.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Newtonsoft.Json;
3 |
4 | namespace GameSample {
5 | ///
6 | /// Data that contains the dimensions of the map.
7 | ///
8 | [JsonObject(MemberSerialization.OptIn)]
9 | public class MapBoundsData : Data.NonVersioned {
10 | ///
11 | /// Width the map
12 | ///
13 | [JsonProperty]
14 | public int Width;
15 |
16 | ///
17 | /// Height of the map
18 | ///
19 | [JsonProperty]
20 | public int Height;
21 | }
22 | }
--------------------------------------------------------------------------------
/GameLogic/MovementData.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Forge.Utilities;
3 | using Newtonsoft.Json;
4 | using System.Runtime.CompilerServices;
5 |
6 | namespace GameSample {
7 | ///
8 | /// Data that contains movement information for an object. Because this data type extends
9 | /// ConcurrentVersioned, it can be modified multiple times per update.
10 | ///
11 | [JsonObject(MemberSerialization.OptIn)]
12 | public class MovementData : Data.ConcurrentVersioned {
13 | ///
14 | /// The velocity of the object. This can be modified by multiple threads at the same time,
15 | /// so we ensure that it is synchronized.
16 | ///
17 | [JsonProperty]
18 | public Vector2r Velocity {
19 | get;
20 | private set;
21 | }
22 |
23 | ///
24 | /// Multiples the velocity by the given factors.
25 | ///
26 | /// The x factor to multiply the velocity by.
27 | /// The z factor to multiple the velocity by.
28 | [MethodImpl(MethodImplOptions.Synchronized)]
29 | public void MultVelocity(Real x, Real z) {
30 | Velocity = new Vector2r(Velocity.X * x, Velocity.Z * z);
31 | }
32 |
33 | public override void CopyFrom(MovementData source) {
34 | this.Velocity = source.Velocity;
35 | }
36 |
37 | ///
38 | /// If this data type needed to do some bookkeeping after each update (because modifications
39 | /// can happen concurrently), we can do it in this function. MovementData doesn't need any
40 | /// bookkeeping, so the function is empty.
41 | ///
42 | public override void ResolveConcurrentModifications() {
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/GameLogic/MovementSystem.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Forge.Utilities;
3 | using Newtonsoft.Json;
4 | using System;
5 |
6 | namespace GameSample {
7 | ///
8 | /// The movement system ensures that objects do not leave the map and also moves them according
9 | /// to their velocity.
10 | ///
11 | [JsonObject(MemberSerialization.OptIn)]
12 | public class MovementSystem : BaseSystem, Trigger.Update {
13 | ///
14 | /// Every update, we want to ensure that objects are inside the map and we also want to move
15 | /// the object according to its velocity.
16 | ///
17 | public void OnUpdate(IEntity entity) {
18 | MapBoundsData mapBounds = GlobalEntity.Current();
19 |
20 | RespondToMapBounds(mapBounds, entity);
21 | IntegratePosition(entity);
22 | }
23 |
24 | ///
25 | /// Moves an object to its next position according to its current velocity.
26 | ///
27 | private static void IntegratePosition(IEntity entity) {
28 | PositionData pos = entity.Current();
29 | MovementData mov = entity.Current();
30 |
31 | entity.Modify().Position = new Bound(
32 | pos.Position.X + mov.Velocity.X,
33 | pos.Position.Z + mov.Velocity.Z,
34 | pos.Position.Radius
35 | );
36 | }
37 |
38 | ///
39 | /// Changes an objects velocity if it has left the map.
40 | ///
41 | private static void RespondToMapBounds(MapBoundsData mapBounds, IEntity entity) {
42 | PositionData pos = entity.Current();
43 | MovementData mov = entity.Current();
44 |
45 | if (((pos.Position.Z - pos.Position.Radius) < -mapBounds.Height && mov.Velocity.Z < 0) ||
46 | ((pos.Position.Z + pos.Position.Radius) > mapBounds.Height && mov.Velocity.Z > 0)) {
47 | entity.Modify().MultVelocity(1, -1);
48 | }
49 | if (((pos.Position.X - pos.Position.Radius) < -mapBounds.Width && mov.Velocity.X < 0) ||
50 | ((pos.Position.X + pos.Position.Radius) > mapBounds.Width && mov.Velocity.X > 0)) {
51 | entity.Modify().MultVelocity(-1, 1);
52 | }
53 | }
54 |
55 | ///
56 | /// We only want entities that have both MovementData and PositionData.
57 | ///
58 | public Type[] RequiredDataTypes {
59 | get {
60 | return new[] {
61 | typeof(MovementData), typeof(PositionData)
62 | };
63 | }
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/GameLogic/PaddleCollectionSystem.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Newtonsoft.Json;
3 | using System;
4 | using System.Collections.Generic;
5 |
6 | namespace GameSample {
7 | ///
8 | /// A system that merely collects a list of all paddles in the game. This may be unnecessary in
9 | /// a future version of Forge, but for now it works well as a sample for some more of the
10 | /// triggers.
11 | ///
12 | ///
13 | /// We serialize the object as a reference so that the BallCollisionSystem is properly restored.
14 | ///
15 | [JsonObject(MemberSerialization.OptIn, IsReference = true)]
16 | public class PaddleCollectionSystem : BaseSystem, Trigger.Added, Trigger.Removed {
17 | ///
18 | /// Every paddle in the game.
19 | ///
20 | [JsonProperty]
21 | public List Paddles = new List();
22 |
23 | public void OnAdded(IEntity entity) {
24 | Paddles.Add(entity);
25 | }
26 |
27 | public void OnRemoved(IEntity entity) {
28 | Paddles.Remove(entity);
29 | }
30 |
31 | public Type[] RequiredDataTypes {
32 | get { return new[] { typeof(PositionData), typeof(PaddleData) }; }
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/GameLogic/PaddleData.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Newtonsoft.Json;
3 |
4 | namespace GameSample {
5 | ///
6 | /// Data type used to mark an object as a paddle.
7 | ///
8 | [JsonObject(MemberSerialization.OptIn)]
9 | public class PaddleData : Data.NonVersioned {
10 | }
11 | }
--------------------------------------------------------------------------------
/GameLogic/PositionData.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Forge.Utilities;
3 | using Newtonsoft.Json;
4 |
5 | namespace GameSample {
6 | ///
7 | /// Provides an Entity with a position and a radius. Because the data extends Versioned, we can
8 | /// query the previous state of the data.
9 | ///
10 | [JsonObject(MemberSerialization.OptIn)]
11 | public class PositionData : Data.Versioned {
12 | ///
13 | /// The position and radius of the object.
14 | ///
15 | [JsonProperty]
16 | public Bound Position;
17 |
18 | ///
19 | /// There is another PositionData instance that we should copy values from into this
20 | /// instance.
21 | ///
22 | public override void CopyFrom(PositionData source) {
23 | this.Position = source.Position;
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/GameLogic/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("GameLogic")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("GameLogic")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("840a6021-35bf-4d40-915b-3be295a3875c")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/GameLogic/README.md:
--------------------------------------------------------------------------------
1 | # Files
2 |
3 | The `GameLogic` folder contains the interesting game-specific code.
4 |
5 | `BallCollisionSystem` causes balls to reverse direction when they hit entities with `PaddleData`.
6 |
7 | `BallData` defines what a ball is, and contains data that causes collision response to be temporarily disabled when a ball hits a paddle.
8 |
9 | `BallSpawningData` is data that is stored in the `GlobalEntity` that the `BallSpawningSystem` uses to spawn balls.
10 |
11 | `BallSpawningSystem` instantiates an `ITemplate` (that is defined in `snapshot.json` and `templates.json`) which is defined as a ball.
12 |
13 | `MapBoundsData` defines the size of the map and is only contained on the `GlobalEntity`.
14 |
15 | `MovementData` defines a velocity for an entity so that it can move around the map.
16 |
17 | `MovementSystem` takes entities with both `PositionData` and `MovementData` and moves them.
18 |
19 | `PaddleCollectionSystem` merely collects all entities that have `PaddleData`. This system is used by the `BallCollisionSystem`.
20 |
21 | `PaddleData` tags entities so that the `PaddleCollectionSystem` will contain said entity,
22 |
23 | `PositionData` defines the position of an entity on the map.
24 |
25 | `TemporaryData` gives an entity a limited lifetime; after a certain number of ticks, the `TemporarySystem` will destroy it.
26 |
27 | `TemporarySystem` destroys entities whose `TemporaryData` has reached 0. This system also demos input; `StopDestroyingInput` disables destroying entities and `StartDestroyingInput` enables destroying entities. Actually sending the input into the game is engine specific (as it depends on the input layer); in the XNA sample pressing the 1 key enables destruction and the 2 key disables it.
--------------------------------------------------------------------------------
/GameLogic/TemporaryData.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Newtonsoft.Json;
3 |
4 | namespace GameSample {
5 | ///
6 | /// An entity that contains TemporaryData will be removed after a certain number of game
7 | /// updates.
8 | ///
9 | [JsonObject(MemberSerialization.OptIn)]
10 | public class TemporaryData : Data.NonVersioned {
11 | ///
12 | /// The number of ticks that this object has left alive.
13 | ///
14 | [JsonProperty]
15 | public int TicksRemaining;
16 | }
17 | }
--------------------------------------------------------------------------------
/GameLogic/TemporarySystem.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Forge.Networking.AutomaticTurnGame;
3 | using Newtonsoft.Json;
4 | using System;
5 |
6 | namespace GameSample {
7 | ///
8 | /// Entities will no longer be destroyed by the temporary system.
9 | ///
10 | [JsonObject(MemberSerialization.OptIn)]
11 | public class StopDestroyingInput : IGameInput, IGameCommand { }
12 |
13 | ///
14 | /// Entities will be destroyed by the temporary system.
15 | ///
16 | [JsonObject(MemberSerialization.OptIn)]
17 | public class StartDestroyingInput : IGameInput, IGameCommand { }
18 |
19 | ///
20 | /// The temporary system removes entities who have expired according to their temporary data.
21 | ///
22 | [JsonObject(MemberSerialization.OptIn)]
23 | public class TemporarySystem : BaseSystem, Trigger.Update, Trigger.GlobalInput {
24 | [JsonProperty("Enabled")]
25 | private bool _enabled;
26 |
27 | public void OnUpdate(IEntity entity) {
28 | if (_enabled == false) {
29 | return;
30 | }
31 |
32 | if (entity.Current().TicksRemaining <= 0) {
33 | entity.Destroy();
34 | }
35 |
36 | entity.Modify().TicksRemaining--;
37 | }
38 |
39 | public Type[] RequiredDataTypes {
40 | get { return new[] { typeof(TemporaryData) }; }
41 | }
42 |
43 | public Type[] InputTypes {
44 | get { return new[] { typeof(StopDestroyingInput), typeof(StartDestroyingInput) }; }
45 | }
46 |
47 | public void OnGlobalInput(IGameInput input) {
48 | if (input is StopDestroyingInput) {
49 | _enabled = false;
50 | }
51 |
52 | else if (input is StartDestroyingInput) {
53 | _enabled = true;
54 | }
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Game Sample
2 |
3 | The game sample demos nearly every important feature in Forge, including integration into both Unity and XNA!
4 |
5 |
6 | ## Running in Unity
7 |
8 | Sorry, the gifs are recorded at a low FPS. The games are both actually extremely smooth due to interpolation of position data (implemented in both Unity and XNA; see the `PositionRenderer`), despite the fact that they are both only updating 15 times a second.
9 |
10 | 
11 |
12 | ## Running in XNA
13 |
14 | Open up XNA.sln (if you have XNA installed) to run this demo locally. This gif may look a little funny because the paddles (the big rectangles) are actually being simulated as circles.
15 |
16 | 
17 |
18 | # Overview
19 |
20 | There are four folders.
21 |
22 | - `Assets`: A snapshot.json and templates.json file that will allow you to start up a simple game. These inject systems and data values into the engine. Feel free to look at the JSON files; they describe the serialization format of the game. Forge save games will be serialized into another snapshot.json. One way of viewing the `Unity` editor is a designer of save-game files, and when you start a new game you're really just loading a saved file.
23 | - `GameLogic`: Game logic that is independent from any framework. This builds directly on top of Forge APIs and implements the gameplay.
24 | - `Unity`: Integration into the Unity game engine. This requires the Forge Unity plug-in, which will be available soon.
25 | - `XNA`: Integration into XNA/MonoGame. This currently uses the unpolished XNA Forge bindings (they are found in the Forge directory under XNA).
26 |
27 | # Concepts
28 |
29 | `Forge` has a couple core concepts which allow the magic to happen. They are immutability, data, systems, and events.
30 |
31 | In regards to immutability, and speaking very roughly, there are 3 game states in memory at all times that you game can work with; the previous state, the current state, and the future state. The previous and current states are read-only, while the future state is write-only. Systems can be notified that a data instance has been modified and then it can query the previous state to see what it's old value was. This is one of the ways in which initialization/update order are solved.
32 |
33 | The game is composed of `IEntities` which contain `IData` instances (there are a variety of IData flavors, from ones which are Versioned (they support querying their previous states), to NonVersioned, which do not support querying, and Concurrent variants, which allow multiple writes in the same update). A data type can be something simple like your entities health or perhaps its position. Crucially, _data types contain no game logic_.
34 |
35 | Game logic goes into `ISystems`, which are executed concurrently on multiple threads. `ISystems` can listen for a number of `Triggers`, such as when an entity has been added. Further, they can express interest in only certain types of entities, for example, a `MovementSystem` can request only entities which have `MovementData` and `PositionData`. Some of the triggers are pretty nifty, such as `Trigger.Modified`, which allows a system to be notified whenever an entity that it contains is modified (for example, the entity's position has changed). The immutability system then allows the system to query the old position even while systems are processing the entities new position.
36 |
37 | `ISystems` do *not* deal with rendering any of the game state. Instead, the events API is used to notify the 3rd party renderer about how the simulation state has changed. Almost all of the busy work here is automated by the Unity/XNA integration packages.
38 |
39 | Additionally, most games need to create new entities at runtime; `ITemplates` are preconfigured entities which can be instantiated at runtime. They are similar in nature to Unity's prefabs. `ITemplates` are the only way to create new `IEntity` instances at runtime.
40 |
41 | ## License
42 | This sample is freely available under the MIT license.
43 |
--------------------------------------------------------------------------------
/Unity/MapBoundsRenderer.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Neon.Unity;
3 | using UnityEngine;
4 |
5 | namespace GameSample {
6 | ///
7 | /// Prepares the GameObject that contains the MapBoundsData so that the dimensions of the map
8 | /// are visible.
9 | ///
10 | [CustomDataRegistry(typeof(MapBoundsData))]
11 | public class MapBoundsRenderer : DataRenderer {
12 | protected override void OnInitialize() {
13 | MapBoundsData data = _entity.Current();
14 | transform.localScale = new Vector3(data.Width * 2, 1, data.Height * 2);
15 | transform.position = new Vector3(0, -2, 0);
16 | }
17 |
18 | public override void UpdateVisualization(float percentage) {
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/Unity/MapBoundsRenderer.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d7d32ba8faeab2649b0dda0abc81c6b9
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Unity/PositionRenderer.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Forge.Utilities;
3 | using Neon.Unity;
4 | using UnityEngine;
5 |
6 | namespace GameSample {
7 | ///
8 | /// Performs interpolation and rendering for PositionData.
9 | ///
10 | [CustomDataRegistry(typeof(PositionData))]
11 | public class PositionRenderer : DataRenderer {
12 | protected override void OnInitialize() {
13 | PositionData data = _entity.Current();
14 |
15 | float radius = data.Position.Radius.AsFloat * 2;
16 | transform.localScale = new Vector3(radius, radius, radius);
17 | }
18 |
19 | public override void UpdateVisualization(float percentage) {
20 | Vector2r previous = ToVec(_entity.Previous().Position);
21 | Vector2r current = ToVec(_entity.Current().Position);
22 |
23 | float interpolatedX = Interpolate(previous.X.AsFloat, current.X.AsFloat, percentage);
24 | float interpolatedZ = Interpolate(previous.Z.AsFloat, current.Z.AsFloat, percentage);
25 |
26 | transform.position = new Vector3(interpolatedX, transform.position.y, interpolatedZ);
27 | }
28 |
29 | private static Vector2r ToVec(Bound bound) {
30 | return new Vector2r(bound.X, bound.Z);
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/Unity/PositionRenderer.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8bee4554ccea0604fa08f9cc0a43c720
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/Unity/Resources.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5d2637547650c394abbd7e1260481e83
3 | folderAsset: yes
4 | DefaultImporter:
5 | userData:
6 |
--------------------------------------------------------------------------------
/Unity/Resources/BallPrefab.prefab:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1 &100000
4 | GameObject:
5 | m_ObjectHideFlags: 0
6 | m_PrefabParentObject: {fileID: 0}
7 | m_PrefabInternal: {fileID: 100100000}
8 | serializedVersion: 4
9 | m_Component:
10 | - 4: {fileID: 400000}
11 | - 23: {fileID: 2300000}
12 | - 33: {fileID: 3300000}
13 | m_Layer: 0
14 | m_Name: PongPrefab
15 | m_TagString: Untagged
16 | m_Icon: {fileID: 0}
17 | m_NavMeshLayer: 0
18 | m_StaticEditorFlags: 0
19 | m_IsActive: 1
20 | --- !u!4 &400000
21 | Transform:
22 | m_ObjectHideFlags: 1
23 | m_PrefabParentObject: {fileID: 0}
24 | m_PrefabInternal: {fileID: 100100000}
25 | m_GameObject: {fileID: 100000}
26 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
27 | m_LocalPosition: {x: 0, y: 0, z: 0}
28 | m_LocalScale: {x: .200000003, y: .200000003, z: .200000003}
29 | m_Children: []
30 | m_Father: {fileID: 0}
31 | --- !u!23 &2300000
32 | Renderer:
33 | m_ObjectHideFlags: 1
34 | m_PrefabParentObject: {fileID: 0}
35 | m_PrefabInternal: {fileID: 100100000}
36 | m_GameObject: {fileID: 100000}
37 | m_Enabled: 1
38 | m_CastShadows: 1
39 | m_ReceiveShadows: 1
40 | m_LightmapIndex: 255
41 | m_LightmapTilingOffset: {x: 1, y: 1, z: 0, w: 0}
42 | m_Materials:
43 | - {fileID: 10302, guid: 0000000000000000f000000000000000, type: 0}
44 | m_SubsetIndices:
45 | m_StaticBatchRoot: {fileID: 0}
46 | m_UseLightProbes: 0
47 | m_LightProbeAnchor: {fileID: 0}
48 | m_ScaleInLightmap: 1
49 | m_SortingLayer: 0
50 | m_SortingOrder: 0
51 | m_SortingLayerID: 0
52 | --- !u!33 &3300000
53 | MeshFilter:
54 | m_ObjectHideFlags: 1
55 | m_PrefabParentObject: {fileID: 0}
56 | m_PrefabInternal: {fileID: 100100000}
57 | m_GameObject: {fileID: 100000}
58 | m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
59 | --- !u!1001 &100100000
60 | Prefab:
61 | m_ObjectHideFlags: 1
62 | serializedVersion: 2
63 | m_Modification:
64 | m_TransformParent: {fileID: 0}
65 | m_Modifications: []
66 | m_RemovedComponents: []
67 | m_ParentPrefab: {fileID: 0}
68 | m_RootGameObject: {fileID: 100000}
69 | m_IsPrefabParent: 1
70 | m_IsExploded: 1
71 |
--------------------------------------------------------------------------------
/Unity/Resources/BallPrefab.prefab.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0f381c4521a10964896d6f2495b36a75
3 | NativeFormatImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Unity/Resources/PaddlePrefab.prefab:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1 &100000
4 | GameObject:
5 | m_ObjectHideFlags: 0
6 | m_PrefabParentObject: {fileID: 0}
7 | m_PrefabInternal: {fileID: 100100000}
8 | serializedVersion: 4
9 | m_Component:
10 | - 4: {fileID: 400000}
11 | - 23: {fileID: 2300000}
12 | - 33: {fileID: 3300000}
13 | m_Layer: 0
14 | m_Name: PaddlePrefab
15 | m_TagString: Untagged
16 | m_Icon: {fileID: 0}
17 | m_NavMeshLayer: 0
18 | m_StaticEditorFlags: 0
19 | m_IsActive: 1
20 | --- !u!4 &400000
21 | Transform:
22 | m_ObjectHideFlags: 1
23 | m_PrefabParentObject: {fileID: 0}
24 | m_PrefabInternal: {fileID: 100100000}
25 | m_GameObject: {fileID: 100000}
26 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
27 | m_LocalPosition: {x: 0, y: 0, z: 0}
28 | m_LocalScale: {x: 1, y: 1, z: 1}
29 | m_Children: []
30 | m_Father: {fileID: 0}
31 | --- !u!23 &2300000
32 | Renderer:
33 | m_ObjectHideFlags: 1
34 | m_PrefabParentObject: {fileID: 0}
35 | m_PrefabInternal: {fileID: 100100000}
36 | m_GameObject: {fileID: 100000}
37 | m_Enabled: 1
38 | m_CastShadows: 1
39 | m_ReceiveShadows: 1
40 | m_LightmapIndex: 255
41 | m_LightmapTilingOffset: {x: 1, y: 1, z: 0, w: 0}
42 | m_Materials:
43 | - {fileID: 10302, guid: 0000000000000000f000000000000000, type: 0}
44 | m_SubsetIndices:
45 | m_StaticBatchRoot: {fileID: 0}
46 | m_UseLightProbes: 0
47 | m_LightProbeAnchor: {fileID: 0}
48 | m_ScaleInLightmap: 1
49 | m_SortingLayer: 0
50 | m_SortingOrder: 0
51 | m_SortingLayerID: 0
52 | --- !u!33 &3300000
53 | MeshFilter:
54 | m_ObjectHideFlags: 1
55 | m_PrefabParentObject: {fileID: 0}
56 | m_PrefabInternal: {fileID: 100100000}
57 | m_GameObject: {fileID: 100000}
58 | m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
59 | --- !u!1001 &100100000
60 | Prefab:
61 | m_ObjectHideFlags: 1
62 | serializedVersion: 2
63 | m_Modification:
64 | m_TransformParent: {fileID: 0}
65 | m_Modifications: []
66 | m_RemovedComponents: []
67 | m_ParentPrefab: {fileID: 0}
68 | m_RootGameObject: {fileID: 100000}
69 | m_IsPrefabParent: 1
70 | m_IsExploded: 1
71 |
--------------------------------------------------------------------------------
/Unity/Resources/PaddlePrefab.prefab.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 35bafa5bbca961f469f7b005c6a424cb
3 | NativeFormatImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Unity/Resources/WorldPrefab.prefab:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1001 &100100000
4 | Prefab:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | m_Modification:
8 | m_TransformParent: {fileID: 0}
9 | m_Modifications: []
10 | m_RemovedComponents: []
11 | m_ParentPrefab: {fileID: 0}
12 | m_RootGameObject: {fileID: 0}
13 | m_IsPrefabParent: 1
14 | m_IsExploded: 1
15 |
--------------------------------------------------------------------------------
/Unity/Resources/WorldPrefab.prefab.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 81bee1eb6026ccc4e999574713bee3f4
3 | NativeFormatImporter:
4 | userData:
5 |
--------------------------------------------------------------------------------
/Unity/SystemProvider.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Neon.Unity;
3 | using System.Collections.Generic;
4 |
5 | namespace GameSample {
6 | ///
7 | /// Provides the systems that should be used when generating the level.
8 | ///
9 | public class SystemProvider : ISystemProvider {
10 | public IEnumerable GetSystems() {
11 | PaddleCollectionSystem paddles = new PaddleCollectionSystem();
12 | yield return paddles;
13 | yield return new BallCollisionSystem(paddles);
14 | yield return new MovementSystem();
15 | yield return new BallSpawningSystem();
16 | yield return new TemporarySystem();
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/Unity/SystemProvider.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 08c0249d83e20294d8f907ccd070dd9a
3 | MonoImporter:
4 | serializedVersion: 2
5 | defaultReferences: []
6 | executionOrder: 0
7 | icon: {instanceID: 0}
8 | userData:
9 |
--------------------------------------------------------------------------------
/XNA.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.21005.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XNA", "XNA\XNA\XNA.csproj", "{55DEEFF6-2A0C-4454-823D-F2BCD8644C5D}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XNAContent", "XNA\XNAContent\XNAContent.contentproj", "{97E2A491-3907-46F5-A4D0-66781E1A1AC7}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameLogic", "GameLogic\GameLogic.csproj", "{A0314C4B-6CBA-4D0F-B32F-24B450A0DDEF}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Debug|Mixed Platforms = Debug|Mixed Platforms
16 | Debug|x86 = Debug|x86
17 | Release|Any CPU = Release|Any CPU
18 | Release|Mixed Platforms = Release|Mixed Platforms
19 | Release|x86 = Release|x86
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {55DEEFF6-2A0C-4454-823D-F2BCD8644C5D}.Debug|Any CPU.ActiveCfg = Debug|x86
23 | {55DEEFF6-2A0C-4454-823D-F2BCD8644C5D}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
24 | {55DEEFF6-2A0C-4454-823D-F2BCD8644C5D}.Debug|Mixed Platforms.Build.0 = Debug|x86
25 | {55DEEFF6-2A0C-4454-823D-F2BCD8644C5D}.Debug|x86.ActiveCfg = Debug|x86
26 | {55DEEFF6-2A0C-4454-823D-F2BCD8644C5D}.Debug|x86.Build.0 = Debug|x86
27 | {55DEEFF6-2A0C-4454-823D-F2BCD8644C5D}.Release|Any CPU.ActiveCfg = Release|x86
28 | {55DEEFF6-2A0C-4454-823D-F2BCD8644C5D}.Release|Mixed Platforms.ActiveCfg = Release|x86
29 | {55DEEFF6-2A0C-4454-823D-F2BCD8644C5D}.Release|Mixed Platforms.Build.0 = Release|x86
30 | {55DEEFF6-2A0C-4454-823D-F2BCD8644C5D}.Release|x86.ActiveCfg = Release|x86
31 | {55DEEFF6-2A0C-4454-823D-F2BCD8644C5D}.Release|x86.Build.0 = Release|x86
32 | {97E2A491-3907-46F5-A4D0-66781E1A1AC7}.Debug|Any CPU.ActiveCfg = Debug|x86
33 | {97E2A491-3907-46F5-A4D0-66781E1A1AC7}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
34 | {97E2A491-3907-46F5-A4D0-66781E1A1AC7}.Debug|x86.ActiveCfg = Debug|x86
35 | {97E2A491-3907-46F5-A4D0-66781E1A1AC7}.Release|Any CPU.ActiveCfg = Release|x86
36 | {97E2A491-3907-46F5-A4D0-66781E1A1AC7}.Release|Mixed Platforms.ActiveCfg = Release|x86
37 | {97E2A491-3907-46F5-A4D0-66781E1A1AC7}.Release|x86.ActiveCfg = Release|x86
38 | {A0314C4B-6CBA-4D0F-B32F-24B450A0DDEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 | {A0314C4B-6CBA-4D0F-B32F-24B450A0DDEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 | {A0314C4B-6CBA-4D0F-B32F-24B450A0DDEF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
41 | {A0314C4B-6CBA-4D0F-B32F-24B450A0DDEF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
42 | {A0314C4B-6CBA-4D0F-B32F-24B450A0DDEF}.Debug|x86.ActiveCfg = Debug|Any CPU
43 | {A0314C4B-6CBA-4D0F-B32F-24B450A0DDEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
44 | {A0314C4B-6CBA-4D0F-B32F-24B450A0DDEF}.Release|Any CPU.Build.0 = Release|Any CPU
45 | {A0314C4B-6CBA-4D0F-B32F-24B450A0DDEF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
46 | {A0314C4B-6CBA-4D0F-B32F-24B450A0DDEF}.Release|Mixed Platforms.Build.0 = Release|Any CPU
47 | {A0314C4B-6CBA-4D0F-B32F-24B450A0DDEF}.Release|x86.ActiveCfg = Release|Any CPU
48 | EndGlobalSection
49 | GlobalSection(SolutionProperties) = preSolution
50 | HideSolutionNode = FALSE
51 | EndGlobalSection
52 | EndGlobal
53 |
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.AllLibraries.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Forge.AllLibraries.dll
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.AllLibraries.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Forge.AllLibraries.pdb
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.Collections.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Forge.Collections.dll
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.Collections.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Forge.Collections.pdb
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.Collections.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Forge.Collections
5 |
6 |
7 |
8 |
9 | An unordered collection of items.
10 |
11 |
12 |
13 |
14 | Copies from the given bag into this one.
15 |
16 | The bag to copy from
17 |
18 |
19 |
20 | Creates a duplicate of this bag that has a different backing array.
21 |
22 |
23 |
24 |
25 | Returns the index of the given item in the bag, or -1 if it is not found.
26 |
27 |
28 |
29 |
30 | Removes the item at given index from the bag in O(1) time. This operation does not
31 | maintain the order of elements inside of the bag!
32 |
33 |
34 |
35 |
36 | Clears all stored items from this instance.
37 |
38 |
39 |
40 |
41 | Remove the item from the bag. This is O(n) and has to scan the bag to find the item.
42 |
43 | True if the item was found and removed, false otherwise.
44 |
45 |
46 |
47 | Returns true if the Bag contains an instance of the given item.
48 |
49 | The item to search for.
50 | True if it is in the bag, false otherwise.
51 |
52 |
53 |
54 | A set of items where only one is active and used.
55 |
56 | The type of item stored.
57 |
58 |
59 |
60 | The stored items
61 |
62 |
63 |
64 |
65 | The _currentKeyboardState item that we are accessing
66 |
67 |
68 |
69 |
70 | Initializes a new instance of the class.
71 |
72 | The number of instances to allocate
73 |
74 |
75 |
76 | Initializes a new instance of the class.
77 |
78 | The instances to swap between.
79 |
80 |
81 |
82 | Swaps out the _currentKeyboardState item for the next one.
83 |
84 | The item that was deactivated
85 |
86 |
87 |
88 | Gets the currently active item.
89 |
90 |
91 |
92 |
93 | Returns an item in the rotation queue that is relative to the current item by the given
94 | offset.
95 |
96 | How far away from the current item
97 |
98 |
99 |
100 |
101 | Provides a queue where pushing is assumed to be done concurrently, but reading is done in a
102 | single-thread where no writing is done.
103 |
104 | The type of object stored.
105 |
106 |
107 |
108 | All thread-local bags; this is used when iterating over the entire contents of the bag.
109 |
110 |
111 |
112 |
113 | The thread-local bag that is used for appending items.
114 |
115 |
116 |
117 |
118 | Used to set the value of CanWrite.
119 |
120 |
121 |
122 |
123 | Construct a new concurrent writer bag.
124 |
125 |
126 |
127 |
128 | Adds the item in the collection.
129 |
130 |
131 | This is a thread-safe function.
132 |
133 | The item to enqueue
134 |
135 |
136 |
137 | Returns all items inside of the bag as a list. This method is not thread safe. This
138 | method does *not* clear the collection.
139 |
140 |
141 |
142 |
143 | Calls the iterator over every item in the bag and then clears the bags that were
144 | iterated.
145 |
146 |
147 | This method is **NOT** thread-safe; do NOT call Add while iterating the items.
148 |
149 | The function to invoke on the items.
150 |
151 |
152 |
153 | Gets/sets if writing is enabled or disabled. Thread-safe. Provides debug diagnostics
154 | only and is not critical for correct behavior. This is set to false by the methods which
155 | read collections as they are doing their reading.
156 |
157 |
158 |
159 |
160 | Interface for objects which are monitoring a specific region.
161 |
162 |
163 |
164 |
165 | Called when the given item has entered the region.
166 |
167 |
168 |
169 |
170 | Called when an item has left the region.
171 |
172 |
173 |
174 |
175 | Returns true if this rect intersects with the parameter rect.
176 |
177 |
178 |
179 |
180 | Returns true if the given point is contained with this rect.
181 |
182 |
183 |
184 |
185 | Returns true if this rect fully contains the parameter rect.
186 |
187 |
188 |
189 |
190 | Returns true if this rect is either intersecting with or fully contains the parameter
191 | rect.
192 |
193 |
194 |
195 |
196 | The items that the node contains
197 |
198 |
199 |
200 |
201 | The monitors that watch for adds/removes in this node
202 |
203 |
204 |
205 |
206 | The width/height of each chunk
207 |
208 |
209 |
210 |
211 | All of the chunks
212 |
213 |
214 |
215 |
216 | Stores a list of items where the are gaps between items; not every index in the array
217 | contains an element.
218 |
219 |
220 |
221 |
222 | The internal array of elements inside of the array.
223 |
224 |
225 |
226 |
227 | Creates a new SparseArray with the default capacity.
228 |
229 |
230 |
231 |
232 | Creates a new SparseArray with the given capacity.
233 |
234 | The capacity to initialize with
235 |
236 |
237 |
238 | Creates a new sparse array from the given enumerator.
239 |
240 | The items to allocate the array from.
241 |
242 |
243 |
244 | Clears out all elements inside of the SparseArray.
245 |
246 |
247 |
248 |
249 | Removes the element at the given index.
250 |
251 | The index of the element to remove
252 | If an element was removed
253 |
254 |
255 |
256 | Checks to see if there is an element at the given index.
257 |
258 | The index to check.
259 | True if there is a contained element, false otherwise.
260 |
261 |
262 |
263 | Gets the value associated with the specified key.
264 |
265 | The key whose value to get.
266 | When this method returns, the value associated with the specified
267 | key, if the key is found; otherwise, the default value for the type of the
268 | parameter. This parameter is passed uninitialized.
269 | true if the object that implements
270 | contains an element with the
271 | specified key; otherwise, false.
272 |
273 |
274 |
275 | Ensures that index is a valid index into the Elements array.
276 |
277 | The index to verify.
278 |
279 |
280 |
281 | Returns an enumerator that iterates through the collection.
282 |
283 |
284 |
285 |
286 | Gets or sets the element at the given index.
287 |
288 | The index to set
289 | If getting, then the value at the given index.
290 |
291 |
292 |
293 | Contains two items which can be swapped between a Previous and a Current state.
294 |
295 | The type of item stored
296 |
297 |
298 |
299 | The first item
300 |
301 |
302 |
303 |
304 | The second item
305 |
306 |
307 |
308 |
309 | The current item
310 |
311 |
312 |
313 |
314 | Initializes a new instance of the class.
315 |
316 | The first item.
317 | The second item.
318 |
319 |
320 |
321 | Swap the Current and Previous items.
322 |
323 |
324 |
325 |
326 | The current item.
327 |
328 |
329 |
330 |
331 | The previous item.
332 |
333 |
334 |
335 |
336 | A list of items that is unordered. This provides O(1) addition, O(1) removal, and O(1)
337 | iteration. However, having all of these nice properties requires some metadata to be stored
338 | on each item, which means that Add takes a parameter of metadata for the stored item. Same
339 | with remove.
340 |
341 | The type of item to store.
342 |
343 |
344 |
345 | The stored list of items.
346 |
347 |
348 |
349 |
350 | Creates a new UnorderedList with the given capacity.
351 |
352 | The capacity to give to the list
353 |
354 |
355 |
356 | Checks to see if the given item is contained in the UnorderedList. This is O(1).
357 |
358 | The item to check
359 | The item's metadata
360 | True if the item is contained, false otherwise
361 |
362 |
363 |
364 | Removes the stored item.
365 |
366 | True if the item was removed, false otherwise
367 |
368 |
369 |
370 | Adds an item to the list. The location of the item in the list is unspecified.
371 |
372 |
373 |
374 |
375 | The number of stored objects in Items.
376 |
377 |
378 |
379 |
380 | Set or get the item at the specified index.
381 |
382 |
383 |
384 |
385 | Data stored inside of the UnorderedList.
386 |
387 |
388 |
389 |
390 |
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.Entities.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Forge.Entities.dll
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.Entities.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Forge.Entities.pdb
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.Extensions.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Forge.Extensions.dll
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.Extensions.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Forge.Extensions.pdb
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.Extensions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Forge.Extensions
5 |
6 |
7 |
8 |
9 | Common extensions of types which implement the IList[T] interface.
10 |
11 |
12 |
13 |
14 | Shuffle the specified list.
15 |
16 | The list to shuffle.
17 |
18 |
19 |
20 | Checks if the given list is empty.
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.Networking.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Forge.Networking.dll
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.Networking.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Forge.Networking.pdb
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.Networking.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Forge.Networking
5 |
6 |
7 |
8 |
9 | Supports turn-based games where there are a high number of game turns per second (>5) that
10 | are automatically ended.
11 |
12 |
13 |
14 |
15 | How much time has elapsed since the last time we popped an update?
16 |
17 |
18 |
19 |
20 | Accumulator used for clients when they are updating (so if we receive two updates really
21 | quickly, we don't want to actually execute those updates immediately; we instead want to
22 | wait until we can update them).
23 |
24 |
25 |
26 |
27 | How much time has elapsed since the last time we updated?
28 |
29 |
30 |
31 |
32 | How much time should elapse between updates for us to meet our target updates/second?
33 |
34 |
35 |
36 |
37 | Create a new AutomaticTurnGame.
38 |
39 | The networking context.
40 | The number of updates/turns that will occur every
41 | second.
42 |
43 |
44 |
45 | Clean up the game from the NetworkContext.
46 |
47 |
48 |
49 |
50 | Send the given set of game commands to the server. It will be processed at a later point
51 | by every client.
52 |
53 | The commands to send.
54 |
55 |
56 |
57 | Update the game. Potentially dispatch game commands for execution by all computers if
58 | enough time has elapsed.
59 |
60 | The amount of time that has elapsed since the last call to
61 | Update.
62 |
63 |
64 |
65 | The number of updates we second the game should run at.
66 |
67 |
68 |
69 |
70 | Configure the lag between giving input and actually receiving that input. A lower value
71 | will cause stuttering on slow networks, but user responsiveness will be higher. A higher
72 | value will cause less stuttering, but lower user responsiveness.
73 |
74 |
75 |
76 |
77 | Returns how far along we are until the next update.
78 |
79 |
80 |
81 |
82 | Client code that is executed upon the receipt of a network message.
83 |
84 |
85 |
86 |
87 | Handle a network message.
88 |
89 | The player that sent the message.
90 | The message itself (an instance of a type from
91 | HandledTypes) .
92 |
93 |
94 |
95 | The types that this message handler can process.
96 |
97 |
98 |
99 |
100 | Sends commands out for the network turn.
101 |
102 |
103 |
104 |
105 | If the local computer issues a command turn N, then the command will actually be
106 | executed on turn (N+TurnDelay). This parameter heavily impacts responsiveness. This
107 | value is only used on the server but can be changed by any computer on the network. A
108 | low value will mean that user input will get processed more quickly, but the game is
109 | more likely to stutter from a missed update.
110 |
111 |
112 |
113 |
114 | Helper class that simplifies the management of delayed messages.
115 |
116 | The type of message to store.
117 |
118 |
119 |
120 | Construct a new circular queue with the given capacity.
121 |
122 | How big the queue should be.
123 |
124 |
125 |
126 | Read only value to get the current turn delay that the server is using.
127 |
128 |
129 |
130 |
131 | Does the client has an update ready to be executed?
132 |
133 |
134 |
135 |
136 | Does the client have a large backlog of updates that are waiting to be executed?
137 |
138 |
139 |
140 |
141 | A message transmitted over the network. Network messages are always transmitted in order and
142 | reliably.
143 |
144 |
145 |
146 |
147 | Every command (from every computer) that should be issued.
148 |
149 |
150 |
151 |
152 | The update the commands should be issued on.
153 |
154 |
155 |
156 |
157 | Message that goes from clients to the server specifying commands that have been issued.
158 |
159 |
160 |
161 |
162 | The requested commands to issue.
163 |
164 |
165 |
166 |
167 | The update number that the command was submitted on.
168 |
169 |
170 |
171 |
172 | Message that only the server processes to adjust the turn delay.
173 |
174 |
175 |
176 |
177 | The new delay for the game.
178 |
179 |
180 |
181 |
182 | An IGameCommand is some user input that modifies game state during a turn. This interface is
183 | not implemented internally; instead it gives some type safety for the API (otherwise only
184 | object could be used as parameter types).
185 |
186 |
187 |
188 |
189 | Processes ChatNetworkMessages and adds them to a displayable message list depending on if
190 | the local player should be allowed to see the message.
191 |
192 |
193 |
194 |
195 | The local player.
196 |
197 |
198 |
199 |
200 | All received chat messages.
201 |
202 |
203 |
204 |
205 | All chat messages that should be displayed.
206 |
207 |
208 |
209 |
210 | Returns true if this computer should display the message for the given set of message
211 | receivers.
212 |
213 |
214 |
215 |
216 | A network message that is used when sending chat messages.
217 |
218 |
219 |
220 |
221 | The content of the chat message.
222 |
223 |
224 |
225 |
226 | The player that sent the message.
227 |
228 |
229 |
230 |
231 | Specifies what players should see the given message. This will be empty if every player
232 | should see the message, and non-empty if not everyone should see it.
233 |
234 |
235 |
236 |
237 | A chat message that has been received.
238 |
239 |
240 |
241 |
242 | The time that the message was received.
243 |
244 |
245 |
246 |
247 | The player that sent the message.
248 |
249 |
250 |
251 |
252 | The content of the message.
253 |
254 |
255 |
256 |
257 | This class contains Lidgren.Network configuration settings that are used when creating
258 | NetPeer (typically either a NetServer or a NetClient type) instances.
259 |
260 |
261 |
262 |
263 | The port that is used when hosting.
264 |
265 |
266 |
267 |
268 | Global application name that is used to distinguish Forge.
269 |
270 |
271 |
272 |
273 | Contains the core APIS for sending and receiving chat messages.
274 |
275 |
276 |
277 |
278 | The networking context to use for retrieving our local player and for adding our
279 | ChatNetworkMessage handler.
280 |
281 |
282 |
283 |
284 | The ChatMessageHandler we use to get chat messages from.
285 |
286 |
287 |
288 |
289 | Construct a new ChatManager using the given networking context and the given object for
290 | mapping network players to a directed player relation graph.
291 |
292 | The networking context.
293 |
294 |
295 |
296 | Cleans up the ChatManager from the NetworkContext it was constructed with.
297 |
298 |
299 |
300 |
301 | Send a chat message to all players that have the given relationship with the sending
302 | player.
303 |
304 | The message to send.
305 | The players that should receive the message.
306 |
307 |
308 |
309 | Sends a chat message to every player.
310 |
311 | The message to send.
312 |
313 |
314 |
315 | All of the chat messages that have been received that should be displayed.
316 |
317 |
318 |
319 |
320 | All received chat messages.
321 |
322 |
323 |
324 |
325 | The hosting player.
326 |
327 |
328 |
329 |
330 | The title of the game.
331 |
332 |
333 |
334 |
335 | Contains information about a running server.
336 |
337 |
338 |
339 |
340 | The player that is hosting the server.
341 |
342 |
343 |
344 |
345 | The title of the server.
346 |
347 |
348 |
349 |
350 | The IP that can be used to connect to the server.
351 |
352 |
353 |
354 |
355 | This class makes it simple to automatically discover servers that are running on the local
356 | network.
357 |
358 |
359 |
360 |
361 | The NetClient we use to run the discovery service.
362 |
363 |
364 |
365 |
366 | The servers that we have discovered.
367 |
368 |
369 |
370 |
371 | Attempts to discover all running servers on the local network. DiscoveredLocalServers
372 | will contain the result; it may change over time.
373 |
374 |
375 |
376 |
377 | Clears out the list of discovered servers.
378 |
379 |
380 |
381 |
382 | Returns a list containing all servers that have been discovered thus far.
383 |
384 |
385 |
386 |
387 | Object that monitors the connection and disconnection of other computers.
388 |
389 |
390 |
391 |
392 | The given player has connected.
393 |
394 |
395 |
396 |
397 | The given player has disconnected.
398 |
399 |
400 |
401 |
402 | Common code for LobbyMember and LobbyHost.
403 |
404 |
405 |
406 |
407 | The network context that we use for core networking operations.
408 |
409 |
410 |
411 |
412 | Message handler used to determine if we've received a LobbyLaunchedNetworkMessage.
413 |
414 |
415 |
416 |
417 | Get all members of the lobby, including the host.
418 |
419 |
420 |
421 |
422 | Is the given player the host of the lobby?
423 |
424 |
425 |
426 |
427 | Dispose the lobby.
428 |
429 |
430 |
431 |
432 | Returns true if the lobby has launched. Make sure to dispose of the lobby.
433 |
434 | True if the lobby has launched, false if it hasn't.
435 |
436 |
437 |
438 | Try to launch the lobby. All players have to be ready in order to launch.
439 |
440 |
441 | You can also use HasLaunched to determine if the lobby has started. However, HasLaunched
442 | will not actually start the game and will only return the lobby launch status.
443 |
444 | True if the launch attempt was successful, false otherwise.
445 |
446 |
447 |
448 | Host a new lobby.
449 |
450 | The player that is creating the server.
451 | The settings to use for the lobby.
452 | A lobby host if successful.
453 |
454 |
455 |
456 | Change the map.
457 |
458 |
459 |
460 |
461 | Kick the given lobby member from the lobby.
462 |
463 | The member to kick.
464 |
465 |
466 |
467 | Return players that are not ready.
468 |
469 |
470 |
471 |
472 | Settings used for creating a lobby.
473 |
474 |
475 |
476 |
477 | The password required for entering the lobby. Use an empty string for "no" password.
478 |
479 |
480 |
481 |
482 | The serialized map that the lobby is hosting, ie, the data that lobby members will
483 | download.
484 |
485 |
486 |
487 |
488 | Map manager used to get hashes for serialized maps.
489 |
490 |
491 |
492 |
493 | The sending client is ready to launch the game.
494 |
495 |
496 |
497 |
498 | The sending client is not ready to launch the game.
499 |
500 |
501 |
502 |
503 | Handles network messages for determining if every player is ready to launch the game.
504 |
505 |
506 |
507 |
508 | Players that are ready to launch.
509 |
510 |
511 |
512 |
513 | Players that are not ready to launch.
514 |
515 |
516 |
517 |
518 | The networking context.
519 |
520 |
521 |
522 |
523 | Returns true if every player is ready.
524 |
525 |
526 |
527 |
528 | Network message sent when the lobby has been launched.
529 |
530 |
531 |
532 |
533 | Network message sent by the lobby server to verify that all clients have the given map.
534 |
535 |
536 |
537 |
538 | The hash code for the map, used to check to see if we need to download it.
539 |
540 |
541 |
542 |
543 | Network message sent by a lobby client to request a map download.
544 |
545 |
546 |
547 |
548 | Network message sent to lobby clients by the lobby server after the lobby server has
549 | received a LobbyMapDownloadedRequestedNetworkMessage.
550 |
551 |
552 |
553 |
554 | Processes map download request messages and also sends map verification messages to new
555 | clients. Supports changing the current map (which causes a rebroadcast for map
556 | verification) .
557 |
558 |
559 |
560 |
561 | Interface used to check if a map exists and optionally save a downloaded map if one does
562 | not.
563 |
564 |
565 |
566 |
567 | Map download handler for the lobby client. Receives map verification messages and map
568 | download messages. If the verification message fails, then a map download request message is
569 | sent to the server.
570 |
571 |
572 |
573 |
574 | A member of a lobby.
575 |
576 |
577 |
578 |
579 | Try to join the lobby at the given IP end point as the given player.
580 |
581 | The IP address that the lobby server is running at.
582 | The map manager that will be used to check to see if we have a
583 | map and to save a downloaded map.
584 | This player that will be used to uniquely identify
585 | ourselves.
586 | The password that the lobby host has set.
587 |
588 |
589 |
590 | The given player has joined the network.
591 |
592 |
593 |
594 |
595 | The given player has left the network.
596 |
597 |
598 |
599 |
600 | Specifies which computers an INetworkMessage should be delivered to.
601 |
602 |
603 |
604 |
605 | All computers process the message. Each computer will processes each message in the same
606 | order. That is, computer A sends message A, and computer B sends message B, both
607 | computers will process both messages in the same order (whether it be A then B or B then
608 | A is undefined, but both computers will select the same (a,b) or (b,a) group).
609 |
610 |
611 | In regards to implementation details, this message type requires that the message be
612 | sent to the server before any computer can process it (for ordering purposes). The
613 | server then rebroadcasts the message to every computer for execution. This is not
614 | particularly lightweight, but it does simplify networking logic.
615 |
616 |
617 |
618 |
619 | The message should be processed by *only* the server. This message type can only be sent
620 | by any computer in the network, whether it be a client or a server.
621 |
622 |
623 |
624 |
625 | The message should be processed by all clients but *not* the server. This message type
626 | can only be sent by the server.
627 |
628 |
629 |
630 |
631 | A network player is an abstraction over a network connection.
632 |
633 |
634 |
635 |
636 | The name that the player gave themselves.
637 |
638 |
639 |
640 |
641 | The GUID that uniquely identifies this player. This GUID can be per-session and does not
642 | need to be permanent.
643 |
644 |
645 |
646 |
647 | Determines whether the specified see cref="System.Object" }, is equal to this instance.
648 |
649 | The to compare with this
650 | instance.
651 | true if the specified is equal to this
652 | instance; otherwise, /c>.
653 |
654 |
655 |
656 | Returns a hash code for this instance.
657 |
658 | A hash code for this instance, suitable for use in hashing algorithms and data
659 | structures like a hash table.
660 |
661 |
662 |
663 | Base type that all INetworkMessageHandlers should extend from (for a simplified API).
664 |
665 | The type of message that this handler handles.
666 |
667 |
668 |
669 | Holds important information about the current network connection and additionally about
670 | INetworkMessage listeners.
671 |
672 |
673 |
674 |
675 | Enumerable container that merely contains LocalPlayer.
676 |
677 |
678 |
679 |
680 | If the context is a client, then this is the Lidgren.Network client object.
681 |
682 |
683 |
684 |
685 | If we're a server, then this is the password for the server.
686 |
687 |
688 |
689 |
690 | If we're a server, this is the list of objects which want to know when a client has
691 | connected or disconnected.
692 |
693 |
694 |
695 |
696 | Networking dispatcher that is used for sending messages.
697 |
698 |
699 |
700 |
701 | Private constructor for NetworkContext; NetworkContexts can only be created using the
702 | static helper methods.
703 |
704 | The local player
705 |
706 |
707 |
708 | Creates a new server.
709 |
710 | The player that is running this server.
711 | The password that clients have to have to connect.
712 | A network context for the created server.
713 |
714 |
715 |
716 | Tries to fetch all possible IPs that might be possible for clients to connect to the
717 | server with. This operation throws an exception if the context is not a server.
718 |
719 |
720 |
721 |
722 | Creates a new client connection connected to the given IP end point. This method blocks
723 | until we know if the client has either connected or disconnected.
724 |
725 | The IP to connect to.
726 | This computer's player.
727 | The password that the server is expecting.
728 |
729 |
730 |
731 |
732 | Returns true if the given Player is the server.
733 |
734 | The player to check.
735 | True if the player is the server, otherwise false.
736 |
737 |
738 |
739 | Kicks the given player. This function is only operable if the context is a server
740 | (otherwise an exception is thrown).
741 |
742 | The player to kick.
743 |
744 |
745 |
746 | Adds the given message handler to the network context.
747 |
748 | The network message handler to add.
749 |
750 |
751 |
752 | Removes the given message handler from the context. If the dispatcher was not previously
753 | contained in the context, then an exception is thrown.
754 |
755 | The network message handler to remove.
756 |
757 |
758 |
759 | Add a new connection monitor listener. This allows for client code to be notified when
760 | another player connects or disconnects from the network.
761 |
762 | The connection monitor to add.
763 |
764 |
765 |
766 | Remove a previously added connection monitor. If the monitor was not found when removing
767 | it, an exception is thrown.
768 |
769 | The connection monitor to remove.
770 |
771 |
772 |
773 | Update the network context; ie, invoke handlers for received network messages if we're a
774 | client or broadcast out received messages if we're a server.
775 |
776 |
777 |
778 |
779 | Send the given message to the given recipients.
780 |
781 | The computers that should receive the message.
782 | The message to send.
783 |
784 |
785 |
786 | Send the given message to only the specified recipient.
787 |
788 | The player that should receive the message.
789 | Who to send the message to.
790 |
791 |
792 |
793 | Creates an outgoing message with the given sender, message, broadcast state.
794 |
795 | The player who is sending this message.
796 | The message to send.
797 | If the server receives this message, should it broadcast it out
798 | to all clients?
799 |
800 |
801 |
802 | Helper method to lookup the network connection based on the given network player.
803 |
804 |
805 |
806 |
807 | If the context is a server, then this is the Lidgren.Network server object.
808 |
809 |
810 |
811 |
812 | Returns the internal NetPeer instance that represents the core connection.
813 |
814 |
815 |
816 |
817 | Returns true if this NetworkConext is acting as a server.
818 |
819 |
820 |
821 |
822 | Returns true if this NetworkContext is acting as a client.
823 |
824 |
825 |
826 |
827 | The local player.
828 |
829 |
830 |
831 |
832 | Message format for NetIncomingMessageType.Data
833 |
834 |
835 |
836 |
837 | Hail message format used when connecting to a server.
838 |
839 |
840 |
841 |
842 | The player connecting.
843 |
844 |
845 |
846 |
847 | The password to use when connecting.
848 |
849 |
850 |
851 |
852 | This class serves as a registry for INetworkMessageHandlers. It supports efficient lookup of
853 | message type to message handler responders.
854 |
855 |
856 | In the overall context of Forge.Network, this class serves a critical function as the core
857 | mechanism for the event-based message processing loop. The NetworkContext is the primary
858 | user of this type. NetworkContext receives and sends out INetworkMessages; when it receives
859 | an INetworkMessage, it checks its NetworkMessageDispatcher to see if there are any handlers
860 | that need to be invoked.
861 |
862 |
863 |
864 |
865 | The message handlers; the key is the type of message, and the value is the list of
866 | handlers that can respond to that message type.
867 |
868 |
869 |
870 |
871 | Create a new NetworkMessageDispatcher that has no registered message handlers.
872 |
873 |
874 |
875 |
876 | Helper method to get all message handlers that can respond to the given message type.
877 |
878 |
879 |
880 |
881 | Adds a message handler.
882 |
883 | The handler to add.
884 |
885 |
886 |
887 | Remove the message handler. Throws an exception if the handler was not previously added.
888 |
889 | The handler to remove.
890 |
891 |
892 |
893 | Invoke all registered INetworkMessageHandlers for the given message and sender.
894 |
895 |
896 |
897 |
898 | API for interacting with the pausing subsystem.
899 |
900 |
901 |
902 |
903 | Network context that we use to transmit pause messages.
904 |
905 |
906 |
907 |
908 | Message handler that processes the pause messages.
909 |
910 |
911 |
912 |
913 | Create a new PauseManager instance.
914 |
915 | The networking context to use.
916 |
917 |
918 |
919 | Cleans up resources that the PauseManager uses in the NetworkContext.
920 |
921 |
922 |
923 |
924 | Returns the current pause status for the game. Setting this value emits a network
925 | message that changes the pause status to the given value for all computers in the
926 | network.
927 |
928 |
929 |
930 |
931 | If the game is paused, then this returns who paused the game. If the game is not paused,
932 | then this returns nothing.
933 |
934 |
935 |
936 |
937 | Updates the pause status when SetPauseStatusNetworkMessages are received.
938 |
939 |
940 |
941 |
942 | Getter/setter for if the game is paused.
943 |
944 |
945 |
946 |
947 | Returns who paused the game if it is paused.
948 |
949 |
950 |
951 |
952 | Network message to set the current pause status for the game.
953 |
954 |
955 |
956 |
957 |
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.Utilities.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Forge.Utilities.dll
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.Utilities.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Forge.Utilities.pdb
--------------------------------------------------------------------------------
/XNA/DLLs/Forge.Utilities.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Forge.Utilities
5 |
6 |
7 |
8 |
9 | Thread-safe activation trigger that only activates once.
10 |
11 |
12 | In a sense, this is equivalent to extending Interlocked to operate on booleans.
13 |
14 |
15 |
16 |
17 | An activated activation state
18 |
19 |
20 |
21 |
22 | A deactivated activation state.
23 |
24 |
25 |
26 |
27 | Have we been activated?
28 |
29 |
30 |
31 |
32 | Initializes a new instance of the AtomicActivation class in an unactivated state.
33 |
34 |
35 |
36 |
37 | Resets the activation state, so that Activate() will return true on then next call.
38 |
39 |
40 |
41 |
42 | Returns true if the activation state was previously unactivated.
43 |
44 | True if the activation activated for this call
45 |
46 |
47 |
48 | Returns true if the current activation state is activated.
49 |
50 |
51 |
52 |
53 | Returns true if this bound is either intersecting or colliding with the other bound.
54 |
55 |
56 |
57 |
58 | Returns true if the given point is contained within this bound.
59 |
60 |
61 |
62 |
63 | Returns true if the given point is contained within this bound.
64 |
65 |
66 |
67 |
68 | Provides methods which format a string without garbage allocation.
69 |
70 |
71 | The format strings only go from {0} to {9} and do not support any customizations.
72 | Backslashes are also not supported.
73 |
74 |
75 |
76 |
77 | Returns a random long from min (inclusive) to max (exclusive)
78 |
79 | The given random instance
80 | The inclusive minimum bound
81 | The exclusive maximum bound. Must be greater than min
82 |
83 |
84 |
85 | Returns a random long from 0 (inclusive) to max (exclusive)
86 |
87 | The given random instance
88 | The exclusive maximum bound. Must be greater than 0
89 |
90 |
91 |
92 | Returns a random long over all possible values of long (except long.MaxValue, similar to
93 | random.Next())
94 |
95 | The given random instance
96 |
97 |
98 |
99 | Log messages.
100 |
101 |
102 |
103 |
104 | Get a logger for the given type.
105 |
106 |
107 |
108 |
109 | Log messages.
110 |
111 | The type that is sending the log message
112 |
113 |
114 |
115 | The log4net logger used to log messages.
116 |
117 |
118 |
119 |
120 | Helper for Maybe[T] by providing local type inference at Just and Empty call sites.
121 |
122 |
123 |
124 |
125 | Returns a new Maybe instance containing the given value.
126 |
127 |
128 |
129 |
130 | Returns a maybe instance that is empty.
131 |
132 | The type of the maybe instance.
133 | An empty Maybe[T] instance.
134 |
135 |
136 |
137 | Some common extensions for the maybe class.
138 |
139 |
140 |
141 |
142 | Lifts a maybe into another maybe using the given lifting function. If the given maybe is
143 | empty, then an empty maybe is returned.
144 |
145 | The type of the original maybe The
146 | type of the new maybe
147 | The maybe to transform
148 | The lifting function that will transform the maybe
149 | A new maybe created by the lifting function
150 |
151 |
152 |
153 | Lifts a maybe into another maybe using the given lifting function. If the given maybe is
154 | empty, then an empty maybe is returned.The returned maybe is never empty.
155 |
156 | The type of the original maybe The
157 | type of the new maybe
158 | The maybe to transform
159 | The lifting function that will transform the maybe
160 | A new maybe created by the lifting function
161 |
162 |
163 |
164 | C# has a limitation where non-reference generic types cannot be contravariant (the Maybe
165 | generic type should be contravariant). This function eases that limitation by providing
166 | automatic casting to a higher Maybe type.
167 |
168 |
169 |
170 |
171 | Maybe wraps another type and is used to signal to other code that it might not return a
172 | result. It performs the same function as null, but in a more type-safe manner that provides
173 | more clarity into the contract that function exhibits.
174 |
175 | The type of value stored in the Maybe instance
176 |
177 |
178 |
179 | The stored value in the maybe instance. Only contains interesting data if _hasValue is
180 | true (otherwise the data is garbage).
181 |
182 |
183 |
184 |
185 | True if the maybe instance is currently holding a value.
186 |
187 |
188 |
189 |
190 | Creates a new Maybe container that holds the given value.
191 |
192 |
193 |
194 |
195 | Internal constructor used to construct the maybe. Used primarily in construction of the
196 | Empty element.
197 |
198 |
199 |
200 |
201 | Default empty instance.
202 |
203 |
204 |
205 |
206 | Gets the underlying value.
207 |
208 |
209 | If IsEmpty returns true, then this method will throw an InvalidOperationException.
210 |
211 |
212 |
213 |
214 | Returns true if this Maybe has a value stored in it.
215 |
216 |
217 |
218 |
219 | Returns true if this Maybe is empty, it, it does not have a value stored in it.
220 |
221 |
222 |
223 |
224 | An object that can be used as a value in a GeneralStreamingContext instance.
225 |
226 |
227 |
228 |
229 | Object that implements the streaming context that all converters which expect a streaming
230 | context expect the streaming context to be a type of.
231 |
232 |
233 |
234 |
235 | The context objects
236 |
237 |
238 |
239 |
240 | Creates a new GeneralStreamingContext with the given initial objects.
241 |
242 |
243 |
244 |
245 | Returns the context object associated with the type T.
246 |
247 |
248 |
249 |
250 | Sets the context object of type T to an instance of new T().
251 |
252 |
253 |
254 |
255 | Sets the context object of type T with the given value.
256 |
257 |
258 |
259 |
260 | Removes the context object associated with type T.
261 |
262 |
263 |
264 |
265 | Wraps the notification pattern, where something happens multiple times but the listeners
266 | should only be notified once.
267 |
268 |
269 | The Notifier API is thread-safe.
270 |
271 | The type of the parameter.
272 |
273 |
274 |
275 | Have we already notified the listeners?
276 |
277 |
278 |
279 |
280 | Parameter to notify listeners with.
281 |
282 |
283 |
284 |
285 | Initializes a new instance of the class.
286 |
287 | The parameter to notify listeners with.
288 |
289 |
290 |
291 | Resets this notifier so that it will notify listeners again.
292 |
293 |
294 |
295 |
296 | Notify the listeners if they have not already been notified.
297 |
298 |
299 |
300 |
301 | Allows objects to listen for notifications. If the notifier has already been triggered,
302 | then the added listener is immediately called.
303 |
304 |
305 |
306 |
307 | A PropertyMetadata describes a discovered property or field in a TypeMetadata.
308 |
309 |
310 |
311 |
312 | The cached name of the property/field.
313 |
314 |
315 |
316 |
317 | Writes a value to the property that this property metadata represents, using given
318 | object instance as the context.
319 |
320 |
321 |
322 |
323 | Reads a value from the property that this property metadata represents, using the given
324 | object instance as the context.
325 |
326 |
327 |
328 |
329 | The type of value that is stored inside of the property. For example, for an int field,
330 | StorageType will be typeof(int).
331 |
332 |
333 |
334 |
335 | Initializes a new instance of the PropertyMetadata class from a property member.
336 |
337 |
338 |
339 |
340 | Initializes a new instance of the PropertyMetadata class from a field member.
341 |
342 |
343 |
344 |
345 | Determines whether the specified object is equal to this one.
346 |
347 |
348 |
349 |
350 | Determines whether the specified object is equal to this one.
351 |
352 |
353 |
354 |
355 | Returns a hash code for this instance.
356 |
357 | A hash code for this instance, suitable for use in hashing algorithms and data
358 | structures like a hash table.
359 |
360 |
361 |
362 | The member info that we read to and write from.
363 |
364 |
365 |
366 |
367 | A Real value implements floating point operations on the CPU. It does not adhere any any
368 | IEEE standard, but has the extremely important attribute of providing identical semantics on
369 | every CPU which executes it. This is otherwise impossible to guarantee in the CLR,
370 | especially when 3rd party code is running and/or C++ DLL access is unavailable to set x87
371 | FPU rounding modes.
372 |
373 |
374 |
375 |
376 | Assuming this real has a base 10 representation, this shifts the decimal value to the
377 | left by count digits.
378 |
379 |
380 |
381 |
382 | Returns the number of digits in the given value. The negative sign is not considered a
383 | digit.
384 |
385 |
386 |
387 |
388 | Creates a real value with that is 0.number. For example, CreateDecimal(123) will create
389 | a real value that is equal to "0.123".
390 |
391 |
392 | CreateDecimal(1, 0005, 4) will create 1.0005 CreateDecimal(1, 5, 4) will create 1.0005
393 |
394 |
395 |
396 |
397 |
398 | Create a fixed-int number from parts. For example, to create 1.5 pass in 1 and 500.
399 |
400 | The number above the decimal. For 1.5, this would be 1.
401 | The number below the decimal, to three digits. For 1.5, this
402 | would be 500. For 1.005, this would be 5.
403 | A fixed-int representation of the number parts
404 |
405 |
406 |
407 | Serializes Real values to JSON and back as floats. Without using a converter, Reals
408 | would be serialized as an object ({}) which would create a lot of unnecessary bloat.
409 |
410 |
411 |
412 |
413 | Container type that holds a reference to another object.
414 |
415 | The type of object to store a reference to.
416 |
417 |
418 |
419 | Helper methods for Newtonsoft.JSON
420 |
421 |
422 |
423 |
424 | Returns the two arrays merged together.
425 |
426 |
427 |
428 |
429 | Helper method to create the JsonSerializerSettings that all of the serialization methods
430 | use.
431 |
432 | The converters to use in the settings.
433 | Context objects to use
434 | An appropriate JsonSerializerSettings instance.
435 |
436 |
437 |
438 | Returns a deep clone of the given object instance.
439 |
440 | The type of object to clone.
441 | The original object to clone.
442 | Specific JSON converters to use when deserializing the
443 | object.
444 | Initial context objects to use when deserializing
445 | An identical clone to the given instance.
446 |
447 |
448 |
449 | Returns a deep clone of the given object instance.
450 |
451 | The type of object to clone.
452 | The original object to clone.
453 | An identical clone to the given instance.
454 |
455 |
456 |
457 | Returns the serialized version of the given instance, optionally using the given
458 | converters during the serialization process.
459 |
460 | The type of object to serialize.
461 | The object instance itself to serialize.
462 | The converters to use during the serialization process.
463 | Context objects to use
464 | A serialized version of the given object.
465 |
466 |
467 |
468 | Returns the serialized version of the given instance, optionally using the given
469 | converters during the serialization process.
470 |
471 | The type of object to serialize.
472 | The object instance itself to serialize.
473 | A serialized version of the given object.
474 |
475 |
476 |
477 | Deserializes the given JSON data (hopefully created using Serialize for maximal
478 | compatibility) into an object instance of type T.
479 |
480 | The type of the object to deserialize.
481 | The serialized state of the object.
482 | Converters to use during the deserialization process.
483 | Context objects to use
484 | A deserialized object of type T (or a derived type) that was generated from the
485 | given JSON data.
486 |
487 |
488 |
489 | Deserializes the given JSON data (hopefully created using Serialize for maximal
490 | compatibility) into an object instance of type T.
491 |
492 | The type of the object to deserialize.
493 | The serialized state of the object.
494 | A deserialized object of type T (or a derived type) that was generated from the
495 | given JSON data.
496 |
497 |
498 |
499 | We completely override how Json.NET serializes types
500 |
501 |
502 |
503 |
504 | Discover types, even if they are not in the proper assembly.
505 |
506 |
507 |
508 |
509 | Singleton instance
510 |
511 |
512 |
513 |
514 | Caches type name to type lookups. Type lookups occur in all loaded assemblies.
515 |
516 |
517 |
518 |
519 | Cache from fully qualified type name to type instances.
520 |
521 |
522 |
523 |
524 | Cache from Type to the respective TypeMetadata.
525 |
526 |
527 |
528 |
529 | Assemblies indexed by their name.
530 |
531 |
532 |
533 |
534 | Does a direct lookup for the given type, ie, goes directly to the assembly identified by
535 | assembly name and finds it there.
536 |
537 | The assembly to find the type in.
538 | The name of the type.
539 | The found type.
540 | True if the type was found, false otherwise.
541 |
542 |
543 |
544 | Tries to do an indirect type lookup by scanning through every loaded assembly until the
545 | type is found in one of them.
546 |
547 | The name of the type.
548 | The found type.
549 | True if the type was found, false otherwise.
550 |
551 |
552 |
553 | Find a type with the given name. An exception is thrown if no type with the given name
554 | can be found. This method searches all currently loaded assemblies for the given type.
555 |
556 | The fully qualified name of the type.
557 | A hint for the assembly to start the search with
558 |
559 |
560 |
561 | Finds the associated TypeMetadata for the given type.
562 |
563 | The type to find the type metadata for.
564 | A TypeMetadata that models the given type.
565 |
566 |
567 |
568 | Extensions to the Type API.
569 |
570 |
571 |
572 |
573 | Searches for a particular implementation of the given interface type inside of the type.
574 | This is particularly useful if the interface type is an open type, ie, typeof(IFace[]),
575 | because this method will then return IFace[] but with appropriate type parameters
576 | inserted.
577 |
578 | The base type to search for interface
579 | The interface type to search for. Can be an open generic
580 | type.
581 | The actual interface type that the type contains, or null if there is no
582 | implementation of the given interfaceType on type.
583 |
584 |
585 |
586 | Returns true if the baseType is an implementation of the given interface type. The
587 | interface type can be generic.
588 |
589 | The type to search for an implementation of the given
590 | interface
591 | The interface type to search for
592 |
593 |
594 |
595 |
596 | Provides a view of an arbitrary type that unifies a number of discrete concepts in the CLR.
597 | Arrays and Collection types have special support, but their APIs are unified by the
598 | TypeMetadata so that they can be treated as if they were a regular type.
599 |
600 |
601 |
602 |
603 | Creates a new instance of the type that this metadata points back to.
604 |
605 |
606 | Activator.CreateInstance cannot be used because TypeMetadata can point to an Array.
607 |
608 |
609 |
610 |
611 | Hint that there will be size number of elements stored in the given collection. This
612 | method is completely optional, but if the collection is an array then it will improve
613 | the performance of AppendValue.
614 |
615 | The collection type.
616 | The size hint to use for the collection
617 |
618 |
619 |
620 | Appends a value to the end of the array or collection. If the collection is an array,
621 | then the item is added to array[indexHint]. If it is a collection, then the item is just
622 | appended to the end of the collection.
623 |
624 |
625 |
626 |
627 | Initializes a new instance of the TypeMetadata class from a type. Use TypeCache to get
628 | instances of TypeMetadata; do not use this constructor directly.
629 |
630 |
631 |
632 |
633 | Recursive method that adds all of the properties and fields from the given type into the
634 | given list. This method also fetches inherited properties by using the TypeCache to
635 | retrieve the TypeMetadata for the parent type.
636 |
637 | The type to process to collect properties from.
638 | The list of properties that should be appended to
639 |
640 |
641 |
642 | The cached Add method in ICollection[T]. This only contains a value if IsCollection is
643 | true.
644 |
645 |
646 |
647 |
648 | True if the base type is an array. If true, accessing Properties will throw an
649 | exception. IsCollection is also true if _isArray is true.
650 |
651 |
652 |
653 |
654 | Attempts to remove the property with the given name.
655 |
656 | The name of the property to remove.
657 | True if the property was removed, false if it was not found.
658 |
659 |
660 |
661 | The type that this metadata is modeling, ie, the type that the metadata was constructed
662 | off of.
663 |
664 |
665 |
666 |
667 | Iff this metadata maps back to a Collection or an Array type, then this is the type of
668 | element stored inside the array or collection. Otherwise, this method throws an
669 | exception.
670 |
671 |
672 |
673 |
674 | True if the base type is a collection. If true, accessing Properties will throw an
675 | exception.
676 |
677 |
678 |
679 |
680 | The properties on the type. This is used when importing/exporting a type that does not
681 | have a user-defined importer/exporter.
682 |
683 |
684 |
685 |
686 | Generates unique integers that are sequential. This class is thread-safe.
687 |
688 |
689 |
690 |
691 | The next integer to generate.
692 |
693 |
694 |
695 |
696 | Returns the next unique int.
697 |
698 |
699 |
700 |
701 | Notifies that UniqueIdGenerator that the given ID has already been consumed. Please note
702 | that this API is not thread-safe.
703 |
704 |
705 |
706 |
707 | Swaps two ref objects.
708 |
709 | The type of objects to swap.
710 | Object a
711 | Object b
712 |
713 |
714 |
715 |
--------------------------------------------------------------------------------
/XNA/DLLs/Lidgren.Network.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Lidgren.Network.dll
--------------------------------------------------------------------------------
/XNA/DLLs/Lidgren.Network.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Lidgren.Network.pdb
--------------------------------------------------------------------------------
/XNA/DLLs/Newtonsoft.Json.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Newtonsoft.Json.dll
--------------------------------------------------------------------------------
/XNA/DLLs/Newtonsoft.Json.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/Newtonsoft.Json.pdb
--------------------------------------------------------------------------------
/XNA/DLLs/log4net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/DLLs/log4net.dll
--------------------------------------------------------------------------------
/XNA/XNA/ExtendedSpriteBatch.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Xna.Framework;
2 | using Microsoft.Xna.Framework.Graphics;
3 | using System;
4 |
5 | namespace XNA.GameSample {
6 | ///
7 | /// An extended version of the SpriteBatch class that supports line and rectangle drawing.
8 | ///
9 | ///
10 | /// This class has been taken from http://stackoverflow.com/a/7863816
11 | ///
12 | public class ExtendedSpriteBatch : SpriteBatch {
13 | ///
14 | /// The texture used when drawing rectangles, lines and other primitives. This is a 1x1
15 | /// white texture created at runtime.
16 | ///
17 | public Texture2D WhiteTexture { get; protected set; }
18 |
19 | public ExtendedSpriteBatch(GraphicsDevice graphicsDevice)
20 | : base(graphicsDevice) {
21 | this.WhiteTexture = new Texture2D(this.GraphicsDevice, 1, 1);
22 | this.WhiteTexture.SetData(new Color[] { Color.White });
23 | }
24 |
25 | ///
26 | /// Draw a line between the two supplied points.
27 | ///
28 | /// Starting point.
29 | /// End point.
30 | /// The draw color.
31 | public void DrawLine(Vector2 start, Vector2 end, Color color) {
32 | float length = (end - start).Length();
33 | float rotation = (float)Math.Atan2(end.Y - start.Y, end.X - start.X);
34 | this.Draw(this.WhiteTexture, start, null, color, rotation, Vector2.Zero, new Vector2(length, 1), SpriteEffects.None, 0);
35 | }
36 |
37 | ///
38 | /// Draw a rectangle.
39 | ///
40 | /// The rectangle to draw.
41 | /// The draw color.
42 | public void DrawRectangle(Rectangle rectangle, Color color) {
43 | this.Draw(this.WhiteTexture, new Rectangle(rectangle.Left, rectangle.Top, rectangle.Width, 1), color);
44 | this.Draw(this.WhiteTexture, new Rectangle(rectangle.Left, rectangle.Bottom, rectangle.Width, 1), color);
45 | this.Draw(this.WhiteTexture, new Rectangle(rectangle.Left, rectangle.Top, 1, rectangle.Height), color);
46 | this.Draw(this.WhiteTexture, new Rectangle(rectangle.Right, rectangle.Top, 1, rectangle.Height + 1), color);
47 | }
48 |
49 | ///
50 | /// Fill a rectangle.
51 | ///
52 | /// The rectangle to fill.
53 | /// The fill color.
54 | public void FillRectangle(Rectangle rectangle, Color color) {
55 | this.Draw(this.WhiteTexture, rectangle, color);
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/XNA/XNA/Forge/DataRegistry.cs:
--------------------------------------------------------------------------------
1 | using Forge.Collections;
2 | using Forge.Entities;
3 | using System;
4 | using System.Collections.Generic;
5 |
6 | namespace Forge.XNA {
7 | ///
8 | /// Specifies that the given type should be used as a custom data renderer.
9 | ///
10 | public class CustomDataRegistryAttribute : Attribute {
11 | ///
12 | /// The type of data that the annotated type renders.
13 | ///
14 | public Type DataType;
15 |
16 | public CustomDataRegistryAttribute(Type dataType) {
17 | DataType = dataType;
18 | }
19 | }
20 |
21 | public static class DataRegistry {
22 | ///
23 | /// Returns all types that have a CustomDataRegistryAttribute attribute.
24 | ///
25 | private static IEnumerable> GetTypesWithAttribute()
26 | where AttributeType : Attribute {
27 | foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) {
28 | foreach (Type type in assembly.GetTypes()) {
29 | object[] attributes = type.GetCustomAttributes(typeof(AttributeType), true);
30 | if (attributes.Length > 0) {
31 | yield return Forge.Utilities.Tuple.Create(type, (AttributeType)attributes[0]);
32 | }
33 | if (attributes.Length > 1) {
34 | throw new InvalidOperationException("Too many satisfying attributes");
35 | }
36 | }
37 | }
38 | }
39 |
40 | static DataRegistry() {
41 | foreach (var tuple in GetTypesWithAttribute()) {
42 | DataAccessor dataAccessor = new DataAccessor(tuple.Item2.DataType);
43 | int id = dataAccessor.Id;
44 |
45 | Type type = tuple.Item1;
46 | if (type.IsSubclassOf(typeof(DataRenderer))) {
47 | _renderers[id] = type;
48 | }
49 | }
50 | }
51 |
52 | ///
53 | /// Fast lookup from DataAccessor id to renderer type.
54 | ///
55 | private static SparseArray _renderers = new SparseArray();
56 |
57 | ///
58 | /// Attempts to create a new DataRenderer instance for the given type.
59 | ///
60 | public static bool TryGetRenderer(DataAccessor dataType, out DataRenderer renderer) {
61 | int id = dataType.Id;
62 |
63 | if (_renderers.ContainsKey(id)) {
64 | Type rendererType = _renderers[id];
65 | renderer = (DataRenderer)Activator.CreateInstance(rendererType);
66 | return true;
67 | }
68 |
69 | renderer = null;
70 | return false;
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/XNA/XNA/Forge/DataRenderer.cs:
--------------------------------------------------------------------------------
1 | using Forge.Collections;
2 | using Forge.Entities;
3 | using Forge.Utilities;
4 | using XNA.GameSample;
5 |
6 | namespace Forge.XNA {
7 | ///
8 | /// Base MonoBehavior type that can be used to implement custom data renderers. DataRenderers
9 | /// need to be annotated with a CustomDataRegistry attribute.
10 | ///
11 | public abstract class DataRenderer : IVisualizable {
12 | protected IQueryableEntity _entity;
13 |
14 | public void Initialize(IQueryableEntity entity) {
15 | _entity = entity;
16 | Visualizer.Instance.Add(this);
17 |
18 | OnInitialize();
19 | }
20 |
21 | public void Dispose() {
22 | Visualizer.Instance.Remove(this);
23 |
24 | OnDisposed();
25 | }
26 |
27 | ///
28 | /// Called when the renderer has been initialized. The entity that this renderer will
29 | /// operate on is populated under _entity.
30 | ///
31 | protected abstract void OnInitialize();
32 |
33 | ///
34 | /// Called when the renderer has been destroyed.
35 | ///
36 | protected abstract void OnDisposed();
37 |
38 | ///
39 | /// Called when the renderer should draw itself.
40 | ///
41 | public abstract void Draw(ExtendedSpriteBatch spriteBatch, float percentage);
42 |
43 | private UnorderedListMetadata _visualizationMetadata = new UnorderedListMetadata();
44 | public UnorderedListMetadata VisualizationMetadata {
45 | get { return _visualizationMetadata; }
46 | }
47 |
48 | protected static Vector2r Interpolate(Vector2r start, Vector2r end, float percentage) {
49 | return new Vector2r(
50 | Interpolate(start.X, end.X, percentage),
51 | Interpolate(start.Z, end.Z, percentage));
52 | }
53 |
54 | protected static Real Interpolate(Real start, Real end, float percentage) {
55 | Real delta = end - start;
56 | return start + (delta * percentage);
57 |
58 | //return (start * (1 - percentage)) + (end * percentage);
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/XNA/XNA/Forge/EntityContainerEventMonitor.cs:
--------------------------------------------------------------------------------
1 | using Forge.Collections;
2 | using Forge.Entities;
3 | using System;
4 | using System.Collections.Generic;
5 |
6 | namespace Forge.XNA {
7 | ///
8 | /// An IEventMonitor that manages the creation of EntityContainers and registering/removing data
9 | /// from those EntityContainers as the data state changes in entities.
10 | ///
11 | [EventMonitorAutomaticInstantiation]
12 | internal class EntityContainerEventMonitor : IEventMonitor {
13 | private SparseArray> _renderers = new SparseArray>();
14 |
15 | private SparseArray GetRenderers(IEntity entity) {
16 | SparseArray renderers;
17 |
18 | if (_renderers.TryGetValue(entity.UniqueId, out renderers) == false) {
19 | renderers = new SparseArray();
20 | _renderers[entity.UniqueId] = renderers;
21 | }
22 |
23 | return renderers;
24 | }
25 |
26 | private void OnDataAdded(AddedDataEvent addedData) {
27 | var accessor = new DataAccessor(addedData.AddedDataType);
28 |
29 | DataRenderer renderer;
30 | if (DataRegistry.TryGetRenderer(accessor, out renderer)) {
31 | SparseArray renderers = GetRenderers(addedData.Entity);
32 | renderer.Initialize(addedData.Entity);
33 | renderers[accessor.Id] = renderer;
34 | }
35 | }
36 |
37 | private void OnDataRemoved(RemovedDataEvent removedData) {
38 | SparseArray renderers;
39 | if (_renderers.TryGetValue(removedData.Entity.UniqueId, out renderers)) {
40 | var accessor = new DataAccessor(removedData.RemovedDataType);
41 |
42 | if (renderers.ContainsKey(accessor.Id)) {
43 | DataRenderer renderer = renderers[accessor.Id];
44 | renderers.Remove(accessor.Id);
45 |
46 | renderer.Dispose();
47 | }
48 | }
49 | }
50 |
51 | private void OnEntityCreated(IEntity entity) {
52 | _renderers[entity.UniqueId] = new SparseArray();
53 | }
54 |
55 | private void OnEntityDestroyed(IEntity entity) {
56 | SparseArray renderers;
57 | if (_renderers.TryGetValue(entity.UniqueId, out renderers)) {
58 |
59 | foreach (KeyValuePair renderer in renderers) {
60 | renderer.Value.Dispose();
61 | }
62 | }
63 |
64 | _renderers.Remove(entity.UniqueId);
65 | }
66 |
67 | public void Initialize(IEventNotifier notifier) {
68 | notifier.OnEvent(evnt => {
69 | OnEntityCreated(evnt.Entity);
70 | });
71 | notifier.OnEvent(evnt => {
72 | OnEntityDestroyed(evnt.Entity);
73 | });
74 | notifier.OnEvent(OnDataAdded);
75 | notifier.OnEvent(OnDataRemoved);
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/XNA/XNA/Forge/GameEngineManager.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Forge.Networking.AutomaticTurnGame;
3 | using Forge.Networking.Core;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using XNA.GameSample;
8 |
9 | namespace Forge.XNA {
10 | public class GameEngineManager {
11 | private IGameEngine _gameEngine;
12 | public NetworkContext _networkContext;
13 | public AutomaticTurnGame _turnGame;
14 |
15 | public IGameEngine Engine {
16 | get {
17 | return _gameEngine;
18 | }
19 | }
20 |
21 | public GameEngineManager(string snapshotJson, string templateJson, int targetUpdatesPerSecond) {
22 | // allocate the engine
23 | // TODO: examine the maybe, make sure the game actually loaded
24 | _gameEngine = GameEngineFactory.CreateEngine(snapshotJson, templateJson).Value;
25 |
26 | // create the event monitors
27 | CreateEventMonitors(_gameEngine.EventNotifier);
28 |
29 | _networkContext = NetworkContext.CreateServer(new Player("test-player"), "");
30 | _turnGame = new AutomaticTurnGame(_networkContext, targetUpdatesPerSecond);
31 | }
32 |
33 | public void SendCommand(IGameCommand command) {
34 | _turnGame.SendCommand(new List() { command });
35 | }
36 |
37 | public void Update(float elapsedMilliseconds) {
38 | // update network and the turn game
39 | _networkContext.Update();
40 | _turnGame.Update(elapsedMilliseconds);
41 |
42 | // try to update the game
43 | List commands;
44 | if (_turnGame.TryUpdate(out commands)) {
45 | _gameEngine.Update(commands.Cast()).Wait();
46 | _gameEngine.SynchronizeState().Wait();
47 | _gameEngine.DispatchEvents();
48 | }
49 | }
50 |
51 | public void Draw(ExtendedSpriteBatch spriteBatch) {
52 | Visualizer.Instance.Draw(spriteBatch, _turnGame);
53 | }
54 |
55 | ///
56 | /// Discovers allocatable event monitors, allocates them, and then initializes them with the
57 | /// given event notifier.
58 | ///
59 | /// The event notifier to initialize the monitors with
60 | private static void CreateEventMonitors(IEventNotifier eventNotifier) {
61 | var monitors =
62 | from assembly in AppDomain.CurrentDomain.GetAssemblies()
63 | from type in assembly.GetTypes()
64 | where typeof(IEventMonitor).IsAssignableFrom(type)
65 | where type.IsAbstract == false
66 | where type.IsInterface == false
67 | where type.IsClass == true
68 | where Attribute.IsDefined(type, typeof(EventMonitorAutomaticInstantiationAttribute))
69 | select (IEventMonitor)Activator.CreateInstance(type, /*nonPublic:*/ true);
70 |
71 | foreach (IEventMonitor monitor in monitors) {
72 | monitor.Initialize(eventNotifier);
73 | }
74 | }
75 | }
76 | }
--------------------------------------------------------------------------------
/XNA/XNA/Forge/IEventMonitor.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using System;
3 |
4 | namespace Forge.XNA {
5 | ///
6 | /// Annotation required by types which implement IEventMonitor signifying that they should be
7 | /// automatically instantiated.
8 | ///
9 | ///
10 | /// This attribute is not really necessary; instead, it is used because it greatly increases
11 | /// code-reading clarity.
12 | ///
13 | public sealed class EventMonitorAutomaticInstantiationAttribute : Attribute {
14 | }
15 |
16 | ///
17 | /// A type that can monitor IEvents that are coming out of the game engine. These are
18 | /// automatically discovered and instantiated when a new GameEngine is created.
19 | ///
20 | public interface IEventMonitor {
21 | ///
22 | /// Initialize the event monitor.
23 | ///
24 | /// The event notifier to register the monitor with.
25 | void Initialize(IEventNotifier notifier);
26 | }
27 | }
--------------------------------------------------------------------------------
/XNA/XNA/Forge/PrefabData.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Newtonsoft.Json;
3 |
4 | // PrefabData must always be in namespace Forge to retain compatibility across rendering engines.
5 | namespace Forge {
6 | ///
7 | /// Data that specifies that an IEntity should use a prefab as its base GameObject instead of an
8 | /// empty one.
9 | ///
10 | [JsonObject(MemberSerialization.OptIn)]
11 | public class PrefabData : Data.NonVersioned {
12 | ///
13 | /// The prefab to use for getting the base GameObject that will render the IEntity instance
14 | /// that this data instance is attached to.
15 | ///
16 | [JsonProperty("PrefabResourcePath")]
17 | public string PrefabResourcePath;
18 | }
19 | }
--------------------------------------------------------------------------------
/XNA/XNA/Forge/README.md:
--------------------------------------------------------------------------------
1 | ## Warning
2 |
3 | This file contains an early version of the future Forge XNA integration package. This code is still very unpolished. Sorry!
--------------------------------------------------------------------------------
/XNA/XNA/Forge/Visualizer.cs:
--------------------------------------------------------------------------------
1 | using Forge.Collections;
2 | using Forge.Networking.AutomaticTurnGame;
3 | using XNA.GameSample;
4 |
5 | namespace Forge.XNA {
6 | public class Visualizer {
7 | public static Visualizer Instance = new Visualizer();
8 |
9 | ///
10 | /// Should the visualizer interpolate between frames?
11 | ///
12 | public bool Interpolate = true;
13 |
14 | ///
15 | /// The list of items that need to be rendered (or rather, have their rendering states
16 | /// updated) .
17 | ///
18 | protected UnorderedList _visualizable = new UnorderedList();
19 |
20 | ///
21 | /// Add the given item to the list of items which will receive visualization events.
22 | ///
23 | /// The visualized item.
24 | public void Add(IVisualizable visualizable) {
25 | _visualizable.Add(visualizable, visualizable.VisualizationMetadata);
26 | }
27 |
28 | ///
29 | /// Removes the given item from the list of items that receive visualization events.
30 | ///
31 | /// The visualized item.
32 | public void Remove(IVisualizable visualizable) {
33 | _visualizable.Remove(visualizable, visualizable.VisualizationMetadata);
34 | }
35 |
36 | ///
37 | /// Draws every visualizable element.
38 | ///
39 | public void Draw(ExtendedSpriteBatch spriteBatch, AutomaticTurnGame game) {
40 | float interpolate = 1.0f;
41 | if (Interpolate) {
42 | interpolate = game.InterpolationPercentage;
43 | }
44 |
45 | foreach (IVisualizable visualizable in _visualizable) {
46 | visualizable.Draw(spriteBatch, interpolate);
47 | }
48 | }
49 | }
50 |
51 | ///
52 | /// Interface for objects which should visualize themselves from the entity system.
53 | ///
54 | public interface IVisualizable {
55 | ///
56 | /// Used by the visualizer for fast removes.
57 | ///
58 | UnorderedListMetadata VisualizationMetadata {
59 | get;
60 | }
61 |
62 | ///
63 | /// Draw the object.
64 | ///
65 | /// How much to interpolate from the previous state to the current
66 | /// state (a value between [0, 1]).
67 | void Draw(ExtendedSpriteBatch spriteBatch, float percentage);
68 | }
69 | }
--------------------------------------------------------------------------------
/XNA/XNA/Game.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/XNA/Game.ico
--------------------------------------------------------------------------------
/XNA/XNA/GameThumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/XNA/XNA/GameThumbnail.png
--------------------------------------------------------------------------------
/XNA/XNA/PositionRenderer.cs:
--------------------------------------------------------------------------------
1 | using Forge.Entities;
2 | using Forge.Utilities;
3 | using Forge.XNA;
4 | using GameSample;
5 | using Microsoft.Xna.Framework;
6 |
7 | namespace XNA.GameSample {
8 | ///
9 | /// Renders entities which have position data
10 | ///
11 | [CustomDataRegistry(typeof(PositionData))]
12 | internal class PositionRenderer : DataRenderer {
13 | protected override void OnInitialize() {
14 | }
15 |
16 | protected override void OnDisposed() {
17 | }
18 |
19 | public override void Draw(ExtendedSpriteBatch spriteBatch, float percentage) {
20 | Bound prev = _entity.Previous().Position;
21 | Bound curr = _entity.Current().Position;
22 |
23 | // some magic constants that center the rendering in the window; the sample doesn't
24 | // bother to properly setup a coordinate system
25 | Real scale = 25;
26 | Real zoffset = 250;
27 | Real xoffset = 350;
28 |
29 | int x = (Interpolate(prev.X, curr.X, percentage) * scale + xoffset).AsInt;
30 | int z = (Interpolate(-prev.Z, -curr.Z, percentage) * scale + zoffset).AsInt;
31 | int radius = (Interpolate(prev.Radius, curr.Radius, percentage) * scale).AsInt;
32 |
33 | Rectangle rectangle = new Rectangle(x - radius, z - radius, 2 * radius, 2 * radius);
34 | spriteBatch.DrawRectangle(rectangle, Color.BlanchedAlmond);
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/XNA/XNA/Program.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace XNA.GameSample {
3 | #if WINDOWS || XBOX
4 | internal static class Program {
5 | ///
6 | /// The main entry point for the application.
7 | ///
8 | private static void Main(string[] args) {
9 | using (var game = new XnaGame()) {
10 | game.Run();
11 | }
12 | }
13 | }
14 | #endif
15 | }
--------------------------------------------------------------------------------
/XNA/XNA/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("XNA")]
9 | [assembly: AssemblyProduct("XNA")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyCopyright("Copyright © 2014")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type. Only Windows
19 | // assemblies support COM.
20 | [assembly: ComVisible(false)]
21 |
22 | // On Windows, the following GUID is for the ID of the typelib if this
23 | // project is exposed to COM. On other platforms, it unique identifies the
24 | // title storage container when deploying this assembly to the device.
25 | [assembly: Guid("1af6f0d8-c40e-4c78-8171-59bc34e65a43")]
26 |
27 | // Version information for an assembly consists of the following four values:
28 | //
29 | // Major Version
30 | // Minor Version
31 | // Build Number
32 | // Revision
33 | //
34 | [assembly: AssemblyVersion("1.0.0.0")]
--------------------------------------------------------------------------------
/XNA/XNA/XNA.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {55DEEFF6-2A0C-4454-823D-F2BCD8644C5D}
5 | {6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
6 | Debug
7 | x86
8 | WinExe
9 | Properties
10 | XNA
11 | XNA
12 | v4.0
13 | Client
14 | v4.0
15 | Windows
16 | Reach
17 | 1d8da9b6-9fa2-4be1-b3db-6bbf0df03f6a
18 | Game
19 | Game.ico
20 | GameThumbnail.png
21 | publish\
22 | true
23 | Disk
24 | false
25 | Foreground
26 | 7
27 | Days
28 | false
29 | false
30 | true
31 | 0
32 | 1.0.0.%2a
33 | false
34 | false
35 | true
36 |
37 |
38 | true
39 | full
40 | false
41 | bin\x86\Debug
42 | DEBUG;TRACE;WINDOWS
43 | prompt
44 | 4
45 | true
46 | false
47 | x86
48 | false
49 |
50 |
51 | pdbonly
52 | true
53 | bin\x86\Release
54 | TRACE;WINDOWS
55 | prompt
56 | 4
57 | true
58 | false
59 | x86
60 | true
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | ..\DLLs\Forge.AllLibraries.dll
69 |
70 |
71 | ..\DLLs\Forge.Collections.dll
72 |
73 |
74 | ..\DLLs\Forge.Entities.dll
75 |
76 |
77 | ..\DLLs\Forge.Extensions.dll
78 |
79 |
80 | ..\DLLs\Forge.Networking.dll
81 |
82 |
83 | ..\DLLs\Forge.Utilities.dll
84 |
85 |
86 | ..\DLLs\Lidgren.Network.dll
87 |
88 |
89 | ..\DLLs\log4net.dll
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | ..\DLLs\Newtonsoft.Json.dll
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | true
123 |
124 |
125 |
126 |
127 | {a0314c4b-6cba-4d0f-b32f-24b450a0ddef}
128 | GameLogic
129 |
130 |
131 | XNAContent
132 | Content
133 |
134 |
135 |
136 |
137 | False
138 | Microsoft .NET Framework 4 Client Profile %28x86 and x64%29
139 | true
140 |
141 |
142 | False
143 | .NET Framework 3.5 SP1 Client Profile
144 | false
145 |
146 |
147 | False
148 | .NET Framework 3.5 SP1
149 | false
150 |
151 |
152 | False
153 | Windows Installer 3.1
154 | true
155 |
156 |
157 | False
158 | Microsoft XNA Framework Redistributable 4.0
159 | true
160 |
161 |
162 |
163 |
164 |
172 |
--------------------------------------------------------------------------------
/XNA/XNA/XNA.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | en-US
11 | false
12 |
13 |
--------------------------------------------------------------------------------
/XNA/XNA/XnaGame.cs:
--------------------------------------------------------------------------------
1 | using Forge.XNA;
2 | using GameSample;
3 | using Microsoft.Xna.Framework;
4 | using Microsoft.Xna.Framework.Graphics;
5 | using Microsoft.Xna.Framework.Input;
6 | using System.IO;
7 | using System.Reflection;
8 |
9 | namespace XNA.GameSample {
10 | public class XnaGame : Microsoft.Xna.Framework.Game {
11 | private ExtendedSpriteBatch _spriteBatch;
12 | private GameEngineManager _gameEngine;
13 | private GraphicsDeviceManager _graphics;
14 |
15 | public XnaGame() {
16 | Assembly.LoadFile(Path.GetFullPath("GameLogic.dll"));
17 | Content.RootDirectory = "Content";
18 |
19 | _graphics = new GraphicsDeviceManager(this);
20 | }
21 |
22 | ///
23 | /// Allows the game to perform any initialization it needs to before starting to run. This
24 | /// is where it can query for any required services and load any non-graphic related
25 | /// content. Calling base.Initialize will enumerate through any components and initialize
26 | /// them as well.
27 | ///
28 | protected override void Initialize() {
29 | base.Initialize();
30 |
31 | // get the JSON that the engine will be initialized with
32 | string snapshotJson = File.ReadAllText("../../../../../Assets/snapshot.json");
33 | string templateJson = File.ReadAllText("../../../../../Assets/templates.json");
34 |
35 | _gameEngine = new GameEngineManager(snapshotJson, templateJson, targetUpdatesPerSecond: 15);
36 | }
37 |
38 | ///
39 | /// LoadContent will be called once per game and is the place to load all of your content.
40 | ///
41 | protected override void LoadContent() {
42 | _spriteBatch = new ExtendedSpriteBatch(GraphicsDevice);
43 | }
44 |
45 | ///
46 | /// Allows the game to run logic such as updating the world, checking for collisions,
47 | /// gathering input, and playing audio.
48 | ///
49 | /// Provides a snapshot of timing values.
50 | protected override void Update(GameTime gameTime) {
51 | // Allows the game to exit
52 | if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
53 | this.Exit();
54 |
55 | if (Keyboard.GetState().IsKeyDown(Keys.D1)) {
56 | _gameEngine.SendCommand(new StartDestroyingInput());
57 | }
58 | if (Keyboard.GetState().IsKeyDown(Keys.D2)) {
59 | _gameEngine.SendCommand(new StopDestroyingInput());
60 | }
61 |
62 | // update with the elapsed seconds
63 | _gameEngine.Update(gameTime.ElapsedGameTime.Milliseconds);
64 |
65 | base.Update(gameTime);
66 | }
67 |
68 | ///
69 | /// This is called when the game should draw itself.
70 | ///
71 | /// Provides a snapshot of timing values.
72 | protected override void Draw(GameTime gameTime) {
73 | GraphicsDevice.Clear(Color.CornflowerBlue);
74 |
75 | _spriteBatch.Begin();
76 | _gameEngine.Draw(_spriteBatch);
77 | _spriteBatch.End();
78 |
79 | base.Draw(gameTime);
80 | }
81 | }
82 | }
--------------------------------------------------------------------------------
/XNA/XNAContent/XNAContent.contentproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {97E2A491-3907-46F5-A4D0-66781E1A1AC7}
5 | {96E2B04D-8817-42c6-938A-82C39BA4D311};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
6 | Debug
7 | x86
8 | Library
9 | Properties
10 | v4.0
11 | v4.0
12 | bin\$(Platform)\$(Configuration)
13 | Content
14 |
15 |
16 | x86
17 |
18 |
19 | x86
20 |
21 |
22 | XNAContent
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
40 |
--------------------------------------------------------------------------------
/demo_unity.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/demo_unity.gif
--------------------------------------------------------------------------------
/demo_xna.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacobdufault/forge-sample/6b18d3fb32a7a5c11df830f934995d0becdd45be/demo_xna.gif
--------------------------------------------------------------------------------