| Problem: | God Classes take on too much responsibility, |
| Solution: | Extract related islands of functionality into separate classes. Leave God classes that don't change often alone. |
| X-Axis: Effort to refactor |
| Y-Axis: Relative churn |
| Color: Priority of what to fix first |
| Circle size: Priority (Visual) of what to fix first |
| Class | Priority | Change Proneness Rank | Effort Rank | Most Recent Commit Date | Commit Count |
|---|---|---|---|---|---|
| Input.kt | 1 | 3 | 2 | 2/27/24, 12:50 PM | 5 |
| Body.java | 2 | 1 | 1 | 2/16/26, 5:41 PM | 1 |
| FXGL.kt | 3 | 4 | 4 | 1/9/25, 3:40 AM | 94 |
| World.java | 4 | 2 | 3 | 2/16/26, 5:41 PM | 1 |
| Problem: | Data Classes are dumb data holders that other classes rely on. |
| Solution: | Move the data/variable(s) to the same class as the operation. |
| X-Axis: Effort to refactor |
| Y-Axis: Relative churn |
| Color: Priority of what to fix first |
| Circle size: Priority (Visual) of what to fix first |
| Class | Priority | Change Proneness Rank | Effort Rank | Most Recent Commit Date | Commit Count |
|---|---|---|---|---|---|
| ReplicationEvent.kt | 1 | 16 | 8 | 2/1/25, 11:52 AM | 4 |
| TimeStep.java | 2 | 10 | 5 | 2/16/26, 5:41 PM | 1 |
| ContactVelocityConstraint.java | 3 | 11 | 6 | 2/16/26, 5:41 PM | 1 |
| ParticleGroupDef.java | 4 | 12 | 7 | 2/16/26, 5:41 PM | 1 |
| ParticleTypeInternal.java | 5 | 13 | 8 | 2/16/26, 5:41 PM | 1 |
| Definitions.kt | 6 | 14 | 9 | 2/16/26, 5:41 PM | 1 |
| JBoxSettings.java | 7 | 15 | 10 | 2/16/26, 5:41 PM | 1 |
| DungeonConfig.java | 8 | 9 | 5 | 2/16/26, 5:41 PM | 1 |
| RopeJoint.java | 9 | 6 | 3 | 2/16/26, 5:41 PM | 1 |
| ParticleDef.java | 10 | 7 | 4 | 2/16/26, 5:41 PM | 1 |
| TimeOfImpact.java | 11 | 8 | 5 | 2/16/26, 5:41 PM | 1 |
| MotorJoint.java | 12 | 3 | 1 | 2/16/26, 5:41 PM | 1 |
| DistanceJoint.java | 13 | 4 | 2 | 2/16/26, 5:41 PM | 1 |
| MouseJoint.java | 14 | 5 | 3 | 2/16/26, 5:41 PM | 1 |
| ObjData.kt | 15 | 2 | 5 | 3/18/23, 4:21 PM | 4 |
| Language.kt | 16 | 1 | 11 | 7/20/22, 3:22 PM | 3 |
| Problem: | Brain Classes are complex, lack cohesion, and have at least one Brain Method. |
| Solution: | Decompose Brain Methods into smaller methods. |
| X-Axis: Effort to refactor |
| Y-Axis: Relative churn |
| Color: Priority of what to fix first |
| Circle size: Priority (Visual) of what to fix first |
| Class | Priority | Change Proneness Rank | Effort Rank | Most Recent Commit Date | Commit Count |
|---|---|---|---|---|---|
| RevoluteJoint.java | 1 | 1 | 1 | 2/16/26, 5:41 PM | 1 |
| Problem: | Child class is large and often complex, but doesn't override or use many of the parent class's methods |
| Solution: | Do one or more of the following: - Extract the child class into a separate class. Move the methods that are used from the parent class into the child class. - Make unused protected members private in the parent class. - If a parent class has multiple children, move methods not used by all descendants to another class. |
| X-Axis: Effort to refactor |
| Y-Axis: Relative churn |
| Color: Priority of what to fix first |
| Circle size: Priority (Visual) of what to fix first |
| Class | Priority | Change Proneness Rank | Effort Rank | Most Recent Commit Date | Commit Count |
|---|---|---|---|---|---|
| MainWindow.kt | 1 | 38 | 3 | 2/24/24, 1:19 PM | 73 |
| AnimatedTexture.kt | 2 | 39 | 11 | 12/27/24, 3:14 PM | 8 |
| MultiplayerSample.java | 3 | 29 | 2 | 5/6/23, 8:22 AM | 4 |
| MainWindow.kt | 4 | 38 | 13 | 2/24/24, 1:19 PM | 73 |
| DialogFactoryService.java | 5 | 31 | 8 | 4/16/23, 3:37 AM | 4 |
| WebAPIService.kt | 6 | 40 | 17 | 1/24/25, 7:48 AM | 7 |
| FXGLApplication.kt | 7 | 42 | 19 | 12/17/25, 11:57 AM | 40 |
| DevService.kt | 8 | 33 | 13 | 1/23/21, 7:25 AM | 20 |
| FXGLAssetLoaderService.kt | 9 | 41 | 21 | 2/19/24, 12:45 PM | 35 |
| UIFactoryService.java | 10 | 32 | 13 | 3/22/24, 8:30 AM | 4 |
| FXGLMenu.kt | 11 | 35 | 16 | 4/2/21, 3:53 AM | 20 |
| GameScene.kt | 12 | 34 | 18 | 1/24/25, 4:15 PM | 19 |
| AudioPlayer.kt | 13 | 17 | 6 | 7/28/21, 11:35 AM | 3 |
| FXGLDefaultMenu.kt | 14 | 36 | 25 | 4/10/26, 5:42 AM | 22 |
| MultiplayerService.kt | 15 | 30 | 20 | 2/1/25, 11:52 AM | 4 |
| MotorJoint.java | 16 | 18 | 9 | 2/16/26, 5:41 PM | 1 |
| WheelJoint.java | 17 | 21 | 12 | 2/16/26, 5:41 PM | 1 |
| TraversableCellMoveComponent.java | 18 | 20 | 12 | 2/16/26, 5:41 PM | 1 |
| CircleComponent.java | 19 | 12 | 5 | 8/2/20, 4:14 AM | 5 |
| ActionComponent.java | 20 | 19 | 12 | 2/16/26, 5:41 PM | 1 |
| PhysicsComponent.java | 21 | 22 | 15 | 2/16/26, 5:41 PM | 1 |
| CellMoveComponent.java | 22 | 23 | 18 | 2/16/26, 5:41 PM | 1 |
| PhysicsCollisionSample.java | 23 | 5 | 1 | 5/29/21, 4:57 AM | 2 |
| Entity.java | 24 | 24 | 22 | 2/16/26, 5:41 PM | 1 |
| PrismaticJoint.java | 25 | 25 | 23 | 2/16/26, 5:41 PM | 1 |
| RevoluteJoint.java | 26 | 26 | 24 | 2/16/26, 5:41 PM | 1 |
| FileSystemService.kt | 27 | 8 | 7 | 7/28/21, 11:16 AM | 5 |
| AStarPathfinder.java | 28 | 27 | 26 | 2/16/26, 5:41 PM | 1 |
| DungeonGrid.java | 29 | 28 | 27 | 2/16/26, 5:41 PM | 1 |
| CutsceneScene.kt | 30 | 14 | 14 | 2/12/26, 4:07 PM | 1 |
| RobotComponent.java | 31 | 6 | 7 | 8/2/20, 4:14 AM | 4 |
| PhysicsPlaygroundSample.java | 32 | 11 | 12 | 3/25/23, 4:56 PM | 3 |
| ParticleShowcaseSample2.java | 33 | 2 | 4 | 5/24/20, 12:32 PM | 2 |
| SaveLoadService.kt | 34 | 10 | 12 | 1/9/25, 3:59 AM | 2 |
| Texture.kt | 35 | 13 | 15 | 12/18/24, 4:45 PM | 3 |
| PongApp.java | 36 | 3 | 8 | 4/23/21, 11:07 AM | 4 |
| BreakoutApp.java | 37 | 1 | 10 | 2/5/26, 3:30 PM | 2 |
| UnoSample.java | 38 | 9 | 18 | 3/30/23, 1:33 PM | 20 |
| CircuitBreakerMiniGame.kt | 39 | 15 | 24 | 2/12/26, 4:07 PM | 1 |
| DialogueScene.kt | 40 | 16 | 28 | 2/12/26, 4:07 PM | 1 |
| Prism.kt | 41 | 7 | 20 | 3/14/21, 5:31 AM | 2 |
| ProgressBar.java | 42 | 4 | 29 | 5/26/21, 10:56 AM | 1 |
| Problem: | Nearly identical code is found in multiple classes, leading to increased maintenance costs. |
| Solution: | - Move duplicated code in the same class into a new method. - Move duplicated code into a separate or parent class. - Move duplicated code in two child classes or in parent/child classes into the parent class. |
| X-Axis: Effort to refactor |
| Y-Axis: Relative churn |
| Color: Priority of what to fix first |
| Circle size: Priority (Visual) of what to fix first |
| Class | Priority | Change Proneness Rank | Effort Rank | Duplicate Partners | Most Recent Commit Date | Commit Count |
|---|---|---|---|---|---|---|
| ParticleSystem.java | 1 | 6 | 3 | callback(int,int,int) ↔ ParticleSystem$CreateParticleGroupCallback.callback(int,int,int) | 2/16/26, 5:41 PM | 1 |
| ParticleSystem.java | 2 | 6 | 3 | callback(int,int,int) ↔ ParticleSystem$JoinParticleGroupsCallback.callback(int,int,int) | 2/16/26, 5:41 PM | 1 |
| PulleyJoint.java | 3 | 4 | 2 | initVelocityConstraints(SolverData) ↔ WheelJoint.initVelocityConstraints(SolverData) | 2/16/26, 5:41 PM | 1 |
| RopeJoint.java | 4 | 3 | 2 | initVelocityConstraints(SolverData) ↔ WheelJoint.initVelocityConstraints(SolverData) | 2/16/26, 5:41 PM | 1 |
| SeparationFunction.java | 5 | 1 | 1 | findMinSeparation(int[],float) ↔ SeparationFunction.evaluate(int,int,float) | 2/16/26, 5:41 PM | 1 |
| WheelJoint.java | 6 | 2 | 2 | initVelocityConstraints(SolverData) ↔ RopeJoint.initVelocityConstraints(SolverData) initVelocityConstraints(SolverData) ↔ PulleyJoint.initVelocityConstraints(SolverData) |
2/16/26, 5:41 PM | 1 |
| Problem: | Method is long, complicated, and uses many variables. |
| Solution: | - Decompose the method into two or more smaller methods. - If part of the method relies heavily on an outside class, extract that functionality out of the calling method and move it to the called class. |
| X-Axis: Effort to refactor |
| Y-Axis: Relative churn |
| Color: Priority of what to fix first |
| Circle size: Priority (Visual) of what to fix first |
| Class | Method | Priority | Change Proneness Rank | Effort Rank | Most Recent Commit Date | Commit Count |
|---|---|---|---|---|---|---|
| MDIWindow.kt | initMovableWindow() | 1 | 8 | 5 | 12/8/23, 1:26 PM | 4 |
| RevoluteJoint.java | solveVelocityConstraints(SolverData) | 2 | 4 | 3 | 2/16/26, 5:41 PM | 1 |
| RevoluteJoint.java | initVelocityConstraints(SolverData) | 3 | 4 | 3 | 2/16/26, 5:41 PM | 1 |
| PrismaticJoint.java | initVelocityConstraints(SolverData) | 4 | 5 | 4 | 2/16/26, 5:41 PM | 1 |
| World.java | solveTOI(TimeStep) | 5 | 6 | 5 | 2/16/26, 5:41 PM | 1 |
| Collision.java | collide(Manifold,EdgeShape,Transform,PolygonShape,Transform) | 6 | 7 | 6 | 2/16/26, 5:41 PM | 1 |
| AStarPathfinder.java | findPath(T[][],T,T,NeighborDirection,AStarCell) | 7 | 1 | 1 | 2/16/26, 5:41 PM | 1 |
| VoronoiDiagram.java | generate(float) | 8 | 2 | 2 | 2/16/26, 5:41 PM | 1 |
| Problem: | Method is more interested in data in other classes than its own class. |
| Solution: | Move the method (or part of the method) to the class where it uses the most data. |
| X-Axis: Effort to refactor |
| Y-Axis: Relative churn |
| Color: Priority of what to fix first |
| Circle size: Priority (Visual) of what to fix first |
| Class | Method | Priority | Change Proneness Rank | Effort Rank | Most Recent Commit Date | Commit Count |
|---|---|---|---|---|---|---|
| FXGLApplication.kt | onInit() | 1 | 172 | 7 | 12/17/25, 11:57 AM | 40 |
| DialoguePane.kt | attachMouseHandler(InLinkPoint) | 2 | 164 | 4 | 12/13/23, 7:24 AM | 48 |
| Engine.kt | logVersion() | 3 | 173 | 22 | 1/24/25, 4:56 PM | 114 |
| DialoguePane.kt | disconnectOutLink(OutLinkPoint) | 4 | 164 | 15 | 12/13/23, 7:24 AM | 48 |
| FXGLApplication.kt | saveScreenshot() | 5 | 172 | 24 | 12/17/25, 11:57 AM | 40 |
| DialoguePane.kt | load(SerializableGraph) | 6 | 164 | 17 | 12/13/23, 7:24 AM | 48 |
| FXGLApplication.kt | initAndLoadLocalization() | 7 | 172 | 28 | 12/17/25, 11:57 AM | 40 |
| AnimatedTexture.kt | updateImage() | 8 | 151 | 8 | 12/27/24, 3:14 PM | 8 |
| FXGLApplication.kt | startImpl(MainWindow) | 9 | 172 | 29 | 12/17/25, 11:57 AM | 40 |
| FXGLDefaultMenu.kt | onUpdate(double) | 10 | 143 | 2 | 4/10/26, 5:42 AM | 22 |
| DialoguePane.kt | attachMouseHandler(NodeView) | 11 | 164 | 24 | 12/13/23, 7:24 AM | 48 |
| FXGLAssetLoaderService.kt | loadTexture(String,double,double) | 12 | 167 | 28 | 2/19/24, 12:45 PM | 35 |
| FXGLAssetLoaderService.kt | loadJSON(URL,Class<T>) | 13 | 167 | 28 | 2/19/24, 12:45 PM | 35 |
| FXGLApplication.kt | postServicesInit() | 14 | 172 | 34 | 12/17/25, 11:57 AM | 40 |
| HandTrackingService.kt | onHandInput(String) | 15 | 157 | 20 | 1/24/25, 7:58 AM | 4 |
| DialoguePane.kt | onAdded(DialogueNode,double,double) | 16 | 164 | 28 | 12/13/23, 7:24 AM | 48 |
| FXGLAssetLoaderService.kt | load(AssetType,LoadParams) | 17 | 167 | 31 | 2/19/24, 12:45 PM | 35 |
| ResourceExtractor.kt | extract(URL,String) | 18 | 154 | 19 | 12/26/24, 6:53 AM | 3 |
| DialoguePane.kt | onAdded(DialogueEdge) | 19 | 164 | 29 | 12/13/23, 7:24 AM | 48 |
| DialoguePane.kt | initGridListener(null) | 20 | 164 | 29 | 12/13/23, 7:24 AM | 48 |
| MainWindow.kt | show() | 21 | 150 | 20 | 2/24/24, 1:19 PM | 73 |
| ReflectionFunctionCaller.kt | invoke(String,Array<Any>) | 22 | 137 | 8 | 12/16/24, 12:32 PM | 3 |
| RPCService.kt | rpcRun(String,List<String>) | 23 | 156 | 29 | 1/24/25, 5:30 AM | 4 |
| FXGLDefaultMenu.kt | createOptionsMenu() | 24 | 143 | 17 | 4/10/26, 5:42 AM | 22 |
| MainUI.kt | openSaveAsDialog(MainUI$DialogueTab) | 25 | 153 | 27 | 12/28/23, 6:14 AM | 30 |
| ReflectionFunctionCaller.kt | call(String,Array<String>) | 26 | 137 | 12 | 12/16/24, 12:32 PM | 3 |
| FXGLDefaultMenu.kt | addNewInputBinding(UserAction,Trigger,null) | 27 | 143 | 19 | 4/10/26, 5:42 AM | 22 |
| MainWindow.kt | onStageResize() | 28 | 150 | 26 | 2/24/24, 1:19 PM | 73 |
| MainWindow.kt | onStageResize() | 29 | 150 | 26 | 2/24/24, 1:19 PM | 73 |
| MainWindow.kt | show() | 30 | 150 | 26 | 2/24/24, 1:19 PM | 73 |
| OSService.kt | startProcessTask(String,Map<String,String>,Consumer<String>) | 31 | 155 | 31 | 10/11/25, 8:20 AM | 3 |
| EntityBuilder.kt | from(SpawnData) | 32 | 152 | 30 | 7/22/22, 4:07 AM | 35 |
| MainWindow.kt | computeScaledDimensions() | 33 | 150 | 30 | 2/24/24, 1:19 PM | 73 |
| MainWindow.kt | createFXScene(null) | 34 | 150 | 31 | 2/24/24, 1:19 PM | 73 |
| MainWindow.kt | initStage() | 35 | 150 | 31 | 2/24/24, 1:19 PM | 73 |
| ReflectionFunctionCaller.kt | addFunctionCallTarget(Any) | 36 | 137 | 20 | 12/16/24, 12:32 PM | 3 |
| FXGLDefaultMenu.kt | createContentAchievements() | 37 | 143 | 26 | 4/10/26, 5:42 AM | 22 |
| TilesetLoader.kt | loadImage(String,String,int,int) | 38 | 120 | 5 | 2/16/26, 5:41 PM | 1 |
| FXGLDefaultMenu.kt | createMenuBodyMainMenu() | 39 | 143 | 31 | 4/10/26, 5:42 AM | 22 |
| FXGLDefaultMenu.kt | createMenuBodyGameMenu() | 40 | 143 | 34 | 4/10/26, 5:42 AM | 22 |
| Collision.java | computeEdgeSeparation(Collision$EPAxis) | 41 | 109 | 2 | 2/16/26, 5:41 PM | 1 |
| NodeViews.kt | addOptionView(Option) | 42 | 125 | 18 | 12/13/23, 7:24 AM | 19 |
| ContactSolver.java | storeImpulses() | 43 | 111 | 5 | 2/16/26, 5:41 PM | 1 |
| EntityInspector.kt | generateView(null) | 44 | 134 | 28 | 1/8/22, 3:48 AM | 8 |
| Collision.java | findMaxSeparation(Collision$EdgeResults,PolygonShape,Transform,PolygonShape,Transform) | 45 | 109 | 4 | 2/16/26, 5:41 PM | 1 |
| DevPane.kt | createContentDevVars() | 46 | 124 | 19 | 12/17/25, 11:57 AM | 21 |
| ObjModelLoader.kt | parseFaceVertex(String,ObjData) | 47 | 132 | 27 | 3/18/23, 4:21 PM | 6 |
| Collision.java | set(Collision$ClipVertex) | 48 | 109 | 6 | 2/16/26, 5:41 PM | 1 |
| ObjModelLoader.kt | parseUseMaterial(List<String>,ObjData) | 49 | 132 | 29 | 3/18/23, 4:21 PM | 6 |
| ObjModelLoader.kt | parseMaterialLib(List<String>,ObjData) | 50 | 132 | 31 | 3/18/23, 4:21 PM | 6 |
| TMXLevelLoader.kt | createTileLayerEntities(TiledMap,TilesetLoader) | 51 | 119 | 19 | 2/16/26, 5:41 PM | 1 |
| ObjModelLoader.kt | load(URL,Map<Function1<String,boolean>,Function2<List<String>,T,void>>,T) | 52 | 132 | 32 | 3/18/23, 4:21 PM | 6 |
| AnimationBuilder.kt | buildSequence(Array<?>}>) | 53 | 133 | 33 | 12/30/22, 4:29 PM | 7 |
| Input.kt | makeMouseEvent(null,{undefined}<>,double,double,InputModifier) | 54 | 127 | 28 | 2/27/24, 12:50 PM | 5 |
| Input.kt | onMouseEvent(MouseEventData) | 55 | 127 | 29 | 2/27/24, 12:50 PM | 5 |
| ObjModelLoader.kt | load(URL) | 56 | 132 | 35 | 3/18/23, 4:21 PM | 6 |
| DevPane.kt | createContentEntities() | 57 | 124 | 28 | 12/17/25, 11:57 AM | 21 |
| BoundingBoxComponent.kt | isOutside(double,double,double,double) | 58 | 112 | 17 | 2/16/26, 5:41 PM | 1 |
| MultiplayerService.kt | addInputReplicationReceiver({undefined}<>,Input) | 59 | 122 | 27 | 2/1/25, 11:52 AM | 4 |
| MultiplayerService.kt | setUpNewConnection(MultiplayerService$ConnectionData) | 60 | 122 | 30 | 2/1/25, 11:52 AM | 4 |
| TMXLevelLoader.kt | parseTextProperty(TiledObject,String,StartElement) | 61 | 119 | 28 | 2/16/26, 5:41 PM | 1 |
| TMXLevelLoader.kt | parseMapProperty(TiledMap,StartElement) | 62 | 119 | 28 | 2/16/26, 5:41 PM | 1 |
| TMXLevelLoader.kt | parseImage(Tile,StartElement) | 63 | 119 | 28 | 2/16/26, 5:41 PM | 1 |
| TMXLevelLoader.kt | parseObjectProperty(TiledObject,StartElement) | 64 | 119 | 28 | 2/16/26, 5:41 PM | 1 |
| TMXLevelLoader.kt | parseImage(Tileset,StartElement) | 65 | 119 | 28 | 2/16/26, 5:41 PM | 1 |
| ContactSolver.java | initialize(ContactPositionConstraint,Transform,Transform,int) | 66 | 111 | 21 | 2/16/26, 5:41 PM | 1 |
| TMXLevelLoader.kt | parseData(Layer,String,StartElement) | 67 | 119 | 29 | 2/16/26, 5:41 PM | 1 |
| TMXLevelLoader.kt | parseObjectPolyline(TiledObject,StartElement,boolean) | 68 | 119 | 29 | 2/16/26, 5:41 PM | 1 |
| TMXLevelLoader.kt | parseTileLayer(Layer,StartElement) | 69 | 119 | 30 | 2/16/26, 5:41 PM | 1 |
| Distance.java | writeCache(Distance$SimplexCache) | 70 | 94 | 6 | 2/16/26, 5:41 PM | 1 |
| TMXLevelLoader.kt | parseTileset(Tileset,StartElement) | 71 | 119 | 32 | 2/16/26, 5:41 PM | 1 |
| ContactSolver.java | warmStart() | 72 | 111 | 25 | 2/16/26, 5:41 PM | 1 |
| BoundingShape.kt | toBox2DShape(null,BoundingBoxComponent,null) | 73 | 101 | 16 | 2/16/26, 5:41 PM | 1 |
| TMXLevelLoader.kt | load(URL,GameWorld) | 74 | 119 | 35 | 2/16/26, 5:41 PM | 1 |
| BoundingBoxComponent.kt | range(double,double) | 75 | 112 | 29 | 2/16/26, 5:41 PM | 1 |
| TMXLevelLoader.kt | parseMap(TiledMap,StartElement) | 76 | 119 | 36 | 2/16/26, 5:41 PM | 1 |
| ContactManager.java | destroy(Contact) | 77 | 84 | 3 | 2/16/26, 5:41 PM | 1 |
| DynamicTree.java | moveProxy(int,AABB,Vec2) | 78 | 99 | 18 | 2/16/26, 5:41 PM | 1 |
| BoundingBoxComponent.kt | checkCollisionPAT(null,null,TransformComponent,TransformComponent) | 79 | 112 | 31 | 2/16/26, 5:41 PM | 1 |
| GoapPlanner.kt | plan(Set<GoapAction>,PropertyMap,PropertyMap) | 80 | 116 | 35 | 2/16/26, 5:41 PM | 1 |
| DFSPathfinder.kt | findPath(int,int,int,int,null,MutableList<T}>) | 81 | 118 | 37 | 2/16/26, 5:41 PM | 1 |
| TMXLevelLoader.kt | parseObject(Layer,TiledObject,StartElement) | 82 | 119 | 38 | 2/16/26, 5:41 PM | 1 |
| TilesetLoader.kt | loadView(int,boolean,boolean) | 83 | 120 | 39 | 2/16/26, 5:41 PM | 1 |
| ContactSolver.java | solveVelocityConstraints() | 84 | 111 | 31 | 2/16/26, 5:41 PM | 1 |
| GoapPlanner.kt | buildGraph(GoapPlanner$Node,MutableList<GoapPlanner$Node>,Set<GoapAction>,PropertyMap) | 85 | 116 | 36 | 2/16/26, 5:41 PM | 1 |
| Collision.java | clipSegmentToLine(Collision$ClipVertex[],Collision$ClipVertex[],Vec2,float,int) | 86 | 109 | 30 | 2/16/26, 5:41 PM | 1 |
| EdgeShape.java | computeDistanceToOut(Transform,Vec2,int,Vec2) | 87 | 83 | 5 | 2/16/26, 5:41 PM | 1 |
| Body.java | advance(float) | 88 | 86 | 9 | 2/16/26, 5:41 PM | 1 |
| CircleShape.java | computeDistanceToOut(Transform,Vec2,int,Vec2) | 89 | 92 | 16 | 2/16/26, 5:41 PM | 1 |
| CircleShape.java | computeMass(MassData,float) | 90 | 92 | 16 | 2/16/26, 5:41 PM | 1 |
| CircleShape.java | containsPoint(Transform,Vec2) | 91 | 92 | 16 | 2/16/26, 5:41 PM | 1 |
| Distance.java | readCache(Distance$SimplexCache,DistanceProxy,Transform,DistanceProxy,Transform) | 92 | 94 | 19 | 2/16/26, 5:41 PM | 1 |
| CircleShape.java | raycast(Unknown,Unknown,Transform,int) | 93 | 92 | 18 | 2/16/26, 5:41 PM | 1 |
| BoundingShape.kt | toBox2DShape(null,BoundingBoxComponent,null) | 94 | 101 | 27 | 2/16/26, 5:41 PM | 1 |
| BoundingShape.kt | polygon(DoubleArray) | 95 | 101 | 28 | 2/16/26, 5:41 PM | 1 |
| World.java | createJoint(Unknown) | 96 | 80 | 8 | 2/16/26, 5:41 PM | 1 |
| CollisionGrid.kt | insert(null) | 97 | 81 | 9 | 2/16/26, 5:41 PM | 1 |
| EdgeShape.java | computeAABB(AABB,Transform,int) | 98 | 83 | 11 | 2/16/26, 5:41 PM | 1 |
| ContactManager.java | addPair(Object,Object) | 99 | 84 | 12 | 2/16/26, 5:41 PM | 1 |
| TextLevelLoader.kt | load(URL,GameWorld) | 100 | 85 | 13 | 2/16/26, 5:41 PM | 1 |
| Body.java | synchronizeTransform() | 101 | 86 | 14 | 2/16/26, 5:41 PM | 1 |
| DynamicTree.java | createProxy(AABB,Object) | 102 | 99 | 27 | 2/16/26, 5:41 PM | 1 |
| Island.java | resetFlagsAndSynchronizeBroadphaseProxies() | 103 | 75 | 5 | 2/16/26, 5:41 PM | 1 |
| PolygonShape.java | computeDistanceToOut(Transform,Vec2,int,Vec2) | 104 | 70 | 2 | 2/16/26, 5:41 PM | 1 |
| PrismaticJoint.java | getJointSpeed() | 105 | 73 | 5 | 2/16/26, 5:41 PM | 1 |
| AchievementService.kt | bindToVars(PropertyMap) | 106 | 63 | 6 | 2/12/26, 4:07 PM | 1 |
| Inventory.kt | incrementQuantity(T,int) | 107 | 55 | 3 | 2/12/26, 4:07 PM | 1 |
| Inventory.kt | fill(int) | 108 | 55 | 6 | 2/12/26, 4:07 PM | 1 |
| PropertyMap.kt | remove(String) | 109 | 49 | 2 | 2/20/24, 12:07 PM | 23 |
| Shop.kt | buyFrom(Shop<T>,TradeItem<T>,int) | 110 | 53 | 7 | 2/12/26, 4:07 PM | 1 |
| CircuitBreakerMiniGame.kt | isPlayerCollidingWithWalls() | 111 | 62 | 17 | 2/12/26, 4:07 PM | 1 |
| CircuitBreakerMiniGame.kt | getMazeCell(null) | 112 | 62 | 17 | 2/12/26, 4:07 PM | 1 |
| Maze.kt | generateMaze(int,int) | 113 | 54 | 11 | 2/12/26, 4:07 PM | 1 |
| AchievementService.kt | onChange(double,double) | 114 | 63 | 20 | 2/12/26, 4:07 PM | 1 |
| AchievementService.kt | onChange(int,int) | 115 | 63 | 20 | 2/12/26, 4:07 PM | 1 |
| PropertyMap.kt | setValue(String,Any) | 116 | 49 | 7 | 2/20/24, 12:07 PM | 23 |
| InventoryListView.kt | updateItem(ItemStack<T>,boolean) | 117 | 58 | 18 | 2/12/26, 4:07 PM | 1 |
| CutsceneScene.kt | parseLine(String) | 118 | 61 | 21 | 2/12/26, 4:07 PM | 1 |
| MiniGameService.kt | startTriggerSequence(List<{undefined}>,double,Consumer<TriggerSequenceResult>) | 119 | 67 | 28 | 2/12/26, 4:07 PM | 1 |
| Inventory.kt | add(T,ItemConfig,int) | 120 | 55 | 17 | 2/12/26, 4:07 PM | 1 |
| MiniGameService.kt | startTriggerMash(KeyTrigger,double,double,Consumer<TriggerMashResult>) | 121 | 67 | 30 | 2/12/26, 4:07 PM | 1 |
| MiniGameService.kt | startCircuitBreaker(int,int,double,double,null,Consumer<CircuitBreakerResult>) | 122 | 67 | 30 | 2/12/26, 4:07 PM | 1 |
| DialogueScriptRunner.kt | callEqualityCheckFunction(String) | 123 | 68 | 31 | 2/12/26, 4:07 PM | 1 |
| IntroScene.kt | playAnim3() | 124 | 46 | 11 | 12/13/21, 12:31 PM | 10 |
| CircuitBreakerMiniGame.kt | onUpdate(double) | 125 | 62 | 27 | 2/12/26, 4:07 PM | 1 |
| AchievementService.kt | onChange(boolean,boolean) | 126 | 63 | 28 | 2/12/26, 4:07 PM | 1 |
| TradeListView.kt | updateItem(TradeItem<?>,boolean) | 127 | 65 | 30 | 2/12/26, 4:07 PM | 1 |
| Viewport.kt | bindToFit(double,double,Array<?}>) | 128 | 44 | 12 | 9/14/23, 8:36 AM | 10 |
| IntroScene.kt | playAnim2() | 129 | 46 | 16 | 12/13/21, 12:31 PM | 10 |
| HandLandmarksView.kt | update(Hand,HandViewConfig) | 130 | 39 | 10 | 1/23/25, 3:54 PM | 1 |
| FaceDetectionFromImageService.kt | onFaceInput(String) | 131 | 42 | 16 | 4/8/25, 3:14 AM | 1 |
| Logger.kt | doLog(String,String,LoggerLevel) | 132 | 31 | 7 | 7/17/21, 2:12 AM | 2 |
| HandTrackingFromImageService.kt | onHandInput(String) | 133 | 41 | 20 | 4/7/25, 5:39 AM | 1 |
| NetService.kt | onExecute() | 134 | 35 | 15 | 11/13/21, 2:51 PM | 3 |
| Console.kt | parse(String) | 135 | 40 | 20 | 8/26/22, 3:40 PM | 12 |
| IntroScene.kt | onUpdate(double) | 136 | 46 | 26 | 12/13/21, 12:31 PM | 10 |
| AnimatedValue.kt | animate(null,null,double,null) | 137 | 47 | 28 | 12/17/25, 11:57 AM | 4 |
| ErrorSubScene.kt | makeErrorMessage() | 138 | 33 | 20 | 2/24/25, 12:56 PM | 6 |
| Concurrent.kt | newThread(Runnable) | 139 | 28 | 16 | 9/5/20, 12:38 PM | 9 |
| Logger.kt | makeMessage(String,String,LoggerLevel) | 140 | 31 | 21 | 7/17/21, 2:12 AM | 2 |
| Texture.kt | deriveColor(double,double,double,double) | 141 | 38 | 28 | 12/18/24, 4:45 PM | 3 |
| UDPClient.kt | connect() | 142 | 12 | 3 | 3/28/21, 12:54 PM | 1 |
| Texture.kt | outline(null,int) | 143 | 38 | 29 | 12/18/24, 4:45 PM | 3 |
| ParticleShowcaseSample2.java | spawnParticles(Entity) | 144 | 9 | 1 | 5/24/20, 12:32 PM | 2 |
| UDPConnection.kt | sendUDP(ByteArray) | 145 | 13 | 5 | 3/28/21, 12:54 PM | 1 |
| PersistentStorageHandler.kt | onLoad(DataFile) | 146 | 36 | 29 | 11/21/21, 4:08 AM | 2 |
| PhysicsPlaygroundSample.java | onActionBegin() | 147 | 34 | 28 | 3/25/23, 4:56 PM | 3 |
| KeyInputBuilder.kt | run() | 148 | 22 | 17 | 3/19/21, 5:29 AM | 3 |
| Cuboid.kt | createMesh() | 149 | 16 | 12 | 5/4/21, 7:18 AM | 1 |
| SaveLoadService.kt | onLoad(DataFile) | 150 | 32 | 28 | 1/9/25, 3:59 AM | 2 |
| FileSystemAccess.kt | loadFileNames(String,boolean) | 151 | 26 | 27 | 4/13/20, 7:08 AM | 4 |
| FileSystemAccess.kt | loadLastModifiedFileName(String,boolean) | 152 | 26 | 27 | 4/13/20, 7:08 AM | 4 |
| FileSystemAccess.kt | loadDirectoryNames(String,boolean) | 153 | 26 | 27 | 4/13/20, 7:08 AM | 4 |
| FileSystemAccess.kt | loadFileNames(String,boolean,List<FileExtension>) | 154 | 26 | 29 | 4/13/20, 7:08 AM | 4 |
| Prism.kt | createMesh() | 155 | 29 | 32 | 3/14/21, 5:31 AM | 2 |
| InputCapture.kt | read(Bundle) | 156 | 17 | 23 | 5/26/21, 10:44 AM | 1 |
| Platform.kt | get() | 157 | 27 | 33 | 7/28/21, 11:16 AM | 6 |
| PerlinNoiseGenerator.kt | noise1D(double) | 158 | 7 | 14 | 3/25/21, 4:47 PM | 6 |
| VirtualInput.kt | createView(VirtualButton) | 159 | 20 | 28 | 5/26/21, 10:44 AM | 1 |
| SubSceneSampleApp.kt | initSettings(GameSettings) | 160 | 21 | 29 | 12/7/20, 4:30 AM | 2 |
| VirtualInput.kt | createView(VirtualButton) | 161 | 20 | 29 | 5/26/21, 10:44 AM | 1 |
| VirtualInput.kt | createView(VirtualButton) | 162 | 20 | 29 | 5/26/21, 10:44 AM | 1 |
| FileOutput.kt | cleanOldLogs(Path) | 163 | 11 | 22 | 3/28/21, 11:39 AM | 1 |
| NineSliceTextureBuilder.kt | adjustVertically(Texture,double) | 164 | 15 | 29 | 4/15/21, 11:48 AM | 1 |
| NineSliceTextureBuilder.kt | adjustHorizontally(Texture,double) | 165 | 15 | 29 | 4/15/21, 11:48 AM | 1 |
| LoadingScene.kt | updateItem(SaveFile,boolean) | 166 | 8 | 28 | 2/2/20, 7:52 AM | 2 |
| ZephTest.kt | initInput() | 167 | 6 | 27 | 7/4/20, 1:14 PM | 1 |
| ZephTest.kt | initSettings(GameSettings) | 168 | 6 | 28 | 7/4/20, 1:14 PM | 1 |
| DestructibleApp.kt | initGame() | 169 | 3 | 27 | 4/27/20, 12:55 PM | 1 |
| ImageMergerApp.kt | start() | 170 | 1 | 27 | 8/14/19, 11:38 AM | 1 |
| AASubdivision.kt | divide(null,int,int) | 171 | 4 | 30 | 4/27/20, 12:55 PM | 1 |
| Torus.kt | createMesh() | 172 | 10 | 36 | 3/14/21, 5:31 AM | 1 |
| DestructibleApp.kt | destroy(null) | 173 | 3 | 30 | 4/27/20, 12:55 PM | 1 |
| Problem: | Method calls too many methods from a few unrelated classes (often in a separate package). |
| Solution: | Move the calling method to a class more closely related to the other classes that the original method can call. |
| X-Axis: Effort to refactor |
| Y-Axis: Relative churn |
| Color: Priority of what to fix first |
| Circle size: Priority (Visual) of what to fix first |
| Class | Method | Priority | Change Proneness Rank | Effort Rank | Most Recent Commit Date | Commit Count |
|---|---|---|---|---|---|---|
| HandTrackingSample.java | initGame() | 1 | 30 | 10 | 3/26/24, 3:57 AM | 2 |
| ParticleSystem.java | solveRigid(TimeStep) | 2 | 27 | 9 | 2/16/26, 5:41 PM | 1 |
| ParticleSystem.java | reportFixture(Fixture) | 3 | 27 | 10 | 2/16/26, 5:41 PM | 1 |
| Island.java | solveTOI(TimeStep,int,int) | 4 | 28 | 12 | 2/16/26, 5:41 PM | 1 |
| RevoluteJoint.java | initVelocityConstraints(SolverData) | 5 | 22 | 7 | 2/16/26, 5:41 PM | 1 |
| PrismaticJoint.java | initVelocityConstraints(SolverData) | 6 | 26 | 13 | 2/16/26, 5:41 PM | 1 |
| ParticleSystem.java | reportFixture(Fixture) | 7 | 27 | 14 | 2/16/26, 5:41 PM | 1 |
| PrismaticJoint.java | solveVelocityConstraints(SolverData) | 8 | 26 | 15 | 2/16/26, 5:41 PM | 1 |
| World.java | solve(TimeStep) | 9 | 29 | 18 | 2/16/26, 5:41 PM | 1 |
| RevoluteJoint.java | solveVelocityConstraints(SolverData) | 10 | 22 | 13 | 2/16/26, 5:41 PM | 1 |
| World.java | solveTOI(TimeStep) | 11 | 29 | 21 | 2/16/26, 5:41 PM | 1 |
| PrismaticJoint.java | solvePositionConstraints(SolverData) | 12 | 26 | 19 | 2/16/26, 5:41 PM | 1 |
| ParticleSystem.java | createParticleGroup(ParticleGroupDef) | 13 | 27 | 20 | 2/16/26, 5:41 PM | 1 |
| Island.java | solve(TimeStep,Vec2,boolean) | 14 | 28 | 21 | 2/16/26, 5:41 PM | 1 |
| ContactManager.java | addPair(Object,Object) | 15 | 11 | 5 | 2/16/26, 5:41 PM | 1 |
| RevoluteJoint.java | solvePositionConstraints(SolverData) | 16 | 22 | 16 | 2/16/26, 5:41 PM | 1 |
| WheelJoint.java | initVelocityConstraints(SolverData) | 17 | 23 | 17 | 2/16/26, 5:41 PM | 1 |
| Distance.java | distance(Unknown,Distance$SimplexCache,Unknown) | 18 | 25 | 19 | 2/16/26, 5:41 PM | 1 |
| Collision.java | collide(Manifold,EdgeShape,Transform,PolygonShape,Transform) | 19 | 12 | 7 | 2/16/26, 5:41 PM | 1 |
| PolygonShape.java | setImpl(Vec2[],int) | 20 | 19 | 14 | 2/16/26, 5:41 PM | 1 |
| AStarPathfinder.java | findPath(T[][],T,T,NeighborDirection,AStarCell) | 21 | 15 | 11 | 2/16/26, 5:41 PM | 1 |
| HitBox.java | applyTransform(Unknown) | 22 | 4 | 1 | 2/16/26, 5:41 PM | 1 |
| Collision.java | collideEdgeAndCircle(Manifold,EdgeShape,Transform,CircleShape,Transform) | 23 | 12 | 9 | 2/16/26, 5:41 PM | 1 |
| Body.java | resetMassData() | 24 | 10 | 8 | 2/16/26, 5:41 PM | 1 |
| ContactManager.java | collide() | 25 | 11 | 9 | 2/16/26, 5:41 PM | 1 |
| VoronoiDiagram.java | generate(float) | 26 | 6 | 5 | 2/16/26, 5:41 PM | 1 |
| SeparationFunction.java | initialize(Distance$SimplexCache,DistanceProxy,Sweep,DistanceProxy,Sweep,float) | 27 | 7 | 6 | 2/16/26, 5:41 PM | 1 |
| ReflectionUtils.java | getCallingClass(Class<T>,String) | 28 | 2 | 2 | 9/15/20, 3:54 AM | 19 |
| CutsceneScene.kt | parseLine(String) | 29 | 3 | 3 | 2/12/26, 4:07 PM | 1 |
| DestructibleApp.kt | initGame() | 30 | 1 | 4 | 4/27/20, 12:55 PM | 1 |
| Problem: | Method calls a few methods in many classes |
| Solution: | Reduce the size of the calling method. Extract methods from the calling method into the target classes. |
| X-Axis: Effort to refactor |
| Y-Axis: Relative churn |
| Color: Priority of what to fix first |
| Circle size: Priority (Visual) of what to fix first |
| Class | Method | Priority | Change Proneness Rank | Effort Rank | Most Recent Commit Date | Commit Count |
|---|---|---|---|---|---|---|
| NodeInspectorPane.kt | generateView(DialogueNode) | 1 | 31 | 1 | 12/13/23, 7:24 AM | 6 |
| AnimationBuilder.kt | buildSequence(Array<?>}>) | 2 | 29 | 3 | 12/30/22, 4:29 PM | 7 |
| ObjModelLoader.kt | load(URL) | 3 | 28 | 5 | 3/18/23, 4:21 PM | 6 |
| DialoguePane.kt | onRemoved(DialogueEdge) | 4 | 32 | 9 | 12/13/23, 7:24 AM | 48 |
| OSService.kt | startProcessTask(String,Map<String,String>,Consumer<String>) | 5 | 30 | 10 | 10/11/25, 8:20 AM | 3 |
| ObjModelLoader.kt | load(URL,Map<Function1<String,boolean>,Function2<List<String>,T,void>>,T) | 6 | 28 | 11 | 3/18/23, 4:21 PM | 6 |
| Input.kt | handlePressed(null) | 7 | 26 | 10 | 2/27/24, 12:50 PM | 5 |
| ContactSolver.java | initializeVelocityConstraints() | 8 | 20 | 7 | 2/16/26, 5:41 PM | 1 |
| TilesetLoader.kt | loadView(String) | 9 | 25 | 12 | 2/16/26, 5:41 PM | 1 |
| ConstantVolumeJoint.java | ConstantVolumeJoint(World,ConstantVolumeJointDef) | 10 | 13 | 1 | 2/16/26, 5:41 PM | 1 |
| CollisionGrid.kt | insert(null) | 11 | 24 | 12 | 2/16/26, 5:41 PM | 1 |
| PhysicsWorld.java | notifyCollisions() | 12 | 12 | 1 | 2/16/26, 5:41 PM | 1 |
| TMXLevelLoader.kt | parse(InputStream) | 13 | 19 | 8 | 2/16/26, 5:41 PM | 1 |
| ContactSolver.java | init(ContactSolver$ContactSolverDef) | 14 | 20 | 9 | 2/16/26, 5:41 PM | 1 |
| TimeOfImpact.java | timeOfImpact(TimeOfImpact$TOIOutput,TimeOfImpact$TOIInput) | 15 | 21 | 10 | 2/16/26, 5:41 PM | 1 |
| Contact.java | update(ContactListener) | 16 | 16 | 6 | 2/16/26, 5:41 PM | 1 |
| Collision.java | collidePolygons(Manifold,PolygonShape,Transform,PolygonShape,Transform) | 17 | 17 | 7 | 2/16/26, 5:41 PM | 1 |
| GameWorld.kt | reset() | 18 | 22 | 12 | 2/16/26, 5:41 PM | 1 |
| TilesetLoader.kt | loadViewHex(String) | 19 | 25 | 15 | 2/16/26, 5:41 PM | 1 |
| DFSPathfinder.kt | findPath(int,int,int,int,null,MutableList<T}>) | 20 | 14 | 5 | 2/16/26, 5:41 PM | 1 |
| Body.java | destroyFixture(Fixture) | 21 | 15 | 6 | 2/16/26, 5:41 PM | 1 |
| ParticleSwarmSample.java | initGame() | 22 | 7 | 2 | 3/26/23, 4:25 PM | 1 |
| UnoSample.java | playCard(Hand,Entity,Runnable) | 23 | 8 | 3 | 3/30/23, 1:33 PM | 20 |
| DialogueScriptRunner.kt | callFunction(String) | 24 | 11 | 8 | 2/12/26, 4:07 PM | 1 |
| UDPClient.kt | connect() | 25 | 3 | 1 | 3/28/21, 12:54 PM | 1 |
| SenseAISample.java | onUpdate(double) | 26 | 6 | 4 | 3/21/24, 6:53 AM | 2 |
| FileOutput.kt | cleanOldLogs(Path) | 27 | 2 | 4 | 3/28/21, 11:39 AM | 1 |
| Endpoint.java | openTCPConnection(Socket,int,Class<T>) | 28 | 4 | 6 | 3/28/21, 12:54 PM | 1 |
| RobotComponent.java | tryMovingState(EntityState,int) | 29 | 5 | 9 | 8/2/20, 4:14 AM | 4 |
| MassUnitsRTSSample.java | initGame() | 30 | 10 | 14 | 12/27/24, 2:57 AM | 1 |
| NetService.kt | onExecute() | 31 | 9 | 14 | 11/13/21, 2:51 PM | 3 |
| ImageMergerApp.kt | start() | 32 | 1 | 13 | 8/14/19, 11:38 AM | 1 |
| Problem: | Method is called by many methods in many classes |
| Solution: | - Move the method closer to the calling classes (move the behavior closer to the data) if it is small. - If it is a large method, treat it as a Brain Method and decompose it into two or more smaller methods. |
| X-Axis: Effort to refactor |
| Y-Axis: Relative churn |
| Color: Priority of what to fix first |
| Circle size: Priority (Visual) of what to fix first |
| Class | Method | Priority | Change Proneness Rank | Effort Rank | Most Recent Commit Date | Commit Count |
|---|---|---|---|---|---|---|
| Input.kt | addAction(UserAction,InputSequence) | 1 | 49 | 4 | 2/27/24, 12:50 PM | 5 |
| Entity.java | translateX(double) | 2 | 40 | 1 | 2/16/26, 5:41 PM | 1 |
| Entity.java | translateY(double) | 3 | 40 | 3 | 2/16/26, 5:41 PM | 1 |
| IWorldPool.java | popRot() | 4 | 48 | 11 | 2/16/26, 5:41 PM | 1 |
| IWorldPool.java | pushRot(int) | 5 | 48 | 11 | 2/16/26, 5:41 PM | 1 |
| Entity.java | getTransformComponent() | 6 | 40 | 4 | 2/16/26, 5:41 PM | 1 |
| ParticleEmitter.java | setEmissionRate(double) | 7 | 39 | 8 | 2/16/26, 5:41 PM | 1 |
| Entity.java | getViewComponent() | 8 | 40 | 9 | 2/16/26, 5:41 PM | 1 |
| Body.java | getWorldPointToOut(Vec2,Vec2) | 9 | 44 | 13 | 2/16/26, 5:41 PM | 1 |
| Body.java | setAwake(boolean) | 10 | 44 | 13 | 2/16/26, 5:41 PM | 1 |
| PhysicsComponent.java | setLinearVelocity(double,double) | 11 | 31 | 1 | 2/16/26, 5:41 PM | 1 |
| PhysicsComponent.java | setOnPhysicsInitialized(Runnable) | 12 | 31 | 1 | 2/16/26, 5:41 PM | 1 |
| ParticleEmitter.java | setNumParticles(int) | 13 | 39 | 9 | 2/16/26, 5:41 PM | 1 |
| Entity.java | getPosition() | 14 | 40 | 10 | 2/16/26, 5:41 PM | 1 |
| Rotation.java | mulToOutUnsafe(Rotation,Vec2,Vec2) | 15 | 46 | 16 | 2/16/26, 5:41 PM | 1 |
| Fixture.java | getBody() | 16 | 32 | 3 | 2/16/26, 5:41 PM | 1 |
| World.java | getPool() | 17 | 38 | 9 | 2/16/26, 5:41 PM | 1 |
| ParticleEmitter.java | setSize(double,double) | 18 | 39 | 10 | 2/16/26, 5:41 PM | 1 |
| Rotation.java | set(float) | 19 | 46 | 17 | 2/16/26, 5:41 PM | 1 |
| IWorldPool.java | pushVec2(int) | 20 | 48 | 19 | 2/16/26, 5:41 PM | 1 |
| IWorldPool.java | popVec2() | 21 | 48 | 19 | 2/16/26, 5:41 PM | 1 |
| SceneService.kt | popSubScene() | 22 | 27 | 2 | 1/9/25, 3:40 AM | 9 |
| GameApplication.java | launch(String[]) | 23 | 50 | 25 | 1/9/25, 3:40 AM | 165 |
| SceneService.kt | pushSubScene(SubScene) | 24 | 27 | 3 | 1/9/25, 3:40 AM | 9 |
| FXGLMath.java | clamp(float,float,float) | 25 | 25 | 3 | 9/11/21, 2:29 PM | 37 |
| PropertyMap.kt | setValue(String,Any) | 26 | 28 | 6 | 2/20/24, 12:07 PM | 23 |
| FXGLMath.java | sqrtF(float) | 27 | 25 | 5 | 9/11/21, 2:29 PM | 37 |
| Animation.kt | onUpdate(double) | 28 | 21 | 3 | 11/28/21, 11:53 AM | 3 |
| Animation.kt | start() | 29 | 21 | 6 | 11/28/21, 11:53 AM | 3 |
| FXGLMath.java | abs(float) | 30 | 25 | 10 | 9/11/21, 2:29 PM | 37 |
| Vec2.java | length() | 31 | 16 | 4 | 3/18/21, 2:45 PM | 15 |
| FXGLMath.java | randomColor() | 32 | 25 | 15 | 9/11/21, 2:29 PM | 37 |
| Vec2.java | crossToOutUnsafe(float,Vec2,Vec2) | 33 | 16 | 7 | 3/18/21, 2:45 PM | 15 |
| Vec2.java | negateLocal() | 34 | 16 | 10 | 3/18/21, 2:45 PM | 15 |
| Logger.kt | warning(String,Throwable) | 35 | 19 | 14 | 7/17/21, 2:12 AM | 2 |
| Vec2.java | set(float,float) | 36 | 16 | 12 | 3/18/21, 2:45 PM | 15 |
| Vec2.java | getLengthAndNormalize() | 37 | 16 | 14 | 3/18/21, 2:45 PM | 15 |
| Vec2.java | dot(Vec2,Vec2) | 38 | 16 | 18 | 3/18/21, 2:45 PM | 15 |
| Vec2.java | cross(Vec2,Vec2) | 39 | 16 | 18 | 3/18/21, 2:45 PM | 15 |
| Vec2.java | setZero() | 40 | 16 | 18 | 3/18/21, 2:45 PM | 15 |
| Logger.kt | warning(String) | 41 | 19 | 22 | 7/17/21, 2:12 AM | 2 |
| Vec2.java | addLocal(Vec2) | 42 | 16 | 20 | 3/18/21, 2:45 PM | 15 |
| Vec2.java | mulLocal(double) | 43 | 16 | 20 | 3/18/21, 2:45 PM | 15 |
| Vec2.java | subLocal(Vec2) | 44 | 16 | 21 | 3/18/21, 2:45 PM | 15 |
| Logger.kt | debug(String) | 45 | 19 | 24 | 7/17/21, 2:12 AM | 2 |
| Vec2.java | set(Vec2) | 46 | 16 | 23 | 3/18/21, 2:45 PM | 15 |
| Bundle.kt | get(String) | 47 | 2 | 10 | 6/13/20, 5:03 AM | 5 |
| Cell.java | getX() | 48 | 4 | 12 | 3/4/21, 7:17 AM | 1 |
| Cell.java | getY() | 49 | 4 | 12 | 3/4/21, 7:17 AM | 1 |
| Bundle.kt | put(String,Serializable) | 50 | 2 | 13 | 6/13/20, 5:03 AM | 5 |
| Problem: | Sealed class has many permitted subtypes, making the hierarchy hard to maintain and exhaustive when expressions become unwieldy. |
| Solution: | Re-evaluate the domain model. Consider grouping subtypes into intermediate sealed classes or using a different pattern. |
| X-Axis: Effort to refactor |
| Y-Axis: Relative churn |
| Color: Priority of what to fix first |
| Circle size: Priority (Visual) of what to fix first |
| Class | Priority | Change Proneness Rank | Effort Rank | Most Recent Commit Date | Commit Count |
|---|---|---|---|---|---|
| FXGLAssetLoaderService.kt | 1 | 1 | 1 | 2/19/24, 12:45 PM | 35 |
| Problem: | Data class contains non-accessor methods with business logic, violating the data carrier principle. |
| Solution: | Move business logic to separate service classes. Keep data classes as pure data holders with only accessor methods. |
| X-Axis: Effort to refactor |
| Y-Axis: Relative churn |
| Color: Priority of what to fix first |
| Circle size: Priority (Visual) of what to fix first |
| Class | Priority | Change Proneness Rank | Effort Rank | Most Recent Commit Date | Commit Count |
|---|---|---|---|---|---|
| Images.kt | 1 | 5 | 1 | 4/7/25, 5:04 AM | 11 |
| Triggers.kt | 2 | 4 | 3 | 2/24/25, 3:41 PM | 5 |
| Triggers.kt | 3 | 4 | 3 | 2/24/25, 3:41 PM | 5 |
| Hand.kt | 4 | 2 | 2 | 1/23/25, 3:54 PM | 2 |
| Console.kt | 5 | 1 | 2 | 8/26/22, 3:40 PM | 12 |
| Cycle Name | Priority | Class Count | Relationship Count |
|---|---|---|---|
| Shape | 1 | 67 | 229 |
| SeparationFunction | 2 | 65 | 222 |
| TimeOfImpact$TOIInput | 3 | 59 | 199 |
| FixtureDef | 4 | 54 | 184 |
| ParticleGroupDef | 5 | 53 | 179 |
| BoundingShape | 6 | 52 | 174 |
| GenericCollision | 7 | 51 | 166 |
| DefaultWorldPool | 8 | 49 | 158 |
| Fixture$FixtureProxy | 9 | 46 | 155 |
| BroadPhase | 10 | 45 | 153 |
| QueryCallback | 11 | 44 | 148 |
| Body | 12 | 40 | 131 |
| Joint | 13 | 39 | 129 |
| ContactManager | 14 | 38 | 122 |
| ParticleGroup | 15 | 38 | 124 |
| Island | 16 | 37 | 117 |
| ParticleSystem$UpdateBodyContactsCallback | 17 | 37 | 121 |
| ParticleSystem$DestroyParticlesInShapeCallback | 18 | 35 | 104 |
| ParticleSystem$SolveCollisionCallback | 19 | 33 | 91 |
| LoadingScene | 20 | 32 | 81 |
| FXGLDefaultMenu$PressAnyKeyState | 21 | 31 | 78 |
| Viewport | 22 | 27 | 68 |
| BroadPhaseStrategy | 23 | 22 | 56 |
| ContactSolver | 24 | 22 | 72 |
| DynamicTreeNode | 25 | 20 | 51 |
| ContactSolver$ContactSolverDef | 26 | 19 | 48 |
| DefaultWorldPool$2 | 27 | 16 | 38 |
| FXGLVirtualJoystick | 28 | 13 | 30 |
| PrimaryStageWindow | 29 | 13 | 27 |
| Entity$ComponentMap | 30 | 12 | 24 |
| GameScene$MouseWarper | 31 | 12 | 24 |
| VirtualInput | 32 | 11 | 25 |
| AnimationBuilder | 33 | 9 | 28 |
| Console | 34 | 9 | 17 |
| ContactManager$ContactRegister | 35 | 7 | 19 |
| DevPane | 36 | 7 | 13 |
| CollisionResult | 37 | 5 | 10 |
| EntityPool | 38 | 5 | 9 |
| EmbeddedPaneWindow | 39 | 4 | 5 |
| NodeView | 40 | 4 | 9 |
| Array$ArrayIterator | 41 | 3 | 4 |
| AnimatedTexture | 42 | 3 | 5 |
| PhysicsComponent | 43 | 3 | 4 |
| UnoSample | 44 | 2 | 2 |
| PulleyJoint | 45 | 2 | 2 |
| WheelJoint | 46 | 2 | 2 |
| Vec2 | 47 | 2 | 2 |
| RevoluteJoint | 48 | 2 | 2 |
| MouseTrigger$Companion | 49 | 2 | 2 |
| RopeJointDef | 50 | 2 | 2 |
| Subscriber | 51 | 2 | 2 |
| Connection | 52 | 2 | 2 |
| Logger | 53 | 2 | 2 |
| WeldJoint | 54 | 2 | 2 |
| MouseJointDef | 55 | 2 | 2 |
| FrictionJointDef | 56 | 2 | 2 |
| DistanceJointDef | 57 | 2 | 2 |
| PrismaticJointDef | 58 | 2 | 2 |
| ConstantVolumeJoint | 59 | 2 | 2 |
| MotorJointDef | 60 | 2 | 2 |
| PropertyMap | 61 | 2 | 2 |
| GearJointDef | 62 | 2 | 2 |
| Classes | Relationships |
|---|---|
| Shape* | Shape → AABB : 1 |
| AABB | AABB → IWorldPool : 11* |
| IWorldPool* | IWorldPool → Contact : 7* IWorldPool → Collision : 1 IWorldPool → TimeOfImpact : 1* IWorldPool → Distance : 1 |
| Distance | Distance → Distance$Simplex : 10 Distance → DistanceProxy : 8 |
| DistanceProxy | DistanceProxy → Shape : 6 DistanceProxy → CircleShape : 2 DistanceProxy → PolygonShape : 3 DistanceProxy → ChainShape : 7 DistanceProxy → EdgeShape : 2 |
| EdgeShape | EdgeShape → Shape : 9 EdgeShape → AABB : 1 |
| ChainShape | ChainShape → Shape : 5 ChainShape → AABB : 1 ChainShape → EdgeShape : 7 |
| PolygonShape | PolygonShape → Shape : 9 PolygonShape → AABB : 1 |
| CircleShape | CircleShape → Shape : 17 CircleShape → AABB : 1 |
| Distance$Simplex | Distance$Simplex → DistanceProxy : 6 |
| TimeOfImpact | TimeOfImpact → IWorldPool : 3 TimeOfImpact → Distance : 1 TimeOfImpact → DistanceProxy : 4 TimeOfImpact → SeparationFunction : 6 TimeOfImpact → TimeOfImpact$TOIInput : 1 |
| TimeOfImpact$TOIInput | TimeOfImpact$TOIInput → Shape : 2 TimeOfImpact$TOIInput → DistanceProxy : 6 |
| SeparationFunction | SeparationFunction → DistanceProxy : 24 |
| Collision* | Collision → Shape : 8 Collision → EdgeShape : 2 Collision → PolygonShape : 16 Collision → CircleShape : 4 Collision → Collision$EPCollider : 3 |
| Collision$EPCollider | Collision$EPCollider → EdgeShape : 1 Collision$EPCollider → PolygonShape : 3 Collision$EPCollider → Collision : 2* |
| Contact* | Contact → Shape : 2 Contact → IWorldPool : 2 Contact → ContactEdge : 6 Contact → Fixture : 20* Contact → ContactListener : 4 Contact → Body : 6* Contact → GenericCollision : 1 |
| GenericCollision | GenericCollision → Shape : 2 GenericCollision → IWorldPool : 2 GenericCollision → Distance : 1 |
| Body* | Body → Shape : 1 Body → IWorldPool : 7 Body → Contact : 3 Body → World : 25* Body → Fixture : 28 Body → JointEdge : 5* Body → ContactEdge : 5 Body → BroadPhase : 2 Body → FixtureDef : 2 Body → ContactManager : 2 Body → DestructionListener : 2 Body → Joint : 1* |
| Joint | Joint → IWorldPool : 2 Joint → Body : 4 Joint → World : 1* Joint → JointDef : 2 Joint → JointEdge : 4 |
| JointEdge | JointEdge → Body : 1 JointEdge → Joint : 1* |
| JointDef | JointDef → Body : 2 JointDef → World : 1* |
| World* | World → Shape : 2 World → AABB : 3 World → IWorldPool : 3 World → TimeOfImpact : 1 World → TimeOfImpact$TOIInput : 5 World → Contact : 24 World → Body : 82 World → Joint : 22 World → JointEdge : 1 World → JointDef : 1 World → ContactManager : 13 World → ParticleSystem : 32 World → DestructionListener : 3 World → ParticleDestructionListener : 3 World → DefaultWorldPool : 1 World → DynamicTree : 1 World → DefaultBroadPhaseBuffer : 1 World → ContactEdge : 3 World → Island : 23 World → Fixture : 16 World → World$WorldQueryWrapper : 2 World → QueryCallback : 2 World → BroadPhase : 2 World → World$WorldRayCastWrapper : 2 World → RayCastCallback : 2 World → ParticleGroupDef : 1 World → ParticleGroup : 7 World → ParticleBodyContact : 1 World → ContactFilter : 1 World → ContactListener : 1 |
| ContactListener | ContactListener → Contact : 4* |
| ContactFilter | ContactFilter → Fixture : 4 |
| Fixture* | Fixture → Shape : 12 Fixture → AABB : 8 Fixture → Contact : 4 Fixture → Body : 7* Fixture → World : 2* Fixture → HitBox : 3 Fixture → Fixture$FixtureProxy : 6 Fixture → FixtureDef : 1 Fixture → ContactEdge : 1 Fixture → BroadPhase : 8 |
| BroadPhase | BroadPhase → AABB : 3 |
| ContactEdge | ContactEdge → Contact : 1* ContactEdge → Body : 1* |
| FixtureDef | FixtureDef → Shape : 2 |
| Fixture$FixtureProxy | Fixture$FixtureProxy → AABB : 2 Fixture$FixtureProxy → Fixture : 1* |
| HitBox | HitBox → Shape : 1 HitBox → BoundingShape : 5* HitBox → SAT : 2* |
| SAT | SAT → HitBox : 2 |
| BoundingShape* | BoundingShape → HitBox : 1 BoundingShape → BoundingBoxComponent : 1 |
| BoundingBoxComponent | BoundingBoxComponent → HitBox : 5 BoundingBoxComponent → CollisionResult : 2 BoundingBoxComponent → Box3DShapeData : 4* |
| Box3DShapeData | Box3DShapeData → HitBox : 1 Box3DShapeData → BoundingShape : 1 Box3DShapeData → BoundingBoxComponent : 1 |
| CollisionResult | CollisionResult → HitBox : 6 |
| ParticleBodyContact | ParticleBodyContact → Body : 1 |
| ParticleGroup | ParticleGroup → ParticleSystem : 2* |
| ParticleSystem* | ParticleSystem → Shape : 7 ParticleSystem → AABB : 10 ParticleSystem → Body : 16 ParticleSystem → World : 10* ParticleSystem → ParticleBodyContact : 10 ParticleSystem → ParticleGroup : 25 ParticleSystem → ParticleSystem$DestroyParticlesInShapeCallback : 3* ParticleSystem → ParticleSystem$CreateParticleGroupCallback : 2* ParticleSystem → ParticleGroupDef : 19 ParticleSystem → ParticleSystem$JoinParticleGroupsCallback : 2* ParticleSystem → ParticleDestructionListener : 3 ParticleSystem → ParticleSystem$UpdateBodyContactsCallback : 2 ParticleSystem → ParticleSystem$SolveCollisionCallback : 2* |
| ParticleSystem$SolveCollisionCallback | ParticleSystem$SolveCollisionCallback → Shape : 2 ParticleSystem$SolveCollisionCallback → AABB : 1 ParticleSystem$SolveCollisionCallback → Body : 2 ParticleSystem$SolveCollisionCallback → Fixture : 6 ParticleSystem$SolveCollisionCallback → ParticleSystem : 6 ParticleSystem$SolveCollisionCallback → QueryCallback : 1 |
| QueryCallback | QueryCallback → Fixture : 1 |
| ParticleSystem$UpdateBodyContactsCallback | ParticleSystem$UpdateBodyContactsCallback → Shape : 2 ParticleSystem$UpdateBodyContactsCallback → AABB : 1 ParticleSystem$UpdateBodyContactsCallback → Body : 5 ParticleSystem$UpdateBodyContactsCallback → Fixture : 6 ParticleSystem$UpdateBodyContactsCallback → ParticleBodyContact : 1 ParticleSystem$UpdateBodyContactsCallback → ParticleSystem : 7* ParticleSystem$UpdateBodyContactsCallback → QueryCallback : 1 |
| ParticleDestructionListener | ParticleDestructionListener → ParticleGroup : 1 |
| ParticleSystem$JoinParticleGroupsCallback | ParticleSystem$JoinParticleGroupsCallback → ParticleGroup : 2 ParticleSystem$JoinParticleGroupsCallback → ParticleSystem : 2 |
| ParticleGroupDef | ParticleGroupDef → Shape : 3 |
| ParticleSystem$CreateParticleGroupCallback | ParticleSystem$CreateParticleGroupCallback → ParticleSystem : 2 ParticleSystem$CreateParticleGroupCallback → ParticleGroupDef : 2 |
| ParticleSystem$DestroyParticlesInShapeCallback | ParticleSystem$DestroyParticlesInShapeCallback → Shape : 3 ParticleSystem$DestroyParticlesInShapeCallback → ParticleSystem : 3 |
| RayCastCallback | RayCastCallback → Fixture : 1 |
| World$WorldRayCastWrapper | World$WorldRayCastWrapper → Fixture : 2 World$WorldRayCastWrapper → BroadPhase : 2 World$WorldRayCastWrapper → Fixture$FixtureProxy : 2 World$WorldRayCastWrapper → RayCastCallback : 2 |
| World$WorldQueryWrapper | World$WorldQueryWrapper → BroadPhase : 2 World$WorldQueryWrapper → Fixture$FixtureProxy : 2 World$WorldQueryWrapper → QueryCallback : 2 |
| Island | Island → Contact : 4 Island → Body : 46 Island → Joint : 6 Island → ContactListener : 3 Island → ContactEdge : 1 Island → ContactSolver : 16 Island → ContactSolver$ContactSolverDef : 4 |
| ContactSolver$ContactSolverDef | ContactSolver$ContactSolverDef → Contact : 1 |
| ContactSolver | ContactSolver → Shape : 4 ContactSolver → Contact : 8 ContactSolver → Body : 2 ContactSolver → Fixture : 6 ContactSolver → ContactSolver$ContactSolverDef : 1 |
| DefaultBroadPhaseBuffer | DefaultBroadPhaseBuffer → AABB : 7 DefaultBroadPhaseBuffer → BroadPhase : 1 DefaultBroadPhaseBuffer → BroadPhaseStrategy : 14 |
| BroadPhaseStrategy | BroadPhaseStrategy → AABB : 4 |
| DynamicTree | DynamicTree → AABB : 39 DynamicTree → BroadPhaseStrategy : 1 DynamicTree → DynamicTreeNode : 53 |
| DynamicTreeNode | DynamicTreeNode → AABB : 2 |
| DefaultWorldPool | DefaultWorldPool → IWorldPool : 2 DefaultWorldPool → Distance : 3 DefaultWorldPool → TimeOfImpact : 3 DefaultWorldPool → Collision : 3 DefaultWorldPool → Contact : 14 DefaultWorldPool → DefaultWorldPool$1 : 1 DefaultWorldPool → DefaultWorldPool$2 : 1 DefaultWorldPool → DefaultWorldPool$3 : 1 DefaultWorldPool → DefaultWorldPool$4 : 1 DefaultWorldPool → DefaultWorldPool$5 : 1 DefaultWorldPool → DefaultWorldPool$6 : 1 DefaultWorldPool → DefaultWorldPool$7 : 1 |
| DefaultWorldPool$7 | DefaultWorldPool$7 → Contact : 2 |
| DefaultWorldPool$6 | DefaultWorldPool$6 → Contact : 2 |
| DefaultWorldPool$5 | DefaultWorldPool$5 → Contact : 2 |
| DefaultWorldPool$4 | DefaultWorldPool$4 → Contact : 2 |
| DefaultWorldPool$3 | DefaultWorldPool$3 → Contact : 2 |
| DefaultWorldPool$2 | DefaultWorldPool$2 → Contact : 2 |
| DefaultWorldPool$1 | DefaultWorldPool$1 → Contact : 2 |
| DestructionListener | DestructionListener → Joint : 1* DestructionListener → Fixture : 1 |
| ContactManager | ContactManager → IWorldPool : 9 ContactManager → Contact : 36 ContactManager → Body : 17* ContactManager → ContactListener : 4 ContactManager → ContactFilter : 5 ContactManager → Fixture : 30 ContactManager → BroadPhase : 4 ContactManager → ContactEdge : 1 ContactManager → Fixture$FixtureProxy : 4 ContactManager → ContactManager$ContactRegister : 5 |
| ContactManager$ContactRegister | ContactManager$ContactRegister → Contact : 2 |